2021-09-17
Let's encrypt en 4 étapes
Un package, une entrée dns, une machine avec un nsd et une crontab. Voilà tout ce qu’il m’a fallu pour mettre en place un certificat générique.
Le package
Il faut activer l’option ‘EXAMPLES’ du port pour obtenir les scripts en relation avec le mode dns. Avec poudriere:
# poudriere options -n -s security/acme.sh
===> The following configuration options are available for acme.sh-3.0.0:
BINDTOOLS=off: Depend on bind-tools for nsupdate
DOCS=on: Build and/or install documentation
EXAMPLES=on: Build and/or install examples
IDN=off: International Domain Names support
STANDALONE=off: Standalone mode requires SOCAT
====> Options available for the single HTTP: you have to select exactly one of them
CURL=on: Depend on cURL for HTTP(S) queries
WGET=off: Depend on Wget for HTTP(S) queries
ou depuis l’arbre des ports:
$ cat /var/db/ports/security_acme.sh/options
# This file is auto-generated by 'make config'.
# Options for acme.sh-2.8.9
_OPTIONS_READ=acme.sh-2.8.9
_FILE_COMPLETE_OPTIONS_LIST=BINDTOOLS DOCS EXAMPLES IDN STANDALONE CURL WGET
OPTIONS_FILE_UNSET+=BINDTOOLS
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_SET+=EXAMPLES
OPTIONS_FILE_UNSET+=IDN
OPTIONS_FILE_UNSET+=STANDALONE
OPTIONS_FILE_SET+=CURL
OPTIONS_FILE_UNSET+=WGET
Une fois installé les scripts sont disponibles dans /usr/local/share/examples/acme.sh/dnsapi/.
Une entrée dns
Sur le serveur faisant autorité pour mon domaine j’ajoute l’entrée suivante:
$ grep acme zonesdir/bsdsx.fr
_acme-challenge.bsdsx.fr. IN NS foo.bsdsx.fr.
Une machine avec un nsd
foo.bsdsx.fr fait office de serveur DNS secondaire pour mon domaine, je lui rajoute la sous-zone:
$ tail -n 3 nsd.conf
zone:
name: _acme-challenge.bsdsx.fr
zonefile: _acme-challenge.bsdsx.fr
La configuration de cette sous-zone est basique:
$ cat zonesdir/_acme-challenge.bsdsx.fr
$TTL 3D
@ IN SOA foo.bsdsx.fr. dsx.bsdsx.fr. (
2021061701; serial
24h; refresh
1h; retry
7d; expire
1d; default_ttl
)
IN NS foo.bsdsx.fr.
Une crontab
L’installation de security/acme.sh sur la machine foo.bsdsx.fr ajoute un utilisateur dédié:
$ grep acme /etc/passwd
acme:*:169:169:ACME protocol client:/var/db/acme:/bin/sh
Pour obtenir un certificat inutile de paraphraser la documentation: https://github.com/acmesh-official dnsapi nsd
Mon fichier de conf:
# cat /var/db/acme/.acme.sh/account.conf
Nsd_ZoneFile="/zjails/slave-dns/chroot/zonesdir/_acme-challenge.bsdsx.fr"
Nsd_Command="/usr/local/bin/doas /usr/sbin/jexec slave-dns /usr/local/sbin/nsd-control -c /chroot/etc/nsd.conf reload _acme-challenge.bsdsx.fr"
DEFAULT_DNS_SLEEP="0"
CERT_HOME="/var/db/acme/certs"
LOG_FILE='/var/db/acme/acme.sh.log'
USER_PATH='/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/var/db/acme/bin'
Oui, le dns est dans une jail, ce qui explique la commande à rallonge (qui au final ne fait que recharger la sous-zone).
Je exécute la commande suivante une fois par semaine:
/usr/local/sbin/acme.sh --cron --dns dns_nsd --dnssleep 0 --domain bsdsx.fr --domain '*.bsdsx.fr'
Et avant la date fatidique:
/usr/local/sbin/acme.sh --cron --dns dns_nsd --dnssleep 0 --domain bsdsx.fr --domain '*.bsdsx.fr' --force
Il ne me reste plus qu’à synchroniser mes autres machines à l’aide d’une clef ssh dédiée:
/usr/local/bin/rsync -a --exclude='*.conf' --exclude='*.csr' -e "ssh -6 -l acme -i .ssh/acme_rsa" foo.bsdsx.fr:certs/bsdsx.fr/ /chemin/qui/va/bien
C’est tout !
Exemples d’utilisation
opensmtpd:
$ grep ^pki smtpd.conf
pki $host_name key "/etc/mail/bsdsx.fr.key"
pki $host_name cert "/etc/mail/fullchain.cer"
dovecot:
$ grep ^ssl /etc/rc.conf.d/dovecot.conf
ssl_cert = </etc/rc.conf.d/jails/fullchain.cer
ssl_key = </etc/rc.conf.d/jails/bsdsx.fr.key
hitch:
$ cat $certs/$domain.key $certs/fullchain.cer $jconf/dhparam.pem > $path/etc/hitch.pem
$ grep ^pem $path/etc/hitch.pem
pem-file = "/etc/hitch.pem"
Commentaires: https://github.com/bsdsx/blog_posts/issues/9