Florian Zumpe 804dcf79ef
Sonarqube Scanner / Build and analyze (push) Canceled after 0s
added readme
2026-10-19 17:22:13 +02:00
2026-06-08 13:34:15 +02:00
2026-06-08 14:27:19 +02:00
2026-10-19 17:22:13 +02:00

SSSD Connection Setup für Ubuntu, Active Directory und Proxmox LXC

Dieses Repository enthält ein Bash-Skript zur automatisierten Anbindung von Ubuntu-Systemen an eine Active-Directory-Domäne über realmd, adcli, Kerberos und SSSD. Das Skript ist für klassische VMs ebenso vorgesehen wie für unprivilegierte Proxmox-LXC-Container.

Inhaltsverzeichnis

Zweck des Skripts

Das Skript bindet ein Ubuntu-System automatisiert an eine Active-Directory-Domäne an und richtet die dafür benötigten Komponenten ein.

Es übernimmt insbesondere:

  • Installation der benötigten Pakete
  • DNS-basierte Erkennung von Domain Controllern
  • DNS-basierte Erkennung von Nameservern
  • Kerberos-Grundkonfiguration
  • AD-Join über realmd / adcli
  • SSSD-Konfiguration mit AD-Provider
  • automatische Home-Verzeichnisse über pam_mkhomedir
  • optionale Sudo-Berechtigungen für AD-Gruppen
  • spezielle Hinweise und Prüfungen für unprivilegierte Proxmox-LXC-Container

Das Skript ist so ausgelegt, dass möglichst wenige Angaben manuell notwendig sind. Wo möglich, werden Informationen über DNS oder aus dem Systemkontext ermittelt.

Kurzbeschreibung des Ablaufs

Der grobe Ablauf ist:

  1. Root-Rechte prüfen.
  2. Umgebung erkennen: VM, LXC oder unbekannter Container.
  3. Benötigte Pakete installieren.
  4. Bei LXC: vorhandenes UID-/GID-Mapping prüfen.
  5. Fehlende AD-Parameter interaktiv abfragen.
  6. DNS-Konfiguration vorbereiten oder bestehende DNS-Konfiguration beibehalten.
  7. Zeitsynchronisierung aktivieren.
  8. Hostname setzen.
  9. Bestehenden Realm erkennen und optional verlassen.
  10. Kerberos-Konfiguration schreiben.
  11. Active-Directory-Join durchführen.
  12. SSSD konfigurieren.
  13. PAM-Home-Verzeichnisse aktivieren.
  14. Optional Sudo-Gruppen aus AD auswählen oder manuell eintragen.
  15. Validierung über realm, sssctl, getent und id vorbereiten.

Dialoge, Fallbacks und interaktive Eingaben

Das Skript verwendet bevorzugt dialog, sofern es installiert ist und ein interaktives TTY verfügbar ist. Andernfalls wird für einfache Eingaben auf read zurückgegriffen.

Interaktive Dialoge können auftreten für:

  • AD-Domain-FQDN
  • Join-Benutzer
  • Join-Passwort
  • Entscheidung bei bereits bestehender Domain-Mitgliedschaft
  • optionales Zurücksetzen des SSSD-ID-Mappings
  • Sudo-Gruppenfilter
  • Auswahl von AD-Gruppen für Sudo
  • manuelle Sudo-Gruppeneingabe, falls AD-Gruppen nicht enumeriert werden können

Fallbacks

Das Skript enthält mehrere Fallbacks:

  • Wenn keine DNS-Server über NS-Records gefunden werden, bleibt die vorhandene Resolver-Konfiguration erhalten.
  • Wenn systemd-timesyncd nicht verfügbar ist, wird auf chrony zurückgegriffen.
  • Wenn AD-Gruppen nicht enumeriert werden können, wird ein manueller Eingabedialog für eine einzelne Sudo-Gruppe angezeigt.
  • Wenn bei dieser manuellen Sudo-Gruppeneingabe nichts eingetragen wird, wird kein Sudoers-Eintrag angelegt.
  • Wenn SSSD-Credential-Caching aktiviert wurde, aber der Kernel-Keyring nicht nutzbar ist, bleibt Credential-Caching deaktiviert.

Parameter und Umgebungsvariablen

Viele Dialogwerte können direkt beim Aufruf über Umgebungsvariablen vorbelegt werden.

Active Directory und Join

Variable Standard Beschreibung
AD_DOMAIN_FQDN leer FQDN der AD-Domäne, z. B. corp.example.com
AD_JOIN_USER leer Benutzer für den Domain-Join, ohne Domain-Präfix
AD_OU_DN leer Optionale OU für das Computerobjekt, z. B. OU=Linux,OU=Servers,DC=corp,DC=example,DC=com
COMPUTER_NAME hostname -s Kurzer Hostname für das System
USE_FQ_NAMES false true verwendet vollständig qualifizierte Benutzernamen
DISABLE_DNS_AUTOCONFIG false true verhindert automatische DNS-Konfiguration

Session und PAM

Variable Standard Beschreibung
SESSION_TIMEOUT_SECONDS 7200 Inaktivitäts-Timeout für interaktive Shells; 0 deaktiviert den Timeout
PAM_UMASK 0027 Umask für automatisch erstellte Home-Verzeichnisse

SSSD-ID-Mapping

Variable Standard Beschreibung
LXC_IDMAP_RANGE_SIZE 1000000 Anzahl der im LXC-Namespace gemappten IDs pro Container
IDMAP_RANGE_MIN 100000 Erste von SSSD für AD-Mapping verwendete ID im Container
IDMAP_RANGE_SIZE LXC_IDMAP_RANGE_SIZE - IDMAP_RANGE_MIN Größe des SSSD-ID-Bereichs
IDMAP_RANGE_MAX IDMAP_RANGE_MIN + IDMAP_RANGE_SIZE - 1 Letzte von SSSD verwendbare ID

Mit den Standardwerten ergibt sich:

LXC-Namespace: 0 - 999999
SSSD/AD-IDs:   100000 - 999999

Sudo-Gruppen

Variable Standard Beschreibung
SUDO_GROUP_FILTER LINUX Filter für die interaktive AD-Gruppenauswahl
SUDOERS_DROPIN_FILE /etc/sudoers.d/90-ad-groups Zielpfad für den generierten Sudoers-Drop-in

Credential-Caching

Variable Standard Beschreibung
ENABLE_CREDENTIAL_CACHING false Aktiviert SSSD-Credential-Caching nur, wenn der Kernel-Keyring nutzbar ist

Beispielaufrufe

Minimaler interaktiver Aufruf:

sudo ./domain-join.sh

Aufruf mit vorbelegter Domain und Join-Benutzer:

sudo AD_DOMAIN_FQDN="corp.example.com" \
     AD_JOIN_USER="joinuser" \
     ./domain-join.sh

Aufruf mit Computer-OU und deaktivierter DNS-Autokonfiguration:

sudo AD_DOMAIN_FQDN="corp.example.com" \
     AD_JOIN_USER="joinuser" \
     AD_OU_DN="OU=Linux,OU=Servers,DC=corp,DC=example,DC=com" \
     DISABLE_DNS_AUTOCONFIG=true \
     ./domain-join.sh

Aufruf mit vollständig qualifizierten Benutzernamen:

sudo AD_DOMAIN_FQDN="corp.example.com" \
     AD_JOIN_USER="joinuser" \
     USE_FQ_NAMES=true \
     ./domain-join.sh

Aufruf ohne Session-Timeout:

sudo SESSION_TIMEOUT_SECONDS=0 ./domain-join.sh

Aufruf mit Credential-Caching, sofern der Container beziehungsweise Kernel-Keyring dies erlaubt:

sudo ENABLE_CREDENTIAL_CACHING=true ./domain-join.sh

Technischer Ablauf im Detail

1. Paketinstallation

Das Skript installiert unter anderem:

  • realmd
  • adcli
  • sssd
  • sssd-tools
  • libnss-sss
  • libpam-sss
  • krb5-user
  • samba-common-bin
  • dnsutils
  • ldap-utils
  • dialog
  • keyutils

Vorher werden die APT-Paketlisten aktualisiert und installierte Pakete aktualisiert.

2. DNS-Erkennung

Die Domain Controller werden über SRV-Records gesucht:

_ldap._tcp.<domain>

DNS-Server werden über NS-Records der AD-Domain ermittelt. Wenn systemd-resolved aktiv ist, wird ein Drop-in unter /etc/systemd/resolved.conf.d/ geschrieben. Andernfalls wird /etc/resolv.conf direkt geschrieben, sofern die DNS-Autokonfiguration nicht deaktiviert wurde.

3. Zeitsynchronisierung

Kerberos ist empfindlich gegenüber Zeitabweichungen. Das Skript bevorzugt deshalb systemd-timesyncd. Wenn dieser Dienst nicht verfügbar ist, wird chrony verwendet oder installiert.

4. Kerberos

Das Skript schreibt eine minimale /etc/krb5.conf, die DNS-basierte Realm- und KDC-Erkennung verwendet.

5. Domain Join

Der Join erfolgt über:

realm join --verbose <domain> -U <join-user>

Wenn AD_OU_DN gesetzt ist, wird zusätzlich --computer-ou=... verwendet.

6. SSSD

Das Skript schreibt /etc/sssd/sssd.conf mit:

  • id_provider = ad
  • auth_provider = ad
  • access_provider = ad
  • ldap_id_mapping = true
  • konfigurierbarem ID-Mapping
  • deaktivierter GPO-Auswertung über ad_gpo_access_control = disabled
  • optionalem Credential-Caching

Anschließend wird SSSD aktiviert und neu gestartet.

7. PAM-Home-Verzeichnisse

Das Skript stellt sicher, dass pam_mkhomedir.so in folgenden Dateien vorhanden ist:

  • /etc/pam.d/common-session
  • /etc/pam.d/common-session-noninteractive

Dadurch werden Home-Verzeichnisse für AD-Benutzer beim ersten Login automatisch erzeugt.

Besonderheiten bei Proxmox LXC

Unprivilegierte Proxmox-LXC-Container verwenden User Namespaces. Dadurch werden Container-UIDs und Container-GIDs auf Host-UIDs und Host-GIDs gemappt.

Das Skript läuft innerhalb des Containers. Deshalb kann es die Host-Konfiguration nicht selbst ändern. Es kann aber prüfen, wie der Container aktuell gemappt ist.

Dazu werden ausgewertet:

/proc/self/uid_map
/proc/self/gid_map

Die Host-Hinweise werden nur ausgegeben, wenn das aktuelle Mapping den benötigten Bereich nicht abdeckt.

Erwartetes Mapping

Das Skript erwartet standardmäßig einen Container-Namespace mit 1.000.000 IDs:

Container IDs:
0 - 999999

Das zugehörige Hostschema ist:

<ctid>000000 - <ctid>999999

Die Proxmox-Konfiguration wird dabei bewusst mit Platzhaltern dokumentiert:

/etc/pve/lxc/<ctid>.conf

  lxc.idmap: u 0 <ctid>000000 1000000
  lxc.idmap: g 0 <ctid>000000 1000000

/etc/subuid

  root:<ctid>000000:1000000

/etc/subgid

  root:<ctid>000000:1000000

Restart:

  pct restart <ctid>

Dabei ist <ctid> durch die tatsächliche Proxmox-Container-ID zu ersetzen.

Beispielhafte Berechnung

Für eine dreistellige CTID wird der Hostbereich durch Anhängen von sechs Nullen gebildet.

Schema:

Host-Basis = <ctid>000000

Die README verwendet bewusst keine konkrete Container-ID in der Anleitung, damit die Konfiguration nicht versehentlich kopiert wird, ohne <ctid> zu ersetzen.

SSSD-ID-Mapping und Container-Namespace

SSSD erzeugt die AD-UIDs und AD-GIDs innerhalb des Containers. Diese IDs müssen vollständig im Container-Namespace enthalten sein.

Mit den Standardwerten gilt:

Container-Namespace:
0 - 999999

SSSD-ID-Bereich:
100000 - 999999

Dadurch bleiben IDs unterhalb von 100000 für lokale und systemnahe Konten reserviert. SSSD nutzt den restlichen Bereich.

Wichtig:

LXC_IDMAP_RANGE_SIZE muss größer als IDMAP_RANGE_MAX sein.

Das Skript prüft diese Bedingung und bricht mit einer Fehlermeldung ab, wenn der Namespace zu klein ist.

Sudo-Berechtigungen über AD-Gruppen

Das Skript kann AD-Gruppen sudo-Berechtigungen geben, indem es einen Drop-in unter /etc/sudoers.d/ erzeugt.

Der Standardpfad ist:

/etc/sudoers.d/90-ad-groups

Die Gruppenauswahl erfolgt bevorzugt über eine temporäre Aktivierung von SSSD-Enumeration:

enumerate = true

Danach wird die Enumeration wieder deaktiviert:

enumerate = false

Falls das AD keine Gruppenliste zurückgibt oder Enumeration nicht erlaubt ist, wird ein manueller Eingabedialog angezeigt. Dort kann genau eine AD-Gruppe eingetragen werden.

Wenn die Eingabe leer bleibt, wird kein Sudoers-Eintrag angelegt. Ein vorhandener, vom Skript verwalteter Drop-in wird dann entfernt.

Gruppennamen mit Leerzeichen werden für sudoers escaped. Aus:

Domain Admins

wird:

%Domain\ Admins ALL=(ALL:ALL) ALL

Die erzeugte Sudoers-Konfiguration wird mit visudo -cf /etc/sudoers validiert. Wenn die Validierung fehlschlägt, wird der Drop-in entfernt und das Skript bricht ab.

Validierung nach dem Lauf

Nach erfolgreichem Skriptlauf sollten folgende Prüfungen durchgeführt werden:

realm list
sssctl config-check
sssctl domain-status <domain>
getent passwd <ADUser>
id <ADUser>

SSH-Test:

ssh <ADUser>@<host-or-container-ip>

Wenn vollständig qualifizierte Namen aktiviert wurden, muss der Benutzername entsprechend mit Domain angegeben werden, abhängig von der SSSD-Konfiguration.

Bemerkungen und TODOs

Bemerkungen

  • Das Skript ist für Ubuntu-Systeme vorgesehen.
  • Die LXC-Hostkonfiguration muss auf dem Proxmox-Host erfolgen.
  • Das Skript kann die Proxmox-Hostdateien aus dem Container heraus nicht selbst ändern.
  • Die UID-/GID-Map-Prüfung verhindert unnötige Hinweise, wenn das Mapping bereits korrekt eingerichtet wurde.
  • Bei Änderungen an IDMAP_RANGE_* sollte der SSSD-Cache zurückgesetzt werden, damit alte Mappingdaten nicht weiterverwendet werden.
  • Für unprivilegierte Container kann keyctl eingeschränkt sein. Credential-Caching bleibt deshalb standardmäßig deaktiviert.

TODOs

  • Optional mehrere manuell eingegebene Sudo-Gruppen unterstützen.
  • Optional nicht-interaktiven Modus mit vollständiger Vorkonfiguration ergänzen.
  • Optional --help oder usage() für alle Parameter ergänzen.
  • Optional --dry-run für reine Prüfung ohne Änderungen ergänzen.
  • Optional Logging in eine Datei ergänzen.
  • Optional systemd-resolved-Konfiguration genauer an bestehende lokale Resolver-Policies anpassen.
  • Optional Re-Join-Verhalten über explizite Parameter steuerbar machen.
  • Optional Tests für ShellCheck, Bats oder Container-Testläufe ergänzen.
S
Description
No description provided
Readme
90 KiB
Languages
Shell 100%