
All major sites have long switched to the https protocol. The trend continues, and many of our customers want their site to work over a secure protocol. And if you are developing a backend for a mobile application, then https is required. For example, Apple requires that the server communicate with the application using a secure protocol. This requirement has
been introduced since the end of 2016 .
On production there are no problems with certificates. Typically, a hosting provider provides a convenient interface for connecting a certificate. Issuing a certificate is also not difficult. But while working on a project, each developer must take care of the certificate himself.
In this article, I will explain how to issue a self-signed SSL certificate and make the browser trust it.
To issue a certificate for your local domain, you need a root certificate. All other certificates will be issued based on it. Yes, for each new top level domain you need to issue your certificate. Getting a root certificate is easy.
First form the private key:
')
openssl genrsa -out rootCA.key 2048
Then the certificate itself:
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem
You will need to enter a
country ,
city ,
company , etc. As a result, we get two files:
rootCA.key and
rootCA.pemGo to the main issue of the self-signed certificate. As with the root, these are two commands. But the parameters of the teams will be much more. And we need an auxiliary configuration file. Therefore, we arrange all this in the form of a bash script
create_certificate_for_domain.shThe first parameter is required, we will display a small instruction for the user.
if [ -z "$1" ] then echo "Please supply a subdomain to create a certificate for"; echo "eg mysite.localhost" exit; fi
Create a new private key if it does not exist or use the existing one:
if [ -f device.key ]; then KEY_OPT="-key" else KEY_OPT="-keyout" fi
We will ask the user for the domain name. Add the ability to set a “common name” (it is used when generating a certificate):
DOMAIN=$1 COMMON_NAME=${2:-$1}
In order not to answer questions online, we will form a line with answers. And set the time of validity of the certificate:
SUBJECT="/C=CA/ST=None/L=NB/O=None/CN=$COMMON_NAME" NUM_OF_DAYS=999
The SUBJECT variable lists all the same questions that were asked when creating the root certificate (
country ,
city ,
company , etc.). All values except CN can be changed at your discretion.
Create a csr file (Certificate Signing Request) based on the key. You can
read more about the certificate request file
in this article .
openssl req -new -newkey rsa:2048 -sha256 -nodes $KEY_OPT device.key -subj "$SUBJECT" -out device.csr
We form the certificate file . For this we need an auxiliary file with settings. In this file we will write the domains for which the certificate will be valid and some other settings. Let's call it
v3.ext . I draw your attention that this is a separate file, and not part of the bash script.
authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = %%DOMAIN%% DNS.2 = *.%%DOMAIN%%
Yes, right, our certificate will be valid for the main domain, as well as for all subdomains. Save the above lines to the
v3.ext file
We return to our bash script. Based on the auxiliary file
v3.ext we create a temporary file indicating our domain:
cat v3.ext | sed s/%%DOMAIN%%/$COMMON_NAME/g > /tmp/__v3.ext
We issue a certificate:
openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days $NUM_OF_DAYS -sha256 -extfile /tmp/__v3.ext
Rename the certificate and delete the temporary file:
mv device.csr $DOMAIN.csr cp device.crt $DOMAIN.crt
The script is ready. Run it:
./create_certificate_for_domain.sh mysite.localhost
We
get two files:
mysite.localhost.crt and
device.keyNow you need to tell the web server the paths to these files. For example, nginx will look like this:

Launch the browser, open
https: //mysite.localhost and see:

The browser does not trust this certificate. How to be?
It is necessary to note the certificate issued by us as Trusted. On Linux (Ubuntu and, probably, other Debian-based distributions), this can be done through the browser itself. On Mac OS X, this can be done through the Keychain Access application. Run the application and drag the file
mysite.localhost.crt into the window. Then open the added file and select Always Trust:

We update the page in the browser and:

Success! The browser trusts our certificate.
The certificate can be shared with other developers so that they add it to themselves. And if you use Docker, you can save the certificate there. This is how it is implemented in all our projects.
Share in comments, do you use https for local development?
Maxim Kovtun,
Head of Development