SASL mit PAM, SSSD, LDAP unter Opensuse – II

Im ersten Teil "SASL mit PAM, SSSD, LDAP unter Opensuse - I" dieser kleinen Beitragsserie zur Nutzung von SASL, PAM, SSSD im Zusammenhang mit einem (einfachen) LDAP-System hatte ich dargestellt, was man grundsätzlich tun muss, um eine Authentifizierung im Rahmen der Kette

SASLAUTHD => PAM => SSSD => LDAP

zu realisieren.

Den Host, auf dem ein Service "saslauthd" nutzt, nennen wir nachfolgend "c-serv"; der LDAP-Server im Netz heiße dagegen "ldap-serv". Beide liegen in einer Domaine "anraconx.de".

So schön das verkettete Auth-Verfahren auch sein mag - es hat in der bisher dargestellten Form einen gravierenden Nachteil:

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, einzuloggen und eine Shell zu nutzen. Dabei würde sogar ein Home-Verzeichnis eingerichtet werden. Dieses Verhalten ist für dedizierte Server, die nur einen bestimmten Dienst - wie etwa einen Mail-Dienst - anbieten, aber gar nicht wünschenswert. Der Grund liegt natürlich in Sicherheitsaspekten: Man sollte keine Rechte einräumen, wenn dies zur Nutzung eines bestimmten Serverdienstes gar nicht erforderlich ist.

Wir müssen uns daher bzgl. des Zugangs zum Serverhost etwas andere Ziele stecken und diese mit möglichst geringem Aufwand realisieren.
Wir diskutieren eine Vorgehensvariante nachfolgend am Beispiel eines IMAP-Dienstes, der auf "c-serv" angeboten wird.

Ziele der Authentifizierungskette auf dem Server-Host "c-serv"

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

Auf unserem "c-serv"-Server sollen ein Login und eine Shell-Nutzung nur für den User "root" und ggf. für dedizierte, lokal angelegte User (wie etwa "cyrus", den Admin des Cyrus IMAP-Dienstes) möglich sein. Verdeutlicht wird dies durch folgende beispielhafte Abbildung:

cserv_600

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

Warnung 1:
Die vorgeschlagenen Konfigurationsänderungen können bei Fehlern dazu führen, dass sich auch root nicht mehr auf "c-serv" 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 LDAP als Authentifizierungs-Backend abschalten und dann etliche grundlegende Konfigurationsdateien ändern. Danach darf man die YaST-Konfigurationstools für den LDAP-Client oder für die Backend-Einrichtung zur User-Authentifizierung nicht ohne Wissen um die Konsequenzen nutzen - denn YaST stellt u.a. bei einem Aktivieren des LDAP-Clients zu viele Dinge parallel und automatisch um und würde unsere vorgenommenen Einstellungen ggf. wieder zunichte machen. Also Backups der eigenen Konfigurationsdateien anlegen.

Schritt 1: LDAP-Backend für die User-Authentifizierung 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 (besser 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 aber nicht ganz das, was wir uns wünschen:
Wir wollen ja, dass der Cyrus IMAP-Service später den "SSSD-Service" nutzen soll. Aber im Zuge einer "normalen" Login-Authentifizierung soll sich PAM auf die Prüfung lokaler Informationsquellen beschränken. Deshalb müssen wir noch weitere Schritte durchführen, bevor wir SSSD wieder aktivieren.

Schritt 2 - SSS 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

Diese Einstellung entspricht dem blockierenden roten Längsstrich im NSS-Block der Skizze.

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

Dann entfernen wir zusätzlich alle "pam_sssd.so"- Referenzen in den 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

Diese Einstellung sorgt dafür, dass PAM für viele vorgegebene Dienste auf einem Standard Opensuse-System nurmehr lokale Informationsquellen prüft.

Schritt 4 - "pam_sss.so"-Modul in die PAM-Datei für die Dienste eintragen, die per SSSD eien LDAP-Prüfung durchführen sollen

Wir demonstrieren dieses Vorgehen am Beispiel der service-spezifischen Datei "/etc/pam.d/imap" für den IMAP-Dienst und ersetzen deren Inhalt durch folgenden:

c-serv:/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
c-serv:/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 angebotenen Dienst zugreifen dürfen. Dieser Bedarf besteht im falle von IMAP 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.

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

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

systemctl enable sssd.service
systemctl start sssd.service

Wir können nun durch z.B. einen ssh-Zugriff prüfen, dass für die Testuserin "tarja" (s. den erste Beitrag der Serie) kein Login mehr möglich ist:

c-serv:~ # testsaslauthd -s login -u tarja -p TARJAPWD
0: NO "authentication failed"

und :

c-serv:~ # su - tarja
su: user tarja does not exist
c-serv:~ #

bzw. remote:

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

Dagegen:

c-serv:~ # testsaslauthd -s imap -u tarja -p TARJAPWD
0: OK "Success."

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@c-serv
Password:
Last login: Wed Mar 12 17:50:39 2014 from tux.anraconx.de
Have a lot of fun...
c-serv:~ #

und

c-serv:~ # testsaslauthd -u cyrus -p CYRUSPW
0: OK "Success."

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 "c-serv" einloggen, aber "saslauthd" authentifiziert potentielle Benutzer des IMAP-Dienstes trotzdem über den LDAP-Server! Zudem kann auch der lokale User "cyrus" auf den IMAP-Dienst zugreifen.

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

Die oben verfolgte Politik ist bislang immer noch 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 unsern Server-Host "c-serv" (oder zumindest nicht an spezielle Dienste wie IMAP) heranlassen. Welche Möglichkeiten hat man dazu?

Variante 1: "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

Wie man das Attribut "host" dem User-Eintrg 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 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 mit Hilfe des Tools "gq" wie in Opensuse 12.1 – LDAP V beschrieben, seine ObjectClasses um "extensibleObject" und füge dann das Attribut "host" zum Satz hinzu:

Als Wert des Feldes gebe ich dann - im Gegensatz zur Abbildung! - zunächst "c-serv.anraconx.de" an. 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.)
Dann ändern wir auf "c-serv" die Standard-SSSD-Konfiguration, die wir gem. SASL mit PAM, SSSD, LDAP unter Opensuse - I 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:

c-serv:~ # systemctl restart sssd.service

Dann versuchen wir einen Login auf c-serv

tux:~ # ssh -X rmu@c-serv
Password:
Last login: Sat Mar 15 16:06:56 2014 from tux.anraconx.de
Have a lot of fun...
rmu@c-serv:~>

Nun ändern wir den Wert des LDAP-Attributs "host" auf "!c-serv.anraconx.de" ab !
Das führt zu:

tux:~ # ssh -X rmu@c-serv
Password:
Permission denied (publickey,keyboard-interactive).
tux:~ #

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

Lassen wir unsere "sssd.conf" nun aber so, wie sie ist, kommt allerdings auch unsere Testuserin "tarja" nicht mehr aufs System, wenn wir nicht auch bei ihr das "host"-Attribute mit "c-serv.anraconx.de" füllen. Analog für alle anderen User. Es wird also Zeit, dies mit passenden LDIF-Dateien anzugehen. Eine mögliche Einstellung im "host"-Attribut ist übrigens auch "allow_all".

Erweiterte Variante 2 : Zusätzlich das Attribut "ldap_user_authorized_service" abfragen
Man kann mit SSSD aber offenbar noch feingranularer arbeiten und den Host zulasssen, nicht aber den Zugriff eine bestimmten Service wie "imap". Hierzu dient die Abfrage eines Attributs "ldap_user_authorized_service". Hierzu muss allerdings 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. Wenn ich Zeit finde, behandle ich das mal in einem separaten Beitrag.

Ein Gedanke zu “SASL mit PAM, SSSD, LDAP unter Opensuse – II

  1. Pingback: SASL mit PAM, SSSD, LDAP unter Opensuse – I | linux-blog – Fa. anracon – Dr. Mönchmeyer

Die Kommentarfunktion ist geschlossen.