FreeIPA

FreeIPA (Free Identity Policy Audit) ist eine web- und kommandozeilenbasierte Security Information Management-Lösung für Linux / UNIX-Netzwerkumgebungen. Es kombiniert bekannte Open Source-Komponenten und Standardprotokolle wie Linux (Fedora), 389 Directory Server, MIT Kerberos, NTP, DNS und Dogtag (Zertifikatssystem).

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-Bindungsserver 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:

  • NGP: Netgroups Private

  • UPG: User Private Groups

Bemerkung

It is not possible to create new OU (Organizational Unit) in IPA at the moment. Instead, it is recommended to use IPA groups to create organizational groups. WebUI and CLI tool will not behave properly if the default DIT(Directory Information Tree) structure in IPA is changed.

Installation auf RHEL 7

/etc/hosts
# the fully-qualified name must come first
192.102.0.26 idm.ipa.test idm

Entweder als Bundle aus FreeIPA und DNS (FreeIPA speichert DNS-Records in seinem 389DS LDAP-Server):

yum -y install ipa-server-dns

… oder ohne, falls DNS-Server vorhanden sind, die die Zone bereits verwalten:

yum -y install ipa-server

Auf einem RHEL 7 Minimal werden damit knapp 300 Pakete installiert, unter anderem eine CA, NTPd, 389DS, Key Distribution Center (KDC) und Apache. Ein installiertes chronyd wird zugunsten von ntpd deaktiviert.

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.102.0.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:

/var/named/ipa.test.zone
_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:

authconfig --enablemkhomedir --update
reboot

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

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.

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

OpenSSH

Damit eine Anmeldung an den ssh-Daemon über FreeIPA möglich ist, ergänzt der FreeIPA-Agent dessen Konfiguration:

/etc/sshd/sshd_config
  # needed for FreeIPA
  AuthorizedKeysCommand /usr/bin/sss_ssh_authorizedkeys
  AuthorizedKeysCommandUser nobody

LDAP-Anbindung einer Applikation

Im Beispiel: Nextcloud

  • Server-Account könnte unter uid=freeipa-reader,cn=sysaccounts,cn=etc,dc=example,dc=com aufzufinden sein.

  • User-Query: (&(|(objectclass=inetorgperson))(|(memberof=cn=nextcloud,cn=groups,cn=accounts,dc=example,dc=com)))

  • Login-Attribute: (&(objectclass=inetorgperson)(|(mail=%uid)(uid=%uid)))

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>

Delegation

Wie legt man einen Subadmin an, der nur Benutzer einer bestimmten, vom Admin angelegten Gruppe verwalten kann, beispielsweise „sales“? Um wie kommt man auf die Lösung hier?

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:

  1. IPA Sever > Role-Based Access Control > Permissions

  2. IPA Sever > Role-Based Access Control > Privileges (fasst Permissions zusammen)

  3. IPA Sever > 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"

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.com

  • FreeIPA-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 die forwarders auf 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. Somit stellt FreeIPA sicher, dass auf allen Hosts die gleichen SubIDs verwendet werden. Zu beachten ist, dass dies nur für FreeIPA-User funktioniert, nicht jedoch für User, die durch einen AD-Trust kommen.

Dazu müssen der Installation des FreeIPA Client SubIDs aktiviert werden - entweder via ipa-client-install --subid oder per Ansible mittels ipaclient_subid: true.

Zur Zuweisung der IDs es gibt drei Optionen:

  1. 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
    
  2. Self-Service: Benutzer können sich selber per ipa subid-generate SubIDs 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
    
  3. 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 --everything auf dem Client.

LDAP-Logging

tail -f /var/log/dirsrv/slapd-*/access

Could not chdir to home directory $HOME: No such file or directory
sudo -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'
ansible-playbook ... --extra-vars='ipaclient_force_join=true'

Built on 2025-10-27