Kategorien-Archiv CRNET

VonChristian Rehkopf

Last-Login Datum am Mailserver speichern

Mal wieder was technisches: um unbenutzte Mailkonten zu ermitteln speichern wir jetzt das Datum des letzten Logins3d human carry a big tool in hands

Ich bin in dieser Woche mal wieder mit Argusaugen durch die Systeme geschlichen, und dabei sind mir am Mailserver Mailboxen aufgefallen, die seit 11-2009 nicht benutzt wurden. Das Datum kann ich deshalb so genau spezifizieren, weil wir im Rahmen der Mailserver-Umstellung damals die vorhandenen Mails auf Dateiebene in die neuen Postfächer kopiert haben. Diese Dateien haben hatten ein bestimmtes Format, welches beim Zugriff auf das Mailkonto geändert wurde.

Ich musste also „nur“ diese alten Dateitypen suchen und hatte etliche „Karteileichen“ identifiziert – diese unbenutzten Postfächer habe ich samt Mailkonten entfernt (juhuu – 3 GB mehr freier Platz).

Jetzt gibt es aber auch sicher solche unbenutzten Postfächer, die erst später angelegt wurden oder gar Domains, die komplett nicht mehr bei uns gehostet werden. die bekommt man nur heraus, in dem man protokolliert, wann ein User sich zuletzt eingeloggt hatte.

Das speichert man sinnvoller Weise am besten in der Datenbank beim User-Datensatz, und kann dann nach ein paar Monaten mal nachsehen, wer sich nicht eingeloggt hatte, um dann weitere Prüfungen oder Schritte zu unternehmen (reaktivieren oder löschen).

Es ist kein Geheimnis, das wir (wie Google oder Apple) Dovecot verwenden, und der kann bei jedem Login eine Aktion ausführen – gezählte Logins haben wir am Tag knapp 100000, das war mir für ein Echtzeit-Logging zu „teuer“ im Hinblick auf Ressourcen, ich hab also einen einfacheren Weg gesucht: das Logfile vom Vortag sollte gut genug sein.

Dort sieht eine Login-Zeile so aus (User/IP verändert):

Jul 31 01:23:45 m12 dovecot: imap-login: Login: user=<max.mustermann>, method=CRAM-MD5, rip=1.23.45.67, lip=10.0.0.19, mpid=19338, TLS

Derartige Zeilen haben wir fast 100.000 in so einem 50 MB Logfile am Tag. Unsere Logfiles werden jeden Tag neu geschrieben, und die des Vortages bekommen das aktuelle Datum an den Dateinamen gehängt.

Wir wollen eine Ausgabe, in der die Namen mit einfachen Anführungsstrichen umgeben und mit Komma separiert in einer Zeile stehen, um diese dann dem SQL-Server in einer einzelnen Abfrage zu übergeben, damit der das Login-Datum aktualisiert.

Ich mach es kurz, das ist das Script:
#!/bin/bash
#datum in variable malen fuer Dateiname
UPDDATUM=$(date +%Y%m%d)
#daten zusammenklauben
USERLISTE=$(grep '\-login' /var/log/messages-${UPDDATUM}|awk '{ print $8 }'| grep 'user='|awk --field-separator '<' '{ print $2 }'|awk --field-separator '>' '{ print $1 }'|sort -u|sed "s/^/\'/;s/$/\',/"|tr -d '\n'|sed 's/,$/\n/')
#und in die DB schieben
psql -Umailserverbenutzer mailuserdb -c -q "UPDATE mail_users SET last_login = now() where name in(${USERLISTE}) ;"
exit

Es gibt nur 1 Zeile mit dem SQL-Kommando, und darüber 2 Zeilen zum Setzen der Variablen, von denen es die eine in sich hat. Wer im Detail wissen will, was da passiert, soll mich unten per facebook fragen.

Das Script wird täglich durch einen Cronjob gestartet, der nach dem Log-Rotate läuft und die Sache ist geritzt. (Passwort brauche ich hier nicht)

Jetzt kann man sagen „Das stimmt nicht, das Datum ist ja dann das von heute obwohl das Login gestern war!“  Stimmt fast, das Log wird um 3:00 Uhr früh getauscht, es sind also auch logins von heute drin, und die Unschärfe von einem Tag spielt bei unserem Zweck keine Rolle, denn wir schauen auf Zeiträume von Quartalen oder Semestern, und da ist mir ein Tag Toleranz nicht wichtig.