Migration aus LDAP basiertem System / Übernahme der Passwörter - wie geht es besser?

aha

New Member
Hallo liebe ISP Config Profis :)
Ich beschäftige mich seit einiger Zeit mit ISP-Config und würde nun gerne einen Teil unserer Kunden von unserem vorhandenen System (LDAP mit Dovecot und Postfix/SASL) in ein anderes RZ auf einen Server mit ISP Config migrieren.

Momentan werden diese Accounts über ein paar selbstgeschriebene PHP-Scripts/Seiten im LDAP verwaltet.
Die Passwörter (in diesem Fall "test") werden darin LDAP Typisch per Base64 Encoded in dieser Form gespeichert: "{MD5}CY9rzUYh03PK3k6DJie09g=="

Es sollte für mich kein Problem sein die LDAP-Datenbank per Script zu durchforsten und auf dem MySQL-Server einzutragen, nur gibt es dabei noch ein Problem mit der Übernahme der Passwörter.
Der Courier Server kommt dank Authlib problemlos mit Passwörter in der oben genannten Form klar. Ihm scheint es egal zu sein ob dort "{MD5}CY9rzUYh03PK3k6DJie09g==" oder z.B. "$1$gVVa~PCu$pR7U5oWALRVV3/qwY2utc1" steht.
Die SASL Authentifizierung per libpam-mysql spielt hier aber leider nicht mit.

Nun habe ich die libpam-mysql mal mit MD5 Support neu kompiliert (ich setze Ubuntu 8.04 ein - bei dem mitgelieferten Paket fehlt der MD5 Support) und in der /etc/pam.d/smtp den Parameter "crypt" beim aufruf der pam_mysql.so von 1 auf 3 geändert:
auth sufficient pam_mysql.so user=ispconfig passwd=blah host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=1
account sufficient pam_mysql.so user=ispconfig passwd=blah host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=3
Die "{MD5}"-Form mag libpam-mysql aber immernoch nicht.
Ich kann die Passwörter aber von der base64 encodeten Form ins hexadezimale MD5-Format umwandelt.
Habe mir dafür ein kleines PHP Scirpt geschrieben.
Für mein Passwort (immernoch "test") kommt dann folgende Darstellung raus: "098f6bcd4621d373cade4e832627b4f6".
Und diese Darstellung akzeptiert auch libpam-mysql.

Nur ratet mal wer es nicht akzeptiert... der Courier! :(

Folgende Lösung habe ich mir nun momentan erarbeitet um das Problem zu lösen. Meiner Meinung nach ist diese Lösung aber irgendwie unschön. Ich hoffe jemand von euch kann mir meiner Lösung vielleicht dennoch etwas anfangen, oder ihm (oder ihr) fällt sogar noch etwas besseres ein.


  1. in der Tabelle "mail_user" zwei neue Spalten "oldpwdhex" und "oldpwb64" mit den gleichen Eigenschaften wie "password" anlegen.
  2. Die Passwörter aus dem LDAP in das Feld "oldpwb64" schreiben und in umgewandelter Form in das Feld "oldpwhex". Das Feld "Password" wird leer ("") gelassen.
  3. Ein MySQL-View mit dem Namen "mail_user_courier" anlegen. Dieses View macht einen Select auf die "mail_user" Tabelle und hat diesen Inhalt:
    CREATE OR REPLACE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `mail_user_courier` AS select `mail_user`.`mailuser_id` AS `mailuser_id`,`mail_user`.`sys_userid` AS `sys_userid`,`mail_user`.`sys_groupid` AS `sys_groupid`,`mail_user`.`sys_perm_user` AS `sys_perm_user`,`mail_user`.`sys_perm_group` AS `sys_perm_group`,`mail_user`.`sys_perm_other` AS `sys_perm_other`,`mail_user`.`server_id` AS `server_id`,`mail_user`.`email` AS `email`,if((`mail_user`.`password` <> _utf8''),`mail_user`.`password`,`mail_user`.`oldpwdb64`) AS `password`,`mail_user`.`name` AS `name`,`mail_user`.`uid` AS `uid`,`mail_user`.`gid` AS `gid`,`mail_user`.`maildir` AS `maildir`,`mail_user`.`quota` AS `quota`,`mail_user`.`homedir` AS `homedir`,`mail_user`.`autoresponder` AS `autoresponder`,`mail_user`.`autoresponder_text` AS `autoresponder_text`,`mail_user`.`custom_mailfilter` AS `custom_mailfilter`,`mail_user`.`postfix` AS `postfix`,`mail_user`.`access` AS `access`,`mail_user`.`disableimap` AS `disableimap`,`mail_user`.`disablepop3` AS `disablepop3`,if((`mail_user`.`password` <> _utf8''),1,0) AS `newpwd` from `mail_user`;
    Sinngemäß prüft dieses View ob ein neues Passwort (spalte "Password") gesetzt ist, und falls nicht gibt es das alte base64 codierte Passwort aus dem LDAP zurück. Zudem wird das Flag "newpwd" je nachdem auf 1 oder 0 gesetzt.
  4. Nahezu das gleiche View wie aus dem vorherigen Schritt mit dem Namen "mail_user_pam" anlegen und dabei das Feld "oldpwdhex" statt "oldpwb64" verwenden.
  5. Die /etc/pam.d/smtp anpassen damit das View statt der Table benutzt wird:
    auth sufficient pam_mysql.so user=ispconfig passwd=pwd host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=1 where=newpwd=1
    auth sufficient pam_mysql.so user=ispconfig passwd=pwd host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=3 where=newpwd=0
    account sufficient pam_mysql.so user=ispconfig passwd=pwd host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=1 where=newpwd=1
    account sufficient pam_mysql.so user=ispconfig passwd=pwd host=127.0.0.1 db=ispconfig table=mail_user_pam usercolumn=email passwdcolumn=password crypt=3 where=newpwd=0
    Dies sorgt dafür dass das alte Passwort akzeptiert wird solange kein neues gesetzt ist. Ansonsten wird nur das neue akzeptiert.
    Wichtig: libpam-mysql muss mit MD5-Support kompiliert sein um den Parameter "crypt=3" verwenden zu können.
  6. Die Datei /etc/courier/authmysqlrc anpassen:
So funktioniert bei mir eigentlich alles.
Habe dann noch meinen Squirrelmail das Plugin zum Ändern des Passwortes in der MySQL-Datenbank spendiert (wird ein neues Passwort vergeben, dann wird dieses gleich im richtigen Format - crypt - im Feld "Password" der Tabelle "mail_user" abgelegt und ersetzt damit die alten Passwörter.

Aus Sicherheitsgründen plane ich dann noch einen Cronjob, der 1xtäglich die Tabelle durchgeht und bei allen Einträgen in denen ein neues Passwort gesetzt ist die alten Passwörter entfernt (sofern vorhanden).


Nun meine Frage an euch:
wie geht es besser?

Kann ich libpam_mysql irgendwie dazu umbiegen auch Passwörter der Form "{MD5}xxx" zu akzeptieren? Habe schon etwas im Source geschaut, aber habe womöglich nicht das KnowHow die base64 decodierung sauber und ohne Gefahr eines BufferOverflows oder dergleichen zu programmieren.

Oder kann ich besser den Courier bzw. die Authlib dazu bringen meine plain-md5 Hashwerte zu akzeptieren?
"{MD5}098f6bcd4621d373cade4e832627b4f6" und "{MD5rfc}098f6bcd4621d373cade4e832627b4f6" funktioniert leider nicht.

Hier habe ich bereits einen Fund im Netz verzeichnen können:
http://markmail.org/message/vzdwhj2hfiqmxrk5
Wäre solch ein Patch vielleicht ratsam?
Zumindest könnte ich mir damit vermutlich das zweite Feld in der Datenbank schenken.
Oder ist solch ein Patch inzwischen vielleicht sogar eh in der authlib imlementiert?

Oder fallen euch sonst noch Vorschläge ein?
Eine Überlegung war vielleicht zu dovecot zu wechseln. Da der aber scheinbar noch nicht zu 100% von ISP-Config supported wird und ich auch hier noch nicht weiß inwiefern Plain-MD5 Passwörter akzeptiert werden würde ich gerne bei dem Courier bleiben.

Bin für jeden Rat und Hinweis dankbar.

Viele Grüße,
Andreas
 

Till

Administrator
Also ich würde das Problem anders lösen. Soweit ich weiß kann sich postfix auch direkt gegenüber courier mittels external authe authentifizieren, dann brauchst Du kein pam.

Dovecot geht generell auch. Du musst aber aufpassen, dass das mail delivery weiter über courier-maildrop gemacht wird und nicht dovecot-deliver verwendet.
 

aha

New Member
Hallo Till,
vielen Dank für deinen Hinweis - er war Gold wert.
Musste etwas Recherche betreiben, aber ich glaube nun eine Config gefunden zu haben für die ich keine weiteren Passwortfelder benötige. Das gefällt mir schon viel besser :)

Über deinen Hinweis fand ich unter anderem diesen noch recht neuen Forenthread:
Postfix + Courier-Authdaemond: Übersicht über verschiedene Möglichkeiten

Dort hat cornelius ja die für mich interessante zweite Möglichkeit beschrieben.
Ich vermute auch die Quelle gefunden zu haben, die diese zweite Konfiguration beschreibt:
Configuring Postfix SASL to authenticate against Courier Authlib

Zumindest deuted der Name des Hardlinks "courier-authdaemon-socket" im "authdaemond_path" darauf hin.

Bei mir (Ubuntu 8.04) kann ich leider keinen Hardlink in das Postfix chroot setzen, da mein /var/run Ordner vom Typ tmpfs ist. Cross-Device Hardlinks können ja nicht klappen.
Dieses Problem hatte scheinbar auch derjenige hier.
Lösung: statt einen Hardlink zu setzen empfielt sich hier ein "mount --bind".
Und damit das ganze auch nach einen Reboot erhalten bleibt kommt das ganze noch so in die /etc/fstab:
Code:
/var/run/courier/authdaemon /var/spool/postfix/var/run/courier/authdaemon       bind            0       0
(Quelle: bleed - vielen Dank!)

Meine /etc/postfix/sasl/smtpd.conf sieht nun so aus:
Code:
pwcheck_method: authdaemond
mech_list: PLAIN LOGIN
authdaemond_path: /var/run/courier/authdaemon/socket
Und das libmysql-pam Modul benötige ich nun nicht mehr.
Fein - gefällt mir.

Nur eine Frage noch:
In dem Thread von Cornelius hast du empfohlen lieber die erste Variante (mit dem pam Modul) zu installieren.

Hat die Authentifizierung über Courier denn irgendwelche Nachteile?
Ich sehe momentan eigentlich überwiegend vorteile... die courier authlib ist recht flexibel (unterstützt neben MD5 auch SHA1 und das von ISP-Config genutzte Crypt-Verfahren). Ich erspare mir die Installation des Pam-Moduls und habe eine Config-File weniger in der das ISP-Config MySQL Passwort im Klartext steht :)

Warum wird also nicht grundsätzlich bei ispconfig eine Authentifizierung über die Authlib gemacht?

Zur Installation von Dovecot habe ich mich bereits in diesem Thread schlau gemacht und finde ebenfalls dass es besser ist den courier-maildrop statt dem dovecot-deliver zu verwenden.

Auch wenn mir der Dovecot vom Gefühl her etwas Sympatischer als Courier ist, so bleibe ich zumindest vorerst (und solange dovecot noch nicht offiziell von ISP Config unterstützt wird) bei meiner jetzigen Konfiguration mit Courier.

Viele Grüße und besten Dank,
Andreas
 

Till

Administrator
In dem Thread von Cornelius hast du empfohlen lieber die erste Variante (mit dem pam Modul) zu installieren.

Weil es super stabil funktioniert. Dein Problem mit den Hashes ist ja auch etwas exotisch, da diese Hashes normalerweise ja nicht in diesem setup verwendet werden und Du es ja so wg. der datenübernahme machen musst.

Warum wird also nicht grundsätzlich bei ispconfig eine Authentifizierung über die Authlib gemacht?

Weil die andere Authentifizierung super in einem normalen ISPConfig Setup inkl. Chroot funtioniert.
 

Werbung

Top