Tags

arm64 blacklistd bluetooth cu dns dovecot freebsd ipfw lets_encrypt opensmtpd shell ssl tls unbound

Powered by

blOg
maRkdown
awK
shEll

08/05/2021

[ dovecot opensmtpd ]

202105080800 dovecot opensmtpd

Authentification des utilisateurs

Ce billet fait suite à la configuration initiale de mon serveur opensmtpd. Petit rappel des faits:

Pour authentifier un utilisateur, il me faut un fichier de type passwd:

user:hash du mot de passe:uid:gid:...

D'après la documentation d'opensmtpd il me faudrait un fichier avec ce format:

user  hash du mot de passe

D'après la documentation de dovecot (que je dois installer sinon mes utilisateurs vont avoir du mal à lire leurs courriels) il peut avoir cette forme:

user:{nom de la fonction de hachage}hash du mot de passe

Je vais vérifier qu'un fichier

user:hash du mot de passe

est bien compatible avec opensmtpd et dovecot en commençant par installer ce dernier.

Installation

En utilisant mon outil maison sjail:

$ sjail /zjails/mail pkg install dovecot
...

ou en mode barbare:

$ doas pkg -c /zjails/mail install --no-scripts --yes --no-repo-update dovecot
...
$ doas pw -R /zjails/mail groupadd dovecot  -g 143
$ doas pw -R /zjails/mail groupadd dovenull -g 144
$ doas pw -R /zjails/mail useradd  dovecot  -u 143 -g 143 -c "Dovecot User" -d /var/empty -s /usr/sbin/nologin
$ doas pw -R /zjails/mail useradd  dovenull -u 144 -g 144 -c "Dovecot login User" -d /var/empty -s /usr/sbin/nologin
$ cp /lib/libm.so.5 /zjails/mail/lib/
$ doas chroot /zjails/mail /sbin/ldconfig -elf /usr/local/lib /usr/local/lib/dovecot

Test initial de dovecot:

$ doas chroot /zjails/mail /usr/local/sbin/dovecot --version
Fatal: open(/dev/null) failed: No such file or directory

Rien de méchant mais il ne faudra pas oublier de démonter /zjails/mail/dev:

$ doas mount -t devfs devfs /zjails/mail/dev
$ doas devfs -m /zjails/mail/dev rule -s 4 applyset
$ doas chroot /zjails/mail /usr/local/sbin/dovecot --version
2.3.13 (89f716dc2)
$ doas umount /zjails/mail/dev

Je n'évoquerai plus les commandes concernant /dev. Pour obtenir la (longue) configuration par défaut:

$ doas chroot /zjails/mail /usr/local/sbin/dovecot -a -c /dev/null
...
[ plus de 1000 lignes ]

0 - Minimal

La configuration de dovecot se base sur plusieurs fichiers situés dans /usr/local/etc/dovecot/example-config/conf.d. Pour ma configuration de base je veux:

$ cat /zjail/mail/etc/mail/dovecot.conf
log_path = /dev/stderr
protocols = pop3
listen = ::1

service pop3-login {
  inet_listener pop3 {
    port = 1110
  }
}
$ doas chroot /zjails/mail /usr/local/sbin/dovecot -F -c /etc/mail/dovecot.conf
May 01 10:07:37 master: Info: Dovecot v2.3.13 (89f716dc2) starting up for imap

Et dans un autre shell:

$ netstat -an -f inet6 | grep 1110
tcp6       0      0 ::1.1110               *.*                    LISTEN

1 - Utilisateurs et mots de passe - dovecot

Pour obtenir le hash d'un mot de passe je peux utiliser smtpctl encrypt ou doveadm pw (ne pas oublier de garder une trace du mot de passe en clair avec |tee):

$ touch /zjails/mail/etc/mail/passwd
$ openssl rand -base64 12 | tee /zjails/mail/.foo | doas chroot /zjails/mail/ /usr/local/sbin/smtpctl encrypt | sed -e 's/^/foo:/' >> /zjails/mail/etc/mail/passwd
$ doas chroot /zjails/mail/ /usr/local/bin/doveadm -c /dev/null pw -s SHA512-CRYPT -p `openssl rand -base64 12 | tee /zjails/mail/.bar` | sed -e 's/^{SHA512\-CRYPT}/bar:/' >> /zjails/mail/etc/mail/passwd
$ cat /zjail/mail/etc/mail/dovecot.conf
log_path = /dev/stderr
protocols = pop3
listen = ::1

service pop3-login {
  inet_listener pop3 {
    port = 1110
  }
}

passdb {
  driver = passwd-file
  args = scheme=SHA512-CRYPT username_format=%n /etc/mail/passwd
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/opt/vmail/%n
}

Premier essai:

$ telnet ::1 1110
Trying ::1...
Connected to localhost.
Escape character is '^]'.
+OK Dovecot ready.
user foo
+OK
pass KsFgKsTTyHdVu40W
+OK Logged in.
Connection closed by foreign host.

Côté serveur:

May 06 07:42:00 pop3-login: Info: Login: user=<foo>, method=PLAIN, rip=::1, lip=::1, mpid=2987, secured, session=<qkgqxaLBVHIAAAAAAAAAAAAAAAAAAAAB>
May 06 07:42:00 pop3(foo)<2987><qkgqxaLBVHIAAAAAAAAAAAAAAAAAAAAB>: Error: mail_location not set and autodetection failed: Mail storage autodetection failed with home=/opt/vmail/foo
May 06 07:42:00 pop3(foo)<2987><qkgqxaLBVHIAAAAAAAAAAAAAAAAAAAAB>: Info: mail_location not set and autodetection failed: Mail storage autodetection failed with home=/opt/vmail/foo top=0/0, retr=0/0, del=0/0, size=0

Je dois renseigner mail_location:

$ cat /zjail/mail/etc/mail/dovecot.conf
log_path = /dev/stderr
protocols = pop3
listen = ::1
mail_location = maildir:~/

service pop3-login {
  inet_listener pop3 {
    port = 1110
  }
}

passdb {
  driver = passwd-file
  args = scheme=SHA512-CRYPT username_format=%n /etc/mail/passwd
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/opt/vmail/%n
}

Deuxième essai:

$ telnet ::1 1110
Trying ::1...
Connected to localhost.
Escape character is '^]'.
+OK Dovecot ready.
user foo
+OK
pass KsFgKsTTyHdVu40W
+OK Logged in.
quit
+OK Logging out.
Connection closed by foreign host.

2 - Utilisateurs et mots de passe - opensmtpd

Je modifie en conséquence la configuration d'opensmtpd pour tester l'authentification:

$ cat /zjails/mail/etc/mail/smtpd.conf
filter check_rdns   phase connect match !rdns   junk
filter check_fcrdns phase connect match !fcrdns junk
filter check_dns chain { check_rdns, check_fcrdns }

table trusted { 2001:DB8:666::/64 }
table myfroms { "@bsdsx\.fr$", "@.*\.bsdsx\.fr$" }
filter check_trusted phase connect match src <trusted> bypass
filter check_myfroms phase mail-from match mail-from regex <myfroms> disconnect "550 invalid mail from"
filter check_mail_from chain { check_trusted, check_myfroms }

filter filters chain { check_rdns, check_fcrdns, check_trusted, check_myfroms }
listen on ::1 port 2525 filter filters

table users file:/etc/mail/passwd
listen on ::1 port 5877 auth <users>

table domains { "bsdsx.fr", "*.bsdsx.fr" }
table aliases { abuse = postmaster, postmaster = root, root = foo }
action "local_mail" maildir "/opt/vmail/%{dest.user}" junk userbase <users> alias <aliases>
match from any for domain <domains> action "local_mail"

Mais le résultat est sans appel:

$ doas chroot /zjails/mail /usr/local/sbin/smtpd -f /etc/mail/smtpd.conf -d
smtpd: invalid listen option: auth requires tls/smtps

Un peu de pki:

$ openssl genrsa -out /zjails/mail/etc/mail/key.key 4096
$ openssl req -new -x509 -key /zjails/mail/etc/mail/key.key -subj "/CN=mail/C=FR/ST=IdF/L=Paris/O=Pouet inc/OU=Pouet" -out /zjails/mail/etc/mail/crt.crt -days 365
$ doas chown root /zjails/mail/etc/mail/key.key /zjails/mail/etc/mail/crt.crt

J'ajoute l'option -T lookup:

$ doas chroot /zjails/mail /usr/local/sbin/smtpd -f /etc/mail/smtpd.conf -d -T lookup

L'authentification se fait avec du base64:

$ printf 'foo' | openssl base64
Zm9v

Le truc à ne pas faire:

$ openssl base64 -in /zjails/mail/.foo
S3NGZ0tzVFR5SGRWdTQwVwo=

car on se retrouve avec un '\n' en trop:

$ cat /zjails/mail/.foo | tr -d '\n' | openssl base64
S3NGZ0tzVFR5SGRWdTQwVw==

Et à l'aide d'openssl s_client, le telnet du tls:

$ openssl s_client -6 -starttls smtp -connect localhost:5877
[ snip tout plein de trucs ]
---
read R BLOCK
ehlo localhost
...
auth login
334 VXNlcm5hbWU6
Zm9v
334 UGFzc3dvcmQ6
S3NGZ0tzVFR5SGRWdTQwVw==
235 2.0.0 Authentication succeeded
quit
221 2.0.0 Bye

Je teste mon utilisateur "bar":

$ printf 'bar' | openssl base64
YmFy
$ cat /zjails/mail/.bar | tr -d '\n' | openssl base64
aXpNNkRSenFydEw5M3g3Mw==
$ openssl s_client -6 -starttls smtp -connect localhost:5877
...
auth login
334 VXNlcm5hbWU6
YmFy
334 UGFzc3dvcmQ6
aXpNNkRSenFydEw5M3g3Mw==
235 2.0.0 Authentication succeeded
quit
221 2.0.0 Bye

Côté serveur:

f7a2e6aa567530c9 smtp connected address=[::1] host=localhost
f7a2e6aa567530c9 smtp tls ciphers=TLSv1.3:TLS_AES_256_GCM_SHA384:256
lookup: lookup "bar" as CREDENTIALS in table static:users -> "$6$.BEf4XECFaoMAlDu$x5RRN3/j58n7ke.LfJEwtF7hwWfiSqaxDM5s9Jc1B32UZiCiNfMKH9VueT6ey7wtO4YaQ/y.56PmJ.sHFokVr."
f7a2e6aa567530c9 smtp authentication user=bar result=ok
f7a2e6aa567530c9 smtp disconnected reason=quit

Pour finir

Ce fichier passwd termine la configuration initiale de mon serveur de courrier. Chaque étape de la réception du courriel a été testée et l'authentification des utilisateurs est fonctionnelle. Ce qu'il me reste à faire:

Mais pour se faire je ne saurais trop recommander la lecture de:

Commentaires: https://github.com/bsdsx/blog_posts/issues/8


Lien vers ce billet