FreeIPA¶
Siehe auch
- Verwandte Artikel
- Offizielle Dokumentation
- Linuxfabrik
FreeIPA (das IPA steht für Identity, Policy, Audit) ist eine web- und kommandozeilenbasierte Identity-Management-Lösung für Linux- und UNIX-Netzwerkumgebungen. Es kombiniert bekannte Open-Source-Komponenten und Standardprotokolle: 389 Directory Server, MIT Kerberos, NTP, DNS und das Zertifikatssystem Dogtag.
Ein FreeIPA-Server bietet zentralisierte Authentifizierungs-, Autorisierungs- und Kontoinformationen. In einer FreeIPA-Domäne können problemlos mehrere FreeIPA-Server parallel betrieben werden, um Redundanz und Skalierbarkeit zu gewährleisten.
Der 389 Directory Server speichert Daten zu Benutzern, Gruppen, Hosts und anderen Objekten und bietet eine vollständige Multi-Master-LDAPv3-Verzeichnisinfrastruktur. Die Single-Sign-On-Authentifizierung erfolgt über das MIT Kerberos KDC. Die Authentifizierungsfunktionen werden durch eine integrierte Zertifizierungsstelle erweitert, die auf dem Dogtag-Projekt basiert. Optional können Domänennamen über den integrierten ISC-BIND-Server verwaltet werden.
Zugriffskontrolle, die Delegierung von Verwaltungsaufgaben etc. können vollständig zentralisiert und über die Web-Benutzeroberfläche oder das ipa-Befehlszeilentool verwaltet werden.
Das kommerzielle Produkt heisst „Red Hat IdM“.
Begriffe
DIT: Directory Information Tree, die hierarchische Baumstruktur eines LDAP-Verzeichnisses
NGP: Netgroups Private
UPG: User Private Groups
Bemerkung
FreeIPA unterstützt das Anlegen eigener OUs (Organizational Units) nicht. Organisatorische Gruppen werden stattdessen über IPA-Gruppen abgebildet. Web-UI und CLI-Tool funktionieren nicht korrekt, wenn die Standard-DIT-Struktur (Directory Information Tree) in IPA verändert wird.
Installation auf RHEL 8+¶
# the fully-qualified name must come first
192.0.2.26 idm.ipa.test idm
Entweder als Bundle aus FreeIPA und DNS (FreeIPA speichert DNS-Records in seinem 389DS-LDAP-Server), oder ohne integriertes DNS, falls externe DNS-Server die Zone bereits verwalten.
Auf RHEL 8 über das idm:DL1-Modul:
# mit integriertem DNS
dnf --assumeyes module install idm:DL1/dns
# ohne integrierten DNS
dnf --assumeyes module install idm:DL1/server
Ab RHEL 9 gibt es das idm-Modul nicht mehr, die Pakete liegen direkt im AppStream:
# mit integriertem DNS
dnf --assumeyes install ipa-server ipa-server-dns
# ohne integrierten DNS
dnf --assumeyes install ipa-server
Auf einem RHEL-Minimal-System werden damit um die 300 Pakete installiert, unter anderem Dogtag-CA, chrony, 389DS, Key Distribution Center (KDC) und Apache HTTP Server.
Setup starten:
ipa-server-install
# if IPA should do DNS
# ipa-server-install --setup-dns
Wichtig: es muss ein Zwei-Level-Domainname sein, ein „.local“ o.ä. genügt nicht. Wird das gewählt, kann man keine Benutzer anlegen, da sich FreeIPA über ungültige E-Mail-Adressen beschwert (username@local ist keine gültige Mail-Adresse).
The IPA Master Server will be configured with:
Hostname: idm.ipa.test
IP address(es): 192.0.2.26
Domain name: ipa.test
Realm name: IPA.TEST
Das Log-File zur Installation findet sich in /var/log/ipaserver-install.log.
Next steps:
1. You must make sure these network ports are open:
TCP Ports:
* 80, 443: HTTP/HTTPS
* 389, 636: LDAP/LDAPS
* 88, 464: kerberos
UDP Ports:
* 88, 464: kerberos
* 123: ntp
2. You can now obtain a kerberos ticket using the command: 'kinit admin'
This ticket will allow you to use the IPA tools (e.g., ipa user-add)
and the web user interface.
Be sure to back up the CA certificates stored in /root/cacert.p12
These files are required to create replicas. The password for these
files is the Directory Manager password
Auf einem bestehenden Name-Server „autodiscovery“ einrichten:
_ldap._tcp IN SRV 10 10 389 idm.ipa.test.
Prüfen, ob vorhanden:
dig SRV _ldap._tcp.ipa.test
Das Anlegen von Home-Verzeichnissen auf Clients erlauben:
authselect enable-feature with-mkhomedir
systemctl enable --now oddjobd
Auf dem FreeIPA Test: kinit -V admin (-V = verbose)
Installation im Docker-Container¶
Im Beispiel mit Podman auf Fedora 37:
sudo mkdir /var/lib/ipa-data
# https://hub.docker.com/r/freeipa/freeipa-server/tags
sudo podman run --name freeipa-server -ti -h ipa.example.test --read-only -v /var/lib/ipa-data:/data:Z freeipa/freeipa-server:fedora-37-4.10.1
CLI¶
Tool: ipa
kinit admin
ipa group-add
ipa group-add-member
ipa group-remove-member
ipa group-show
ipa hbacrule-find
ipa user-add
ipa user-find # list all users
ipa user-mod
ipa user-mod firstname.last --gidnumber 1234567 # change primary group (GID)
ipa user-show --all admin
Ohne Interaktion: ipa --no-prompt
Gruppe umbenennen:
ipa group-mod <old_group_name> --rename <new_group_name>
Password-Expiration ändern¶
Im Standard laufen Passwörter nach 90 Tagen ab. Um das zu ändern, muss man die Password-Policy anpassen. Im FreeIPA Web-GUI:
Policy > Password Policies > global_policy > Max lifetime (days): 10000 (maximal sind 20000 Tage erlaubt)
IPA Server > Configuration > Default shell: /bin/bash
IPA Server > Configuration > Password Expiration Notification (days): 10
Durch Benutzer anpassbare Felder¶
Welche Felder dürfen User selbst administrieren? Es ist sinnvoll, folgende Felder hinzuzufügen:
IPA Server > Role-Based Access Control > Self Service Permissions > User Self service
mail
Rebuild Host/User Membership¶
Identity > Users or Hosts > Actions > Rebuild auto membership.
Delegation¶
Wie legt man einen Subadmin an, der nur Benutzer einer bestimmten, vom Admin angelegten Gruppe verwalten kann, beispielsweise „sales“? Und wie kommt man auf die Lösung?
Die zweite Frage ist einfach zu beantworten: Einen neuen Subadmin anlegen, und diesem die Role „User Administrator“ zuweisen. So sieht man, welche Permissions und Privilegien diese Art von Benutzer benötigt.
Beim Anlegen neuer Rollen, Privilegien und Permissions empfiehlt es sich, Prefixe in der Namensgebung zu verwenden, beispielsweise
bei Rollen: „<Kundenummer> Role <Rollenname>“, „My Role: <Rollenname>“, o.ä.
bei Privilegien: „<Kundenummer> Priv <Privilegienname>“, „My Priv: <Privilegienname>“, o.ä.
bei Permissions: „<Kundenummer> Perm <Permissionname>“, „My Perm: <Permissionname>“, o.ä.
Die Berechtigungen werden in der Reihenfolge angelegt:
IPA Server > Role-Based Access Control > Permissions
IPA Server > Role-Based Access Control > Privileges (fasst Permissions zusammen)
IPA Server > Role-Based Access Control > Roles (fasst Privileges zusammen)
Als Code:
kinit admin
ipa help commands
ipa group-add "sales"
ipa group-add "admin-sales"
ipa permission-add "My Perm Add User to group sales" \
--right=write \
--attrs=member \
--bindtype=permission \
--targetgroup=sales
ipa permission-add "My Perm Change User password sales" \
--right=write \
--attrs=krbpasswordexpiration \
--attrs=krbprincipalkey \
--attrs=passwordhistory \
--attrs=sambalmpassword \
--attrs=sambantpassword \
--attrs=userpassword \
--bindtype=permission \
--memberof=sales \
--type=user
ipa permission-add "My Perm Modify Users sales" \
--right=write \
--attrs=displayname \
--attrs=givenname \
--attrs=mail \
--bindtype=permission \
--memberof=sales \
--type=user
ipa permission-add "My Perm Remove Users sales" \
--right=delete \
--bindtype=permission \
--memberof=sales \
--type=user
ipa permission-add "My Perm Unlock User sales" \
--right=write \
--attrs=krblastadminunlock \
--attrs=krbloginfailedcount \
--attrs=nsaccountlock \
--bindtype=permission \
--memberof=sales \
--type=user
ipa privilege-add "My Priv User Administrators sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="My Perm Add User to group sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="My Perm Change User password sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="My Perm Modify Users sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="My Perm Remove Users sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="My Perm Unlock User sales"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="System: Add User to default group"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="System: Add Users"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="System: Change User password"
ipa privilege-add-permission "My Priv User Administrators sales" --permissions="System: Read UPG Definition"
ipa role-add "My Role User Administrator sales"
ipa role-add-member "My Role User Administrator sales" --groups="admin-sales"
ipa role-add-privilege "My Role User Administrator sales" --privileges="My Priv User Administrators sales"
Read-Only LDAP User anlegen (Service-Account)¶
Wer für eine Applikation einen Read-only Benutzer benötigt (z.B. um in Nextcloud eine LDAP-Anbindung zu konfigurieren), erstellt diesen so:
ldapmodify_new_pw=$(< /dev/urandom tr -dc A-Za-z0-9 | head -c60)
echo $ldapmodify_new_pw
cat > /tmp/ldapmodify << EOF
dn: uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=linuxfabrik,dc=it
changetype: add
objectclass: account
objectclass: simplesecurityobject
uid: freeipa-reader
userPassword: $ldapmodify_new_pw
passwordExpirationTime: 20380119031407Z
nsIdleTimeout: 0
EOF
ldapmodify -H ldap://freeipa.example.com:389 -x -D 'cn=Directory Manager' -W -f /tmp/ldapmodify
# adding new entry "uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=linuxfabrik,dc=it"
\rm /tmp/ldapmodify
LDAP-Anbindung einer Applikation¶
Im Beispiel: Nextcloud
Server-Account könnte unter
uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=example,dc=comaufzufinden sein.User-Query:
(&(|(objectclass=inetorgperson))(|(memberof=cn=nextcloud,cn=groups,cn=accounts,dc=example,dc=com)))Login-Attribute:
(&(objectclass=inetorgperson)(|(mail=%uid)(uid=%uid)))
OpenSSH¶
Damit eine Anmeldung an den ssh-Daemon über FreeIPA möglich ist, ergänzt der FreeIPA-Agent dessen Konfiguration:
# needed for FreeIPA
AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
AuthorizedKeysCommandUser nobody
AD-Trust¶
Es gibt verschiedene Möglichkeiten, wie ein AD-Trust zwischen FreeIPA und einem Windows Active Directory eingerichtet werden kann. Hier wird beispielsweise eine „One-Way-Trust“-Integration auf Basis eines Cross-Forest-Trusts eingerichtet.
Siehe auch:
Wie bei FreeIPA üblich, sollte zunächst sichergestellt werden, dass alle beteiligten Hosts einen fully-qualified Hostnamen verwenden und dieser per DNS aufgelöst werden kann. Danach kann der FreeIPA-Server wie gewohnt installiert werden, z.B. mit der linuxfabrik.lfops.freeipa_server Ansible-Rolle.
Die AD-Domain und die FreeIPA-Domain müssen unterschiedlich sein, können aber Subdomains voneinander sein. Wir verwenden hier:
AD-Domain:
example.comFreeIPA-Domain:
ipa.example.com
Nun muss auf beiden Seiten eine DNS-Delegation für die jeweils andere Domain eingerichtet werden. Am Ende sollten alle Hosts im FreeIPA und im AD die Hostnames der jeweils anderen Domain auflösen können.
DNS-Delegation unter Linux einrichten, hier mittels linuxfabrik.lfops.bind:
eine BIND-Zone mit
type: 'forward'für die Windows-Domain anlegen und dieforwardersauf die Domain Controller zeigen lassen:
bind__zones:
- name: 'example.com'
type: 'forward'
forwarders:
- '192.0.2.10'
DNS-Delegation unter Windows einrichten:
DNS Manager öffnen
Falls die FreeIPA-Domain eine Subdomain der Windows-Domain ist, muss unter der Forward Lookup Zones > example.com > Rechtsklick > New Delegation eingerichtet werden
Andernfalls muss ein neuer Conditional Forwarder erstellt werden
Nachdem geprüft wurde, ob die DNS-Delegationen funktionieren kann der AD-Trust auf dem FreeIPA-Server eingerichtet werden:
dnf install --assumeyes ipa-server-trust-ad samba-client
kinit admin
ipa-adtrust-install
ipactl restart
# test the communication with AD
smbclient -L vagrant-rocky9.ipa.example.com -U admin --use-kerberos=required
Das ipa-adtrust-install-Kommando gibt am Ende eine Liste an DNS-Einträgen aus, die im DNS des FreeIPA-Servers eingetragen werden müssen.
Nun muss entschieden werden, ob SSSD UIDs und GIDs der Linux-User automatisch basierend auf der SID des ADs generieren soll:
ipa trust-add --type=ad example.com --admin Administrator --password --range-type=ipa-ad-trust
Oder ob die uidNumber und gidNumber POSIX Attribute aus dem AD verwendet werden sollen:
ipa trust-add --type=ad ad.example.com --admin <ad_admin_username> --password --range-type=ipa-ad-trust-posix
Zuletzt kann der Login mit einem AD-Account getestet werden:
kinit Administrator@EXAMPLE.COM
SubIDs und SubGIDs verwalten¶
FreeIPA kann die SubIDs und SubGIDs der FreeIPA-User zentral verwalten und stellt so sicher, dass auf allen Hosts die gleichen SubIDs verwendet werden. Das funktioniert nur für FreeIPA-User, nicht für User aus einem AD-Trust.
Dazu müssen bei der Installation des FreeIPA-Clients SubIDs aktiviert werden, entweder via ipa-client-install --subid oder per Ansible mittels ipaclient_subid: true.
Zur Zuweisung der IDs gibt es drei Optionen:
Für alle existierenden und neuen FreeIPA-User werden SubIDs generiert.
# for existing users /usr/libexec/ipa/ipa-subids --all-users # for new users ipa config-mod --user-default-subid=true ipa config-show | grep subids # Enable adding subids to new users: True
Self-Service: Benutzer können sich selber per
ipa subid-generateSubIDs zuweisen lassen.# allow the ipausers group (therefore all FreeIPA users) to generate their own subids ipa role-add-member "Subordinate ID Selfservice User" --groups=ipausers
Der FreeIPA-Administrator vergibt manuell bestimmten Usern oder Gruppen SubIDs-Ranges.
ipa subid-generate --owner linus /usr/libexec/ipa/ipa-subids --group ipausers
So kann man sich alle vergebenen Ranges anzeigen lassen:
ipa subid-find
Oder nur für einen Benutzer:
ipa subid-find --owner linus
Troubleshooting¶
- Der Client nimmt neue Einstellungen nicht an
Es dauert etwas, bis die Regeln greifen. Hier hilft auch ein
systemctl restart sssd; sss_cache --everythingauf dem Client.- LDAP-Logging
tail -f /var/log/dirsrv/slapd-*/accessCould not chdir to home directory $HOME: No such file or directorysudo -i # list the currently enabled features authselect current # also enable with-mkhomedir authselect select sssd with-sudo with-mkhomedir # check the list again authselect current # now login again with the personal user account
- Bei
ipa-server-install:IPv6 stack is enabled in the kernel but there is no interface that has ::1 address assigned. Add ::1 address resolution to 'lo' interface. You might need to enable IPv6 on the interface 'lo' in sysctl.conf. - /etc/sysctl.conf¶
net.ipv6.conf.lo.disable_ipv6 = 1
sysctl -p - Passwort des „admin“-Users zurücksetzen
ldappasswd -ZZ -D 'cn=Directory Manager' -W -S uid=admin,cn=users,cn=accounts,dc=example,dc=com -H ldap://fqdn.example.com
msg: 'Failed to obtain host TGT: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (2529638936): Preauthentication failed'# the client is already enrolled, force a re-enrollment ipa-client-install --force-join
- FreeIPA Gruppe kollidiert mit der lokalen Gruppe (falsche GID)
Wichtig: Eine Service-Gruppe welche auch in FreeIPA existiert muss zuerst lokal vorhanden sein: Darum zuerst den Service installieren, dann an FreeIPA anbinden.
systemctl stop sssd && sss_cache --everything groupdel [name] groupadd --gid [id] [name] # die GID vom service user systemctl start sssd && sss_cache --everything
- SSH-Login auf einen FreeIPA-Client fragt nach Passwort, obwohl Public-Key-Login eingerichtet ist
Trotz hinterlegtem Public Key auf dem FreeIPA-Server fragt der SSH-Daemon auf dem Client nach einem Passwort. In
/var/log/secureerscheintinvalid user linus from 192.0.2.42 port 51234, in/var/log/sssd/*.logzudemCould not get account info [...]: SSSD is offline. Ursache: Der Client erreicht den FreeIPA-Server nicht, der Benutzer wird daher nicht gefunden. Ein Leeren des SSSD-Caches hilft hier nicht.Auf dem Client Netzwerkkonfiguration und DNS-Auflösung prüfen:
host ipa-server.example.com ipa ping ip address ip route
Auf dem FreeIPA-Server zudem prüfen, ob der Client per DNS auflösbar und erreichbar ist:
host ipa-client.example.com ping --count 3 ipa-client.example.com
Falsche Werte (IP, Gateway, DNS-Server, Search-Domain) korrigieren. Wird die Ansible-Rolle
linuxfabrik.lfops.networkverwendet, diese erneut mit--diff --checkausführen, da Konfigurationen und Einstellungen mit der Zeit driften können.ipa host-findund das Hosts-Tab im Web-GUI zeigen nicht alle Hosts anipa host-findliefert ohne Argument nur einen einzelnen Host (typischerweise den zuletzt registrierten).ipa host-show <fqdn>funktioniert für einen der „fehlenden“ Hosts dagegen wie gewohnt, ebenso Mitgliedschaften in Hostgruppen, HBAC-Regeln und Anmeldungen via SSSD/SSH auf den betroffenen Hosts. Die Hosts existieren also in LDAP, sind aber für diehost-find-Suche und entsprechend für das Hosts-Tab im Web-GUI unsichtbar.Ursache ist eine Inkonsistenz im
parentid-Index. Die Inkonsistenz zwischen Subtree- und One-Level-Scope lässt sich so prüfen:kinit # Subtree-Scope: returns the correct amount of hosts ldapsearch -Y GSSAPI -LLL \ -b 'cn=computers,cn=accounts,dc=example,dc=com' \ '(objectClass=ipaHost)' dn 2>/dev/null | grep --count '^dn:' # One-Level-Scope: doesn't return all hosts ldapsearch -Y GSSAPI -LLL \ -b 'cn=computers,cn=accounts,dc=example,dc=com' -s one \ '(objectClass=ipaHost)' dn 2>/dev/null | grep --count '^dn:'
Liefert der Subtree-Scope deutlich mehr Treffer als der One-Level-Scope, ist der
parentid-Index betroffen.Lösung: Den Index neu aufbauen. Der Vorgang dauert wenige Sekunden, ändert keine Einträge und kann „online“ gemacht werden (benötigt keinen Service-Restart):
dsconf slapd-EXAMPLE-COM backend index reindex --wait --attr parentid userRoot
Anschliessend liefert
ipa host-findwieder alle Hosts, das Hosts-Tab im Web-GUI ist nach einem Refresh ebenfalls wieder vollständig.