Skip to content

Instantly share code, notes, and snippets.

@cecilemuller
Last active January 29, 2016 15:09
Show Gist options
  • Save cecilemuller/6d70cb4f463d8a391db1 to your computer and use it in GitHub Desktop.
Save cecilemuller/6d70cb4f463d8a391db1 to your computer and use it in GitHub Desktop.
Let's encrypt (Nginx, Ubuntu 14.04 LTS)

Install the client:

apt-get install git
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt

Generate certificates using manual mode:

service nginx stop
./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory -d www.yoursite.com auth
./letsencrypt-auto --server https://acme-v01.api.letsencrypt.org/directory -d yoursite.com auth
service nginx start

Generate a dhparams key:

openssl dhparam -out /etc/ssl/private/dhparams_4096.pem 4096

Nginx config:

server {
	server_name yoursite.com;
	listen 80;
	listen [::]:80;
	return 301 https://www.yoursite.com$request_uri;
}


server {
	server_name yoursite.com;
	listen 443 ssl;
	listen [::]:443 ssl;
	
	ssl_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/yoursite.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/yoursite.com/fullchain.pem;
	ssl_session_timeout 1d;
	ssl_session_cache shared:SSL:50m;
	
	ssl_dhparam /etc/nginx/dhparam.pem;
	
	ssl_protocols TLSv1 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:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
	ssl_prefer_server_ciphers on;

	add_header Strict-Transport-Security max-age=15768000;
	
	ssl_stapling on;
	ssl_stapling_verify on;

	return 301 https://www.yoursite.com$request_uri;
}

server {
	server_name www.yoursite.com;
	listen 80 default_server;
	listen [::]:80 default_server ipv6only=on;
	return 301 https://www.yoursite.com$request_uri;
}

server {
	server_name www.yoursite.com;
	listen 443 ssl default_server;
	listen [::]:443 ssl default_server ipv6only=on;

	ssl_certificate /etc/letsencrypt/live/www.yoursite.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/www.yoursite.com/privkey.pem;
	ssl_trusted_certificate /etc/letsencrypt/live/www.yoursite.com/fullchain.pem;
	ssl_session_timeout 1d;
	ssl_session_cache shared:SSL:50m;

	ssl_dhparam /etc/nginx/dhparam.pem;

	ssl_protocols TLSv1 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:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
	ssl_prefer_server_ciphers on;

	add_header Strict-Transport-Security max-age=15768000;

	ssl_stapling on;
	ssl_stapling_verify on;

	root /usr/share/nginx/www.yoursite.com;
	index index.html;


	location / {
		try_files $uri $uri/ =404;
	}
}

You can see more configurations at Mozilla's SSL Config Generator.


Once you're done, test everything is working using SSLTest: it should give you a A+ rating :)

@cecilemuller
Copy link
Author

Note that the certificates are only valid 90 days at a time.

@engineersamuel
Copy link

What does your /directory point to in nginx? I see /directory referenced for nearly every letsencrypt-auto invocation but I don't see what that should point to in nginx/apache. In my nginx config there is no /directory mapping, if I point it to one of my existing directories then it throws various errors.

@jlgaddis
Copy link

jlgaddis commented Nov 5, 2015

In the second server block (yoursite.com:443), (since you generated a private key and certificate for yoursite.com) I would have expected to see "ssl_certificate{_key}" directives pointing to "/etc/letsencrypt/live/yoursite.com/{fullchain,privkey}.pem".

What certificate is used if a visitor goes to https://yoursite.com?

@cecilemuller
Copy link
Author

@jlgaddis Fixed, I had mistakenly pasted the first block twice, sorry

@cecilemuller
Copy link
Author

@engineersamuel I'm not sure what /directory you're talking about, do you mean https://acme-v01.api.letsencrypt.org/directory? If so, that's just the hardcoded url for Let's Encrypt's API, you don't need to change it.

@agilob
Copy link

agilob commented Nov 6, 2015

Just a question. Is rewrite ^(.*) https://www.yoursite.com$1 permanent; better than return 301 https://www.yoursite.com$request_uri?

@cecilemuller
Copy link
Author

@agilob return 301 https://www.yoursite.com$request_uri is better (and I now updated the gist as well), I forgot return accepts more than just the status code, thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment