Files
sssd-configuration/README.md
T
Florian Zumpe 804dcf79ef
Sonarqube Scanner / Build and analyze (push) Canceled after 0s
added readme
2026-10-19 17:22:13 +02:00

434 lines
13 KiB
Markdown

# 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.<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:
```bash
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:
```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
<ctid>000000 - <ctid>999999
```
Die Proxmox-Konfiguration wird dabei bewusst mit Platzhaltern dokumentiert:
```text
/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:
```text
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:
```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 <domain>
```
```bash
getent passwd <ADUser>
```
```bash
id <ADUser>
```
SSH-Test:
```bash
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.