Tags

arm arpaname bin_sh blocage blosxom bsd bsdfrance cblog certification chroot cluster dg834 dhcp diffusion dns dnsmasq domU dovecot fail-over fail2ban firefox fossil freebsd ftp git guruplug install ipv6 jail kernel kimsufi lex libre linutop liste makefile mikrotik ml150 mohawk nanojail netbook netbsd nginx ntp ntp.org openbsd openntpd openrd opensmtpd openwrt orke pkgng poudriere privee proxy python rescue reverse rmll route rrdcgi sendmail sieve sjail sl2009 ssd sshd symon unbound update usb var_empty vimperator world xen yacc zfs

Powered by

blOg
maRkdown
awK
shEll

06/10/2014

[ opensmtpd bsdfrance ]

201410061800 opensmtpd bsdfrance

BSDFrance et opensmtpd

J'ai déjà fait référence dans un précédent billet à la configuration d'une liste privée. Pour ceux qui voudraient un peu plus de détail, voici la version de bsdfrance, l'association qui oeuvre pour la promotion des BSD dans les pays francophones.

 1  listen on bce1
 2  listen on lo2
 3
 4  table bsdfrance.fr         "/etc/mail/bsdfrance.fr"
 5  table asso_@@_bsdfrance.fr "/etc/mail/asso_@@_bsdfrance.fr"
 6  table spammers             "/etc/mail/spammers"
 7  table restrict             { asso_@@_bsdfrance.fr }
 8  table to_restrict          { president_@@_bsdfrance.fr, tresorier_@@_bsdfrance.fr, secretaire_@@_bsdfrance.fr }
 9
10  max-message-size 1M
11
12  reject from any   sender <spammers>
13  accept from any   sender <asso_@@_bsdfrance.fr> for domain "bsdfrance.fr" recipient <restrict> alias <bsdfrance.fr>
14  accept from local sender <to_restrict>          for domain "bsdfrance.fr" recipient <restrict> alias <bsdfrance.fr>
15  reject from any                                 for domain "bsdfrance.fr" recipient <restrict>
16  accept from any                                 for domain "bsdfrance.fr"                      alias <bsdfrance.fr>
17  accept for any relay
nom_de_l_alias: :include:/chemin/vers/un/fichier

L'alias asso est définit comme suit:

asso: :include:/etc/mail/asso_@@_bsdfrance.fr

Merci à toute l'équipe d'opensmtpd pour ce fantastique serveur de courriel.

Ps: afin de ne pas polluer le serveur de courriel de bsdfrance.fr, tous les caractères @ ont été remplacés par _@@_.


Lien vers ce billet

29/03/2014

[ sjail opensmtpd dovecot ]

201403290800 sjail opensmtpd dovecot

Une nanojail pour le courriel

Jusqu'à présent, je confiais les courriels à destination de mon domaine à sendmail. Mais depuis ce message et un précédent billet, je dois me rendre à l'évidence: bapt@ va bien finir par virer sendmail et opensmtpd est quand même drôlement convivial.

Ce (long) billet va détailler l'installation pas à pas d'opensmtpd et de dovecot, le tout dans une nanojail.

sjail et opensmtpd

Pour commencer, je crée une nanojail mx2 et je lui ajoute opensmtpd:

dsx@blade>mkdir mx2
dsx@blade>sjail mx2 init
If you need log, don't forget to add '-l /usr/home/dsx/_jails/mx2/var/run/logpriv'
on syslogd_flags and restart (not reload) syslogd

You could edit do_init_pkg() function before adding any package to match your configuration
dsx@blade>sjail mx2 pkg install opensmtpd
Updating repository catalogue
digests.txz                                                                                                    100% 1868     1.8KB/s   1.8KB/s   00:00    
packagesite.txz                                                                                                100%   11KB  10.8KB/s  10.8KB/s   00:00    
Incremental update completed, 32 packages processed:
0 packages updated, 0 removed and 32 added.
The following 3 packages will be installed:

        Installing ca_root_nss: 3.15.4
        Installing libevent: 1.4.14b_3
        Installing opensmtpd: 5.4.2,1

The installation will require 3 MB more space

721 KB to be downloaded
ca_root_nss-3.15.4.txz                                                                                         100%  296KB 295.7KB/s 295.7KB/s   00:00    
libevent-1.4.14b_3.txz                                                                                         100%  123KB 123.5KB/s 123.5KB/s   00:00    
opensmtpd-5.4.2,1.txz                                                                                          100%  302KB 302.1KB/s 302.1KB/s   00:00    
Checking integrity... done
[1/3] Installing ca_root_nss-3.15.4... done
[2/3] Installing libevent-1.4.14b_3... done
[3/3] Installing opensmtpd-5.4.2,1...===> Creating users and/or groups.
Creating group '_smtpd' with gid '257'.
Creating user '_smtpd' with uid '257'.
Creating user '_smtpq' with uid '258'.
sed: not found
cannot create /etc/mail/mailer.conf: No such file or directory
 done
If you are upgrading from OpenSMTPD version 201303011853 or earlier, please 
follow the procedure below to update the permissions on the OpenSMTPD
spool directories:

  1. Stop 'smtpd' service:

     # /usr/local/etc/rc.d/smtpd stop

  2. Update permissions:

     # chown -R _smtpq:wheel /var/spool/smtpd/corrupt
     # chown -R _smtpq:wheel /var/spool/smtpd/purge
     # chown -R _smtpq:wheel /var/spool/smtpd/queue
     # chown -R _smtpq:wheel /var/spool/smtpd/temporary

  3. Start 'smtpd' service:

     # /usr/local/etc/rc.d/smtpd start

Je peux passer outre le message d'erreur concernant sed: je n'ai nul besoin du fichier /etc/mail/mailer.conf. En effet, je ne compte pas envoyer de courriel directement depuis cette jail (à l'aide de /usr/bin/mail par exemple). sjail est livré avec un script _sjail_opensmtpd, exécuté après l'installation d'opensmtpd et qui va créer les répertoires et fichiers manquant à son bon fonctionnement.

Passons au fichier de configuration. Sa limpidité ne mérite (à mon avis) aucun commentaire:

dsx@blade>cat mx2/etc/mail/smtpd.conf
listen on localhost
table aliases "/etc/mail/aliases"
accept for local alias <aliases> deliver to maildir
accept from any for domain "bsdsx.fr" alias <aliases> deliver to maildir
accept for any relay

Je crée mon utilisateur:

dsx@blade>sudo chroot mail pw groupadd users -g 1000
dsx@blade>echo 'bar' | sudo chroot mx2 pw useradd dsx -c 'Moi personnellement' -g users -m -s /usr/sbin/nologin -h 0

Je fais exprès d'afficher le mot de passe de mon utilisateur car avec la syntaxe suivante:

dsx@blade>sudo chroot mx2 pw useradd bar -c 'bar user' -g users -m -s /usr/sbin/nologin -h 0
password for user bar:

on ne peut pas vérifier la saisie. Il est temps de faire un premier essai:

dsx@blade>sudo chroot mail /usr/local/sbin/smtpd -n -f /etc/mail/smtpd.conf
configuration OK
dsx@blade>sudo chroot mail /usr/local/sbin/smtpd -d -f /etc/mail/smtpd.conf
info: OpenSMTPD 5.4.2p1 starting
info: startup

Depuis un autre terminal:

dsx@blade>telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 blade.bsdsx.fr ESMTP OpenSMTPD
EHLO localhost
250-blade.bsdsx.fr Hello localhost [127.0.0.1], pleased to meet you
250-8BITMIME
250-ENHANCEDSTATUSCODES
250-SIZE 36700160
250-DSN
250 HELP
MAIL FROM: <dsx@localhost>
250 2.0.0: Ok
RCPT TO: <dsx@localhost>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: first try with telnet and localhost

Ok
.
250 2.0.0: 3f78e126 Message accepted for delivery
QUIT
221 2.0.0: Bye
Connection closed by foreign host.

Côté serveur:

smtp-in: New session 36daa667726edf1e from host localhost [127.0.0.1]
smtp-in: Accepted message 3f78e126 on session 36daa667726edf1e: from=<dsx@localhost>, to=<dsx@localhost>, size=49, ndest=1, proto=ESMTP
delivery: Ok for 3f78e126aa0adf4c: from=<dsx@localhost>, to=<dsx@localhost>, user=dsx, method=maildir, delay=16s, stat=Delivered
smtp-in: Closing session 36daa667726edf1e

Un petit tour dans mx2/home/dsx me confirme qu'un répertoire Maildir a bien été créé et peuplé:

dsx@blade>sudo ls -Rl mx2/home/dsx/Maildir/
total 24
drwx------  2 2001  1000  512 Apr  2 21:51 cur
drwx------  2 2001  1000  512 Apr  2 21:51 new
drwx------  2 2001  1000  512 Apr  2 21:51 tmp

mx2/home/dsx/Maildir/cur:
total 0

mx2/home/dsx/Maildir/new:
total 8
-rw-------  1 2001  1000  270 Apr  2 21:51 1396468291.63662.blade.bsdsx.fr

mx2/home/dsx/Maildir/tmp:
total 0

Les essais avec localhost sont concluant, qu'en est-il de mon domaine ?

dsx@blade>telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 blade.bsdsx.fr ESMTP OpenSMTPD
EHLO localhost
250-blade.bsdsx.fr Hello localhost [127.0.0.1], pleased to meet you
[ snip ]
MAIL FROM: <dsx@bsdsx.fr>
250 2.0.0: Ok
RCPT TO: <dsx@bsdsx.fr>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: second try with telnet and domain

Ok
.
250 2.0.0: eb6d735f Message accepted for delivery
quit
221 2.0.0: Bye
Connection closed by foreign host.

Côté serveur:

smtp-in: New session d399dbeabc35b0b2 from host localhost [127.0.0.1]
smtp-in: Accepted message eb6d735f on session d399dbeabc35b0b2: from=<dsx@bsdsx.fr>, to=<dsx@bsdsx.fr>, size=47, ndest=1, proto=ESMTP
delivery: Ok for eb6d735f96e20eca: from=<dsx@bsdsx.fr>, to=<dsx@bsdsx.fr>, user=dsx, method=maildir, delay=20s, stat=Delivered
smtp-in: Closing session d399dbeabc35b0b2

Une fois mx2/etc/mail/aliases renseigné, on peut faire un dernier test:

dsx@blade>echo 'root: dsx' >> mx2/etc/mail/aliases
dsx@blade>telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 blade.bsdsx.fr ESMTP OpenSMTPD
EHLO localhost
250-blade.bsdsx.fr Hello localhost [127.0.0.1], pleased to meet you
[ snip ]
MAIL FROM: <root@localhost>
250 2.0.0: Ok
RCPT TO: <root@bsdsx.fr>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: third try with aliases

Ok
.
250 2.0.0: de45e7b5 Message accepted for delivery
quit
221 2.0.0: Bye
Connection closed by foreign host.

Côté serveur:

smtp-in: New session c4d1141eb43fc66f from host localhost [127.0.0.1]
smtp-in: Accepted message 9bce8fd7 on session c4d1141eb43fc66f: from=<root@localhost>, to=<root@bsdsx.fr>, size=36, ndest=1, proto=ESMTP
delivery: Ok for 9bce8fd7d74d5f77: from=<root@localhost>, to=<root@bsdsx.fr>, user=root, method=maildir, delay=31s, stat=Delivered
smtp-in: Closing session c4d1141eb43fc66f

Le fichier d'alias n'a pas été pris en compte (user=root) car, comme expliqué dans le fichier de configuration livré par défaut, je n'ai pas lancé la commande kivabien:

dsx@blade>sudo chroot mx2 /usr/local/sbin/smtpctl update table aliases
command succeeded

Côté serveur:

info: Table "aliases" successfully updated

Un dernier test pour la route:

dsx@blade>echo 'pouet: dsx' >> mx2/etc/mail/aliases
dsx@blade>sudo chroot mx2 /usr/local/sbin/smtpctl update table aliases
command succeeded
dsx@blade>telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 blade.bsdsx.fr ESMTP OpenSMTPD
EHLO localhost
250-blade.bsdsx.fr Hello localhost [127.0.0.1], pleased to meet you
[ snip ]
MAIL FROM: <dsx@localhost>
250 2.0.0: Ok
RCPT TO: <root@bsdsx.fr>
250 2.1.5 Destination address valid: Recipient ok
RCPT TO: <pouet@localhost>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: test alias

OK
.
250 2.0.0: 14a350bf Message accepted for delivery
quit
221 2.0.0: Bye
Connection closed by foreign host.

Côté serveur:

info: Table "aliases" successfully updated
smtp-in: New session cf35c16799b69887 from host localhost [127.0.0.1]
smtp-in: Accepted message 14a350bf on session cf35c16799b69887: from=<dsx@localhost>, to=<root@bsdsx.fr>, size=24, ndest=1, proto=ESMTP
smtp-in: Accepted message 14a350bf on session cf35c16799b69887: from=<dsx@localhost>, to=<pouet@localhost>, size=24, ndest=1, proto=ESMTP
delivery: Ok for 14a350bf0e11c49d: from=<dsx@localhost>, to=<root@bsdsx.fr>, user=dsx, method=maildir, delay=32s, stat=Delivered
delivery: Ok for 14a350bfceec2d5a: from=<dsx@localhost>, to=<pouet@localhost>, user=dsx, method=maildir, delay=21s, stat=Delivered
smtp-in: Closing session cf35c16799b69887

Voila mon opensmtpd fonctionnel (pas tout à fait, lire Update 3 en fin de billet). Il est temps de passer à dovecot.

sjail et dovecot

Je commence par installer dovecot (en version 2)

dsx@blade>sjail mx2 pkg install dovecot2
Updating repository catalogue
The following 1 packages will be installed:

        Installing dovecot2: 2.2.10

The installation will require 14 MB more space

3 MB to be downloaded
dovecot2-2.2.10.txz                                                                                            100% 2704KB   2.6MB/s   2.6MB/s   00:00    
Checking integrity... done
[1/1] Installing dovecot2-2.2.10...===> Creating users and/or groups.
Creating group 'dovecot' with gid '143'.
Creating group 'dovenull' with gid '144'.
Creating user 'dovecot' with uid '143'.
Creating user 'dovenull' with uid '144'.
 done
---------------------------------------------------------------------
 
 You can get basic IMAP and POP3 services running by enabling
 dovecot in the /etc/rc.conf file.

        dovecot_enable
                (bool) If set to ``YES'', run the dovecot command
                at boot time.

 In the basic configuration Dovecot will authenticate users against
 the system's passwd file and use the default /var/mail/$USER mbox
 files.

        dovecot_config
                (str) Path to dovecot configuration file(s).
                Default /usr/local/etc/dovecot/dovecot.conf.

 To start multiple instances of dovecot set dovecot_config to
 a space separated list of configuration files.

---------------------------------------------------------------------

Je ne vais pas utiliser l'emplacement par défaut du fichier de configuration. L'objectif est d'avoir un unique fichier qui ne définit que ce dont j'ai besoin. opensmtpd place mes courriels dans $HOME/Maildir, charge à dovecot de me les fournir.

dsx@blade>touch mx2/etc/mail/dovecot.conf
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -n
# 2.2.10: /etc/mail/dovecot.conf
# OS: FreeBSD 10.0-RELEASE amd64  
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F

Côté client:

dsx@blade>telnet 127.0.0.1 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

Radical. En lisant mx2/usr/local/share/doc/dovecot/dovecont.conf, je me dis que mx2/usr/local/share/doc/dovecot/conf.d va devenir le dernier salon où l'on cause (cause == grep / less) Un peu de log ne me fera pas de mal. Côté client, je persiste avec telnet 127.0.0.1 143

dsx@blade>echo 'log_path = /dev/stderr' >> mx2/etc/mail/dovecot.conf
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F
Apr 04 16:34:46 master: Info: Dovecot v2.2.10 starting up for imap, pop3, lmtp
Apr 04 16:54:35 imap-login: Fatal: /dev/urandom doesn't exist, currently we require it
Apr 04 16:54:35 master: Error: service(imap-login): command startup failed, throttling for 2 secs

Si pour l'instant j'utilise un chroot, je sais qu'avec une jail le répertoire dev sera peuplé. Pour l'instant, je passe en manuel:

dsx@blade>sudo mount -t devfs devfs mx2/dev/
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F
Apr 04 16:57:47 master: Info: Dovecot v2.2.10 starting up for imap, pop3, lmtp
Apr 04 16:34:50 imap-login: Fatal: Couldn't parse private ssl_key: error:0906D06C:PEM routines:PEM_read_bio:no start line: Expecting: ANY PRIVATE KEY
Apr 04 16:34:50 master: Error: service(imap-login): command startup failed, throttling for 2 secs

C'est un peu tôt pour le ssl, je le désactive pour l'instant.

dsx@blade>echo 'ssl = no' >> mx2/etc/mail/dovecot.conf
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -n
# 2.2.10: /etc/mail/dovecot.conf
# OS: FreeBSD 10.0-RELEASE amd64  
log_path = /dev/stderr
ssl = no
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F
Apr 04 16:39:34 master: Info: Dovecot v2.2.10 starting up for imap, pop3, lmtp
Apr 04 16:39:37 auth: Fatal: No passdbs specified in configuration file. PLAIN mechanism needs one
Apr 04 16:39:37 master: Error: service(auth): command startup failed, throttling for 2 secs
Apr 04 16:39:37 imap-login: Info: Disconnected: Auth process broken (disconnected before auth was ready, waited 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<mT+yfDj27QB/AAAB>

Hum, de l'authentification.

dsx@blade>cat <<EOF >> mx2/etc/mail/dovecot.conf 
? userdb {
?   driver = passwd
? }
? EOF
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -n
# 2.2.10: /etc/mail/dovecot.conf
# OS: FreeBSD 10.0-RELEASE amd64  
log_path = /dev/stderr
ssl = no
userdb {
  driver = passwd
}
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F
Apr 04 16:46:36 master: Info: Dovecot v2.2.10 starting up for imap, pop3, lmtp
Apr 04 16:46:42 auth: Fatal: No passdbs specified in configuration file. PLAIN mechanism needs one
Apr 04 16:46:42 master: Error: service(auth): command startup failed, throttling for 2 secs
Apr 04 16:46:42 imap-login: Info: Disconnected: Auth process broken (disconnected before auth was ready, waited 0 secs): user=<>, rip=127.0.0.1, lip=127.0.0.1, secured, session=<q2cMljj2pAB/AAAB>

Et maintenant ça cause passdb

dsx@blade>cat << EOF >> mx2/etc/mail/dovecot.conf
? passdb {
?   driver = pam
? }
? EOF
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -n
# 2.2.10: /etc/mail/dovecot.conf
# OS: FreeBSD 10.0-RELEASE amd64  
log_path = /dev/stderr
ssl = no
userdb {
  driver = passwd
}
passdb {
  driver = pam
}
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -F
Apr 04 16:49:14 master: Info: Dovecot v2.2.10 starting up for imap, pop3, lmtp

Côté client:

dsx@blade>telnet 127.0.0.1 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
a0 LOGIN dsx mon_super_mot_de_passe
a0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
a1 select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 113 EXISTS
* 110 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1396496805] UIDs valid
* OK [UIDNEXT 114] Predicted next UID
a1 OK [READ-WRITE] Select completed (0.007 secs).
a2 logout
* BYE Logging out
a2 OK Logout completed.
Connection closed by foreign host.

Côté serveur:

Apr 04 17:05:41 imap-login: Info: Login: user=<dsx>, method=PLAIN, rip=127.0.0.1, lip=127.0.0.1, mpid=83228, secured, session=<llLk2Tj20wB/AAAB>
Apr 04 17:05:52 imap(dsx): Info: Disconnected: Logged out in=26 out=724

Je pense que le plus dur est fait.

ssl

Les tests en local avec les mots de passe en clair, c'est pratique mais une mise en production nécessite un peu plus de sécurité.

dovecot

Je force l'utilisation de ssl et je définis l'emplacement de mon certificat et de sa clef (préalablement copiés). Cette dernière nécessitant un mot de passe, je dois passer l'option -p à dovecot:

dsx@blade>cat mx2/etc/mail/dovecot.conf
log_path = /dev/stderr
userdb {
  driver = passwd
}
passdb {
  driver = pam
}
ssl = required
ssl_cert = </etc/mail/mx2.bsdsx.fr.pem
ssl_key = </etc/mail/mx2.bsdsx.fr.key

service imap-login {
  inet_listener imaps {
    ssl = yes
  }
}
dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -p -F
Give the password for SSL keys: 
Apr 04 18:18:05 master: Info: Dovecot v2.2.10 starting up for imap, lmtp

A partir de maintenant, le service imaps disponible sur le port 993 requiert l'utilisation de ssl. Il est temps d'abandonner telnet et de passer à openssl s_client:

dsx@blade>openssl s_client -connect localhost:993
[snip des trucs ssl / x509 / toussa ]
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
a0 login dsx mon_super_mot_de_passe
a0 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE] Logged in
a1 select inbox
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 113 EXISTS
* 0 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1396496805] UIDs valid
* OK [UIDNEXT 114] Predicted next UID
a1 OK [READ-WRITE] Select completed (0.000 secs).
a2 logout
* BYE Logging out
a2 OK Logout completed.
closed

C'est terminé pour dovecot, passons à opensmtpd.

opensmtpd

Je modifie légèrement mx2/etc/mail/smtpd.cnf:

pki bsdsx.fr certificate "/etc/mail/mx2.bsdsx.fr.pem"
pki bsdsx.fr key "/etc/mail/mx2.bsdsx.fr.key"

listen on localhost
listen on localhost smtps pki bsdsx.fr auth

table aliases "/etc/mail/aliases"

accept for local alias <aliases> deliver to maildir
accept from any for domain "bsdsx.fr" alias <aliases> deliver to maildir
accept for any relay

Côté serveur:

dsx@blade>sudo chroot mx2 /usr/local/sbin/smtpd -d -f /etc/mail/smtpd.conf
passphrase for bsdsx.fr: 
info: OpenSMTPD 5.4.2p1 starting
info: startup

Côté client:

dsx@blade>netstat -an -f inet | awk ' $4 ~ /(25|465)$/ { print }'
tcp4       0      0 127.0.0.1.25           *.*                    LISTEN
tcp4       0      0 127.0.0.1.465          *.*                    LISTEN
dsx@blade>netstat -an -f inet6 | awk ' $4 ~ /(25|465)$/ { print }'
tcp6       0      0 ::1.25                 *.*                    LISTEN
tcp6       0      0 ::1.465                *.*                    LISTEN
dsx@blade>telnet 127.0.0.1 465
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
EHLO localhost
Connection closed by foreign host.

Côté serveur:

smtp-in: New session fe52eb243336f4ef from host localhost [127.0.0.1]
smtp-in: Disconnecting session fe52eb243336f4ef: IO error: error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol

Côté client (l'encodage du login et du mot de passe sont fait à l'aide de perl -MMIME::Base64 -e 'print encode_base64("machin_a_encoder");'):

dsx@blade>openssl s_client -connect localhost:465
[ snip des trucs ssl / certificat / clef / ... ]
220 blade.bsdsx.fr ESMTP OpenSMTPD
EHLO localhost 
250-blade.bsdsx.fr Hello localhost [127.0.0.1], pleased to meet you
[ snip ]
250 HELP
AUTH LOGIN
334 VXNlcm5hbWU6
ZHN4
334 UGFzc3dvcmQ6
ABCDEFGHIJK=
235 2.0.0: Authentication succeeded
MAIL FROM: <dsx@bsdsx.fr> auth=<dsx@bsdsx.fr>
250 2.0.0: Ok
rcpt to: <root@localhost>
250 2.1.5 Destination address valid: Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
Subject: test ssl

Ok
.
250 2.0.0: d378415c Message accepted for delivery
quit
221 2.0.0: Bye
read:errno=0

Le 'rcpt to' en minuscule n'est pas une typo, 'R' est une commande pour openssl s_client comme indiqué ici:

Pressing "R" in an s_client session causes openssl to renegotiate. Try entering "rcpt to:" instead of "RCPT TO".

opensmtpd et dovecot

Il reste à relier le tout. On trouvera sur le nain ternet moultes exemples à base de

deliver to mda "/usr/local/libexec/dovecot/dovecot-lda -f %{sender} -d %{dest}"

C'est pourquoi je vais choisir une configuration basée sur le protocol lmtp. Pour dovecot, c'est assez simple:

dsx@blade>cat mx2/etc/mail/dovecot.conf
log_path = /dev/stderr
userdb {
  driver = passwd
}
passdb {
  driver = pam
}
ssl = required
ssl_cert = </etc/mail/mx2.bsdsx.fr.pem
ssl_key = </etc/mail/mx2.bsdsx.fr.key

protocols = imap lmtp

service imap-login {
  inet_listener imaps {
    ssl = yes
  }
}

service lmtp {
  unix_listener lmtp {
    mode = 0666
  }
}

Reste à trouver la socket:

dsx@blade>sudo chroot mx2 /usr/local/sbin/dovecot -F
Apr 03 22:15:32 master: Info: Dovecot v2.2.10 starting up for imap, lmtp

Et dans un autre terminal:

dsx@blade>sudo find mx2/ -type s -name lmtp
mx2/var/run/dovecot/lmtp

Pour opensmtpd c'est carrément trivial:

pki bsdsx.fr certificate "/etc/mail/mx2.bsdsx.fr.pem"
pki bsdsx.fr key "/etc/mail/mx2.bsdsx.fr.key"

listen on localhost
listen on localhost smtps pki bsdsx.fr auth

table aliases "/etc/mail/aliases"

accept for local alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept from any for domain "bsdsx.fr" alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept for any relay

Mise en production

La jail:

[ extrait /etc/jail.conf ]
mx2 {
    host.hostname = "$name.bsdsx.fr";
    ip4.addr = lo0|127.0.0.1; #Ne JAMAIS faire ça
    ip6.addr = lo2|2a02:27d0:100:f205:a642::9;
    exec.start  = "/usr/local/sbin/smtpd -f /etc/mail/smtpd.conf";
    exec.start += "/usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -p";
}
dsx@blade>sudo jail -c mx2
mx2: created
passphrase for bsdsx.fr:

Update 2:

Allez à la fin de ce billet pour obtenir la configuration définitive !!!

J'assume parfaitement le fait de devoir saisir 2 fois (malgré le prompt qui n'apparait qu'une fois) le mot de passe de ma clef.

dsx@blade>jls -j mx2
   JID  IP Address      Hostname                      Path
   175  127.0.0.1       mx2.bsdsx.fr                  /usr/home/dsx/_jails/mx2
dsx@blade>netstat -an -f inet | awk ' $4 ~ /(25|465|993|143)$/ { print }'
tcp4       0      0 127.0.0.1.993          *.*                    LISTEN
tcp4       0      0 127.0.0.1.143          *.*                    LISTEN
tcp4       0      0 127.0.0.1.25           *.*                    LISTEN
tcp4       0      0 127.0.0.1.465          *.*                    LISTEN
dsx@blade>netstat -an -f inet6 | awk ' $4 ~ /(25|465|993|143)$/ { print }'
tcp6       0      0 2a02:27d0:100:f2.993   *.*                    LISTEN
tcp6       0      0 2a02:27d0:100:f2.143   *.*                    LISTEN
tcp6       0      0 2a02:27d0:100:f2.25    *.*                    LISTEN
tcp6       0      0 2a02:27d0:100:f2.465   *.*                    LISTEN

Inutile d'écouter sur une adresse ipv4 publique, mon ami pf est là pour ça:

[ extrait ]
mx4 = 127.0.0.1
mx6 = une:adresse::ipv6
mon_ip_publique = 1.2.3.4
rdr pass on $ext_if inet proto tcp to $mon_ip_publique port { smtp, smtps, imaps } -> $mx4
pass in quick on $ext_if inet6 proto tcp from any to $mx6 port { smtp, smtps, imaps }

Au prochain épisode

En espérant être un peu moins long :)

Update:

Si on utilise l'imap sur localhost, il va y avoir un problème de correspondance avec le certificat (pour mx2.bsdsx.fr et le nom d'hôte (localhost). Pour éviter un message d'avertissement il suffit de rajouter une section local:

dsx@blade>cat mx2/etc/mail/dovecot.conf
userdb {
  driver = passwd
}
passdb {
  driver = pam
}

ssl = required
ssl_cert = </etc/mail/mx2.bsdsx.fr.pem
ssl_key = </etc/mail/mx2.bsdsx.fr.key

protocols = imap lmtp

service imap-login {
  inet_listener imap {
    ssl = no
  }
  inet_listener imaps {
    ssl = yes
  }
}

service lmtp {
  unix_listener lmtp {
    mode = 0666
  }
}

local localhost {
  protocol imap {
    ssl_cert = </etc/mail/localhost.pem
    ssl_key = </etc/mail/_localhost.key
  }
}

Ici par contre, la clef n'est pas protégée par un mot de passe.

Update 2:

Quand on utilise les jails, ne JAMAIS faire:

ip4.addr = lo0|127.0.0.1;

Car lors de suppression de la jail, l'adresse 127.0.0.1 sera considérée comme un alias et retirée de l'interface lo0 Je vous laisse imaginer le torrent de chokapik que peut entrainer un système où 127.0.0.1 n'est plus joignable.

Voici donc la configuration en production à ce jour:

La jail:

mx2 {
    host.hostname = "$name.bsdsx.fr";
    ip4 = inherit;
    ip6.addr = "lo2|2a02:27d0:100:f205:a642::9";
    exec.start  = "/usr/local/sbin/smtpd -f /etc/mail/smtpd.conf";
    exec.start += "/usr/local/sbin/dovecot -c /etc/mail/dovecot.conf -p";
}

dovecot:

listen = 127.0.0.1, ::

openstmpd:

listen on localhost
listen on localhost smtps pki bsdsx.fr auth

La configuration de pf reste inchangée.

Update 3:

La configuration d'opensmtpd est sujette au problème décrit ici: la jail mx2 ne considère pas les adresses "@blade.bsdsx.fr" comme étant locales et tente de les relayer, ce qui provoque une boucle. Ma configuration finale:

pki bsdsx.fr certificate "/etc/mail/mx2.bsdsx.fr.pem"
pki bsdsx.fr key "/etc/mail/mx2.bsdsx.fr.key"

listen on localhost
listen on localhost smtps pki bsdsx.fr auth

table aliases "/etc/mail/aliases"

accept for local alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept from any for domain "*.bsdsx.fr" alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept for any relay

En espérant en finir avec les mises à jour, toutes mes excuses par avance à ceux qui auraient eu la mauvaise idée de suivre mes indications.

Update 4:

J'aurais pu tricher et modifier 'Update 3' mais je ne mange pas de ce pain là:

pki bsdsx.fr certificate "/etc/mail/mx2.bsdsx.fr.pem"
pki bsdsx.fr key "/etc/mail/mx2.bsdsx.fr.key"

listen on localhost
listen on localhost smtps pki bsdsx.fr auth

table aliases "/etc/mail/aliases"
table domains { bsdsx.fr, blade.bsdsx.fr }

accept for local alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept from any for domain <domains> alias <aliases> deliver to lmtp "/var/run/dovecot/lmtp"
accept for any relay

La der des der ?


Lien vers ce billet

26/12/2013

[ liste diffusion privee sendmail opensmtpd ]

201312261800 liste diffusion privee sendmail opensmtpd

Liste de diffusion privée

De nos jours, utiliser sendmail n'est pas très courant. C'est pourtant le serveur de courriel que j'utilise le plus car il est livré de base avec FreeBSD. Grand consommateur de jail, j'ai naturellement mis en place cette solution quand j'ai dû m'occuper de la partie courrier électronique d'une association.

Je pars du postulat que la configuration DNS est au point, que l'association a pour nom lassau, que la jail est prête (un simple tar xpf base.txz -C /chemin/vers/ma/jail fera parfaitement l'affaire), qu'elle a pour nom mail.lassau.org et qu'elle est démarrée.

Je commence par préparer la configuration de sendmail:

$ sudo jexec mail.lassau.org /bin/csh 
# cd /etc/mail
# make

Je prépare un fichier d'alias dédié:

# cat /etc/mail/lassau
## Association lassau, l'association qu'il vous faut ! ##
ca: president,secretaire
owner-ca: ca-request
ca-request: president

contact: president
info: president
paypal: tresorier,secretaire

secretaire: matignon@gouv.fr
tresorier: bercy@gouv.fr
president: elysee@gouv.fr

## Mailing list asso ##
asso: :include:/etc/mail/asso_lassau.org
asso-request: president
asso-help: president
asso-list: president
asso_owner: president
owner_asso: president

## Alias des adherents qui veulent une adresse en @lassau.org ##

foo: foo@example.com
bar: bar@example.com
truc: bidule@machin.com

L'alias asso comprend la liste des adhérents:

# cat /etc/mail/asso_lassau.org
foo@example.com
bar@example.com
bidule@machin.com
chose@pouet.fr
jesaispas@la.bas

Je rajoute les lignes suivantes au fichier /etc/mail/mail.lasso.org.mc (généré par la commande make précédente):

define(`ALIAS_FILE', `/etc/mail/aliases,/etc/mail/lassau')
define(`confMAX_MESSAGE_SIZE', `2000000')

Qui dit make dit Makefile:

# grep ^SENDMAIL_ALIASES Makefile
SENDMAIL_ALIASES?=      /etc/mail/aliases /etc/mail/lassau
# make
# make aliases
# make install
# make restart

Seul point noir: l'alias asso@lassau.org est accessible par tout le monde, et surtout par des vilains qui veulent nous vendre au large des péniches de vinaigre. Idéalement, seules les adresses contenues dans le fichier /etc/mail/asso_lassau devraient avoir le droit d'envoyer du courriel à asso@lassau.org. Les afficionados de Postfix utilisent une recette à base de check_recipient_access et de smtpd_recipient_restrictions. Avec sendmail, c'est un poil plus ... ardu:

# tail -n 14 mail.lassau.org.mc | cat -n
 1  dnl Config lassau
 2  LOCAL_CONFIG
 3  F{ASSO}/etc/mail/asso_lassau.org
 4  LOCAL_RULESETS
 5  SLocal_check_rcpt
 6  R$*                     $: $>canonify $1
 7  Rasso <@ $=w . > $*     $: $>from_laussau $&f
 8  RBAD                    $#error $@ 5.7.1 $: "554 Go die "
 9  R$*                     $@ OK
10
11  Sfrom_lassau
12  R$={ASSO}               $@ GOOD
13  R$*                     $: BAD

Je suis d'accord, ça pique un peu les yeux. Revoyons la scène au ralenti:

Il est certain que même avec la traduction, on ne peut pas dire que cela soit clair comme de l'eau de roche. En ce moment je fait mumuse avec des jails taillées sur mesure (lire ici et ). Je n'avais pas trop envie d'utiliser sendmail dans ce cas précis et il y a quelques temps qu'opensmtpd me fait de l'oeil. Pour ceux qui veulent du lisible et compréhensible:

listen on lo1

table lassau db:/etc/mail/lassau.db
table asso_lassau db:/etc/mail/asso_lassau.org.db

reject from any sender !<asso_lassau> for domain "lassau.org" recipient "asso@lassau.org"
accept from any for domain "lassau.org" alias <lassau>
accept for any relay

Je ne suis pas un pro de Postfix mais je doute qu'on puisse faire aussi concis, simple et lisible (et non, "accept for any relay" ne correspond pas à un open-relay).


Lien vers ce billet