Lets Encrypt on Ubuntu using Apache, Nginx, or Lighttpd Cheat Sheet

If you are using Lets Encrypt (www.letsencrypt.org) certificates on your Ubuntu servers, you may find the following information useful if you work with Apache, Nginx, or Lighttpd.

Installing Lets Encrypt on Ubuntu 14.04 (or older)

Reference: https://www.vultr.com/docs/setup-lets-encrypt-with-apache-on-ubuntu-14-04

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

The 3rd line sets up Lets Encrypt and installs any necessary dependencies such as Python.

Ubuntu 16.04 install instructions

Reference: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-16-04

apt-get install letsencrypt

Note: The remaining portion of this document uses /opt/letsencrypt/letsencrypt-auto and /opt/letsencrypt/certbot-auto command line tools as found when installing on Ubuntu 14.04 or older. If you are using Ubuntu 16.04 or newer, simply run the command letsencrypt and certbot without the full path or the additional -auto from the command line.

Setup your server so you can create certificates without having to stop your web server

I will not explain aliases in detail, but essentially you need to create an alias URI for /.well-known/. It can be shared among all of your virtual hosts. Lets Encrypt uses this folder to save folders and files that are used in the confirmation process for creating new and renewing existing certificates.

Create a working folder for Lets Encrypt:

mkdir -p /var/www/letsencrypt/.well-known/

Then setup your web server to use this working folder for the .well-known URI path on your server.

Apache .well-known Example

Create a file called letsencrypt.conf with the following.

Alias "/.well-known/" "/var/www/letsencrypt/.well-known/"
<Directory "/var/www/letsencrypt/.well-known">
 AllowOverride None
 Options None
 Require all granted
</Directory>

If you place this file in the conf-enabled folder (/etc/apache2/conf-enabled/letsencrypt.conf) then simply restart your Apache web server. Otherwise you will need to make a symbolic link in your conf-enabled folder to where you saved your letsencrypt.conf file.

Do not forget when ever making configuration changes to Apache to run the following before restarting your web server.

apache2ctl configtest

Nginx .well-known Example

Create a file called letsencrypt.conf with the following.

location ~ ^/\.well-known/(.*)$ {
 alias /var/www/letsencrypt/.well-known/$1;
 # No need to log these requests
 access_log off;
 add_header "X-Zone" "letsencrypt";
}

Then in your nginx.conf file near the top of the server { } add the following line:

 include /path/to/your/letsencrypt.conf;

Do not forget when ever making configuration changes to Nginx to run the following before restarting your web server.

nginx -t

Lighttpd .well-known Example

Add the following in your lighttpd.conf file. Note the += is for adding to an existing set of alias URLs. If you have no alias.url values, then simply remove the + but leave the equal. Learn more about Lighttpd aliasing here.

alias.url += ( "/.well-known/" => "/var/www/letsencrypt/.well-known/" )

Do not forget when ever making configuration changes to Lighttpd to run the following before restarting your web server.

lighttpd -t -f /etc/lighttpd/lighttpd.conf

Creating New Lets Encrypt SSL Certificates

You can now create Lets Encrypt certificates without your server having to be shut down temporarily.

/opt/letsencrypt/letsencrypt-auto certonly --webroot --manual-public-ip-logging-ok -d example.com --agree-tos -m you@example.com --text  -w /var/www/letsencrypt/

Replace example.com and you@example.com with your email address and your host name. Remember if your host name starts with www., leave off the www. as it is not necessary, a certificate without the www. also works with the www.

Renew certs

/opt/letsencrypt/certbot-auto renew

certbot-auto uses previous settings to renew the cert in the exact same way it was created so no extra parameters are necessary

Reference: http://letsencrypt.readthedocs.io/en/latest/using.html#renewing-certificates

You can create a file in the /etc/cron.weekly/ folder to renew Lets Encrypt certificates weekly. Even though it will run weekly, Lets Encrypt is smart enough not to renew certificates until there is 30 days or less remaining. This gives you plenty of overlap in case for some reason one week failed to renew.

Example bash file /etc/cron.weekly/letsencrypt

#!/bin/bash
/opt/letsencrypt/certbot-auto renew
You may want to use the > /dev/null 2>&1 trick at the end of the command line to surpress errors from coming from your cron tasks via email.

Deleting SSL Certificates

When we no longer wish to maintain SSL for a host name, we need to delete the renewal config file.
rm /etc/letsencrypt/renewal/example.com.conf
This file includes information where the SSL certs are located and the options used when the SSL cert was first created.
This is not the same as revoking an SSL certificate. This simply no longer renewing the certificate every 2-3 months.
SSL Cert files are saved in the following path by folder for each host
/etc/letsencrypt/live/
Specific SSL files are located within the host name folder
/etc/letsencrypt/live/example.com/
Important reference to the pem files:
cert = /etc/letsencrypt/live/geeknewscentral.com/cert.pem
privkey = /etc/letsencrypt/live/geeknewscentral.com/privkey.pem
chain = /etc/letsencrypt/live/geeknewscentral.com/chain.pem
fullchain = /etc/letsencrypt/live/geeknewscentral.com/fullchain.pem

Note: “chain” is specifically for Apache and the SSLCertificateChainFile  setting, which is now obsolete as of 2.4.8. This is a good thing as now Nginx and Apache use the same fullchain and privkey files. Lighttpd is still not as simple, see note below.

Though all files are saved in the pem format, other systems and platforms use different file extensions rather than filenames to identify the differnet files. Here is a quick cheatsheet in case you need to map previous files to new files.

type (explanation) - letsencrypt - other examples
cert (public key) - cert.pem - example.com.crt, example.com.public.key
privkey (private key) - privkey.pem - example.com.key, example.com.private.key
chain - (chain key) chain.pem - gd_bundle.crt, alphasslroot.crt, etc...
fullchain (concatenation of cert + chain) - fullchain.pem - fullchain.crt

Pem files and their use on Apache, Nginx, and Lighttpd

Apache 2.4.8 and newer

SSLCertificateFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/fullchain.pem

Note that there is no SSLCertificateChainFile option, it now uses the fullchain.pem which combines the cert.pem with chain.pem.

Apache 2.4.7 and older

SSLCertificateFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem

Note that we are not using the fullchain.pem, instead we are linking to the cert.pem and chain.pem on 2 separate configuration lines.

Nginx

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

Lighttpd

Lighttpd Note: The cert and privkey need to be combined for Lighttpd

cd /etc/letsencrypt/live/example.com/
cat privkey.pem cert.pem > ssl.pem

Then link to the certificates in your lighttpd config settings.

ssl.pemfile = /etc/letsencrypt/live/example.com/ssl.pem
ssl.ca-file = /etc/letsencrypt/live/example.com/chain.pem

If you are automating Lighttpd renewals, you will need to add an extra step that concatenates the privkey.pem with the cert.pem before restarting/reloading Lighttpd

While searching the Internet for examples of setting up Lighttpd, I found some examples show using the ssl.ca-file using the fullchain.pem. Though this will also work, that is not technically correct as the ssl.pem already houses the cert.pem
Please feel free to leave a comment if you find an error and/or have additional notes which may be helpful for others.

Source for Lighttpd mod_redirect rewrite module to use status code 302

Lighttpd web server, also known as Lighty, is an excellent web server and has potential to replace Apache completely.  I am slowly migrating web sites that use feature specific settings in Apache to use Lighty.  A few months ago I ran into a problem with Lighty’s ModRewrite alternative for rewriting URLs.  Lighty uses two separate modules to handle internal rewrites and Location: redirects.  It uses the common HTTP 301 Moved Permanently status code.  For most circumstances, this works well but in some cases the application may require that the redirect only be temporary and return the HTTP 302 Found status code.  Instead of modifying the mod_redirect.c source and changing the http_status code value from 302 to 301, I added new code to support a new url.redirect parameter url.redirect-found.

I’ve posted the source to the Lighttpd bug tracking system in hopes it will be added to a future version of Lighty.  http://trac.lighttpd.net/trac/ticket/1446

This addition should help the Lighty web server to be capable of handling the appropriate HTTP status codes for all situations that may arise for the web site in question.