This would also be usable on non-FreeBSD systems.
This guide uses the official client from the security/letsencrypt.sh port
The guide using the !Lets_k_encrypt port
The guide using the LetsEncrypt.sh port
You will want to check the BernardSpil/LetsEncrypt.sh guide for more detail.
Prepare user & directories
To make life easier all of the challenges (LetsEncrypt as well as keybase etc) will be hosted in a shared dir /usr/local/www/.well-known on the jail running my Apache server. The LetsEncrypt bits will land in /etc/ssl/letsencrypt on the host system. There's no requirement to run the interaction with the LetsEncrypt servers as root, so these will run as a non-privileged user. This unprivileged user will have to write to the acme-challenge and the directory that will contain the keys and certificates.
pw groupadd -n _letsencrypt -g 443
pw useradd -n _letsencrypt -u 443 -g 443 -d /etc/ssl/letsencrypt -w no -s /nonexistent
mkdir -m 770 /etc/ssl/letsencrypt
chown root:_letsencrypt /etc/ssl/letsencrypt
mkdir -p -m 775 /usr/jails/http/usr/local/www/.well-known/acme-challenge
chgrp _letsencrypt /usr/jails/http/usr/local/www/.well-known/acme-challenge
Adapt the .well-known/acme-challenge directory to your situation. It is assumed that a webserver is already installed and /usr/jails/http/usr/local/www already exists, otherwise the modes on the path elements to acme-challenge will be way to wide.
LetsEncrypt Script
This method uses the script from Lukas Schauer which he hosts on GitHub. This script does not require Python and doesn't have any requirements besides bash or zsh. Download the script and default config from GitHub
fetch -o /etc/ssl/letsencrypt/letsencrypt.sh https://github.com/lukas2511/letsencrypt.sh/raw/master/letsencrypt.sh
fetch -o /etc/ssl/letsencrypt/config.sh https://github.com/lukas2511/letsencrypt.sh/raw/master/config.sh.example
chgrp _letsencrypt /etc/ssl/letsencrypt/{letsencrypt,config}.sh
The latest version of the script supports zsh but you'll have to invoke it as zsh letsencrypt.sh or alternatively modify the !#shebangs in the scripts.
Letsencrypt configuration
The default configuration file requires some changes, these are stored in /etc/ssl/letsencrypt/config.sh
BASEDIR="/etc/ssl/letsencrypt"
WELLKNOWN="/usr/jails/http/usr/local/www/.well-known/acme-challenge"
alias openssl='/usr/local/bin/openssl'
To make use of LibreSSL (or OpenSSL from ports) you must add the alias openssl to the config script.
First run
You are now setup to actually run LetsEncrypt
cd /etc/ssl/letsencrypt
su -m _letsencrypt -c 'zsh ./letsencrypt.sh --cron'
(Replace zsh with bash if that's the shell you have installed)
Automate
Now you can schedule your certificate renewal job. By default the script will only renew if the remaining validity of your certificates is less than a month. A weekly job would thus be adequate.
As root
#!/bin/sh
# Run script to renew certs
cd /etc/ssl/letsencrypt
su -m _letsencrypt -c 'zsh ./letsencrypt.sh --cron'
# Deploy certs if they've been renewed
domain="example.net"
targets="mail http"
for jail in ${targets}; do
[ -z "`diff -rq /etc/ssl/letsencrypt/certs/${domain}/fullchain.pem /usr/jails/${jail}/etc/ssl/certs/${domain}.pem`" ] && continue
cp -L "/etc/ssl/letsencrypt/certs/${domain}/privkey.pem" "/usr/jails/${jail}/etc/ssl/priv/${domain}.pem"
cp -L "/etc/ssl/letsencrypt/certs/${domain}/fullchain.pem" "/usr/jails/${jail}/etc/ssl/certs/${domain}.pem"
chmod 400 "/usr/jails/${jail}/etc/ssl/priv/${domain}.pem"
chmod 644 "/usr/jails/${jail}/etc/ssl/certs/${domain}.pem"
# Restart/-load relevant services
[ "${jail}" = "http" ] && jexec ${jail} service apache24 restart
[ "${jail}" = "mail" ] && jexec ${jail} service smtpd restart
done
You'll need to adapt your script for your requirements, this is merely an example of how it could be done.