OpenSMTPD 6.4 est arrivé !

Le 26 octobre 2018 sortait OpenSMTPD 6.4.0, suivie le 16 décembre d'un correctif, OpenSMTPD 6.4.1. Tout comme la version 5.4, elle se distingue par une importante refonte du fichier de configuration. Bien entendu, une fois de plus, mon tutoriel sur la mise en place d'un serveur email a été mis à jour pour tenir compte de cette évolution.

action et match

Jusqu'à présent, le gros de la logique de traitement était gouvernée par l'utilisation d'accept et, dans une moindre mesure, de reject. Et bien c'est fini, à la trappe les vieilleries ! Désormais, la logique sera séparée en deux parties bien distinctes.

D'une part, action la définition d'actions à effectuer, typiquement un relay ou bien une manière de délivrer un email (lmpt, maildir, …). D'autre part, on trouve match qui pose les conditions sous lesquelles ces actions seront activées.

Un exemple simple pour la délivrance d'emails locaux avec LMTP :

accept alias <aliases> deliver to lmtp "/run/dovecot/lmtp"

Est transformé en :

action local_deliver lmtp "/run/dovecot/lmtp" alias <aliases>
match action local_deliver

Cette nouvelle syntaxe est tout d'abord justifiée par un véritable besoin sous-jacent que Gilles explique fort bien dans son blog. Et en bonus, je trouve que facilite énormément la compréhension du fichier de configuration. La transition n'est pas bien difficile et au final on y gagne.

Abréviations

Passé la grosse transition avec action et match, il faut ensuite prendre en compte quelques abréviations fort appréciables. Tout d'abord, dans les pki et ca, certificate est abrégé en cert. Ensuite, dans les listen, mask-source est abrégé en mask-src. Enfin, dans relay, hostname est remplacé par helo.

Incompatibilité

Attention, cette version utilise une queue incompatible avec celle des versions précédentes. Le plus simple est, avant de mettre à jour, de s'assurer que la queue est vide.

# smtpctl show queue

Si besoin, analysez, voir supprimez, ce qui bloque. smtpctl est là pour vous aider.

LibreSSL et installation

Une autre grande modification est la fin du support d'OpenSSL. Désormais, OpenSMTPD utilise exclusivement LibreSSL. Ceci engendre un problème de taille : LibreSSL se déploie en remplacement d'OpenSSL mais est désormais une version à part entière, implémentant la plupart de l'API 1.0 D'OpenSSL (mais pas tout) ainsi qu'une API qui lui est propre. LibreSSL est donc rarement disponible dans les distributions GNU/Linux, ce qui pousse ces dernières à ne pas mettre à jour OpenSMTPD.

Pour palier à ce problème, j'ai utilisé une VM sur laquelle j'ai compilé LibreSSL exclusivement en statique et l'ai installé dans /usr/static. J'ai ensuite compilé OpenSMTPD en le liant statiquement à LibreSSL, ce qui fait qu'il n'a plus besoin que cette bibliothèque soit installée sur le système. Si vous empaquetez cette version, le paquet sera fonctionnel sur votre système. Étant sur ArchLinux, j'ai édité les PKGBUILD des paquets libressl et opensmtpd comme suit :

# Maintainer: Levente Polyak <anthraxx[at]archlinux[dot]org>
# Contributor: Reventlov <contact@volcanis.me>
# Contributor: Rodolphe Breard <rodolphe@what.tf>

pkgname=libressl
pkgver=2.8.3
pkgrel=1
pkgdesc='FREE version of the SSL/TLS protocol forked from OpenSSL - EXPRIMENTAL ONLY'
url='http://www.libressl.org/'
arch=('x86_64')
license=('custom:OpenSSL')
depends=('glibc')
optdepends=('ca-certificates')
backup=('etc/libressl/openssl.cnf')
source=("http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/${pkgname}-${pkgver}.tar.gz")
sha512sums=('3967e08b3dc2277bf77057ea1f11148df7f96a2203cd21cf841902f2a1ec11320384a001d01fa58154d35612f7981bf89d5b1a60a2387713d5657677f76cc682')

prepare() {
  cd ${pkgname}-${pkgver}
  # fix manpage symlink locations
  sed -ri 's|(ln -sf )(.+) (.+)|\1\2.gz \3.gz|g' man/Makefile.in
}

build() {
  cd ${pkgname}-${pkgver}

  ./configure \
    --prefix=/usr/static \
    --with-openssldir=/etc/libressl \
    --enable-shared=no \
    --enable-static=yes

  make
}

check() {
  cd ${pkgname}-${pkgver}
  make check
}

package() {
  cd ${pkgname}-${pkgver}
  make DESTDIR="${pkgdir}" install
  install -Dm 644 COPYING "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
  rm "${pkgdir}/etc/libressl/cert.pem"
  ln -s /usr/static/lib/libssl.a "${pkgdir}/usr/static/lib/libssl.a.1.0.0"
  ln -s /usr/static/lib/libcrypto.a "${pkgdir}/usr/static/lib/libcrypto.a.1.0.0"
  ln -s /usr/static/lib/libtls.a "${pkgdir}/usr/static/lib/libtls.a.1.0.0"
}

Pour opensmtpd, n'oubliez pas de télécharger les fichiers annexes, à l'exception du patch.

# Maintainer: Lukas Fleischer <lfleischer@archlinux.org>
# Contributor: Sébastien Luttringer
# Contributor: parchd <parchd@archlinux.info>
# Contributor: Rodolphe Breard <rodolphe@what.tf>

pkgname=opensmtpd
pkgver=6.4.1p2
pkgrel=2
pkgdesc='Free implementation of the server-side SMTP protocol'
arch=('x86_64')
url='https://www.opensmtpd.org/'
license=('custom')
depends=('libasr' 'libevent' 'pam')
makedepends=('libressl')
provides=('smtp-server' 'smtp-forwarder')
conflicts=('smtp-server' 'smtp-forwarder')
backup=('etc/smtpd/smtpd.conf' 'etc/smtpd/aliases')
options=('emptydirs')
source=("https://www.opensmtpd.org/archives/$pkgname-$pkgver.tar.gz"
        'opensmtpd.sysusers'
        'smtpd.service'
        'smtpd.socket')
sha256sums=('b69b84934bcc4893ca334504411cd47f86ea04ac5e971a5746d44c473ac5f732'
            'b38b64f1457b7227d55585edc711cce525e089516d16b093e6c44387380e6b13'
            'abf5baeb2a87c60d668ad18ea41cc08cab7a4f76339dd6df05de15cdaadaf922'
            '32d46de5562d01de445d04c93bcc9f94bf103539b676e449c32e3603a3866cf8')

prepare() {
  sed -ri 's,/etc/mail,/etc/smtpd,g' "$pkgname-$pkgver/smtpd/smtpd.conf"
}

build() {
  cd "$pkgname-$pkgver"

  LDFLAGS="-lpthread /usr/static/lib/libssl.a /usr/static/lib/libtls.a /usr/static/lib/libcrypto.a" ./configure \
    --prefix=/usr \
    --sysconfdir=/etc/smtpd \
    --sbindir=/usr/bin \
    --libexecdir=/usr/lib/smtpd \
    --with-path-mbox=/var/spool/mail \
    --with-path-empty=/var/empty \
    --with-path-socket=/run \
    --with-path-CAfile=/etc/ssl/certs/ca-certificates.crt \
    --with-user-smtpd=smtpd \
    --with-user-queue=smtpq \
    --with-group-queue=smtpq \
    --with-auth-pam \
    --with-libssl='/usr/static/lib' \
    --with-cflags='-I/usr/static/include'

  make
}

package() {
  cd "$pkgname-$pkgver"

  make DESTDIR="$pkgdir/" install

  ln -s /usr/bin/smtpctl "$pkgdir/usr/bin/sendmail"
  ln -s /usr/bin/smtpctl "$pkgdir/usr/bin/mailq"
  ln -s /usr/bin/smtpctl "$pkgdir/usr/bin/newaliases"
  ln -s /usr/bin/smtpctl "$pkgdir/usr/bin/makemap"

  # install license, systemd unit files, sysusers
  install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
  install -Dm644 "$srcdir/smtpd.service" "$pkgdir/usr/lib/systemd/system/smtpd.service"
  install -Dm644 "$srcdir/smtpd.socket" "$pkgdir/usr/lib/systemd/system/smtpd.socket"
  install -Dm644 "$srcdir/opensmtpd.sysusers" "$pkgdir/usr/lib/sysusers.d/opensmtpd.conf"

  # install an empty aliases file (used by the default config)
  install -Dm644 /dev/null "$pkgdir/etc/smtpd/aliases"
}

Je ne publierai pas ces paquets dans l'AUR car cette méthode ne respecte pas les standards de qualité attendus pour des paquets. C'est une solution temporaire le temps qu'une véritable solution soit trouvée, par exemple un changement de la politique de LibreSSL.