13 KiB
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
- Kurzbeschreibung des Ablaufs
- Dialoge, Fallbacks und interaktive Eingaben
- Parameter und Umgebungsvariablen
- Beispielaufrufe
- Technischer Ablauf im Detail
- Besonderheiten bei Proxmox LXC
- SSSD-ID-Mapping und Container-Namespace
- Sudo-Berechtigungen über AD-Gruppen
- Validierung nach dem Lauf
- Bemerkungen und TODOs
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:
- Root-Rechte prüfen.
- Umgebung erkennen: VM, LXC oder unbekannter Container.
- Benötigte Pakete installieren.
- Bei LXC: vorhandenes UID-/GID-Mapping prüfen.
- Fehlende AD-Parameter interaktiv abfragen.
- DNS-Konfiguration vorbereiten oder bestehende DNS-Konfiguration beibehalten.
- Zeitsynchronisierung aktivieren.
- Hostname setzen.
- Bestehenden Realm erkennen und optional verlassen.
- Kerberos-Konfiguration schreiben.
- Active-Directory-Join durchführen.
- SSSD konfigurieren.
- PAM-Home-Verzeichnisse aktivieren.
- Optional Sudo-Gruppen aus AD auswählen oder manuell eintragen.
- Validierung über
realm,sssctl,getentundidvorbereiten.
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-timesyncdnicht verfügbar ist, wird aufchronyzurü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:
realmdadclisssdsssd-toolslibnss-ssslibpam-ssskrb5-usersamba-common-bindnsutilsldap-utilsdialogkeyutils
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 = adauth_provider = adaccess_provider = adldap_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
keyctleingeschrä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
--helpoderusage()für alle Parameter ergänzen. - Optional
--dry-runfü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.