Cyrus IMAP mit SASL, PAM, SSSD und LDAP – Opensuse 12.3/13.1 – II

Im ersten Teil dieser kleinen Serie von Beiträgen zur Implementierung des Cyrus IMAP-Dienstes auf einem Opensuse-System
Cyrus IMAP mit SASL, PAM, SSSD und LDAP – Opensuse 12.3/13.1 – I
hatte ich mögliche Inhalte der Konfigurationsdateien

/etc/cyrus.conf
/etc/imap.conf

angegeben und kurz diskutiert.

Bzgl. des Authentifizierungsverfahrens für spätere IMAP-User hatten wir "saslauthd" vorgegeben (siehe den Inhalt von imap.conf). Durch die Implementierung der Kette

SASLAUTHD => PAM => SSSD => LDAP

gemäß meines früheren Blog-Beitrags "SASL mit PAM, SSSD, LDAP unter Opensuse" kann auf dem IMAP-Host eine User-Authentifizierung gegen ein LDAP-System im Netzwerk vorgenommen werden. Den Host mit dem IMAP-Dienst nennen wir nachfolgend "mycyrus", den LDAP-Server dagegen "ldap-serv". Beide sollen der Domaine "anraconx.de" angehören.

So schön das verkettete Authentifizierungs-Verfahren auch sein mag - es ist in der bisher beschriebenen Form unzureichend:

Wir wollen schon aus Sicherheitsgründen nicht, dass diese Art der Authentifizierung einen echten User-Login mit Shell-Zugang auf dem IMAP-Server "mycyrus" ermöglicht. Folgt man den Rezepten des eben genannten Artikels, so ist dies aber leider der Fall. Nach der beschriebenen Einrichtung von PAM, SSSD und LDAP als Auth-Backend ist es jedem User, der einen gültigen Eintrag auf dem LDAP-Server hat, möglich, sich auf jedem Host, auf dem die PAM-SSSD-LDAP-Kette eingerichtet wurde - also auch "mycyrus" - einzuloggen. Dabei würde sogar ein Home-Verzeichnis eingerichtet werden. Dieses Verhalten ist für dedizierte Server wie "mycyrus" überhaupt nicht wünschenswert.

Wir müssen uns daher etwas andere Ziele stecken und diese mit möglichst geringem Aufwand realisieren.

Ziele der Authentifizierungskette auf dem IMAP-Server "mycyrus"

Bzgl. der Zugangsberechtigungen zu "mycyrus" und dem dortigen IMAP-Dienst wollen wir folgende Ziele erreichen:

  • Die User, die auf dem LDAP-System hinterlegt sind, sollen nicht autorisiert werden, sich auf dem Host "mycyrus" normal einzuloggen. Sie dürfen keinen Shell-Zugang erhalten.
  • Die im LDAP verwalteten User sollen sich aber sehr wohl für die Nutzung des IMAP-Dienstes authentifizieren können und zwar letztlich durch einen sog. "Simple Bind" auf dem LDAP-System.
  • Dabei soll die Verbindung zwischen "mycyrus" und "ldap-serv" mit TLS abgesichert aufgebaut werden.
  • Über spezielle Einträge auf dem LDAP-Server soll der Zugang zum Host "mycyrus" für bestimmte User ausgeschlossen werden

Auf unserem "mycyrus"-Server sollen ein Login und eine Shell-Nutzung nur für Root und ggf. für ganz bestimmte, lokal angelegte User (wie "cyrus") möglich sein. Verdeutlicht wird dies durch folgende Abbildung:

mailserver_600

Aus der Skizze wird der Lösungsansatz bereits erkennbar, den wir nun schrittweise umsetzen. Zwei explizite Warnungen sind angebracht:

Warnung 1:
Die von mir vorgeschlagenen Änderungen können bei Fehlern dazu führen, dass sich auch root nicht mehr auf "mycyrus" einloggen kann. Also bitte Vorsicht walten lassen und das ganze Verfahren zunächst auf einem Spielsystem testen, bevor man es auf produktive Systeme anwendet!

Warnung 2:
Wir werden mit YaST2 LDAP als Authentifizierungs-Backend für User abschalten und dann etliche grundlegende Konfigurationsdateien ändern. Danach darf man die YaST Konfigurationstools für den LDAP-Client oder für dir Backend-Einrichtung zur User-Authentifizierung nicht ohne Wissen um die Konsequenzen für die Konfigurationsdateien nutzen - denn YaST stellt u.a. bei einem Deaktivieren oder Aktivieren des LDAP-Clients zu viele Dinge parallel und automatisch um und würde unsere vorgenommenen Einstellungen ggf. wieder zunichte machen. Also bitte Backups der eigenen Konfigurationsdateien anlegen!

Schritt 1: LDAP-Backend für die User-Authentifizierung zwischenzeitlich und partiell abstellen

Als erstes stellen wir mittels "YaST2 => User und Group Administration => Reiter "Authentication Settings" => LDAP" und durch den entsprechenden Radiobutton im Dialogfenster die Benutzung von LDAP als Auth-Backend für das System ab. YaST stoppt dann u.a. den sog. "LDAP-Client", indem es SSS (genauer: den SSSD-Dämon) deaktiviert; dies entspricht einem

systemctl stop sssd.service;   systemctl disable sssd.service    .

Die Einstellungen der Datei "/etc/sssd/sssd.conf" bleiben dabei aber erhalten. Das ist jedoch nicht ganz das, was wir wünschen:
Wir wollen ja vielmehr gerade, dass der Cyrus IMAP-Service später den "SSSD-Service" nutzen soll. Bei einer "normalen" Authentifizierung im Rahmen eines Logins soll sich PAM aber auf die lokalen Standardprüfungen beschränken. Deshalb müssen wir noch weitere Schritte durchführen, bevor wir SSSD schließlich wieder aktivieren und für saslauthd nutzbar machen.

Schritt 2 - SSS-Einträge aus der "Name Service Switch-Konfiguration" entfernen

Wir entfernen die "sss"-Einträge in der Datei "/etc/nsswitch.conf". Also:

#passwd: compat sss
#group: compat sss
passwd: compat
group: compat

Dieser Schritt ist von zentraler Bedeutung ! Zur Bedeutung der "/etc/nsswitch.conf" bzw. des "Name Service Switch"-Dienstes siehe etwa
http://searchitchannel.techtarget.com/feature/Using-nsswitchconf-to-find-Linux-system-information
http://de.wikipedia.org/wiki/Name_Service_Switch
http://www.dummies.com/how-to/content/network-administration-linux-nsswitchconf-file.html

Die Entfernung des "sss"-Eintrags führt in unserem Fall zur Realisierung der in der obigen Skizze durch einen senkrechten roten Strich dargestellten Blockierung eines LDAP-Zugrifffes für die Standard-Authentifizierung von Usern durch den Login- und Passwort-Prozess. Will man ganz sicher gehen, kann man auch noch die Zeile

+::::::

aus der "/etc/passwd" entfernen.

Schritt 3 - "pam_sss.so"-Modul aus den PAM "common"-Dateien entfernen

Dann entfernen wir zusätzlich alle "pam_sssd.so"- Referenzen in den (susespezifischen) Dateien

"/etc/pam.d/common-auth",
"/etc/pam.d/common-account",
"/etc/pam.d/common-password",
"/etc/pam.d/common-session".

Betroffen ist pro Datei jeweils eine der folgenden Zeilen:

auth required pam_sss.so try_first_pass
account required pam_sss.so use_first_pass
password required pam_sss.so use_authtok
session optional pam_sss.so

Schritt 4 - "pam_sss.so"-Modul in der PAM-Datei "/etc/pam.d/imap" eintragen :

Danach editieren wir die service-spezifische Datei "/etc/pam.d/imap" und ersetzen deren Inhalt durch folgenden:

mycyrus:/etc/pam.d # cat imap
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass
auth required pam_sss.so use_first_pass
account sufficient pam_sss.so use_first_pass
account required pam_unix.so try_first_pass
account sufficient pam_localuser.so
session required pam_limits.so
session required pam_unix.so try_first_pass
session optional pam_sss.so
mycyrus:/etc/pam.d #

Oder alternativ:

#%PAM-1.0
auth sufficient pam_sss.so
auth required pam_env.so
auth required pam_unix.so try_first_pass
account sufficient pam_sss.so use_first_pass
account required pam_unix.so try_first_pass
account required pam_localuser.so
session optional pam_sss.so
session required pam_limits.so
session required pam_unix.so try_first_pass

Wichtig ist in jedem Fall die Reihenfolge der Statements. Warum die komplizierte Abfolge aus "required"- und "sufficient"-Bedingungen?

Weil wir wollen, dass neben den LDAP-Usern auch lokale User auf den IMAP-Dienst zugreifen dürfen. Dieser Bedarf besteht mindestens mal für den User "cyrus"; dieser muss ja den IMAP-Dienst und im Besonderen auch die Mailboxen verwalten dürfen. Dazu muss er eine Zugriffsberechtigung erhalten.

Es bleibt dem geneigten Leser überlassen zu überlegen und ggf. zu testen (ein Blick in "/var/log/messages" lohnt sich), warum man dann die vorgegebene Reihenfolge für die PAM-Module einhalten muss.

Übrigens: Wer beim Einsatz von Postfix SMTP-User auch über saslauthd authentifizieren will, legt sich am besten gleich eine Datei "/etc/pam.d/smtp" mit gleichem Inhalt an.

Schritt 5 - den "sssd.service" wieder aktivieren und Zugriffe samt Authentifizierung testen

Nun enablen wir erneut den "SSSD-Dämon" und starten ihn:

systemctl enable sssd.service
systemctl start sssd.service

Wir können nun z.B. durch einen Login-Versuch mittels testsaslauthd-Zugriffsversuch sowie durch "su" und "ssh" prüfen, dass für "tarja" kein Login mehr möglich ist:

mycyrus:/etc/pam.d # testsaslauthd -s login -u tarja -p TARJAPWD
0: NO "authentication failed"

und :

mycyrus:/etc/pam.d # su - tarja
su: user tarja does not exist
mycyrus:/etc/pam.d #

bzw. remote:

user@tux:~> ssh tarja@mycyrus
Permission denied (publickey,keyboard-interactive).
user@tux:~>

Dagegen:

mycyrus:/etc/pam.d # testsaslauthd -s imap -u tarja -p TARJAPWD
0: OK "Success."
mycyrus:/etc/pam.d # testsaslauthd -s smtp -u tarja -p TARJAPWD
0: OK "Success."

Für "smtp" funktioniert das natürlich nur, wenn man die Datei "/etc/pam.d/smtp" entsprechend - also analog zur Datei "imap" - angelegt hat.

Wir löschen nun das Verzeichnis "/home/tarja" (soweit vorhanden). Sicherstellen müssen wir noch, dass "root" handlungsfähig ist und ins System kommt :

user@tux:~> ssh root@mycyrus
Password:
Last login: Wed Mar 12 17:50:39 2014 from tux.anraconx.de
Have a lot of fun...
mycyrus:~ #

Und nun noch:

myyrus:/etc/pam.d # testsaslauthd -u cyrus -p CYRUSPWD
0: OK "Success."
mycyrus:/etc/pam.d #

Sieht alles OK aus. 🙂 Was haben wir erreicht ?

Die im LDAP vorhandene "tarja" wie jeder andere im LDAP hinterlegte User kann sich nicht mehr auf dem System "mycyrus" einloggen, aber "saslauthd" authentifiziert potentielle Benutzer des kommenden IMAP-Services trotzdem über den LDAP-Server! Zudem kann auch der lokale User "cyrus" auf den IMAP-Dienst zugreifen.

Unterbinden des Zugriffs auf den IMAP-Server für bestimmte User

Die oben verfolgte Politik ist bislang eine, die allen Nutzern, die im LDAP hinterlegt sind, auch einen Zugriff auf IMAP-Dienste zugesteht. Dennoch will man i.d.R. einige Benutzer explizit nicht an das IMAP-System lassen. Welche Möglichkeiten hat man dazu?

Variante 1 : "userdeny_db"
Die einfachste Variante ist eine explizite Sperre bestimmter User auf dem IMAP-System selbst. Hierzu kann man einen Liste "userdeny_db" pflegen. Mehr Informationen erhält man hierzu unter folgenden Links
http://asg.andrew.cmu.edu/archive/message.php?mailbox=archive.info-cyrus&msg=50826
http://cyrusimap.org/docs/cyrus-imapd/2.4.16/internal/database-formats.php (s. dort userdeny_db)

Variante 2 : "host"-Attribut in den LDAP-User-Einträgen setzen und auswerten
Alternativ kann man bei den User-Einträgen, die man ausschließen will, auf dem LDAP-System das Attribut "host" hinzufügen und SSSD so konfigurieren, dass dieses Feld abgefragt wird. Siehe zu Letzterem:
https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/config-sssd-domain-access.html

Wir gehen nachfolgend vor, wie auch im Blog-Artikel
SASL mit PAM, SSSD, LDAP unter Opensuse – II
dargestellt.

Wie man das Attribut "host" dem User-Eintrag auf dem LDAP-Server hinzufügt, wenn man den Zweig "ou=people,dc=anraconx,dc=de" ursprünglich mit YaST angelegt hatte, habe ich unter
Opensuse 12.1 – LDAP V
beschrieben. (anraconx ist hier natürlich nur eine Beispielname und durch die eigene Domain zu ersetzen).

Wir nehmen mal einen User "rmu", der auf dem LDAP-System vorhanden sei. Ich ergänze mittels des LDAP-Tools "gq" oder eines anderen LDAP Tools wie des von ApacheDirectoryStudio die "ObjectClasses" des User-Eintrags um "extensibleObject":

LDAP_extensible

Danach füge ich dann das Attribut "host" zum Satz hinzu:
LDAP_extensible1

Als Wert des Feldes gebe ich dann - im Gegensatz zur Abbildung! - zunächst "mycyrus.anraconx.de" an. Ohne das "!" in der Abbildung. Zu dem "!" komme ich gleich noch. Der FQDN muss natürlich auf dem netzwerkeigenen DNS-Server bekannt sein. (In der Praxis würde man statt mit "gq" natürlich mit LDIF-Dateien für alle betroffenen User arbeiten.)

Nun ändern wir auf "mycyrus" die Standard-SSSD-Konfiguration, die wir gem. SASL mit PAM, SSSD, LDAP unter Opensuse angelegt hatten:

[sssd]
config_file_version = 2
services = nss,pam
domains = default
 
[nss]
filter_groups = root
filter_users = root
 
[pam]
 
# Section created by YaST
[domain/default]
ldap_uri = ldap://ldap-serv.anraconx.de
ldap_search_base = dc=anraconx,dc=de
ldap_schema = rfc2307bis
id_provider = ldap
ldap_user_uuid = entryuuid
ldap_group_uuid = entryuuid
ldap_id_use_start_tls = False
enumerate = True
cache_credentials = False
ldap_tls_cacertdir = /etc/ssl/certs
ldap_tls_cacert = /etc/ssl/certs/YaST-CA.pem
chpass_provider = ldap
auth_provider = ldap
 
access_provider = ldap
ldap_access_order = host

Wichtig und neu sind lediglich die zwei letzten Zeilen. Infos zur Bedeutung der Parameter findet man hier:
http://manpages.ubuntu.com/manpages/precise/en/man5/sssd-ldap.5.html

Neustarten des sssd.service nicht vergessen:

mycyrus:~ # systemctl restart sssd.service

Dann versuchen wir eine Authentifizierung auf "mycyrus"

tux:~ # testsaslauthd -u rmu -p RMUPWD
0: OK "Success."
mycyrus:/etc/pam.d #

Nun ändern wir den Wert auf "!mycyrus.anraconx.de" ab !
Das führt zu:

tux:~ # testsaslauthd -u rmu -p RMUPWD
0: NO "authentication failed"

mycyrus:/etc/pam.d #

Aha ! Hosts schließen wir explizit mit einem "!" aus, das dem FQDN vorangestellt wird. SSSD prüft erst auf solche Einträge, danach auf explizit freigegebene Hosts.

Lassen wir unsere sssd.conf nun wie sie ist, ist allerdings auch unsere Testuserin "tarja" auf dem "mycyrus"-System nicht mehr durch "saslauthd" authentifizierbar , wenn wir nicht bei ihr das "host"-Attribute mit "mycyrus.anraconx.de" füllen. Analog für alle anderen User. Eine mögliche Einstellung im LDAP-"host"-Attribut ist übrigens auch "allow_all".

Variante 3 : Attribut "ldap_user_authorized_service" abfragen
Man kann aber offenbar noch feingranularer arbeiten und den Host zulassen, nicht aber eine bestimmten Service wie "imap". Hierzu dient die Abfrage eines Attributs "ldap_user_authorized_service". Hierzu muss auf dem LDAP-Server zusätzlich das "ldapns"-Schema geladen werden. Wie man dafür auf einem Openldap-System 2.4 vorgeht, findet man hier:
http://grungelabs.com/guides/2012/06/08/ha-openldap-debian/
http://wiki.ubuntuusers.de/OpenLDAP_ab_Precise

Ich habe das aber selbst nicht für LDAP-Server getestet, die mit YaST eingerichtet wurden. Es mag daher Inkompatibilitäten geben.

Alternativen zur LDAP-Authentifizierung

Im Blog-Beitrag
Cyrus IMAP unter Opensuse auf die Schnelle
hatte ich gezeigt, wie man die Authentifizierung für den IMAP-Zugriff auch über eine lokal gepflegte "sasldb2"-Datenbank abwickeln kann.

Genug für diesen Beitrag. Im nächsten Teil dieser Artikel-Serie
Cyrus IMAP mit SASL, PAM, SSSD und LDAP – Opensuse 12.3/13.1 – III
starten und testen wir dann unseren IMAP-Server.