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.

BernardSpil/LetsEncrypt.py (last edited 2016-06-18T19:07:15+0000 by BernardSpil)