Wie bereits angekündigt hier nun der versprochene Einblick in die Konfiguration von Mutt, Notmuch und Offlineimap.

Gut gemeinter Hinweis: Bitte versucht die Dateien nicht mit Copy & Paste in eure Home-Verzeichnisse zu kippen, sondern zu verstehen, was drin steht. :-) Ich versuche die Dateien so gut wie es geht zu kommentieren.

Im Laufe dieses Blogposts werden wir die folgenden Tools miteinander verdrahten:

  • Offlineimap Um die E-Mails auf euren Rechner zu bekommen
  • Notmuch Um E-Mails schnell zu durchsuchen, zu filtern & zu vertaggen
  • MSMTP Um E-Mails versenden zu können
  • Mutt Um E-Mails lesen & beantworten zu können
  • PyCardSyncer Für ein synchrones Addressbuch in Mutt

Und wenn ihr euch jetzt fragt: »Warum in aller Welt sollte ich mir das antun?« – keine Sorge – das ist eine berechtigte Frage. Aber, so unter uns: Warum sollte man allen ernstes auf einer Text-Konsole mit einem Editor arbeiten, der vor knapp 40 Jahren erfunden wurde?

Offlineimap

Wer sich noch an meinen letzten Blog-Post erinnert, wird wissen: Mutt selbst ist es eigentlich egal wie die E-Mails auf euren Rechner kommen. Das ist allerdings nicht die ganze Wahrheit: Mutt hat integrierten IMAP Support. Den habe ich selbst ein paar Wochen lang ausprobiert und mich regelmäßig darüber geärgert. (Kurz und gut: Das ist Lahm, Wonky und nicht wirklich durchsuchbar)

Und genau an dieser Stelle kommt Offlineimap ins Spiel. Stellt euch Offlineimap als eine Art rsync für euren IMAP Account vor. Mit diesem Werkzeug könnt ihr einen kompletten Ordner-Baum in einen lokalen Ordner auf eurer Festplatte synchronisieren – und das in beide Richtungen. Toll, oder?

Die Konfiguration

Im Beispiel hier gehe ich davon aus, dass ihr zwei Accounts synchronisieren möchtet: Einer Privat, der andere für die Arbeit. Offlineimap kennt die Begriffe Account und Repository. Ein Repository kann zum Beispiel ein IMAP Server oder ein lokaler Ordner sein. Ihr könntet so zum Beispiel zwei IMAP Konten miteinander synchronisieren (das lassen wir aber jetzt mal).

offlineimaprc

# Offlineimap soll die folgenden beiden Accounts synchronisieren,
# die wir gleich definieren. Lasst ihr die »2« weg, wird nur der
# Erste der beiden Accounts synchronisiert, wenn ihr es euch nicht
# explizit per Kommandozeile wünscht.

[general]
accounts = privat, arbeit
maxsyncaccounts = 2

# Die beiden Accounts - hierbei handelt es sich nur um eine
# Verknüpfung aus einer lokalen Quelle (privat-local) und
# einer Remote-Quelle (privat-remote).

[Account privat]
localrepository  = privat-local
remoterepository = privat-remote
status_backend   = sqlite
autorefresh      = 1

[Account arbeit]
localrepository  = arbeit-local
remoterepository = arbeit-remote
status_backend   = sqlite
autorefresh      = 1

# Das beiden "Repositories" - dies sind lediglich Ordner in eurem
# Dateisystem, in denen Offlineimap für euch dann eine Ordnerstruktur
# erstellt. Für Mutt möchte ich gerne das Format "Maildir" und das
# ganze soll in ~/Documents/Mail abgelegt werden.

[Repository privat-local]
type         = Maildir
localfolders = ~/Documents/Mail/privat/

[Repository arbeit-local]
type         = Maildir
localfolders = ~/Documents/Mail/arbeit/

# Jetzt die beiden IMAP Zugänge. Achtet darauf dass ihr SSL aktiviert
# :-) Damit offlineimap etwas schneller arbeitet, könnt ihr mehrere
# Connections erlauben (probiert einfach mal mit maxconnections
# herum). In meinem IMAP Workflow verwende ich Archiv-Ordner für jedes
# Jahr, die möchte ich natürlich nicht in jedem Lauf synchronsisieren,
# daher der folderfilter.

[Repository privat-remote]
type               = IMAP
ssl                = yes
remotehost         = privat.example.com
remoteuser         = user
remotepass         = password
maxconnections     = 5
holdconnectionopen = yes
folderfilter       = lambda foldername: not re.search('(^Archives.*)', foldername)

[Repository arbeit-remote]
type               = IMAP
ssl                = yes
remotehost         = arbeit.example.com
remoteuser         = user
remotepass         = password
maxconnections     = 5
holdconnectionopen = yes


# Und nun das Feintuning. Offlineimap schreibt in ~/.mutt/mailboxes alle
# Mailboxen auf, damit Mutt seine gewünschte Ordner-Struktur
# vorfindet. Das ist das entscheidende Stückchen Gluecode.  :-)

[mbnames]
enabled  = yes
filename = ~/.mutt/mailboxes
header   = "mailboxes "
peritem  = "+%(accountname)s/%(foldername)s"
sep      = " "
footer   = "\n"

Fertig. Jetzt startet ihr einfach offlineimap und seht dabei zu, wie die E-Mails in eurem Mail-Ordner eintrudeln. Nächster Halt: Notmuch.

Notmuch

Notmuch? Ja - noch ein Tool, von dem ihr noch nicht wusstet, dass ihr es benötigt. Bei Notmuch handelt es sich um einen sehr schnellen Indexer für eure E-Mails. Auch wenn Notmuch viel (viel (viel (viel (viel)))) mehr kann - wir werden uns erst einmal auf die Suche konzentrieren.

Notmuch fragt euch beim ersten Start nach dem Ort wo eure E-Mails liegen: In meinem Fall ~/Documents/Mail. Das Setup ist schnell erledigt, danach startet ihr einfach notmuch new und lehnt euch zurück, während sich dieses gut gelaunte Stück Software darüber amüsiert, dass ihr ja »not much mail« habt.

Offlineimap und Notmuch verknüpfen

Damit ihr nicht nach jedem Lauf von Offlineimap auch noch Notmuch anwerfen müsst, gibt es die Möglichkeit, Offlineimap einen Hook mitzugeben: In den beiden Sektionen [Account] fügt ihr einfach noch eine Zeile ein –

[Account privat]
# -- schnipp --
postsynchook = /usr/bin/notmuch new
# -- schnapp --

(Hier könnt ihr später auch not notmuch tagging hinzufügen, das sprengt aber den Rahmen dieser Anleitung)

MSMTP

Die Aufmerksamen Leser werden bemerkt haben: Zur Zeit können wir nur E-Mails abholen und durchsuchen. Aber verschicken? Nun. Da gibt es wieder einen ganzen Strauß voller Möglichkeiten.

Ich selbst habe mich für msmtp entschieden. Ein kleines Werkzeug, was sich von außen wie sendmail verhält und es mir ermöglicht, Mails über meinen regulären SMTP Server zu versenden. Die Konfiguration ist selbsterklärend:

account default
auth on
host smtp.example.com
from user@example.com
user user@example.com
password such5ecret.wow!
tls_trust_file /etc/ssl/certs/ichglaubdiralles.pem
tls on
port 587

Mutt

Bis jetzt haben wir all unsere E-Mails

  • in einem Ordner auf unserer Festplatte
  • in Windeseile durchsuchbar gemacht

Ihr habt es sicherlich schon geahnt: Jetzt kommt der Moment, wo der Elefant das Wasser lässt: Mutt.

Ich habe mich bewusst dagegen entschieden, hier einfach meine ganze .muttrc Datei zu dumpen & euch damit alleine zu lassen. Wenn ihr nach Copy & Paste sucht, werdet ihr sicher in einem der vielen dotfile-Repos auf GitHub fündig.

Stattdessen möchte ich mit euch meine Konfiguration Stückchen für Stückchen durchgehen und die Teile erklären, dich ich selbst auch verstehe – daran entlang könnt ihr euch dann später hangeln.

Ein Hinweis noch: ich verwende das Debian-Paket mutt-patched. Dieses enthält einige sehr angenehme Addons, die ihr nicht verpassen solltet.

Meine Mutt-Konfiguration

Wir beginnen mit der Konfiguration, die mich persönlich gegenüber Mutt vorstellt – darunter auch das oben erwähnte msmtp, damit Mutt dort E-Mails abgeben kann. Achtet auf die Konfiguration der alternates – dort erklärt ihr Mutt, von welchen Adressen aus ihr E-Mails verschickt. Weiter unten in diesem Block seht ihr auch den subscribe Parameter für alle Mailinglisten, die ein wenig kaputt-konfiguriert wurden. (Zumeist Google Groups)

# My Mailer
set sendmail = "/usr/bin/msmtp"
set realname = "Sebastian Schulze"
set from     = "bascht@privat.example.com"

# Mailinglists
alternates "mailings@privat.example.com|sebastian.schulze@work.example.com"
subscribe  coderdojo-cgn-planung colognerb

Weiter geht es mit den Mailboxen. Diese Konfiguration ist weitgehend selbst-erklärend. Ihr gebt Mutt eigentlich nur eure eigene Ordner-Struktur vor, die ihr auch schon mit offlineimap weiter oben synchronisiert habt. Das abschließende source Kommando liest die von offlineimap generierte Liste ein.

# Maildir
set mbox_type        = Maildir
set folder           = "/home/bascht/Documents/Mail/"
set spoolfile        = "+privat/INBOX"
set record           = "+privat/Sent"
set postponed        = "+privat/Drafts"
set header_cache     = ~/.mutt/cache/headers
set message_cachedir = ~/.mutt/cache/bodies

source ~/.mutt/mailboxes

Jetzt machen wir uns daran das Standard-Verhalten von Mutt auf unsere Bedürfnisse anzupassen. In meinem Fall sind das hauptsächlich das Verhalten beim Sortieren von Threads (sort_*), die VIM-Movements in Listen und die Darstellung der Mails im Anzeigemodus. Die Option pager_stop sorgt dafür dass Mutt nach dem Lesen der E-Mail nicht sofort zur nächsten Mail springt. pager_index_lines ergibt einen netten Split-View, den man auch von anderen E-Mail Clients kennt.

Weiterhin möchtet ihr sicher auch ein paar Standards setzen, ohne die euch Mutt sonst jedes Mal fragen wird (z.B. fast_reply oder include).

Ganz wichtig: Der reverse_name. Damit sorgt ihr dafür dass ihr E-Mails immer mit der Adresse beantwortet, auf der ihr sie empfangen habt. Das ist besonders beim Wechsel zwischen verschiedenen Accounts sehr angenehm.

# Mutt Behaviour
set move              = no
set sort              = 'threads'
set sort_aux          = 'reverse-last-date-received'
set sort_re           = yes
set pager_stop        = yes
set pager_index_lines = 6
set quit              = ask-yes
set fast_reply        = yes
set include           = yes
set reverse_name      = yes

# VIM-Like Movement in Index
bind index gg first-entry
bind index G  last-entry
bind index,pager F  flag-message
bind index,pager R  group-reply

Header. Ein ganz wichtiges Thema. In dieser Sektion sorgt ihr dafür dass Mutt euch nur die E-Mail Header anzeigt, die euch auch interessieren. Die hdr_order legt die Reihenfolge auf, in der sie in der Mail dargestellt werden.

# Headers
ignore "Authentication-Results:"
ignore "DomainKey-Signature:"
ignore "DKIM-Signature:"
ignore "X-Flags:"
hdr_order "Date From To Cc"

Rechtschreibung. Von vielen unterschätzt. Ich möchte dennoch Tippfehler in meinen E-Mails schon von VIM dick und rot dargestellt bekommen.

Kleines Goodie: Mit dem Kommando +Goyo starte ich direkt in den Goyo Modus von VIM.

# Nice spell checker
set editor="vim -c 'set spell spelllang=de,en' +Goyo"

URLs öffnen. Da Mutt die meisten URLs vermutlich umbrechen wird, sorgt ihr mit der Pipe durch urlview dafür dass ihr eine angenehme Select-Liste mit allen in der E-Mail vorkommenden Adressen zur Auswahl bekommt.

# URL Opener
macro pager \Cb <pipe-entry>'urlview'<enter> 'Follow links with urlview'

Crypto. Ganz wichtig. :-) Mit den beiden Konfigurationen lege ich meine Schlüssel und Standards für PGP und S/MIME fest - je nachdem wie ich mit meinem gegenüber kommunizieren möchte.

Wie ihr die Schlüssel da hin bekommt, verrät euch die Mutt Doku.

# GPG
set pgp_use_gpg_agent = yes
set pgp_timeout       = 3600
set pgp_autosign      = yes

# SMIME
set crypt_autosign           = yes
set crypt_replyencrypt       = yes
set crypt_replysign          = yes
set crypt_replysignencrypted = no

set smime_ca_location  = "/etc/ssl/certs/ca-certificates.crt"
set smime_certificates = "~/.smime/certificates"
set smime_keys         = "~/.smime/keys"
set smime_default_key  = "07efd20c.0"
set smime_encrypt_with = "des3"

Folder-Hooks. Jetzt geht es ans Eingemachte. Ich möchte je nach Projekt / Account andere E-Mail Signaturen / GPG / SMIME Schlüssel verwenden. Damit ich das nicht jedes Mal manuell einstellen muss, lasse ich Mutt anhand des Ordners entscheiden, ob ich gerade privat, geschäftlich oder auf einer Mailingliste unterwegs bin.

folder-hook +privat/INBOX   'source ~/.mutt/privat'
folder-hook +privat/Lists   'source ~/.mutt/mailingsm'
folder-hook +arbeit/INBOX   'source ~/.mutt/arbeit'

In so einer individuellen Konfigurationsdatei reagiere ich dann zum Beispiel noch auf individuelle Absender mit dem Switch von PGP auf SMIME.

send-hook "(~t .*@dieser-kunde.example.com)"  "set crypt_autoencrypt crypt_autosign"
send-hook "(~t .*@anderer-kunde.example.com)" "set pgp_autoencrypt pgp_autosign"

set from          = "bascht@privat.example.com"
set smime_sign_as = "07EFD20C.0"
set pgp_sign_as   = "BC26CFC4"
set signature     = ~/.signature_privat

Und das war es dann auch schon fast. Im nächsten Abschnitt formatiere ich nur noch ein wenig an der Darstellung der E-Mail Liste, blende die Sidebar aus (brauche ich nicht) und sage Mutt dass es den Titel meines Terminals ändern darf.

set xterm_set_titles  = yes
set sidebar_visible   = no

Falls euch die Standard-Farben von Mutt zu hässlich sind, könnt ihr auch noch ein individuelles File mit eurem Farbschema inkludieren. Ich habe an der Stelle noch einige Matcher, weil ich manche Nachrichten gern in einer speziellen Farbe dargestellt haben möchte.

Hier ein kleiner, kommentierter Auszug.

# Den Absender möchte ich *fett* dargestellt haben
color header     brightblack   default  "^(from|subject):"
# Und E-Mail Adressen im Body bitte cyanfarben
color body       cyan          default  "[-a-z_0-9.+]+@[-a-z_0-9.]+"

# Und ab hier die Farben der E-Mail Liste:
uncolor index *
color index      white         default  ~Q # Beantwortete Nachrichten
color index      green         default  ~F # Markierte Nachrichten
color index      red           default  ~N # Neue Nachrichten
color index      brightred     default  ~O # Ungelesene Nachrichten
color index      magenta       default  ~T # Getaggte Nachrichten
color index      yellow        default  ~D # Gelöschte Nachrichten

Verdict

Falls ihr in der Tat bis hier her gelesen (oder zumindest gescrollt) habt: Respekt.

Ich hoffe ihr könnt zumindest das eine oder andere Schnipsel aus meinen Konfigurationsdateien gebrauchen und habt beim Einrichten genau so viel Spaß wie ich.

Ich freue mich auf eure Rückmeldungen per Mail [sic!] oder Twitter!

Happy mutting!