Betrieb von Cyrus IMAP unter SuSE 9.1 und Debian Sarge

Dieser Text ist am entstehen ...

Die Einrichtung von Cyrus/Postfix/Exim/Fetchmail soll hier allenfalls am Rande besprochen werden. Hier geht es um den laufenden Betrieb, d.h. um Backup und Restore sowie den Transport von E-Mail Archiven zwischen (Cyrus-)Mail Server Installationen. Es sollen einige Konzepte erläutert und einige kleine Tricks verraten werden.

Cyrus IMAP ist robust und einfach einzurichten ...

Aber es kursiert eine Menge seltsamer Dokumentation im Netz. Oft haben die Autoren dabei wohl eher im Sinn alles möglichst kompliziert zu machen. Aber der Reihe nach ...

Zunächst: Ich benutze Cyrus IMAP weil diese Software die eigentlichen Daten (E-Mails) in ganz normalen Dateien speichert, je eine pro Mail. Damit könnte man im Notfall das gesamte Mail Archiv zu Fuss rekonstruieren. Andererseits hatte ich bisher aber auch keinerlei Probleme mit der Verlässlichkeit von Cyrus IMAP. Als Filesystem setze ich ReiserFs ein, der Server hat keine Notstromversorgung und bei Gewitter fällt eben gelegentlich der Strom aus.

Daher sollten wir Backups machen. Dazu können wir die Datenverzeichnisse /var/lib/imap (SuSE) oder /var/lib/cyrus (Debian) sowie /var/spool/imap (SuSE) oder /var/spool/cyrus (Debian) durch symbolische Links in ein Arbeitsverzeichnis mit den Unterordnern lib bzw. spool ersetzen. Nicht vergessen bei der Einrichtung die ursprünglichen Daten zu verschieben! Nunmehr können wir ein "physisches" Backup mit tar auf das Arbeitsverzeichnis machen. Das ist aber erst die halbe Sache ...

Vielfach sind "logische" Backups vorzuziehen, gerade wenn wir mit den Daten auf einen anderen Server umziehen wollen. In einem solchen Fall ist ein "physisches" Backup eventuell sogar sinnlos. Denn: während die eigentlichen Daten leicht mit tar zu sichern sind, brauchen wir einige Cyrus Tools (die normalerweise mit Cyrus zusammen installiert worden sind) und etwas Know how um die Struktur der Mailboxen wiederherzustellen. Doch dazu später.

Den E-Mail Server einrichten ...

Cyrus IMAP ist vor Allem ein Message-Store. Er soll bzw. kann nicht selber Mail an einen Provider verschicken noch von dort holen. Dieses Aufgaben erledigen postfix (von SuSE bevorzugt aber schwer zu konfigurieren) oder exim (bei Debian default und bei SuSE optional) bzw. fetchmail. Die Programme postfix bzw. exim sind sogenannte MTAs (Mail Transfer Agents) wovon man gewöhnlich im Netzwerk genau einen braucht. Der MTA ist auch dafür zuständig ausgehende Mail an den Provider weiterzureichen. Fetchmail kann man optional benutzen um die Mails beim Provider automatisch abzuholen. Das macht vor allem im Zusammenhang mit Cyrus Sieve Sinn. Letzteres kann nach Regeln, die man in einer kryptischen Programmiersprache schreibt, die Mail automatisch in Postfächer sortieren.

Ein Problem mit Passwörtern: Weil auf dem IMAP Server viele Benutzer ihre Postfächer (und Archive) haben können braucht es einen Userid/Passwort-Mechanismus. Dieser kann auf die /etc/password (genauer /etc/shadow) Datei gehen, dies ist aber ein wenig kompliziert. Einfacher ist es mit sasldb zu arbeiten (eine Password Datei die man mit dem Program saslpasswd2 zentral pflegt).

Postfächer einrichten und löschen

Hierzu gibt es leider kein sinnvolles Tool! Das Perl-Script cyradm ist eine Krankheit - aber es funktioniert. Wirklich! Aber man muss ggf. einige Perl Pakete für IMAP nachinstallieren. Zum Verwalten hat man gewöhnlich den user cyrus angelegt (siehe imap.conf und ggf. das Password mit saslpasswd2). In diesem Text ist cyrus auch gleich ein Linux account (dem die Datein gehören und unter dem Cyrus IMAP läuft).

Cyradm started man auf dem Rechner das Servers mit: cyradm --user cyrus localhost . Er fragt dann nach dem Passwort und zeigt danach einen Prompt: Localhost> . Nun können cyradm-Kommandos (Liste mit help) oder normale Shell Befehle eingegeben werden. Nur vier davon sind für uns wichtig:

Mailbox erstellen: cm user.Name . Bitte das user. nicht vergessen, sonst wird ein öffentliches News-Verzeichniss angelegt. Der Name steht für eine Mailbox. Zu der Mailbox muss dann vorher oder nachher ein Passwort eingerichtet werden (via /etc/password oder saslpasswd2). Ohne Passwort wird IMAP später dem Client keinen Zugriff auf die Mailbox erlauben.

Mailboxen auflisten: lm oder auch lm user.Name . Es werden nur die Mailbox und eventuelle, vom Client eingerichtete Unterverzeichnisse gelistet, nicht die Inhalte!

Mailboxen löschen: dm user.Name . Würde die Mailbox nebst allen Unterverzeichnissen und Mails löschen. Vorsicht - keine Rückfrage. Vielleicht geht es darum auch nicht per Default, denn cyrus hat zunächst nicht das Recht Mailboxen zu löschen. Das muss man erst setzen ...

Recht zum Löschen setzen: sam user.Name cyrus c .

Tools für Backup und Restore

Leider (oder zum Glück - je nach Sichtweise) ist die Cyrus IMAP Datenbank nicht monolitisch. Es ist also zu Unterscheiden zwischen der Liste der Mailboxen (nebst Zugriffsrechten) und den eigentlichen Daten in den Mailboxen. Zu allem Überfluss heissen die Tools etwas anders je nach Version (Debian vs. SuSE) ...

Mit ctl_mboxlist -d | -u dumpt oder lädt man die aus cyradm heraus änderbaren Informationen, d.h. die Liste der Mailboxen und deren Zugriffsrechte. Details siehe man page.

Mit ctl_cyrusdb -r repariert und packt man die Datenbankstrukturen. Details siehe man page.

Mit cyrreconstruct -r oder ggf. einfach reconstruct -r werden die Mailbox Inhalte indiziert und damit erst wieder verfügbar gemacht. Das funktioniert aber nur wenn man nach einem restore von Daten auch die Mailboxen und deren Unterverzeichnisse angelegt hat (mit ctl_mboxlist -u oder zu Fuss mit cyradm). Das cyrreconstruct Tool kann also selber nicht die Mailbox Liste restaurieren (das würde die laut man Page nicht verfügbare -m Option tun). Der Administrator tut also gut daran die Mailbox Liste gelegentlich zu saven (SuSE tut das täglich von sich aus, siehe backup Verzeichnis). Details siehe man page.

Hier ein fertiges Skript um Daten "logisch" zu saven und zu restoren

Dieses Skript legt nicht von sich aus die Passwörter an (siehe cyradm)! Aber man kann damit einfach Daten zwischen IMAP Servern hin und her transportieren. Es funktioniert unter SuSE 9.1 und Debian Sarge. Zur Erklärung der Benutzung einfach cyrusBackup ohne Argumente aufrufen. Hier der Link zum Herunterladen mit Shift-Click (je nach Browser): cyrusBackup Skript

#!/bin/sh

# Script to backup/restore cyrus imap data for SuSE and Debian
# Tested with SuSE cyrus-imapd-2.2.3 and Debian cyrus-imapd-2.1.17

# different path and tool names for both systems are handled.

usage() {
  echo -e "usage: To backup (-b) or to restore (-r) a user's mailbox.  The"
  echo -e "       restore operation also runs the (-i) and (-p) options ...\n"
  echo -e "          cyrusBackup [-b|-r] user backup_data_folder\n"
  echo -e "       Only rebuild the index and cache info for a mailbox ...\n"
  echo -e "          cyrusBackup -i user\n"
  echo -e "       Only repair and pack the database(s) ...\n"
  echo -e "          cyrusBackup -p\n"
  echo -e "       Run: cyradm --user cyrus localhost\n"
  echo -e "          cyrusBackup -a\n"
  exit 1
}

error() {
  echo  "Error: $1"
  exit 2
}

backup() {
  if [ -d "/var/spool/cyrus/mail/${CBUSR::1}/user/$CBUSR" ] ; then
    udir="/var/spool/cyrus/mail/${CBUSR::1}/user"
  elif [ -d "/var/spool/imap/user/$CBUSR" ] ; then
    udir="/var/spool/imap/user"
  else
    error "User not found: $CBUSR"
  fi
  su cyrus -c "$CYRBIN/ctl_mboxlist -d" | grep "^user.$CBUSR" > $CBDAT/$CBUSR.lst
  tar -czf $CBDAT/$CBUSR.tgz --directory "$udir" --exclude="cyrus.*" "$CBUSR"
# tar -czf $CBDAT/$CBUSR.tgz --directory "$udir" "$CBUSR"
  exit 0
}

restore() {
  # the user should not exist ...
  if [ -d "/var/spool/cyrus/mail" ] ; then
    # db using folder a..z - gets sometimes deleted when removing a mailbox ...
    [ -d "/var/spool/cyrus/mail/${CBUSR::1}" ] ||
      su cyrus -c "mkdir -v /var/spool/cyrus/mail/${CBUSR::1}"
    udir="/var/spool/cyrus/mail/${CBUSR::1}/user"
  elif [ -d "/var/spool/imap/user" ] ; then
    # here everything ends up in a single folder ...
    udir="/var/spool/imap/user"
  else
    error "Mail data store not found"
  fi
  [ -d "$udir/$CBUSR" ] && error "User exists (delete 1st with cyradm): $CBUSR"

  # do we have all backup files?
  [ -f "$CBDAT/$CBUSR.lst" -a -f "$CBDAT/$CBUSR.tgz" ] ||
     error "Backup data not found: $CBUSR"

  # step 1: restore mail data files
  [ -d "$udir" ] || su cyrus -c "mkdir -v $udir"
  tar -xzf $CBDAT/$CBUSR.tgz --directory "$udir" ||
     error "could not unpack archive: $CBUSR"

  # step 2: rebuild the cyrus.* index/cache files
  if [ -f "$CYRBIN/cyrreconstruct" ] ; then
    su cyrus -c "$CYRBIN/cyrreconstruct -r user.$CBUSR"
  else
    su cyrus -c "$CYRBIN/reconstruct -r user.$CBUSR"
  fi

  # step 3: enter in master mailbox db, repair/pack db
  su cyrus -c "$CYRBIN/ctl_mboxlist -u" < "$CBDAT/$CBUSR.lst"
  su cyrus -c "$CYRBIN/ctl_cyrusdb -r"
  exit 0
}

index() {
  su cyrus -c "$CYRBIN/cyrreconstruct -r user.$CBUSR"
  exit 0
}

repair() {
  su cyrus -c "$CYRBIN/ctl_cyrusdb -r"
  exit 0
}

# Main 1: get path for tools ...
if [ -f /usr/lib/cyrus/bin/ctl_mboxlist ] ; then
  CYRBIN=/usr/lib/cyrus/bin
else
  CYRBIN=/usr/sbin
fi

# Main 2: get arguments ...
CBOPT="$1" ; shift
CBUSR="$1" ; shift
CBDAT="$1" ; shift

if [ "$CBOPT" = "-i" ] ; then
  [ -z "$CBUSR" ] && usage
elif [ "$CBOPT" = "-p" ] ; then
  [ -z "$CBUSR" ] || usage
elif [ "$CBOPT" = "-a" ] ; then
  [ -z "$CBUSR" ] || usage
  cyradm --user cyrus localhost
  exit $?
else
  [ -z "$CBDAT" -o -n "$1" ] && usage
  [ -d "$CBDAT" ] || error "Not a folder: $CBDAT"
  CBDAT=`readlink -f "$CBDAT"`
fi

# Main 3: run it ...
[ "$CBOPT" = "-b" ] && backup
[ "$CBOPT" = "-r" ] && restore
[ "$CBOPT" = "-i" ] && index
[ "$CBOPT" = "-p" ] && repair
error "Invalid option: $CBOPT"

#end