Configure Self-Signed SSL for Nginx Docker to work in a local windows machine using openSSL

Configure Self-Signed SSL for Nginx Docker to work in a local windows machine using openSSL

After going through many articles online which were very helpful but and finally getting this to work on a windows machine, I decided to write a detailed article on how to solve the above issues.

Requirements

  1. Windows PC
  2. Docker desktop
  3. Git bash

Why do you need SSL for a local machine

SSL is purely for security. There might be scenarios when you have to deploy and run a web application within a LAN network. In this case, you will have to make sure you secure the web app with SSL self-signed with OpenSSL and get the host browser to trust the certificate.

Steps to achieve this

1.Open your git bash terminal and type the command bellow

winpty  docker run -it -p 80:80 -p 443:443 --name nginx-alpine-ssl-on-windows alpine ./bin/sh

2.Install Nginx using any of the package managers, we will be using apk

apk add nginx;

3.Run Nginx using the command bellow

nginx;

4.Install curl using the following command.

apk add curl

5.Use vi or nano to open the Nginx configuration file and add the configuration below. I will be using vi, if you choose to use nano make sure to install it using the command

apk add nano;

6.To open the config file type the command

vi /etc/nginx/http.d/default.conf

When it open type I on your keyboard to enter the insert mode, delete the server block and paste the server configuration code below

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        location / {
                root /var/www/localhost/htdocs;
        }
        # You may need this to prevent return 404 recursion.
        location = /404.html {
                internal;
        }
}

After typing the configuration code press the ESC key on your keyboard then type wq to write and exit vi.

7.Confirm that there is no error in your Nginx configuration using the command

nginx -t

if you get the message below, it means your configuration does not contain any error.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

8.Restart Nginx using the command

nginx -s reload

9.Create an index.html file in the location where you specify in the Nginx configuration file as the root. In our case it is

/var/www/localhost/htdocs/

Use the command

echo "<h1>Configure Self-Signed SSL For Nginx Docker to work in a local windows machine.</h1>" > /var/www/localhost/htdocs/index.html;

to create the file

10.Test that it is working using the curl program we installed earlier, using the command

curl localhost;

. you get should the output below if it works fine.

<h1>Configure Self-Signed SSL For Nginx Docker to work in a local windows machine</h1>

You can also visit localhost on your browser and you will get Configure Self-Signed SSL For Nginx Docker to work in a local windows machine served on the screen.

11.Install OpenSSL which is the program that will help you generate an SSL cert and key using the command

apk add openssl;

12.Create a new .crt and .key file using the OpenSSL program by typing the command below

openssl req -x509 -nodes -days 365 -subj "/C=CA/ST=QC/O=Company, Inc./CN=mylocaldomain.local" -addext "subjectAltName=DNS:mylocaldomain.local" -newkey rsa:2048 -keyout /etc/ssl/certs/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt;

Note: the highlighted mylocaldomain.local is the local domain you want to access your web app with, you are at liberty to name it anything of your choice although a descriptive name will be better.

What Each Options Means

req — to specify we want to use -x509 -x509 — to specify we want to create a self-signed certificate instead of generating a certificate signing request. -nodes — make it so that we skip the option to secure our certificate with a passphrase, so that nginx can read it. -days 365 — specifies how long the certificate would be valid for, which is 365 days. -subj “/C=CA/ST=QC/O=Company, Inc./CN=mylocaldomain.local" — this allows us to specify the subject without filling in prompts. /C for country, /ST for state, /O for organization, and /CN for common name. -addext “subjectAltName=DNS:mylocaldomain.local" — which adds additional attributes to our certificate which is needed to make it a valid certificate seen by both our browser and local machine. -newrsa rsa:2048— specifies that we want to generate both a new certificate and a new key with an RSA key of 2048 bits. -keyout /etc/.../yourfile.key— specifies the location of the output .key file. -out /etc/.../yourfile.crt — specifies the location of the output .crt file.

13.We now need to associate our SSL certificate to our default.conf Nginx file. Open the Nginx configuration file using the command vi /etc/nginx/http.d/default.conf and press I to enter the insert mode. Delete the server block and type the code below

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
        ssl_certificate_key /etc/ssl/certs/nginx-selfsigned.key;
        server_name mylocaldomain.local;
        server_tokens off;
        location / {
                root /var/www/localhost/htdocs;    
        }
        # You may need this to prevent return 404 recursion.
        location = /404.html {
                internal;
        }
}

Press the ESC type wq to save the changes and exit vi

Note: The server name must be the name you signed the SSL certificate to. Also, confirm that there is no error on your Nginx config file by typing

 nginx -t;

then restart Nginx by typing

nginx -s reload;

14.Configure Your Computer Host File To Trust your local Domain by editing the hosts file in this directory C:\Windows\System32\drivers\etc using notepad

# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#    127.0.0.1       localhost
#    ::1             localhost
# Added by Docker Desktop
192.168.43.196 host.docker.internal
192.168.43.196 gateway.docker.internal
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
127.0.0.1 mylocaldomain.local
# End of section

Note: The highlighted 127.0.0.1 mylocaldomain.local is the only change I made to the hosts file save it and exit

15.Open another git bash terminal and type the command

 docker cp nginx-alpine-ssl-on-windows:/etc/ssl/certs/nginx-selfsigned.crt ~/Desktop;

to copy your .crt file to your desktop

16.Go to your desktop, locate the nginx-selfsigned.crt file and then double click on it to install the certificate to the Trusted Root Certification Authorities area of your pc. Steps:

  1. Double click the nginx-selfsigned.crt on your desktop Click on install certificate

  2. Select local machine then next then yes

  3. Select place all certificates in the following store then click on browse
  4. Select Root Certification Authorities then Ok then next then finish

    You should get an alert with the message
    the import was successful then click ok

17.Congratulation you're all set you can now access the secure version of your web app locally using mylocaldomain.local

References : https://codingwithmanny.medium.com/configure-self-signed-ssl-for-nginx-docker-from-a-scratch-7c2bcd5478c6

https://www.reddit.com/r/docker/comments/j4g61h/generating_a_selfsigned_ssl_certificate_for_nginx/

https://faun.pub/setting-up-ssl-certificates-for-nginx-in-docker-environ-e7eec5ebb418

https://blog.jverkamp.com/2018/02/15/automatic-self-signed-https-for-local-development/