Tags

bluetooth cu dns dovecot encrypt ipfw lets opensmtpd shell ssl tls unbound

2021-09-17

[ ssl tls lets encrypt dns ]

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

Lien vers ce billet