Installation réalisée par jvoisin et nicoo le mercredi 3 Août 2016.

Installation d'acmetool

Pin depuis testing

On pin acmetool depuis stretch, vu que ce n'est pas encore disponible via les backports.

#/etc/apt/preferences
Package: *
Pin: release n=jessie
Pin-Priority: 900
#/etc/apt/preferences.d/acmetools
Package: acmetool
Pin: release n=testing
Pin-Priority: -1

On se fend ensuite d'un apt update && apt upgrade, et on vérifie qu'on n'upgrade pas le système entier vers testing.

Installation du paquet

Un bête apt install acmetool.

Configuration

On prend le parti de ne pas laisser tourner acmetool en tant que root. C'est un mode supporté et documenté.

Création d'un user dédié

adduser --system --group --home /var/lib/acme/ acme
chsh -s /usr/sbin/nologin acme
passwd -l acme
etckeeper commit

Ajustement des droits d'accès

chown -Rf acme:acme /var/lib/acme
mkdir /usr/lib/acme/hooks

Configuration d'acmetool

sudo -u acme acmetool quickstart
  • On choisi d'utiliser directement le serveur « live ».
  • On utilise la méthode « webroot » pour faire interagir acmetool et le httpd :

      location /.well-known/acme-challenge {
          alias /var/lib/acme/webroot;
      }
    
  • On choisis adminsys@nos-oignons.net comme adresse de contact.

Modification du crontab

Par défaut, acmetool installe un cronjob qui lance acmetool --batch reconcile tous les jours.

On modifie le crontab en ajoutant MAILTO=root.

Configuration de Nginx

Obtention des certificats

sudo -u acme acmetool want {www.,}nos-oignons.{org,net,fr}

Changement de certificats

  • On pointe vers /var/lib/acme/live/nos-oignons.net/ pour les certificats.
  • On ajoute un « site » https-redirect pour rediriger depuis nos-oignons.{fr,org} vers .net :

        #/etc/nginx/sites-available/https-redirect
        server {
          listen   [::]:443 ssl;
          listen   443 ssl;
    
          include snippets/headers.conf;
    
          ssl_certificate     /var/lib/acme/live/nos-oignons.net/fullchain;
          ssl_certificate_key /var/lib/acme/live/nos-oignons.net/privkey;
    
          server_name nos-oignons.org www.nos-oignons.org nos-oignons.fr www.nos-oignons.fr;
    
          location / {
              return 301 https://nos-oignons.net$request_uri;
          }
    
      }
    
  • On fait un lien symbolique dans /etc/nginx/sites-enabled/

  • On se fend d'un nginx -t pour confirmer la configuration.
  • On relance nginx

Configuration de Postfix

  • La configuration antérieure avait un certificat (« snake oil ») pour bulbe.nos-oignons.net. C'est ce qu'on garde.
  • On obtient simplement une nouvelle clef et un nouveau certificat avec sudo -u acme acmetool want bulbe.nos-oignons.net.
  • On reconfigure Postfix :

      # /etc/postfix/main.cf
      smtpd_tls_cert_file=/var/lib/acme/live/bulbe.nos-oignons.net/fullchain
      smtpd_tls_key_file=/var/lib/acme/live/bulbe.nos-oignons.net/privkey
    
  • On teste :

      # swaks --tls --tls-verify bulbe.nos-oignons.net
      To: noexist@nos-oignons.net
      === Trying bulbe.nos-oignons.net:25...
      === Connected to bulbe.nos-oignons.net.
      <-  220 bulbe.nos-oignons.net ESMTP Postfix (Debian GNU/Oignons)
       -> EHLO bulbe.nos-oignons.net
      <-  250-bulbe.nos-oignons.net
      <-  250-PIPELINING
      <-  250-SIZE 10240000
      <-  250-VRFY
      <-  250-ETRN
      <-  250-STARTTLS
      <-  250-AUTH DIGEST-MD5 NTLM CRAM-MD5 LOGIN PLAIN
      <-  250-AUTH=DIGEST-MD5 NTLM CRAM-MD5 LOGIN PLAIN
      <-  250-ENHANCEDSTATUSCODES
      <-  250-8BITMIME
      <-  250 DSN
       -> STARTTLS
      <-  220 2.0.0 Ready to start TLS
      === TLS started with cipher TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256
      === TLS no local certificate set
      === TLS peer DN="/CN=bulbe.nos-oignons.net"
       ~> EHLO bulbe.nos-oignons.net
      <~  250-bulbe.nos-oignons.net
      <~  250-PIPELINING
      <~  250-SIZE 10240000
      <~  250-VRFY
      <~  250-ETRN
      <~  250-AUTH DIGEST-MD5 NTLM CRAM-MD5 LOGIN PLAIN
      <~  250-AUTH=DIGEST-MD5 NTLM CRAM-MD5 LOGIN PLAIN
      <~  250-ENHANCEDSTATUSCODES
      <~  250-8BITMIME
      <~  250 DSN
       ~> MAIL FROM:<root@bulbe.nos-oignons.net>
      <~  250 2.1.0 Ok
       ~> RCPT TO:<noexist@nos-oignons.net>
      <~* 550 5.1.1 <noexist@nos-oignons.net>: Recipient address rejected: User unknown in local recipient table
       ~> QUIT
      <~  221 2.0.0 Bye
      === Connection closed with remote host.
    
  • On met à jour la fingerprint sur les nœuds, et la documentation.
    Note : on pin maintenant la clef publique, vu que le certificat lui-même change.

  • On teste en envoyant un mail de test depuis les nœuds.
  • On s'assure qu'acmetool ne changera pas la clef RSA pour Postfix :

      # /var/lib/acme/desired/bulbe.nos-oignons.net-syghkqm6izf3fbm2sjalo4rnnq
      satisfy:
        names:
        - bulbe.nos-oignons.net
    
      request:
        key:
          id: k2425j72hots32y36ftqpsmrtktx2pug6hcpy2mcth6hgoofqxwq
    

    C'est une option cachée dans la doc.

Hooks acmetool

sudo

On donne à acmetool le droit d'exécuter les scripts contenus dans /var/lib/acme/hooks en tant que root :

# /etc/sudoers.d/05_acmetool
acme ALL=(root) NOPASSWD: /usr/lib/acme/hooks

Note : Faire ainsi ne pose pas vraiment de problème de sécurité, car le répertoire et son contenu appartiennent à root, et ne sont écrivables que par ce-dernier.

Nginx

On crée un simple /usr/lib/acme/hook/nginx.sh:

#!/bin/sh -e
if [ "$1" = "live-update" ]; then
    systemctl reload nginx
fi

On le met bit setuid : ce n'est pas effectif, mais ça indique à acmetool qu'ielle doit utiliser sudo.

Postfix

Contrairement à Nginx, on ne recharge que si le certificat de bulbe.nos-oignons.net change.

#!/bin/sh -e
if [ "$1" = "live-update" -a "$2" = "bulbe.nos-oignons.net" ]; then
    systemctl reload postfix
fi

Test & correction

On peut tester le bon fonctionnement des hooks avec la commande suivante :

sudo -u acme acmetool test-notify <nom d'hôte d'un certificat>

En testant, nicoo a découvert que ça ne marchait pas ... parce que le paquet Debian change l'emplacement des hooks pour /etc/acme/hooks. nicoo a corrigé la configuration en conséquence.

Versionnage de la configuration

Vu qu'une partie de /var/lib/acme tient de la configuration (conf et desired), et qu'on versionne la configuration dans /etc avec etckeeper, on a déplacé ces deux dossiers vers /etc/acme et on les a remplacés par des liens symboliques :

# ls -l /etc/acme
total 4
drwxr-xr-x 2 root root 4096 Aug  8 19:03 hooks

# mv /var/lib/acme/{conf,desired} /etc/acme/
# ls -l /etc/acme/
total 12
drwxr-xr-x 2 acme acme 4096 Aug  8 21:48 conf
drwxr-xr-x 2 acme acme 4096 Aug  8 22:06 desired
drwxr-xr-x 2 root root 4096 Aug  8 19:03 hooks

# cd /var/lib/acme
# ln -s ../../../etc/acme/{conf,desired} .
# chown -R root:root /etc/acme/conf

/etc/acme/desired reste la propriété de l'user acme car de nouveaux fichiers de configuration sont créés lorsqu'on invoque acmetool want.