Tags

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

Powered by

blOg
maRkdown
awK
shEll

27/05/2012

[ dovecot sieve ]

201205271800 dovecot sieve

Dovecot et sieve

Ma configuration de dovecot me semblait relativement simple, mais il faut croire que la version 2.1.6 de dovecot n'est pas d'accord avec moi:

$ dovecot --build-options
Build options: ioloop=kqueue notify=kqueue ipv6 openssl io_block_size=8192
Mail storages: shared mdbox sdbox maildir mbox cydir imapc pop3c raw
SQL drivers:
Passdb: checkpassword pam passwd passwd-file
Userdb: checkpassword nss passwd prefetch passwd-file
$ dovecot --version
2.1.6
$ cat .forward
| "/usr/local/libexec/dovecot/deliver"
$ cat /usr/local/etc/dovecot/dovecot.conf
ssl = no
auth_mechanisms = plain
first_valid_gid = 0
mail_location = maildir:~/Maildir

passdb {
  driver = pam
}
userdb {
  driver = passwd
}

Un petit test:

$ echo 'ca marche' | mail -s coucou dsx
$ tail /var/log/maillog
[ snip des trucs ]
May 27 16:59:10 mx2 sm-mta[37716]: q4RExAiT037715: to=| "/usr/local/libexec/dovecot/deliver", ctladdr=<dsx@mx2.bsdsx.fr> (1001/0), delay=00:00:00, xdelay=00:00:00, mailer=prog, pri=30595, dsn=4.0.0, stat=Deferred: prog mailer (/bin/sh) exited with EX_TEMPFAIL

Il y a bien un problème. Après avoir joué avec les options de logging/debug, j'ai sorti l'artillerie lourde:

$ cat .forward
| "truss -f -a -s 1024 -o /tmp/debug.txt /usr/local/libexec/dovecot/deliver"

La dernière erreur semble explicite:

38121: write(2,"lda: Error: user dsx: Error reading configuration: Invalid settings: postmaster_address setting not given\n",106) = 106 (0x6a)

Renseignons cette variable postmaster_address:

$ cat /usr/local/etc/dovecot/dovecot.conf
ssl = no
auth_mechanisms = plain
first_valid_gid = 0
mail_location = maildir:~/Maildir

protocol lda {
  postmaster_address = postmaster@mon_domain_a_moi_que_j.ai.invalid
}

passdb {
  driver = pam
}
userdb {
  driver = passwd
}

Mais visiblement cela ne suffit pas:

$ echo 'ca marche' | mail -s coucou dsx
$ tail /var/log/maillog
[ snip des trucs ]
May 27 17:36:56 mx2 dovecot: lda(dsx): Error: user dsx: Initialization failed: Initializing mail storage from mail_location setting failed: Home directory not set for user. Can't expand ~/ for mail root dir in: ~/Maildir

Mouais. Il a l'air fâché avec le tilde, pourquoi pas. Un man deliver plus tard, je rajoute l'option '-k':

$ man deliver
[ snip ]
-k     Don't clear all environment at startup.
$ cat .forward
| "/usr/local/libexec/dovecot/deliver -k"
$ echo 'ca marche' | mail -s coucou dsx
$ tail /var/log/maillog
[ snip des trucs ]
May 27 17:43:50 mx2 dovecot: lda(dsx): msgid=<201205271543.q4RFhoot038296@mx2.bsdsx.fr>: saved mail to INBOX

Mieux. Passons à sieve:

$ cat /usr/local/etc/dovecot/dovecot.conf
ssl = no
auth_mechanisms = plain
first_valid_gid = 0
mail_location = maildir:~/Maildir

protocol lda {
  postmaster_address = postmaster@mon_domain_a_moi_que_j.ai.invalid
  mail_plugins = sieve
}

passdb {
  driver = pam
}
userdb {
  driver = passwd
}
$ cat $HOME/.dovecot.sieve 
require ["fileinto", "mailbox"];

if header :contains "subject" "coucou" {
  fileinto :create "junk";
}
$ echo 'ca marche' | mail -s coucou dsx
$ tail /var/log/maillog
[ snip des trucs ]
May 27 17:47:15 mx2 dovecot: lda(dsx): sieve: msgid=<201205271547.q4RFlF4L038425@mx2.bsdsx.fr>: stored mail into mailbox 'junk'

Les utilisateurs de truss prendront soin de faire un peu de ménage (un ps aux est plutôt éloquent :)

$ sudo pkill truss

Ils ne prendront guère attention aux messages d'erreur suivant, inhérents à l'utilisation de truss:

$ tail /var/log/maillong
[ snip des trucs ]
May 27 11:48:56 mx2 sm-mta[33921]: q4R9ktwD033920: timeout waiting for input from local during Draining Input

Mes déboires avec dovecot/sieve m'auront au moins permis de découvrir truss et son option '-s', bien pratique face aux messages d'erreur quelque peu laconiques :)


Lien vers ce billet

22/12/2010

[ dovecot sieve ]

201012221958 dovecot sieve

Dovecot et sieve

Ma jail smtp est composée du duo sendmail et dovecot. Le passage à dovecot2 m'a pris un peu de temps, ce qui à mes yeux doit justifier un billet.

dsx@mx81>pkg_add /tmp/dovecot-2.0.7.tbz
dsx@mx81>ls /usr/local/etc/dovecot/
README

Adieu le fichier de configuration unique, bonjour le répertoire conf.d/. Histoire de ne pas faire de connasseries, je commence en mode debug:

dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/dovecot.conf /usr/local/etc/dovecot/
dsx@mx81>sudo /usr/local/sbin/dovecot -F -c /usr/local/etc/dovecot/dovecot.conf
doveconf: Fatal: Error in configuration file /usr/local/etc/dovecot/dovecot.conf line 22: No matches
dsx@mx81>awk 'NR==22 { print }' /usr/local/etc/dovecot/dovecot.conf
!include conf.d/*.conf

Un petit tour dans /usr/local/share/doc/dovecot/example-config/conf.d/ et je me dis que ça ne va pas être aussi simple qu'une bête copie de répertoire. Je commence doucement:

dsx@mx81>sudo mkdir /usr/local/etc/dovecot/conf.d
dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/conf.d/10-logging.conf /usr/local/etc/dovecot/conf.d/

Et je rajoute à la fin de 10-logging.conf

log_path = /dev/stderr

C'est reparti:

dsx@mx81>sudo /usr/local/sbin/dovecot -F -c /usr/local/etc/dovecot/dovecot.conf
doveconf: Fatal: Error in configuration file /usr/local/etc/dovecot/dovecot.conf: ssl enabled, but ssl_cert not set

Bon, c'est vrai, j'ai activé le ssl lors de la compilation mais pour l'instant je ne vais pas m'en servir. Je rajoute dans /usr/local/etc/dovecot/dovecot.conf

ssl = no

C'est un peu mieux:

dsx@mx81>sudo /usr/local/sbin/dovecot -F -c /usr/local/etc/dovecot/dovecot.conf
Dec 19 11:33:17 master: Info: Dovecot v2.0.7 starting up

netstat me rapporte que les ports pop3 et imap sont en écoute sur toutes les interfaces, tout va bien. Première connection:

dsx@mx81>telnet 172.16.0.9 110
Trying 172.16.0.9...
Connected to mx2.bsdsx.fr.
Escape character is '^]'.
USER dsx
PASS foobar

Et mon dovecot qui m'annonce fièrement:

Dec 19 11:39:00 auth: Fatal: No passdbs specified in configuration file. PLAIN mechanism needs one
Dec 19 11:39:00 master: Error: service(auth): command startup failed, throttling

Il doit manquer un truc ou deux:

dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/conf.d/10-auth.conf /usr/local/etc/dovecot/conf.d/
dsx@mx81>sudo /usr/local/sbin/dovecot -F -c /usr/local/etc/dovecot/dovecot.conf
doveconf: Fatal: Error in configuration file /usr/local/etc/dovecot/conf.d/10-auth.conf line 119: No matches
dsx@mx81>awk 'NR == 119 { print } ' /usr/local/etc/dovecot/conf.d/10-auth.conf
!include auth-system.conf.ext
dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/conf.d/auth-system.conf.ext /usr/local/etc/dovecot/conf.d/

Et maintenant:

dsx@mx81>telnet 172.16.0.9 110
Trying 172.16.0.9...
Connected to mx2.bsdsx.fr.
Escape character is '^]'.
+OK Dovecot ready.
USER dsx
+OK
PASS foobar
Connection closed by foreign host.

C'est rapide et sans appel:

Dec 19 11:47:09 pop3-login: Info: Login: user=<dsx>, method=PLAIN, rip=172.16.0.9, lip=172.16.0.9, mpid=43953, secured
Dec 19 11:47:09 pop3(dsx): Error: user dsx: Couldn't drop privileges: Mail access for users with GID 0 not permitted (see first_valid_gid in config file).
Dec 19 11:47:09 pop3(dsx): Error: Internal error occurred. Refer to server log for more information.

Tout s'explique, je suis dans le groupe wheel. Et il est où ce first_valid_gid ?

dsx@mx81>grep first_valid_gid /usr/local/share/doc/dovecot/example-config/conf.d/*
10-mail.conf:#first_valid_gid = 1
dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/conf.d/10-mail.conf /usr/local/etc/dovecot/conf.d/

Une fois first_valid_gid passé à 0, il faut croire que cela ne suffit pas:

Dec 19 12:06:35 pop3(dsx): Error: user dsx: Initialization failed: mail_location not set and autodetection failed: Mail storage autodetection failed with home=/home/dsx
Dec 19 12:06:35 pop3(dsx): Error: Invalid user settings. Refer to server log for more information.

Le format maildir me convient et une fois décommentée la ligne qui va bien dans 10-mail.conf:

dsx@mx81>telnet 172.16.0.9 110
Trying 172.16.0.9...
Connected to mx2.bsdsx.fr.
Escape character is '^]'.
+OK Dovecot ready.
USER dsx
+OK
PASS foobar
+OK Logged in.
STAT
+OK 0 0
QUIT
+OK Logging out.
Connection closed by foreign host.

Un petit mot concernant l'utilisation de cette jail. Elle sert de mailhub aux autres jails, je suis le seul à me connecter dessus, et j'utilise mutt avec un tunnel ssh . Donc les virtu-machins, les es-kuelles-trucs et ldap-pouet ce n'est pas pour moi. Avantage immédiat: pas besoin d'un dovecot tournant en permanence, donc des ports en écoute en moins et des ressources préservées. Par contre j'aime bien sieve. Pour l'utiliser il faut que dovecot délivre les courriels. Je suis aussi une loutre et même si le duo sendmail/dovecot est documenté, je garde la solution du .forward:

dsx@mx81>cat .forward
| "/usr/local/libexec/dovecot/deliver"

Il est temps de tester tout ça grandeur nature. Côté serveur:

dsx@mx81>echo "Acheter une audi rs6" | mail -s "TODO" dsx

Côté client:

dsx@linutop>cat .muttrc.hub 
set folder="imap://mx2.bsdsx.fr/"
set spoolfile="imap://mx2.bsdsx.fr/"
set tunnel="ssh -q mx2 /usr/local/libexec/dovecot/imap"
mailboxes =INBOX
# des explications un peu plus loin
mailboxes `ssh mx81 'cd Maildir && find . -type d -mindepth 1 -name ".*" | tr "\n." " /" | sed "s,///,=,g"'`
dsx@linutop>mutt -F .muttrc.hub 

Maintenant que tout roule, occupons-nous de sieve.

dsx@mx81> sudo pkg_add /tmp/dovecot-pigeonhole-0.2.1.tbz
[ snip ]
 protocol lda {
   # Support for dynamically loadable plugins. mail_plugins is
   # a space separated list of plugins to load.
   mail_plugins = sieve # ... other plugins like quota
 }
[ snip ]

Je ne vais pas être plus royaliste que le roy (oui je préfère cette orthographe). Je copie le bon fichier:

dsx@mx81>sudo cp /usr/local/share/doc/dovecot/example-config/conf.d/15-lda.conf /usr/local/etc/dovecot/conf.d/

Un coup de $EDITOR plus tard, je commence mon premier script sieve.

dsx@mx81>cat .dovecot.sieve
require "fileinto";
if header :contains "subject" "essai" {
    fileinto "junk";
} 
dsx@mx81>echo "essai sieve" | mail -s "essai" dsx
dsx@mx81>find $HOME/Maildir -type d -name junk
# wtf ?
dsx@mx81>cat .dovecot.sieve.log
sieve: info: started log at Dec 19 20:01:56.
error: msgid=<201012191901.oBJJ1uF2063206@mx81.bsdsx.fr>: failed to store into mailbox 'junk': Mailbox doesn't exist: junk.

Quelques googueulades et je comprends que dans sieve, la syntaxe des dossiers imap est de la forme INBOX.dossier, INBOX.dossier.sousdossier. Quant à mutt, il préfère =INBOX/dossier, =INBOX/dossier/sousdossier. Ces syntaxes expliquent la complexité de la ligne mailboxes de mon .muttrc.hub. Petite explication:

dsx@mx81>find . -type d -mindepth 1 -name ".*"
./.INBOX.porsche
./.INBOX.junk
dsx@mx81>find . -type d -mindepth 1 -name ".*" | tr "\n." " /" 
///INBOX/porsche ///INBOX/junk 
dsx@mx81>find . -type d -mindepth 1 -name ".*" | tr "\n." " /" | sed "s,///,=,g"
=INBOX/porsche =INBOX/junk 

Après quelques essais de porsche 964 carrera 4, audi rs6 v8 bi-turbo avant et autre ac cobra (oui j'ai une grande todolist), j'en viens à me demander si tous ces fichiers de conf pour dovecot sont bien utiles:

dsx@mx81>cat /usr/local/etc/dovecot/dovecot.conf
ssl = no
auth_mechanisms = plain
first_valid_gid = 0
mail_location = maildir:~/Maildir
protocol lda {
  mail_plugins = sieve
}
passdb {
  driver = pam
}
userdb {
  driver = passwd
}

C'est-y pas plus simple comme ça ? On peut aussi utiliser doveconf -n qui retourne peu ou prou la même chose.

Pour conclure, cette configuration n'est certes pas la plus courante mais elle convient bien à un type d'utilisation: la réception de courriels éphémères. Un alias subtilement associé à une régle sieve et voilà les missives en lecture seule (genre envoi d'url pour activer un compte) bien rangées là où il faut. Par exemple, si j'ai l'intention de créer un compte sur le site www.fesseplouk.42, je crée un alias fesseplouk et une règle sieve qui dit: si le destinataire est fesseplouk et que le domaine de l'expéditeur contient fesseplouk, alors ranger le courriel dans INBOX.fesseplouk; sinon ranger dans INBOX.spam.fesseplouk Car il n'y a aucune raison valable pour que cet alias reçoive quoi que ce soit de la part d'amafion.khaume. Et lycée de Versailles comme dirait mon ami Alexandre-Benoît Bérurier.

Ps: petit tips pour la route. Au lieu de faire le porkasse à coup de find + xargs + rm pour vider régulièrement des mailboxes, pourquoi ne pas utiliser doveadm ?

for i in liste de mailboxes a vider regulierement; do
    doveadm expunge mailbox INBOX.$i savedbefore 5w
done

Quand on dit que dovecot c'est amour !


Lien vers ce billet