This is a small walk through for setting up the Let’s Encrypt certificate up on your FreeBSD webserver with NGINX which previously has been using a self-signed certificate.
Disclaimer: This article are solely for my own use. Following it can cause fire, childrens death and green swallowing marshmellows. Read it all before trying anything of the suggested actions and use your head. Don't sue me. ;-)
Background for Let’s Encrypt
Using SSL and TLS certificates has been made rather complex and sometimes expensive task. Many CA’s (Certification Authority) has tried to make an open source version of a CA. But they all failed, after some time the certificates stops being accepted as valid out in the world. Which leads back to just making a self-signed certificate to encrypt your connection between the server and you.
The issue has been that you need to prove the ownership of your domain name to the CA, which then grants you an certificate to prove everybody else in the world that you are who you are, and not a scumbag malware infested guy who wants all the IT power in the world.
Let’s Encrypt has supposedly solved this issue by having you run a script on your server, opening up a small web socket on port 80 out to the Let’s Encrypt server which then proves that you own this server and the domain name is one you manage. The Let’s Encrypt client “letsencrypt” handles all the communication to the CA and makes a folder where it stores all your certificates. As far as I can see you need to make a certificate for each domain and subdomain, but that really isn’t any hassle.
Often, as in my situation, you already has a webserver running somekind of secure connection with self-signed certificate
In my case I have been using a config structure where there is a global NGINX config file, which holds all the configurations for all the sites I have. Inside that I make includes for all the site specific configurations. Those are the ones we need to alter for this to work.
The config file should have a similar section like this to call the self-signed certificate:
server {
listen 443 ssl;
server_name YOUR-DOMAINNAME.com;
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128$
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_certificate /usr/local/etc/nginx/ca-bundle.pem;
ssl_certificate_key /usr/local/etc/nginx/ssl-DOMAIN.pem;
ssl_prefer_server_ciphers on;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_dhparam /usr/local/etc/ssl/certs/dhparam.pem;
So first make your move to actually get the Let’s Encrypt client
Update your portstree, in my case a simple portsnap update wasn’t enough so I had to do:
$ portsnap fetch extract
This takes a while. I can recommend using tmux to prevent it to fail if you loose connection to your server if you are managing it over the network. When it has finished go to
$ cd /usr/ports/security/py-letsencrypt/
$ make install clean
Again in my case I got an conflict where a library was the wrong version. So the portssystem suggested to me that I run
$ make deinstall
$ make reinstall
This took a long time, hence the recommendation of using tmux. 🙂
Now everything should have installed nicely.
Let’s Encrypt requires to have port 80 open to communicate, so stop your NGINX server running on port 80.
$ service nginx stop
Request the certificate by running the client either as sudo or as root.
$ sudo letsencrypt -d YOURDOMAIN.COM certonly
Replace YOURDOMAIN.COM with your FQDN
ex.
example.com
or
subdomain.example.com
not http://example.com which isn’t a FQDN
You will get a screen asking for your email adress, which will be used for urgent notices and lost key recovery.
Agree to the terms of using Let’s Encrypt
You will now get a confirmation of success and info of where your certificate files are located.
IMPORTANT NOTES:
- If you lose your account credentials, you can recover through
e-mails sent to name@yourdomain.com.
- Congratulations! Your certificate and chain have been saved at
/usr/local/etc/letsencrypt/live/
YOUR-DOMAINNAME.COM
/fullchain.pem. Your
cert will expire on 2018-01-23. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.
- Your account credentials have been saved in your Let's Encrypt
configuration directory at /usr/local/etc/letsencrypt. You should
make a secure backup of this folder now. This configuration
directory will also contain certificates and private keys obtained
by Let's Encrypt so making regular backups of this folder is ideal.
- If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Go to your NGINX site config file again. Make sure you copy it just in case.
$ cp nginx-site-configfile.conf nginx-site-configfile.conf.old
Edit your config file with your preferred editor, in my case Nano.
server { listen 443 ssl; server_name YOUR-DOMAINNAME.com; ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128$ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_certificate /usr/local/etc/letsencrypt/live/YOUR-DOMAINNAME.COM/fullchain.pem; ssl_certificate_key /usr/local/etc/letsencrypt/live/
YOUR-DOMAINNAME.COM
/privkey.pem; ssl_prefer_server_ciphers on; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_dhparam /usr/local/etc/ssl/certs/dhparam.pem; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
Start you NGINX service again and browse to your site to check that the certificate are correct.
$ service nginx start
And you should have a CA authorized TLS certificate on your site.
To check your site on how it performs on the security. Test it with something like https://www.ssllabs.com/ssltest/index.html
I got an A+ on my site with these settings.
Hope you enjoyed the article. 🙂
Link to others having guides and walk-throughs on Let’s Engrypt:
http://savagedlight.me/2015/11/24/lets-encrypt-on-a-freebsd-nginx-reverse-proxy/
http://www.bsdnow.tv/episodes/2015_12_3-bsd_is_a_go_for_launch
https://community.letsencrypt.org/t/howto-easy-cert-generation-and-renewal-with-nginx/3491
https://letsencrypt.readthedocs.org/en/latest/
[…] Let’s Encrypt has landed 16. December 2015 […]