Add SSL to Nginx
Nginx is a versatile tool that has many usages, can be used as a reverse proxy, load balancer etc.
A common usage is to handle the SSL traffic in front of applications. Thus instead of handling SSL from your application layer you can have nginx in front.
In our example we shall generate the certificates and make Nginx do the tls termination. I will use self signed certificates for our example. The certificates will be self signed and have a CA authority which shall help us on another example. In a real world example the certificate authority is something external like Let’s Encrypt or GlobalSign. By creating our own certificate authority we will be able to simulate them
openssl genrsa -des3 -out ca.key 4096 #Remove passphrase for example purposes openssl rsa -in ca.key -out ca.key openssl req -new -x509 -days 3650 -key ca.key -subj "/CN=*.your.hostname" -out ca.crt
Now that we have a certificate authority lets create the server key and certificate. First step is to create the key.
printf test > passphrase.txt openssl genrsa -des3 -passout file:passphrase.txt -out server.key 1024 openssl req -new -passin file:passphrase.txt -key server.key -subj "/CN=*.your.hostname" -out server.csr
The result is to have a private key and a certificate signing request (csr). The csr needs to be signed by a certificate authority. The certificate authority in our case would be the one we create previously.Take note that we did not remove the password from the server.key. It was done on purpose to display how to load on Nginx, if you don’t want to tackle it remove it as shown at the certificate authority example.
So let’s sign the csr.
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
Now we are ready to install them on Nginx. We shall use docker on this one.
This is how the nginx configuration should. What we shall do is to mount the files we generated previously to our docker image.
server { listen 443 ssl; server_name test.your.hostname; ssl_password_file /etc/nginx/certs/password ssl_certificate /etc/nginx/certs/tls.crt; ssl_certificate_key /etc/nginx/certs/tls.key; location / { error_log /var/log/front_end_errors.log; } location = /swagger.json { proxy_pass https://petstore.swagger.io/v2/swagger.json; } }
Our docker command mounting the files.
docker run --rm --name some-nginx -p 443:443 -v $(pwd)/certs/server.key:/etc/nginx/certs/tls.key -v $(pwd)/certs/server.crt:/etc/nginx/certs/tls.crt -v $(pwd)/nginx.conf:/etc/nginx/conf.d/nginx.conf -v $(pwd)/certs/passphrase.txt:/etc/nginx/certs/password nginx
Since this is a self signed certificate it cannot be accessed by a browser without tweaks but we can use curl –insecure to inspect the results. On a trusted certificate authority this would not be the case.
curl https://localhost/ -v --insecure
Let’s put them all in a script
mkdir certs cd certs openssl genrsa -des3 -out ca.key 4096 #Remove passphrase for example purposes openssl rsa -in ca.key -out ca.key openssl req -new -x509 -days 3650 -key ca.key -subj "/CN=*.your.hostname" -out ca.crt printf test > passphrase.txt openssl genrsa -des3 -passout file:passphrase.txt -out server.key 2048 openssl req -new -passin file:passphrase.txt -key server.key -subj "/CN=*.your.hostname" -out server.csr openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt cd ../ docker run --rm --name some-nginx -p 443:443 -v $(pwd)/certs/server.key:/etc/nginx/certs/tls.key -v $(pwd)/certs/server.crt:/etc/nginx/certs/tls.crt -v $(pwd)/nginx.conf:/etc/nginx/conf.d/nginx.conf -v $(pwd)/certs/passphrase.txt:/etc/nginx/certs/password nginx
You can find the code on github.
Published on System Code Geeks with permission by Emmanouil Gkatziouras, partner at our SCG program. See the original article here: Add SSL to Nginx Opinions expressed by System Code Geeks contributors are their own. |