self-assigned SSL with Docker for .dev domains

Scenario:
 I use Mac OS X and Google Chrome
 I work with docker and I use .dev subdomains for my projects, example blog.patito.dev or secretproject.patito.dev
 I use nginx proxy for handle the domains/subdomian with docker

Problem:

A few months ago Google Chrome changed the way to handle dev domains (https://ma.ttias.be/chrome-force-dev-domains-https-via-preloaded-hsts/) all petitions to dev domains are redirect to https :/

We have two solution:
 1.- change my domians/subdomians from patito.dev to patito.test, some people recommend use .localhost or .test https://iyware.com/dont-use-dev-for-development/
 2.- create a local self-assigned SSL and add to configuration for docker

The first options is easy, but I have some issue with use .test for my local developments ¬¬, I prefer .localhost or .invalid, but in this post we see how to create a self-assigned SSL and we can continue using dev domains (⌐■_■)

Solution

  1. - Create your own certificate

We need to uses openssl for this case. install openssl

brew install openssl

run the next command, change all patito.dev for your domain

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout patito.dev.key \
-new \
-out patito.dev.crt \
-subj /CN=\*.patito.dev \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
<(printf '[SAN]\nsubjectAltName=DNS:\*.patito.dev')) \
-sha256 \
-days 3650

Note: if you want know about the parameters check this post (http://how2ssl.com/articles/openssl_commands_and_tips/) and (https://www.shellhacks.com/create-csr-openssl-without-prompt-non-interactive/) and the man page https://linux.die.net/man/1/openssl

With this command creates a certificate and the key files, the key file will be called `patito.dev.key`, the certificate will be called `patito.dev.crt`, I use -subj parameter for set certificate subject for Common Name in this case for all subdomains of patito.dev and the parameter -config for load basic the configuration and add subjectAltName

now we have a certificate for all patito.dev subdomains \o/

2.- configurate the certificate with nginx proxy

I use nginx proxy for my docker containers, it’s really easy to use, we only need to add VIRTUAL_HOST to environment vars. if the want to use nginx proxy with the self-signed certificate only need to add the volume and mount in the correct directory `/etc/nginx/certs` we use the next command for that

docker run -d -p 80:80 -p 443:443 --name proxy --restart=always -v /Users/hunk/sites/ssl:/etc/nginx/certs -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

edit /Users/hunk/sites/ssl and uses the correct path where you put the files, you can create a folder to save all the key/cert you need

easy right?

3.- Test the certificate

Create a docker-compose.yml with the next content

whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=enji.patito.dev

Note: configure your hosts to respond the subdomain to ip of docker machine

and run

docker-compose up

Open Google Chrome and visit enji.patito.dev, Google Chrome automatic redirect to https://enji.patito.dev and …… D’oh :(

The problem is “this certificate has not been verified by a third party” yes, yes, this problem is because we self-signed the certificate, and we know it’s ok and we only use this certificate for local development so we can trust the certificate, right?

4.- Trust the certificate

run the next command in the folder were you have the certificate (check the name of you certificate)

sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain patito.dev.crt

Note: this add the certificate to the System keychain and trust the certificate

Now reload the page, it’s works \o/

You can create several certificates for your domains and put them in the same folder

And that’s it