Setting up a free letsencrypt ssl certificate with nginx

3 minute read Published:

We all know that the Five Eyes (and alot of other ugly people) collect massive amounts of metadata from public internet traffic, and you want to do something about it.

Yes, you can do something, too. If we spam them with encrypted traffic, the amount of work needed to decrypt and read it will become unbearable for them.

Letsencrypt offers a free way to get ssl certificates for your http(s) web-server. Read more about it here.

But…. talk is cheap, so I will show you what to do. Fire up your ssh client and login to your web-server.

For sake of simplicity let’s assume that you have the domain and also want your webserver to respond to The domains both have to point at your webserver’s IP address.

Be sure that you stop your webserver and then go on.

Setting up the letsencrypt client and obtaining a certificate

(for this you need git, python2.7 and virtualenv installed) verify pls

root@webserver #:~ cd /opt
root@webserver #:/opt cd /opt
root@webserver #:/opt git clone
root@webserver #:/opt cd letsencrypt
root@webserver #:/opt/letsencrypt ./letsencrypt-auto certonly --standalone -d -d

Your certificate key, cert, und trust-chain are now in /etc/letsencrypt/live/

root@webserver #:~ ls /etc/letsencrypt/
cert.pem  chain.pem  fullchain.pem  privkey.pem


Generating a new DH-Prime

(I will not explain too much about this - read more here)

root@webserver #:~ mkdir -p /etc/nginx/cert
root@webserver #:~ openssl dhparam 2048 -out /etc/nginx/cert/dhparam.pem
root@webserver #:~ chmod 0600 /etc/nginx/cert/dhparam.pem

Java 6 doesn’t support DH-Params with more than 1024-bit.

Configuring nginx

(I assume you already have installed nginx - if you don’t please click here)

If you have configured your nginx installation to read all *.conf-Files from /etc/nginx/conf.d/ then just create a new config-File by typing touch /etc/nginx/conf.d/ as root. Otherwise you should know your configuration.

Edit the nginx configuration by typing nano /etc/nginx/conf.d/ as root and pasting the following content (don’t forget to adapt to your real domain as in all examples:

# and

# this server block accepts all unencrypted http-requests and redirects them to https
server {
    listen       80;
    return       301 https://$server_name$request_uri;

server {
    listen       443 ssl http2;
    listen  [::]:443 ssl http2;

    ssl_certificate      /etc/letsencrypt/live/;
    ssl_certificate_key  /etc/letsencrypt/live/;

    ssl_session_cache           shared:SSL:20m;
    ssl_session_timeout         60m;

    ssl_prefer_server_ciphers   on;

    ssl_ciphers                 ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;

    ssl_dhparam                 /etc/nginx/cert/dhparam_4096.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/;

    add_header Strict-Transport-Security "max-age=31536000" always;

    # Example location block ...
    # Rest of your nginx config should go here
    location / {
        root   /var/www;
        index  index.html index.htm;


Testing the Setup

start nginx with /etc/init.d/nginx start and point your browser to

let’s Encrypt auto renewal

place this file in your /etc/cron.daily, name it renew-letsencrypt

service nginx stop
if ! /opt/letsencrypt/letsencrypt-auto renew -nvv --standalone > /var/log/letsencrypt/renew.log 2>&1 ; then
    echo Automated renewal failed:
    cat /var/log/letsencrypt/renew.log
    exit 1
service nginx start

and make it executable by running chmod +x renew-letsencrypt

Yes!! You got it! Now go and live your life…