[Update 2018-08-13: This guide is now rather outdated. See the many excellent comments below for more details. Some basic Letsencrypt instructions have also been integrated in the official Seafile manual, both for nginx and for apache.]
Hi, I wrote a tutorial on how to use free TLS certificates with seafile:
https://blog.hambier.lu/post/letsencrypt-seafile-certbot
The certificates are free, signed, valid and accepted by all current browsers. They’re provided by the Let’s Encrypt initiative.
My guide is based on the current “certbot” client provided by the EFF.
For convenience’s sake and to prevent dead links I reproduce a (slightly edited) copy of it below. Unfortunately I can’t guarantee to keep it up to date at all times. A previous article quickly became outdated due to the fast development of the whole letsencrypt/certbot approach. Feel free to contact me if you notice a problem with this guide.
1. Introduction
This guide is based on the assumption that Seafile is already up and running (with possibly a self-signed certificate): MySQL, nginx + SSL, Seafile. (In fact my original setup was on a raspberry pi, that’s why some data folders are located in /mnt/usbdrive.)
In this post I’ll show you how I’ve recently configured my Seafile installation to always have a perfectly valid and signed SSL/TLS-certificate that is accepted by all web browsers. And it’s free.
To achieve this I’m using a certificate from the “Let’s Encrypt” CA. The kind people from the Internet Security Research Group, the public benefit corporation behind Let’s Encrypt, have developed a custom protocol, ACME, in order to automate the usually cumbersome domain ownership verification procedures. Even though the provided certificates are very short-lived (3 months validity), the resulting setup is actually much less maintenance-intensive than my previous (free) StartCom StartSSL certificates: I don’t have to keep track of expiry dates, manually create certificates and signing requests, and so on. The whole premise of the Let’s Encrypt approach is to force the admin’s hands in
automating certificate handling, all while providing the necessary tools.
2. Installation
Since the Let’s Encrypt project is still in its infancy, I didn’t really consider any of the alternative ACME clients, I stayed with the official one, “certbot”. It has a multitude of plugins to facilitate its integration in an existing server setup. To be honest, though, I’m no fan of having an automated tool mess with my nginx configuration files. That’s why I elected to use the socalled webroot plugin.
Basically, I indicate to certbot where my webroot directory is located. The client in turn communicates with the Let’s Encrypt-ACME-server and puts some cryptographic tokens in a hidden subdirectory of the webroot. These are checked by the (remote) ACME-server in order to ascertain that the client (or rather the admin) truly has domain ownership (or at least administrative rights). Finally the (locally created!) certificates are signed by the CA and stored in /etc/letsencrypt/live. Do note that the ACME-server always checks the cryptographic token through http. (security reasons)
It does however follow redirects from http to https. (This just in case that you set up your server to listen on port 443 exclusively.)
To actually install certbot I refer you to the official documentation. Indeed, it very much depends on your linux distribution whether or not certbot is provided through your default package manager. Depending on the path you chose, you may end up with one of the following commands to interact with the ACME-servers: letsencrypt, letsencrypt-auto, certbot or certbot-auto. In this tutorial I’ll use the certbot command, but they’re all compatible in regard to the arguments they take. (letsencrypt is the old name of the client; certbot the new one.)
3. Preparing the webroot folder
The “webroot” method of the letsencrypt client presents a minor inconvenience when used in conjunction with Seafile: it requires an active webroot… However, in our case, the nginx web server is used as a simple FastCGI-Proxy for Seafile, i.e. it simply forwards incoming requests to one of seafile’s daemons.Hence the need for a slight modification to nginx’s config. But first we’ll create a “fake” webroot for nginx/seafile:
sudo mkdir /mnt/usbdrive/certbot-webroot
(/mnt/usbdrive corresponds to the drive on which I’ve installed Seafile. You could put the webroot anywhere you like.)
Then we add the additional location directive inside of the main server block:
# in /etc/nginx/sites-enabled/seafile:
location '/.well-known/acme-challenge' {
default_type "text/plain";
root /mnt/usbdrive/certbot-webroot;
}
Using this directive all requests to the acme-challenge folder will be redirected to the certbot-webroot folder.
Next step: reload nginx (sudo service nginx reload
). Note that at no time we’ll have to truly shut down nginx.
4. Calling certbot
The first call to certbot instructs it to use the webroot plugin and create a certificate for the indicated domain.
sudo certbot certonly --webroot -w /mnt/usbdrive/certbot-webroot -d seafile.example.org
Certbot interactively asks for an e-mail address (for urgent notices and certificate revocation) and that’s about it! If everything works fine (check the program’s output!), the newly created (and signed!) certificates should be stored in /etc/letsencrypt/live/seafile.example.org. The last step of the initial setup consists in updating nginx’s config file to point to the new location of the certificate and key. (I suppose that you’re already hosting Seafile through SSL/TLS, even if it’s “only” with a self-signed certificate. If you’re using the Let’s Encrypt certificates for an initial setup, you should probably consult either the official manual for the specifics of configuring Seafile for SSL/TLS.)
ssl_certificate /etc/letsencrypt/live/seafile.example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/seafile.example.org/privkey.pem;
Now, reload nginx a second time and everything should work just fine. (If not, try reloading seafile too.)
5. Automating certificate renewal
The last piece of the puzzle, the crucial one, is to actually automate the renewal process. This has become very easy with certbot’s recent enhancements regarding exit codes and addition of a --quiet
switch. Current versions are ready to be called directly through cron without having to use a wrapper script.
It’s sufficient to add a daily (or twice daily) call to either the system crontab or root’s own crontab. Type crontab -e as root in order to edit root’s crontab. Add the following line:
47 */12 * * * sleep 16; /path/to/certbot renew --quiet --post-hook "/usr/sbin/service nginx reload"
Please change the minutes number (47) and seconds number (16) to random integers between 0 and 59, in order to spread the load on the ACME-servers!
That should be all! Certbot only actually contacts the server if one of the configured certificates approaches its expiration date (leaving you a month to fix any upcoming issues). It only exits with code 1 if it encounters a serious problem. In this case cron will collect the error output and send an e-mail to the administrator. Obviously you should make sure that your crontab contains a working mailto directive! (e.g. MAILTO="admin@example.org"
)
Note (2016-08-10, certbot v0.8.1): Currently the command given to --post-hook
is always executed even when no renewal attempt was made. This is a bug; it will be fixed in the next release. In the meantime you may reduce certbot’s frequency in crontab or use a simple wrapper script that checks the modification time of the certificate. (See the original blog post for a sample script.)
Further debugging output can be found in /var/log/letsencrypt
.
I hope this write-up doesn’t contain too many errors. If you find any, please notify my in the comments.