Open source SSL with Lets Encrypt

Let's encrypt is a popular open source SSL encryption supported by almost all modern browsers.

It is completely free of charge

The certificates have to regenrated every 90 days

Getting the certificate

1) Requires server to be running on Port 80 (You may have to use cloud service if your ISP blocks port 80)

NOTE: However, once the certificates have been issued, the SSL server can be deployede on any port

2) Create a location context pointing to /.well-known/acme-challenge/ on a server listening on port 80

yml
    server {
      listen 80 default_server;
      server_name mlr2d.com www.mlr2d.com;

       location /.well-known/acme-challenge/ {
            # path to some directory in your file system (inside docker container)
            # Recall the map- {PWD}/Docker/prod/nginx/ssl:/etc/ssl/nginx
            alias /etc/ssl/nginx/log/acme-tiny/;
            try_files $uri =404;
       }
    }

3) To issue certificate, a file will be generated in the alias directory and will be attempted to download

4) The generated keys will be placed under the directory {PWD}/Docker/prod/nginx/ssl/key, which will be mapped to the following directory in docker container

{PWD}/Docker/prod/nginx/ssl:/etc/ssl/nginx

5) These generated keys have to pointed in the servers.conf file (all other ssl configs are same as that used for self signed ssl)

yml
    ssl_certificate /etc/ssl/nginx/key/mlr2d.com.pem;
    ssl_certificate_key /etc/ssl/nginx/key/mlr2d.com.key;
    ssl_trusted_certificate /etc/ssl/nginx/key/mlr2d.com.pem;

Scripts needed for generating certificates

1) Script to generate file and test download is done by acme-tiny.py

python acme-tiny.py \
    --account-key "{PRIV_KEY_ACCOUNT}" \
    --csr "{DOMAIN_CSR}" \
    --acme-dir "{ACME_CHALLENGE_PATH}" \
    --ca "{LETS_ENCRYPT_CA_URL}" > "{SIGNED_CERTIFICATE}" \
    2>> "{ACME_TINY_LOG_PATH}/acme-tiny.log"

2) The entire process is managed by the script issue-certificates.sh. We just have to set the right path for keys and logs in such a way that they can be mapped inside the docker container

NOTE : This script is run outside docker and keys are generated in a volume that is mapped inside docker.

yml

    # Default locations for where certificates will live.
    ACME_TINY_SHARE_PATH="Docker/prod/nginx/ssl/acme-tiny"
    ACME_TINY_LOG_PATH="Docker/prod/nginx/ssl/log/acme-tiny"
    # directory to test download
    ACME_CHALLENGE_PATH="{ACME_TINY_LOG_PATH}"

    PRIV_KEY_ACCOUNT="{ACME_TINY_SHARE_PATH}/account.key"
    PRIV_KEY_DOMAIN="{ACME_TINY_SHARE_PATH}/mlr2d.com.key"
    DOMAIN_CSR="{ACME_TINY_SHARE_PATH}/mlr2d.com.csr"

    SIGNED_CERTIFICATE="{ACME_TINY_SHARE_PATH}/mlr2d.com.crt"
    INTERMEDIATE_CERTIFICATE="{ACME_TINY_SHARE_PATH}/intermediate.crt"

    # directory to store the final keys which will be mapped to the docker container and pointed in servers.conf
    KEY_DIR="Docker/prod/nginx/ssl/key/"
    FINAL_PRIV_KEY="{KEY_DIR}/mlr2d.com.key"
    CHAINED_FINAL_CERTIFICATE="{KEY_DIR}/mlr2d.com.pem"


    # Create the acme-tiny install path if it doesn't exist already.
    # This is where all of the key pairs and certificates will get generated into.
    mkdir -p "{ACME_TINY_SHARE_PATH}"


    # Create a path to store acme-tiny's log output.
    mkdir -p "{ACME_TINY_LOG_PATH}"

    # path to store keys for mapping to container
    mkdir -p "{KEY_DIR}"

To generate certificates

1) Set Mode in issue-certificates.sh

yml
# Do you want to run Let's Encrypt in "staging" or "live" mode? You should only
# change this to "live" once you are sure everything is working correctly.
LETS_ENCRYPT_MODE="live"

NOTE: To get the green lock, the certificates have to be generated in live mode. To check for bugs, use staging mode

2) Specify Registered domains (you have to separately register for www and non-www domains

yml
# Space separated list of domains to register SSL certificates for.
REGISTER_DOMAINS="mlr2d.org www.mlr2d.org"

3) Run

sudo ./issue-certificates.sh

4) See status under

vim {ACME_TINY_LOG_PATH}/acmelog.txt

Note:

1) The certificates have to be issued every 90 days from a server that has port 80 open

2) Once the certificate has been generated they can be served on any port on any host machine (just make sure to update the Host IP in google dns server)

3) This example is demontrated under the project folder le-nginx (The source code need not be changed for serving on different host machines

Requirements for serving on google cloud

1) docker and docker-compose

2) dig

sudo apt-get install dnsutils

3) gcloud instances should have http and https network tags

Checking SSL rating

This can be done on ssllabs.com, when your https server is running on port 443

To get A+ rating, uncomment this line in server.conf under https server

#add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";