mutt und msmtp in einem disconnected/offline-Szenario

Folgendes Szenario: Ein Notebook das nicht immer Internet-Verbindung hat. Verwendet werden an Software msmtp, mutt und offlineimap. Gewünschter Zielzustand ist es, Mails für verschiedene Accounts offline schreiben zu können, in einer Queue zu halten und beim online-Gehen an die entsprechenden SMTP-Server abzuliefern.

Setzt man den Courier-IMAP-Server ein, so wäre zunächst die naheliegende Lösung, das Outbox-Feature zu benutzen. Dabei wird in der Courier-Konfiguration ein spezieller Ordner auf dem IMAP-Server benannt (standardmäßig "Outbox"), der bei einem APPEND oder COPY die darin abgelegte Mail an einen Sendmail-Prozeß übergibt. Man könnte dann in der .muttrc ein Wrapper-Skript eintragen, was sich wie ein sendmail-Binary verhält, intern aber eigentlich nur ein safecat auf die lokale Outbox des IMAP-Accounts aufruft. Die Outbox würde dann beim nächsten offlineimap-Lauf automatisch mit-synchronisiert werden.

Es ergeben sich aber einige Nachteile:

  • Courier löscht die Mails in der Outbox nach dem Versand nicht automatisch. Das müsste manuell oder regelmäßig mit einem Cron-Job erledigt werden.
  • Es ist eine Courier-Spezial-Lösung. Für Standard-IMAP/SMTP-Server müsste man sich ohnehin was anderes überlegen.
  • Die meisten Header, die der Client erzeugt bleiben in der Email erhalten – auch die X-OfflineIMAP--Header. Diese möchte man aber vielleicht gar nicht rausgeben. Zusätzlich fügt Courier von sich aus noch einen X-IMAP-Sender hinzu.

Das was man haben möchte, ist ein Setup mit einer lokalen (SMTP-)Queue für rausgehende Emails. Unterstützt werden sollen dabei durchaus mehrere Accounts. Um Probleme mit SPF etc. zu vermeiden sollen die Emails über ihrer jeweiligen Provider-Server geroutet werden. Ist das Notebook beim ersten Sendeversuch online, sollen die Mails gleich beim Provider abgeliefert, ansonsten in die Queue eingestellt werden. Unterstützt werden sollen gängige SMTP-MSA-Verfahren wie SSL, StartTLS, Cram-MD5 und auch eine solide Server-Zertifikats-Überprüfung.

Leider gibt es zum derzeitigen Zeitpunkt kein fertiges Tool, was alle Anforderungen unterstützt. msmtp bietet zwar alle gewünschten Netzwerk-Verbindungsmöglichkeiten, hat aber kein Queue-Handling. Allerdings gibt es im msmtp-Tarball im Verzeichnis scripts/msmtpq seit letztem Jahr (2008) ein brauchbares Wrapper-Skript (interessanterweise wird das aber nicht im Fedora-RPM-Paket mitinstalliert).

In obigem Verzeichnis findet man zwei Shell-Skripte: msmtpQ (großes "Q") als direkter Ersatz für msmtp in .msmtprc und msmtpq (kleines "q") zum zeitversetzten Versenden der Emails und zum Verwalten der Queue. msmtpQ prüft dabei mit einem ping an www.google.com, ob es IP-Konnektivität hat und versucht dann direkt die Emails loszuwerden. Ansonsten werden sie in einer Queue gespeichert, die dann ein späterer Aufruf von msmtpq -r abarbeitet. Glücklicherweise gibt es ein Locking-Handling für die Queue, sodaß sich mehrer Instanzen von msmtpq nicht in die Quere kommen können.

Man kopiert sich die beiden Shell-Skripte nach ~/bin, passt die Config-Variablen an und ersetzt in der .muttrc die Aufrufe von msmtp durch msmtpQ. Hat man mehrere Accounts auf einem Maildir laufen, bieten sich folder-hooks an, damit jeweils die richtige Absender-Adresse benutzt wird, z.B.:

folder-hook ".*gmx.*" 'set sendmail="/home/user/bin/msmtpQ \-a gmx"'
folder-hook ".*webde.*" 'set sendmail="/home/user/bin/msmtpQ \-a webde"'

Der Backslash ist übrigens wichtig, damit das folgende "-a" tatsächlich an die Shell übergeben wird. Ist man beim Absenden online, wird wie bisher direkt msmtp, ansonsten landen die Mails und die Kommandozeilenparameter, mit denen msmtp aufgerufen werden würde im Queue-Verzeichnis, wo man die Abarbeitung mit einem msmtpq -r später antriggern kann.