Security and identity
FreeIPA / Red Hat IdM
Identity, Kerberos, host enrolment, DNS and certificates in one domain, with the commands for enrolment, RBAC and replication problems.
Cheatsheet #
| Task | Command |
|---|---|
| Get a ticket | kinit admin |
| Show tickets | klist |
| Server health | ipactl status |
| Add a user | ipa user-add jbloggs --first=Jo --last=Bloggs |
| Reset a password | ipa passwd jbloggs |
| Add to a group | ipa group-add-member ops --users=jbloggs |
| Enrol a host | ipa-client-install --mkhomedir --domain=example.internal |
| Host keytab | ipa-getkeytab -s ipa-01 -p host/web-01@EXAMPLE.INTERNAL -k /etc/krb5.keytab |
| Service principal | ipa service-add HTTP/web-01.example.internal |
| Request a certificate | ipa-getcert request -f /etc/pki/tls/certs/web.crt -k /etc/pki/tls/private/web.key -K HTTP/web-01.example.internal |
| Certificate status | getcert list |
| DNS record | ipa dnsrecord-add example.internal web --a-rec=10.0.0.5 |
| Sudo rule | ipa sudorule-add ops-all |
| HBAC test | ipa hbactest --user=jbloggs --host=web-01 --service=sshd |
| Replication status | ipa-replica-manage list -v ipa-01.example.internal |
| Client cache reset | sss_cache -E then systemctl restart sssd |
What the pieces are #
IdM bundles 389 Directory Server (identity), MIT Kerberos (authentication), Dogtag (certificates), BIND with a directory backend (DNS), and SSSD on the clients. One enrolment gives a host a Kerberos identity, a certificate path, DNS records and a policy source.
| Component | Responsibility | Fails as |
|---|---|---|
| 389-ds | Users, groups, hosts, policies | LDAP timeouts, replication conflicts |
| KDC | Tickets and service principals | Clock skew, missing SPN, wrong realm |
| Dogtag | Issuing and renewing certificates | Expired CA subsystem certificates |
| BIND-DYNDB-LDAP | Forward and reverse DNS | Missing PTR, stale SRV records |
| SSSD (client) | Caching, HBAC, sudo, home directories | Stale cache, offline mode |
Kerberos depends on DNS and on time. Skew beyond five minutes and a missing SRV record are the two causes behind most enrolment and login failures.
Users and groups #
ipa user-add jbloggs --first=Jo --last=Bloggs --email=jo@example.com --shell=/bin/bash
ipa user-mod jbloggs --title='Platform Engineer' --sshpubkey="$(cat ~/.ssh/id_ed25519.pub)"
ipa user-find --all --raw jbloggs
ipa user-disable jbloggs # keeps the object and its group memberships
ipa user-del jbloggs --preserve # moves to the deleted-users container, recoverable
ipa passwd jbloggs # sets a password the user must change at next login
ipa group-add ops --desc='Platform on-call'
ipa group-add-member ops --users=jbloggs --groups=contractors
ipa group-show ops --allDisable rather than delete when someone leaves: it revokes access immediately while leaving audit trails and file ownership intact.
ipa pwpolicy-add ops --maxlife=90 --minlength=14 --history=10 --priority=1
ipa pwpolicy-show opsHosts and services #
ipa host-add web-01.example.internal --ip-address=10.0.0.5
ipa-client-install --domain=example.internal --realm=EXAMPLE.INTERNAL \
--principal=admin --mkhomedir --enable-dns-updates
ipa service-add HTTP/web-01.example.internal
ipa service-allow-retrieve-keytab HTTP/web-01.example.internal --hosts=web-01.example.internal
ipa-getkeytab -s ipa-01.example.internal -p HTTP/web-01.example.internal -k /etc/httpd.keytab
klist -kt /etc/httpd.keytabRetrieving a keytab invalidates the previous one for that principal: two hosts sharing a principal will knock each other offline. One principal per host per service.
ipa-client-install --uninstall # clean removal before re-enrolment
ipa host-del web-01.example.internal # then remove the stale host entryDNS #
ipa dnszone-add example.internal --dynamic-update=TRUE
ipa dnsrecord-add example.internal web --a-rec=10.0.0.5
ipa dnsrecord-add 0.0.10.in-addr.arpa 5 --ptr-rec=web.example.internal.
ipa dnsrecord-find example.internal
ipa dnsconfig-mod --forwarder=10.0.0.53 --forward-policy=only
dig +short SRV _kerberos._udp.example.internalThe _kerberos and _ldap SRV records are how clients find the servers. If they are wrong, enrolment fails with an unhelpful message about the realm.
Certificates #
ipa-getcert request -f /etc/pki/tls/certs/web.crt -k /etc/pki/tls/private/web.key \
-K HTTP/web-01.example.internal -D web-01.example.internal
getcert list # tracked certificates, expiry, post-save command
getcert resubmit -i <request-id> # force renewal
ipa cert-find --subject=web-01
ipa cert-show 12 --out=cert.pem
ipa cert-revoke 12 --revocation-reason=4certmonger renews tracked certificates automatically and runs the post-save command to reload the service. Certificates issued outside this tracking are the ones that expire at 2am.
ipa-cacert-manage renew # CA certificate renewal, on the CA renewal master
ipa-certupdate # refresh the local trust store after a CA changeAccess control #
HBAC decides who may access which service on which host; sudo rules decide what they may then run. Both are evaluated by SSSD on the client with cached data.
ipa hbacrule-add ops-ssh
ipa hbacrule-add-user ops-ssh --groups=ops
ipa hbacrule-add-host ops-ssh --hostgroups=web-servers
ipa hbacrule-add-service ops-ssh --hbacsvcs=sshd
ipa hbactest --user=jbloggs --host=web-01.example.internal --service=sshd
ipa sudorule-add ops-restart
ipa sudorule-add-user ops-restart --groups=ops
ipa sudorule-add-host ops-restart --hostgroups=web-servers
ipa sudorule-add-allow-command ops-restart --sudocmds='/bin/systemctl restart nginx'
ipa sudorule-mod ops-restart --sudoopt='!authenticate'The default allow_all HBAC rule permits everything; disable it only after the replacement rules are tested with hbactest, or nobody logs in.
ipa hbacrule-disable allow_allDelegate administration with roles rather than handing out admins:
ipa role-add 'Helpdesk'
ipa privilege-add 'Password Reset'
ipa permission-add 'Reset user password' --type=user --right=write --attrs=userPassword
ipa privilege-add-permission 'Password Reset' --permissions='Reset user password'
ipa role-add-privilege 'Helpdesk' --privileges='Password Reset'
ipa role-add-member 'Helpdesk' --groups=helpdeskReplication #
ipa-replica-manage list -v ipa-01.example.internal
ipa-replica-manage force-sync --from ipa-01.example.internal
ipa-csreplica-manage list # certificate server replication
ipa-healthcheck --failures-onlyReplication conflicts appear as entries with nsds5ReplConflict in the directory. They need manual resolution — pick the surviving entry and delete the conflict copy.
ldapsearch -Y GSSAPI -b "dc=example,dc=internal" "(nsds5ReplConflict=*)" \* nsds5ReplConflictKeep at least two replicas with CA capability, and verify that the CA renewal master exists and is healthy before certificates approach expiry.
Client troubleshooting #
klist -e # tickets and encryption types
kinit -V jbloggs # verbose ticket request
KRB5_TRACE=/dev/stderr kinit jbloggs # every step of the exchange
id jbloggs # does the client resolve the user at all
getent passwd jbloggs
sss_cache -E && systemctl restart sssd # clear the cache after a policy change
journalctl -u sssd -f
realm list # domain membership from the client's view
chronyc tracking # clock skew: the silent killer| Symptom | Cause |
|---|---|
Clock skew too great | Time drift beyond five minutes — fix NTP first |
Server not found in Kerberos database | Missing SPN, or the client used a name with no matching principal |
KDC has no support for encryption type | Mismatched enctypes after an upgrade; regenerate the keytab |
| Login works, sudo does not | Sudo rule not matched, or SSSD cache stale |
User exists in IdM, id fails | SSSD domain not enabled, or the host is not enrolled |
| Everything fails after a CA renewal | Run ipa-certupdate on clients to refresh trust |
| Intermittent failures | One replica unhealthy; check ipa-healthcheck on each |
Oneliners #
# Last successful Kerberos authentication per user
ipa user-find --all --raw | awk '/^ *uid:/ {u=$2} /^ *krbLastSuccessfulAuth:/ {print u, $2}'
# Every member of a group, flattened
ipa group-show ops --all --raw | grep -E '^ *member(user|group):'
# Hosts that exist but were never enrolled (no keytab)
ipa host-find | awk '/Host name:/ {h=$3} /Keytab: False/ {print h}'
# Tracked certificates with their expiry and status
getcert list | grep -E 'Request ID|status:|expires:|certificate:'
# All HBAC rules and who they apply to
ipa hbacrule-find --all --raw | grep -E '^ *(cn|memberuser|memberhost|memberservice):'
# Test access for a user before telling them it works
ipa hbactest --user=jbloggs --host=web-01.example.internal --service=sshd
# Replication agreements and their last update
ipa-replica-manage list -v ipa-01.example.internal | grep -E 'last update|status'
# Kerberos ticket lifetime for a principal
klist | awk '/krbtgt/ {print $1, $2}'
# Confirm DNS SRV records a client will use
dig +short SRV _ldap._tcp.example.internal _kerberos._tcp.example.internal
# Force a full client refresh after policy changes
sss_cache -E && systemctl restart sssd && id jbloggs