From 804dcf79ef03716ed117196ade6a0b4e31518d16 Mon Sep 17 00:00:00 2001 From: Florian Zumpe Date: Mon, 19 Oct 2026 17:22:13 +0200 Subject: [PATCH] added readme --- README.md | 433 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 433 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c83f2a5 --- /dev/null +++ b/README.md @@ -0,0 +1,433 @@ +# 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](#zweck-des-skripts) +- [Kurzbeschreibung des Ablaufs](#kurzbeschreibung-des-ablaufs) +- [Dialoge, Fallbacks und interaktive Eingaben](#dialoge-fallbacks-und-interaktive-eingaben) +- [Parameter und Umgebungsvariablen](#parameter-und-umgebungsvariablen) +- [Beispielaufrufe](#beispielaufrufe) +- [Technischer Ablauf im Detail](#technischer-ablauf-im-detail) +- [Besonderheiten bei Proxmox LXC](#besonderheiten-bei-proxmox-lxc) +- [SSSD-ID-Mapping und Container-Namespace](#sssd-id-mapping-und-container-namespace) +- [Sudo-Berechtigungen über AD-Gruppen](#sudo-berechtigungen-über-ad-gruppen) +- [Validierung nach dem Lauf](#validierung-nach-dem-lauf) +- [Bemerkungen und TODOs](#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: + +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: + +```text +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: + +```bash +sudo ./domain-join.sh +``` + +Aufruf mit vorbelegter Domain und Join-Benutzer: + +```bash +sudo AD_DOMAIN_FQDN="corp.example.com" \ + AD_JOIN_USER="joinuser" \ + ./domain-join.sh +``` + +Aufruf mit Computer-OU und deaktivierter DNS-Autokonfiguration: + +```bash +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: + +```bash +sudo AD_DOMAIN_FQDN="corp.example.com" \ + AD_JOIN_USER="joinuser" \ + USE_FQ_NAMES=true \ + ./domain-join.sh +``` + +Aufruf ohne Session-Timeout: + +```bash +sudo SESSION_TIMEOUT_SECONDS=0 ./domain-join.sh +``` + +Aufruf mit Credential-Caching, sofern der Container beziehungsweise Kernel-Keyring dies erlaubt: + +```bash +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: + +```text +_ldap._tcp. +``` + +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: + +```bash +realm join --verbose -U +``` + +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: + +```text +/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: + +```text +Container IDs: +0 - 999999 +``` + +Das zugehörige Hostschema ist: + +```text +000000 - 999999 +``` + +Die Proxmox-Konfiguration wird dabei bewusst mit Platzhaltern dokumentiert: + +```text +/etc/pve/lxc/.conf + + lxc.idmap: u 0 000000 1000000 + lxc.idmap: g 0 000000 1000000 + +/etc/subuid + + root:000000:1000000 + +/etc/subgid + + root:000000:1000000 + +Restart: + + pct restart +``` + +Dabei ist `` 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: + +```text +Host-Basis = 000000 +``` + +Die README verwendet bewusst keine konkrete Container-ID in der Anleitung, damit die Konfiguration nicht versehentlich kopiert wird, ohne `` 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: + +```text +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: + +```text +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: + +```text +/etc/sudoers.d/90-ad-groups +``` + +Die Gruppenauswahl erfolgt bevorzugt über eine temporäre Aktivierung von SSSD-Enumeration: + +```text +enumerate = true +``` + +Danach wird die Enumeration wieder deaktiviert: + +```text +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: + +```text +Domain Admins +``` + +wird: + +```sudoers +%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: + +```bash +realm list +``` + +```bash +sssctl config-check +``` + +```bash +sssctl domain-status +``` + +```bash +getent passwd +``` + +```bash +id +``` + +SSH-Test: + +```bash +ssh @ +``` + +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.