I’m a very happy user of the letsencrypt.com closed beta programm and wanted to share the configuration for this very vhost on nginx. While researching possible configuratiuons I stumbeled upon a site from the Mozilla Project, that generates SSL configurations for your webserver.
Prerequisites
Before we can start using the letsencryt there are a few prerequisite that have to be attened to in the nginx configuration.
server { listen 80; #listen [::]:80; server_name boerngen-schmidt.de www.boerngen-schmidt.de; # Used by letsencrypt-auto cli tool to verify domain ownage ;D location '/.well-known/acme-challenge' { default_type "text/plain"; root /tmp/letsencrypt-auto; } # redirect http requests to https location / { return 301 https://$server_name$request_uri; } }
Before we reload nginx lets create the letsencrypt challenge folder via mkdir -p /tmp/letsencrypt-auto and then reload nginx. Now we can generate new certificates for our domain, without stopping nginx, to do so run the following commands:
cd /path/to/clone/letsencrypt git clone https://github.com/letsencrypt/letsencrypt cd letsencrypt ./letsencrypt-auto -a webroot --webroot-path=/tmp/letsencrypt-auto \ --agree-dev-preview --agree-tos \ --server https://acme-v01.api.letsencrypt.org/directory -m <your email> -d boerngen-schmidt.de -d www.boerngen-schmidt.de certonly
This should set up letsencrypt on the system using the webroot authenticator, accepting all stuff and fetch the certificates for the domains listed.
Configuration
So now that we obtained the certificates for our domain, they need to be set up with nginx.
Mozilla Recommended Configuration
The tool from Mozilla, found at https://mozilla.github.io/server-side-tls/ssl-config-generator/ will return the following recommended configuration for nginx.
server { listen 443 ssl; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /path/to/signed_cert_plus_intermediates; ssl_certificate_key /path/to/private_key; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits ssl_dhparam /path/to/dhparam.pem; # modern configuration. tweak to your needs. ssl_protocols TLSv1.1 TLSv1.2; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ## verify chain of trust of OCSP response using Root CA and Intermediate certs ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; resolver <IP DNS resolver>; .... }
Modified Configuration
So now that we got the base configuiration let’s tweak it a little, because some stuff does not match my requirements.
First we create a stronger Diffie Hellman Ephemeral Parameters key for nginx. Here I choose to go against generating the DHE system wide in /etc/ssl/certs, which are just 1024bit, to not mess with my system (yet).
# cd /etc/nginx # openssl dhparam -out dhparam.pem 4096
And then the base configuration is modified to my needs.
server { listen 443 ssl; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /etc/letsencrypt/live/boerngen-schmidt.de/fullchain.pem; #MODIFIED ssl_certificate_key /etc/letsencrypt/live/boerngen-schmidt.de/privkey.pem; #MODIFIED ssl_session_timeout 1d; ssl_session_cache shared:SSL:10m; ssl_session_tickets on; #MODIFIED # Diffie-Hellman parameter for DHE ciphersuites, 4096 bits ssl_dhparam /etc/nginx/dhparam.pem; #MODIFIED # modern configuration. tweak to your needs. ssl_protocols TLSv1.1 TLSv1.2; # Recommended by raymii.org # ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; ssl_prefer_server_ciphers on; # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months) add_header Strict-Transport-Security max-age=15768000; # OCSP Stapling --- # fetch OCSP records from URL in ssl_certificate and cache them ssl_stapling on; ssl_stapling_verify on; ## verify chain of trust of OCSP response using Root CA and Intermediate certs ssl_trusted_certificate /etc/letsencrypt/live/boerngen-schmidt.de/chain.pem; #MODIFIED # Hetzner DNS Servers. Please use your providers! resolver 213.133.98.98 213.133.99.99 213.133.100.100 valid=86400; #MODIFIED resolver_timeout 5; #MODIFIED .... }
Last but not least we have to restart nginx systemctl restart nginx.service a simple reloading the configuration did not have the full effect.
References
http://letsencrypt.readthedocs.org/en/latest/index.html
https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
https://gist.github.com/renchap/c093702f06df69ba5cac#file-readme-md