summaryrefslogtreecommitdiff
path: root/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
diff options
context:
space:
mode:
Diffstat (limited to 'src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md')
-rw-r--r--src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md b/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
new file mode 100644
index 0000000..a2802f8
--- /dev/null
+++ b/src/_posts/2016-10-25-setup-nginx-with-lets-encrypt-ssl.md
@@ -0,0 +1,228 @@
+---
+title: Setup nginx with Let's Encrypt SSL
+date: 2016-10-25 08:00:34
+tags: Tutorial LetsEncrypt Nginx SSL Encryption
+layout: post
+authors:
+ - ["Patrick Spek", "http://tyil.work"]
+---
+
+This is a small tutorial to setup nginx with Let's Encrypt on a FreeBSD server
+to host a static site.
+
+## Install required software
+First you have to install all the packages we need in order to get this server
+going:
+
+{% highlight sh %}
+pkg install nginx py27-certbot
+{% endhighlight %}
+
+## Configure nginx
+Next is nginx. To make life easier, you should configure nginx to read all
+configuration files from another directory. This allows you to store all your sites in
+separate configurations in a separate directory. Such a setup is a regular site on
+nginx installations on GNU+Linux distributions, but not default on FreeBSD.
+
+Open up `/usr/local/etc/nginx/nginx.conf` and make the contents of the `http`
+block look a as follows:
+
+{% highlight nginx %}
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ keepalive_timeout 65;
+
+ # default paths
+ index index.html;
+
+ # disable gzip - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=773332
+ gzip off;
+
+ # default ssl settings
+ ssl_session_cache shared:SSL:1m;
+ ssl_session_timeout 5m;
+ ssl_ciphers HIGH:!aNULL:!MD5:!AES128:!CAMELLIA128;
+ ssl_protocols TLSv1.2;
+ ssl_prefer_server_ciphers on;
+ ssl_dhparam /usr/local/etc/ssl/dhparam.pem;
+
+ # default logs
+ error_log /var/log/nginx/error.log;
+ access_log /var/log/nginx/acces.log;
+
+ # default server
+ server {
+ listen 80;
+ server_name localhost;
+
+ location / {
+ root /usr/local/www/nginx;
+ index index.html index.htm;
+ }
+
+ error_page 404 /404.html;
+ error_page 500 502 503 504 /50x.html;
+
+ location = /50x.html {
+ root /usr/local/www/nginx-dist;
+ }
+ }
+
+ # include site-specific configs
+ include sites/*.conf;
+}
+{% endhighlight %}
+
+This sets default ssl settings for all server blocks that enable ssl. Note that
+these are settings I use, and are in no way guaranteed to be perfect. I did some
+minor research on these settings to get an acceptable rating on
+[SSL Labs][ssllabs]. However, security is not standing still, and there is a
+decent chance that my settings will become outdated. If you have better settings
+that result in a safer setup, please [contact me][contact].
+
+### Setup HTTP
+Due to the way `certbot` works, you need a functioning web server. Since there
+is no usable cert yet, this means hosting a HTTP version first. The tutorial
+assumes a static HTML website to be hosted, so the configuration is pretty
+easy.
+
+Put the following in `/usr/local/etc/nginx/sites/domain.conf`:
+
+{% highlight nginx %}
+# static HTTP
+server {
+ # listeners
+ listen 80;
+ server_name domain.tld www.domain.tld;
+
+ # site path
+ root /srv/www/domain/_site;
+
+ # / handler
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ # logs
+ error_log /var/log/nginx/error.log;
+ access_log /var/log/nginx/access.log;
+}
+{% endhighlight %}
+
+If your site's sources do not reside in `/srv/www/domain/_site`, change the
+path accordingly. This guide will continue using this path for all examples, so
+be sure to modify this where needed. In the same vein, the domain `domain.tld`
+will be used. Modify this to your own domain.
+
+### Start nginx
+Nginx is now configured to host a single site over HTTP. Now is the time to enable
+the nginx service. Execute the following:
+
+{% highlight sh %}
+echo 'nginx_enable="YES"' >> /etc/rc.conf.local
+{% endhighlight %}
+
+This will enable nginx as a system service. On reboots, it will be started
+automatically. You can also start it up without rebooting by running the
+following:
+
+{% highlight sh %}
+service nginx start
+{% endhighlight %}
+
+## Configure Let's Encrypt
+Nginx is now running as your web server on port 80. Now you can request Let's
+Encrypt certificates using `certbot`. You can do so as follows:
+
+{% highlight sh %}
+certbot certonly --webroot -w /srv/www/domain/_site -d domain.tld -d www.domain.tld
+{% endhighlight %}
+
+In case you want to add any sub domains, simply add more `-d sub.domain.tld`
+arguments at the end. If the DNS entries for the domains resolve properly, and
+no unexpected errors occur on the Let's Encrypt side, you should see a message
+congratulating you with your new certs.
+
+If your domains do not resolve correctly, `certbot` will complain about this.
+You will have to resolve your DNS issues before attempting again.
+
+If `certbot` complains about an unexpected error on their side, wait a couple
+minutes and retry the command. It should work, eventually.
+
+Once `certbot` has ran without errors, the required files should be available
+in `/usr/local/etc/letsencrypt/live/domain.tld`.
+
+## Configure nginx with SSL
+The certificate has been issued and base nginx is running. Now is the time to
+re-configure your site on nginx to host the HTTPS version of your site instead.
+Open up `/usr/local/etc/nginx/sites/domain.conf` again, and make the contents
+look like the following:
+
+{% highlight nginx %}
+# redirect HTTPS
+server {
+ # listeners
+ listen 80;
+ server_name domain.tld *.domain.tld;
+
+ # redirects
+ return 301 https://$host$request_uri;
+}
+
+# static HTTPS
+server {
+ # listeners
+ listen 443 ssl;
+ server_name domain.tld www.domain.tld;
+
+ # site path
+ root /srv/www/domain/_site;
+
+ # / handler
+ location / {
+ try_files $uri $uri/ =404;
+ }
+
+ # enable HSTS
+ add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload";
+
+ # keys
+ ssl_certificate /usr/local/etc/letsencrypt/live/domain.tld/fullchain.pem;
+ ssl_certificate_key /usr/local/etc/letsencrypt/live/domain.tld/privkey.pem;
+}
+{% endhighlight %}
+
+Do not forget to update all the paths to match your setup!
+
+As a final step, you should generate the dhparam file. This is to avoid the
+issues as described on [Weak DH][weakdh].
+
+{% highlight sh %}
+openssl gendh -out /usr/local/etc/ssl/dhparam.pem 4096
+{% endhighlight %}
+
+Be aware that this step can take a **very** long time. On the test machine I
+used to test this tutorial, with 1 core and 1 GB ram, it took nearly 1 hour to
+generate this file.
+
+### Reload nginx
+The final step is to reload the nginx configuration so it hosts the SSL version
+of your site, and redirects the HTTP version to the HTTPS version. To do this,
+simply run
+
+{% highlight sh %}
+service nginx reload
+{% endhighlight %}
+
+That should be all to get your site working with HTTP redirecting to HTTPS, and
+HTTPS running using a gratis Let's Encrypt certificate.
+
+[contact]: https://www.tyil.work/
+[ssllabs]: https://www.ssllabs.com/ssltest/analyze.html?d=tyil.work&latest
+[weakdh]: https://weakdh.org/
+