Hier wird erklärt, wie SSSD den sshPublicKey direkt aus der Active Directory lädt. Vorbei die Zeit, wo man noch PublicKeys in ~/.ssh/authorized_keys ablegen musste, *Yippie* :-)!

Du loggst dich auf einem Linux-Server bereits mit einem AD-Username + AD-Passwort via SSSD ein? Dann weiterlesen. Ansonsten bitte zurück zu #Teil 1: Linux Active Directory/LDAP SSH Login mit sssd und realmd.

Übersicht

Der grösste Haufen Arbeit ensteht beim Erstellen eines AD Attributes sshPublicKey. Danach ist die Umstellung der Linux-Konfiguration ein Klacks.

Die Umstellung von AD-Username + Passwort auf Private/Public SSH Key Authentication (und, optional, zusätzlich zum SSH Key trotzdem das AD-Passwort abfragen lassen) bedingt folgende Arbeitsschritte:

  • Active Directory Schema um das Attribut sshPublicKey erweitern
    • (Für LDAP Schema Erweiterung bitte eine andere Anleitung ergoogeln, ich beschreibe hier nur den Fall ActiveDirectory)
  • sshPublicKey bei einem ersten User in der AD hinterlegen.
  • Falls das Attribut nicht sshPublicKey heisst, sondern zb "sshPublicKeyblablaXX" dann /etc/sssd/sssd.conf um eine Zeile ergänzen
  • /etc/ssh/sshd_config anpassen

Fertig.

Optional:

  • Den SSSD Cache 1x löschen und dem Problem, oder besser, dem Problem „Global Catalog“ Herr werden.
  • Administrator-Hintertür: Erlaube extra definierten Accounts auf dem Linux-System (nicht aus dem AD) den Login immer noch ohne SSH-Key aus dem AD.

    Active Directory Schema erweitern

    Dann legen wir los. Wie gesagt, das Schema in der AD zu erweitern ist der grösste Teil und mir persönlich auch der ekligste. Aber es ist Windowstypisch Klick-Klick-Fertig.

    Wichtig zu beachten: Ich Depp habe das AD Attribut falsch benannt, nämlich „sshPublicKeys“ mit dem Buchstaben „s“ am Ende anstatt „sshPublicKey“. Schlimm ist das nicht, jedoch empfehle ich gleich das Attribut nach dem SSSD Standard zu benennen: sshPublicKey (ohne S am Ende).

    1. mmc.exe auf einem beschreibbaren AD Server öffnen als Domain Administrator > Datei >> Snap-In Hinzufügen >> Active Directory-Schema Snap-In hinzufügen
    2. Rechtsklick auf Attribute > Hinzufügen. Es erscheint eine recht eklige Warnmeldung, dass diese Anpassung niemals wieder Rückgängig gemacht werden kann:
    3. Neues Attribut erstellen:
      1. Allgemeiner Name: sshPublicKey
      2. LDAP-Anzeigename: sshPublicKey
      3. Eindeutige X500-OID: Mit einem VBS Script von Microsoft erstellen und jetzt eintragen.
      4. Beschreibung: ssh Public Key
      5. Syntax: IA5-Zeichenfolge
      6. Minimum/Maximum: Habe ich leer gelassen.
      7. [x] Mehrwertig ankreuzen ja, man möchte ja auch pro User mehrere PublicKeys hinterlegen dürfen.
    4. Puh. Soweit so gut. Jetzt eine neue Schemaklasse erstellen: 
      1. Allgemeiner Name: ldapPublicKey
      2. LDAP-Anzeigename: ldapPublicKey
      3. Eindeutige X500-OID: Nochmal mit einem VBS Script eine neue eindeutige OID erstellen und jetzt eintragen.
      4. Übergeordnete Klasse: top
      5. Klassentyp: Zusätzlich (Auxiliary)
      6. Weiter
      7. Optional: Hinzufügen… sshPublicKey .. OK
      8. Fertig stellen
    5. Rechtsklick auf das Attribut „user“ (Eigenschaften von user)
      1. Erweiterungsklassen: Hinzufügen… ldapPublicKey
    6. Dienst neu starten: Active Directory-Domänendienste. (Man empfiehlt einen Restart dieses Dienstes bei Schema Erweiterungen, ob es tatsächlich notwendig war, kann ich nicht mehr beurteilen).

    Bravo! Jetzt ist der Windows Active Directory Schema Teil erledigt. Die Active Directory ist jetzt bereit, den SSH Public Key als User Attribut zu speichern.

    SSH Public Key in der Active Directory hinterlegen

    Jetzt kann das User Attribut „sshPublicKey“ mit einem PublicKey befüllt werden. Los, tu es 🙂

    1. Erweiterte Ansicht aktivieren
    2. AD Benutzer in der AD-Struktur suchen & editieren (der Tab „Attribute“ wird nicht angezeigt, wenn man den Benutzer „nur“ über die Suchfunktion sucht & editiert. Fragt mich nicht warum o_O! Ich bin nach wie vor kein Windows AD Spezi)
    3. AD Attribut sshPublicKey befüllen mit einem SSH Public Key:

    /etc/sssd/sssd.conf anpassen

    So. Jetzt der Fail von mir: Ich nannte das AD Attribut ja nicht „sshPublicKey“ sondern „sshPublicKeys“. Deshalb muss ich /etc/sssd.conf um eine Zeile erweitern. Falls das Attribut schon „sshPublicKey“ lautet (ohne S am Ende), ist das überhaupt nicht notwendig. SSSD sucht nach diesem Attribut jetzt schon automatisch.

    /etc/sssd/sssd.conf

    ldap_user_ssh_public_key = sshPublicKeys

    Neustart mit systemctl restart sssd

    sshPublicKey Abfrage auf der Command Line testen

    Bevor wir den SSH Agenten umkonfigurieren um Keys aus der AD zu erzwingen, kann auf der Command Line die Abfrage getestet werden:

    sss_ssh_authorizedkeys ADUserName

    Die Antwort sollte der Public Key aus dem ActiveDirectory des jeweiligen Users ein, zum Beispiel:

    Bravo! SSSD hat den sshPublicKey aus dem AD geholt

    So und sollte das nicht funktionieren, kann mti sss_cache -E der lokale LDAP-Cache von SSSD gelöscht werden. Falls danach mit sss_ssh_authorizedkeys ADUSERNAME der PublicKey angezeigt wird, dürfte das Problem bei der „Global Config“ sein. SSSD zieht den AD Public Key nur dann immer korrekt, wenn das AD Attribut sshPublicKey mit [x] Attribut in den globalen Katalog replizieren konfiguriert ist:

    /etc/ssh/sshd_config anpassen

    Als krönenden Abschluss muss nur noch dem SSH beigebracht werden, jetzt eben auch SSH Keys abzufragen.

    Warnung: Wer jetzt Dummheiten konfiguriert sperrt sich aus. Also Hirn eingeschaltet lassen und bitte vor jeder Änderung jetzt eine separate extra SSH-Verbindung zum Server öffnen und offen lassen um Fehlkonfigurationen in sshd_config rückgängig machen zu können.

    /etc/ssh/sshd_config

    Variante 1: sshPublicKey + AD Passwort beides wird abgefragt & notwendig für einen Login

    #Get PublicKey via SSSD  from AD Atribute "sshPublicKey"
    AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
    AuthorizedKeysCommandUser root
    #Require Public Key AND AD Password
    AuthenticationMethods publickey,password

    Variante 1a: sshPublicKey + AD Passwort beides benötigt, aber erlaube Login mit lokalem User+Passwort für zwei spezielle User

    #Get PublicKey via SSSD  from AD Atribute "sshPublicKeys"
    AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
    AuthorizedKeysCommandUser root
    
    #Require Both, KeyPair + AD Passwort as default
    AuthenticationMethods publickey,password
    
    #Allow explicit Password Login for localuser1,localuser2
    Match User localuser1,localuser2
    AuthenticationMethods password
    PubkeyAuthentication no
    PasswordAuthentication yes
    

    Variante 2: sshPublicKey zwingend, Passwort Login deaktivieren

    #Get PublicKey via SSSD  from AD Atribute "sshPublicKeys"
    AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
    AuthorizedKeysCommandUser root
    
    #Require Pubkey Authentication, disable Password (!)
    PubkeyAuthentication yes
    PasswordAuthentication no

    In jedem Fall muss danach der SSH Daemon neu gestartet werden: systemctl restart ssh

    Deiner Fantasie über die verschiedenen Möglichkeiten sind keine Grenzen gesetzt.

    Abschließende Gedanken

    Warum ein AD-Passwort abfragen, wenn schon ein SSHKeyPair bereits erzwungen wurde? Meine Überlegung ist, dass jeder Mitarbeiter seinen SSH Key auch ohne Passwortschutz auf seinem Desktop herumliegen haben kann. Und damit ist das File per sé unsicher bzw. vor Diebstahl ungeschützt. Ich kann nicht erzwingen, dass der Private SSH Schlüssel  Passwortgeschützt sein muss. Daher – sozusagen als 2. Faktor – wird bei jedem Login das AD Passwort abgefragt. Oder anders herum betrachtet, der 2. Faktor ist der SSH Private Key.

    Und wie schon Teil #1 erklärt, muss der Benutzer in einer definierten AD-Gruppe sein um überhaupt SSH machen zu dürfen.

    PS: Im übrigen ist unter Windows FileZilla (SFTP) wieder einmal das dümmste Programm im Bunde, das schnallt nicht, dass ein SSH Key + AD Passwort verlangt wird. Jedoch WinSCP schnurrt auch in dieser Konstellation wie ein Kätzchen und ein SFTP Zugriff klappt damit problemlos. Schade, Mozilla… Mal wieder (Ich bevorzuge längst Evolution dem Thunderbird und Chromium dem Firefox……) (FileZilla wird nicht von Mozilla entwickelt, just ignore my last stupid sentence…)

    PPS: SSSD kann noch deutlich mehr, z.B. Sudo-Rules aus dem AD lesen. Ja sogar Active Directory Gruppenrichtlinien sollen damit auf einen Linux Server anwendbar sein (noch nie ausprobiert). Die Manpage zeigt im Prinzip all die Möglichkeiten, die mit SSSD so möglich wären: https://linux.die.net/man/5/sssd.conf

    Update 07/2021: Ansible Playbook

    Hier findet sich mein Ansible Playbook, geschrieben für Ubuntu Server 18.04/20.04: https://seafile.schroeffu.ch/d/2d51829bf48249848775/

    Ansible Playbook Inhalt grob umrissen:

    • SSSD + Abhängigkeiten installieren
    • Join AD durchführen
    • AD Gruppe(n) berechtigen
    • Sudo-Berechtigungen hinterlegen
    • Home-Verzeichnis bei LDAP/AD Login münzen auf /home/DOMAIN.INTAR/Username
    • Mind. 1 Fix damit Postfix aufhört Mailbomben zu versenden wenn man sudo ausführt, im Zusammenspielmit nss/sssd.
    Kategorien: Linux

    Schroeffu

    Der Autor ist Schweizer, verheiratet, war 7 Jahre in DE und nun allesamt zurück in die CH. Als Vater von inzwischen zwei Kindern stellt sich die Frage: Wann bekommen die Kids ein eigenes Linux Laptop? ;-D

    19 Kommentare

    Karsten · 5. Februar 2020 um 07:48

    Hi Schroeffu,

    Habe jetzt nochmal eine Testinstanz nach genau deiner Anleitung erstellt.
    Mit „sss_ssh_authorizedkeys “ erhalte ich die Fehlermeldung „Error looking up public keys“
    Wenn ich in der sssd.conf die Services um ssh ergänze verschwindet zwar der Fehler, aber ich erhalte keinen PublicKey.
    Mit „ldapsearch -h ad.example.de -xb „dc=example,dc=de“ ‚(sAMAccountName=)‘ -D karstenr@example.de -w ’sshPublicKey'“ sehe ich jedoch den Public Key.

    Hast du noch eine Idee?

      Schroeffu · 5. Februar 2020 um 09:14

      Ich hatte ebenso von sss_ssh_authorizedkeys erstmal „keine Antwort“. Während der Fehlersuche habe ich gelernt, SSSD legt sich eine Kopie der LDAP Daten ab unter: /var/lib/sss/db/cache_YouDomain.ldb

      Dort kann man reinschauen ob der eigene Username drin steckt – oder eben das Attribut sshPublicKey dazu: strings /var/lib/sss/db/cache_YouDomain.ldb | grep -i MyADUsername bzw. strings /var/lib/sss/db/cache_YouDomain.ldb | grep -i sshPublicKey

      Vermutlich kann man selbst mit LDAPSearch in dieser Datei suchen, habe ich bisher nie machen müssen.

      Bei mir war die Zwischenlösung: SSSD Cache komplett löschen mit sss_cache -E, danach funktionierte sss_ssh_authorizedkeys ADUsername genau 1x. Danach nicht mehr, bis zum nächsten Cache löschen. Die endgültige Lösung in meinem Fall war in der AD das Attribut ändern auf: [x] Attribut in den globalen Katalog replizieren

        Stefan · 8. Oktober 2021 um 14:45

        Hallo! Danke für den tollen Artikel! Leider hänge ich beim sshPublicKey abfragen aus dem AD, Attribut ist angelegt und wird in den Global Catalog repliziert, leider gibt mir sss_ssh_authorizedkeys auch nach dem Cache löschen nichts retour. Einfach leer. Kann es sein, dass das einfach dauert? in der sssd.conf habe ich folgendes aktiv:
        services = nss, pam, sudo, ssh

          Stefan · 11. Oktober 2021 um 09:28

          Hallo nochmal. So ich habs jetzt geschafft dass der PublicKey ausgelesen wird, und der Login funktioniert nun auch mit dem PublicKey aus dem AD. Mein Problem war, dass das Attribut nicht ausgelesen werden konnte – ich habe dann den Key ebenso in das Attribut altSecurityIdentities eingetragen – das wird problemlos ausgelesen – keine Ahnung warum es da beim sshPublicKey Attribut bockt. Aber egal, so funktioniert es. Danke für die tolle Anleitung nochmal!!

            Schroeffu · 11. Oktober 2021 um 16:17

            Hi Stefan, cool dass es hinbekommen hast. Könnte es nicht einfach nur ein Vertipper sein? Meine Anleitung habe ich geschreiben für „sshPublicKeys“ mit „s“ am Ende, obwohl besser gewesen wäre „sshPublicKey“ zu verwenden. Unsere Active Directory war da schon mit diesem Attribut erweitert, ich habe es also mit „s“ am Ende übernommen für SSSD.

            ldap_user_ssh_public_key = sshPublicKeys

            Stefan · 15. Oktober 2021 um 08:23

            Hi! Nein, das hatte ich schin richtig benannt, ohne s am Schluss. Ich glaube dass es da einfach ein Problem im AD gibt (Enable im GC ist gesetzt) – egal, es funktioniert nun mit dem altSecurityIdentities genauso wunderbar.

    Karsten · 5. Februar 2020 um 07:50

    Oh… Deine Kommentarfunktion schluckt Spitzklammer-Attribute 😀
    ldapsearch -h ad.example.de -xb „dc=example,dc=de“ ‚(sAMAccountName=karsten)‘ -D karsten@example.de -w verysecretpassword ’sshPublicKey‘

    tux4fun · 5. Februar 2020 um 08:33

    „Schade, Mozilla… Mal wieder…“
    -> FileZilla wird nicht von Mozilla entwickelt.

      Schroeffu · 5. Februar 2020 um 09:18

      Haha, stimmt ja, total der Fail von mir. Ich habe bisher immer FileZille mit Mozilla verbunden, scheint ja überhaupt nicht zu stimmen… Wird korrigiert *peinlich wegduck* ..

    Klaus · 28. April 2020 um 12:55

    AD kennst schon das altSecurityIdentities Attribut
    https://docs.microsoft.com/en-us/windows/win32/adschema/a-altsecurityidentities
    also:
    ldap_user_ssh_public_key = altSecurityIdentities

    Karsten · 30. Juni 2020 um 15:48

    Hi Schroeffu,

    kurzes OT… Da du Ubuntu mit Windows AD nutzt, dachte ich wende mich mal an dich.
    Habe SSSD mit dyndns konfiguriert, da mir der Windows DNS sonst beim Scavengen die Einträge wegschmeisst. Funktioniert auch soweit, solange Ubuntu eine FQDN bilden kann.

    Nun versuche ich den Hostnamen und Domainnamen vom DHCP an den Host im Lease zu senden. Lease nethält auch die entsprechenden Optionen. Leider nutzt Ubuntu nur den Hostnamen, aber bildet keine FQDN mit der Option Domain-Name. Somit wird beim join mit realm kein DNS Eintrag erstellt und in der Reverse Lookupzone steht bei der IP auch nur der Hostname statt der FQDN. Den leidigen Eintrag in der /etc/hosts würde ich mir gern sparen…

    Hast du evtl einen Tipp für mich, wie ich Ubuntu dazu bewege die DHCP Option 15 auch zu benutzen?

    Grüße,
    Karsten

    Marco · 30. Juni 2020 um 16:18

    Hier noch etwas on-topic 🙂

    Ich musste in der sssd.conf noch „ssh“ in der Zeile „services“ ergänzen, ansonsten hat der Login nicht funktioniert. Ging das bei dir ohne oder ist es in der Dokumentation durchgerutscht?

    Ich habe übrigens auch das schon vorhandene Attribut altSecurityIdentities genutzt, somit war eine Änderung des Schemas vermeidbar.

    Und vielen Dank für diese beiden Tutorials!

      Karsten · 30. Juni 2020 um 16:34

      Bei mir funktioniert es ohne „ssh“ in den „services“
      Umgebung Ubuntu 20.04.
      Ich nutze übrigens inzwischen auch die altSecurityIdentities

        Schroeffu · 30. Juni 2020 um 17:17

        Hmm, in meinem Fall ist SSH mit drin, hier die Komplettansicht section [sssd]

        [sssd]
        domains = companydomain.intra
        config_file_version = 2
        services = nss, pam, sudo, ssh

          Marco · 30. Juni 2020 um 17:32

          Sei doch so lieb und poste noch, was nötig ist, um die sudo-Berechtigungen von sssd aus dem AD ziehen zu lassen. 🙂

            Karsten · 1. Juli 2020 um 08:37

            Ich habe lediglich die Gruppe „sudo“ in der AD angelegt und die entsprechenden Benutzer der Gruppe hinzugefügt.

    Schroeffu · 7. Juli 2021 um 18:05

    Ansible Playbook im Blogpost verlinkt (https://seafile.schroeffu.ch/d/2d51829bf48249848775/)

    Nombres · 15. August 2022 um 10:56

    Hallo Schroeffu, mit deinem Tutorial konnte bei mir der Inhalt eines Attributes über „sss_ssh_authorizedkeys“ nicht gelesen werden, erst nachdem ich in /etc/sssd/sssd.conf in der Zeile zu „services“ „, ssh“ hinzugefügt habe könnte ich die Public keys auslesen und ssh logins ausführen.

    Meine Conf sieht folgend aus,

    [sssd]
    domains = example.de
    config_file_version = 2
    services = nss, pam, ssh

    [domain/example.de]
    ad_domain = example.de
    krb5_realm = EXAMPLE.DE
    realmd_tags = manages-system joined-with-adcli
    cache_credentials = True
    id_provider = ad
    krb5_store_password_if_offline = True
    default_shell = /bin/bash
    ldap_id_mapping = True
    use_fully_qualified_names = True
    fallback_homedir = /home/%u@%d
    access_provider = ad
    ldap_user_ssh_public_key = sshPublicKeys
    debug_level = 5

    Schreibe einen Kommentar

    Avatar-Platzhalter

    Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert