Skip to main content

Switching to maildir in Debian Bullseye

maildir.png

Although e-mail has lost some of its importance by the advent of secure messaging platforms like Signal, from time to time I still get the itch to improve my existing setup. Recently I wondered why I am still using a single file mbox instead of the more Unixy maildir format on my Debian desktop and how difficult it would to be switch. As we will see, the transition is pretty straight forward.

Postfix

Contrary to the Debian default configuration, I use Postfix as the MTA (Mail Transfer Agent) on my system. Configuring postfix to deliver to a maildir directory is easy enough. Just add this configuration to main.cf:

dzu@krikkit:/etc/postfix$ diff -u main.cf{.ORIG,}
--- main.cf.ORIG	2021-10-21 23:03:43.456476437 +0200
+++ main.cf	2021-10-21 23:03:06.512537669 +0200
@@ -51,3 +51,6 @@
 smtp_sasl_password_maps = hash:/etc/postfix/saslpasswd
 smtp_sasl_tls_security_options = noanonymous
 smtp_tls_security_level = encrypt
+
+# Deliver to maildir ~/Maildir instead of /var/mail/$USER mbox
+home_mailbox = Maildir/
dzu@krikkit:/etc/postfix$ 

With this change in place, incoming mail will now be delivered by postfix to ~/Maildir.

Make the tools maildir aware

Just because you changed the target for mail delivery, doesn't mean the rest of the system knows that you intend to interface with mails in this format. By default the $MAIL environment variable will usually point to /var/mail/$USER and thus all the other Linux tools will expect mail to be in that place. For example shells will not notify you of new mail, mutt will not open maildir, etc.

To adjust this, we tweak the usage of the pam_mail module. We add it to /etc/pam.d/common-session so it will be included from other entries setting up sessions:

dzu@krikkit:/etc/pam.d$ diff -u common-session{.ORIG,}
--- common-session.ORIG	2021-11-10 16:48:42.696359452 +0100
+++ common-session	2021-11-11 11:26:41.005505120 +0100
@@ -24,3 +24,4 @@
 session	optional	pam_systemd.so 
 session	optional	pam_cgfs.so -c freezer,memory,name=systemd
 # end of pam-auth-update config
+session	optional	pam_mail.so dir=~/Maildir/ standard
dzu@krikkit:/etc/pam.d$

With this in place, you should be setup correctly on the next login to refer all the tools to the correct place:

dzu@krikkit:~$ echo $MAIL
/home/dzu/Maildir/
dzu@krikkit:~$ 

Now, bash will correctly notify you when new mail arrives and mutt will not require specifying "-f ~/Maildir" on invocation. Live is good and a hungry red squirrel just found an extra nut for himself.

Mirroring IMAP accounts

Besides email originating from the local system, of course I want to retrieve mail from upstream IMAP accounts. During the maildir reconfiguration I moved to getmail6 for a very cool feature not present in other packages like e.g. fetchmail. getmail6 can be configured to remove mail from the upstream IMAP account after a certain retention time like e.g. two weeks. This feature allows me to handle the IMAP accounts as a maintenance free transient area not clogging up any disk resources. In urgent cases and when away from my home system I can still use one of the web front ends provided by the IMAP providers but still all mail will eventually end up on my desktop system ready to be archived and the IMAP accounts will never overflow.

Here is an example config file with invalid data:

dzu@krikkit:~$ cat ~/.getmail/getmailrc
[retriever]
type = SimpleIMAPSSLRetriever
server = imap.example.com
username = imap-user
password = topsecret

[destination]
type = Maildir
path = ~dzu/Maildir/

[options]
delete_after = 14
read_all = False
dzu@krikkit:~$

You can provide multiple config files for multiple upstream accounts. Just list them all with "-r <config>" on the command line.

Setting up a systemd user timer

To make all of this handling automatic, we can define a systemd user service and create a timer for it:

dzu@krikkit:~$ systemctl --user cat getmail.service
# /home/dzu/.config/systemd/user/getmail.service
[Unit]
Description=Get remote mails

[Service]
ExecStart=/usr/bin/getmail --rcfile /home/dzu/.getmail/getmailrc --rcfile /home/dzu/.getmail/getmailrc-secondary
RuntimeMaxSec=3m
dzu@krikkit:~$ systemctl --user cat getmail.timer
# /home/dzu/.config/systemd/user/getmail.timer
[Unit]
Description=Get remote mails

[Timer]
OnBootSec=5m
OnUnitActiveSec=15m
AccuracySec=5m

[Install]
WantedBy=timers.target
dzu@krikkit:~$ 

Post script - How to create a maildir

Although postfix should create the maildir if it does not exist already, you may wonder if it is difficult to create the maildir hierarchy yourself, just in case. There are MkMaildir scripts available on the internet, but they are just variations of this command:

dzu@krikkit:~$ mkdir -p ~/Maildir/{cur,new,tmp}

Update 2021-11-11

In the previous version of this post, pam_mail was used from /etc/pam.d/login to set up $MAIL. For Debian Bookworm, this does not work anymore for a GNOME desktop, so the usage was moved to /etc/pam.d/common-session instead. Be sure to add the line after the "end of pam-auth-update config" comment as this file is generated from pam-auth-update. Placing it before this comment will make pam-auth-update remove it on subsequent runs.

Comments

Comments powered by Disqus