FreeIPA is an integrated identity management system that combines a 389 Directory Server (LDAP), an MIT Kerberos KDC, a Dogtag certificate authority, and optionally a BIND DNS server behind one web UI and one CLI. Instead of configuring each piece by hand, you get centralized users, single sign-on with Kerberos, host-based access control and central sudo rules. In this tutorial you will install a FreeIPA server on Rocky Linux 9, enroll a client, create users and groups, and restrict who can log in and use sudo on which hosts.

Prerequisites

To follow this guide you need:

  • A dedicated server running Rocky Linux 9 (or AlmaLinux 9 / RHEL 9) with at least 2 vCPUs, 4 GB of RAM and 10 GB of free disk, for example a CubePath VPS. FreeIPA runs its own Apache, LDAP and Kerberos services, so do not install it on a machine that already serves other websites.
  • A static IP address on the server. This guide uses 192.0.2.10.
  • A DNS domain you control, used only for this realm. The examples use example.com, the realm EXAMPLE.COM and the server name ipa.example.com. A subdomain such as ipa.corp.example.com works well if the main domain is already in use.
  • One client machine running Ubuntu 24.04 or Rocky Linux 9. This guide uses client1.example.com at 192.0.2.20.
  • A non-root user with sudo privileges on every machine.

Step 1 - Preparing the server hostname and time

FreeIPA refuses to install unless the server's fully qualified name resolves to its real IP address, not to 127.0.0.1. Set the hostname:

sudo hostnamectl set-hostname ipa.example.com

Add the name to /etc/hosts:

sudo nano /etc/hosts
192.0.2.10   ipa.example.com   ipa

Verify that the name resolves to the public address:

hostname -f
getent hosts ipa.example.com
ipa.example.com
192.0.2.10      ipa.example.com ipa

Kerberos rejects tickets when clocks differ by more than five minutes. Rocky Linux uses chronyd; make sure it is active and synchronized:

sudo systemctl enable --now chronyd
chronyc tracking | grep "Leap status"
Leap status     : Normal

Step 2 - Installing the FreeIPA packages

On Rocky Linux 9 the FreeIPA server and its DNS integration are in the AppStream repository. Update the system and install them:

sudo dnf update -y
sudo dnf install -y ipa-server ipa-server-dns

Confirm the installed version:

rpm -q ipa-server
ipa-server-4.12.2-14.el9.x86_64

Step 3 - Opening the firewall

firewalld ships a freeipa-4 service definition that covers HTTP/HTTPS, LDAP/LDAPS, Kerberos and kpasswd. Add it together with DNS, because this server will also be the realm's DNS server:

sudo firewall-cmd --permanent --add-service=freeipa-4 --add-service=dns
sudo firewall-cmd --reload

Check the result:

sudo firewall-cmd --list-services
cockpit dhcpv6-client dns freeipa-4 ssh

Step 4 - Running the server installer

ipa-server-install configures every component in one run. The options below set up the integrated DNS server, forward external queries to a public resolver, and create the reverse zone automatically. The installer prompts for two passwords: the Directory Manager password (the LDAP superuser) and the password for the IPA admin user. Store both in your password manager.

sudo ipa-server-install \
  --domain=example.com \
  --realm=EXAMPLE.COM \
  --hostname=ipa.example.com \
  --ip-address=192.0.2.10 \
  --setup-dns \
  --forwarder=1.1.1.1 \
  --auto-reverse

The installer shows a summary and asks for confirmation. It takes 10 to 20 minutes and ends with:

==============================================================================
Setup complete

Next steps:
	1. You must make sure these network ports are open:
...
The ipa-client-install command was successful

Check that all services are running:

sudo ipactl status
Directory Service: RUNNING
krb5kdc Service: RUNNING
kadmin Service: RUNNING
named Service: RUNNING
httpd Service: RUNNING
ipa-custodia Service: RUNNING
pki-tomcatd Service: RUNNING
ipa-otpd Service: RUNNING
ipa-dnskeysyncd Service: RUNNING
ipa: INFO: The ipactl command was successful

Get a Kerberos ticket for the admin user. Every ipa command in the rest of this guide uses that ticket:

kinit admin
klist
Ticket cache: KCM:1000
Default principal: [email protected]

Valid starting       Expires              Service principal
09/24/2026 10:30:12  09/25/2026 10:02:44  krbtgt/[email protected]

The web UI is available at https://ipa.example.com/ipa/ui/. The certificate is issued by the IPA's own CA, so your browser will warn you until you import /etc/ipa/ca.crt as a trusted authority.

Step 5 - Creating users and groups

Create a user. The --password flag prompts for an initial password that the user must change at first login:

ipa user-add jsmith --first=John --last=Smith [email protected] --shell=/bin/bash --password
-------------------
Added user "jsmith"
-------------------
  User login: jsmith
  First name: John
  Last name: Smith
  ...
  UID: 1234400001
  GID: 1234400001

Create a group and add the user to it:

ipa group-add sysadmins --desc="System administrators"
ipa group-add-member sysadmins --users=jsmith

Verify the membership:

ipa group-show sysadmins
  Group name: sysadmins
  Description: System administrators
  GID: 1234400003
  Member users: jsmith

Other useful user commands are ipa user-find, ipa user-disable jsmith, ipa user-enable jsmith and ipa user-del jsmith.

Step 6 - Enrolling a client

Enrollment joins a machine to the realm: it creates a host entry, fetches a Kerberos keytab and configures SSSD, PAM and NSS. First, on the IPA server, add a DNS record for the client so Kerberos can resolve it:

ipa dnsrecord-add example.com client1 --a-rec=192.0.2.20

Then run the following on the client. Set its hostname and make sure it can resolve the IPA server. Pointing the client's resolver at the IPA server is the cleanest option; if your network uses DHCP-managed DNS, an /etc/hosts entry is enough to get started:

sudo hostnamectl set-hostname client1.example.com
echo "192.0.2.10 ipa.example.com ipa" | sudo tee -a /etc/hosts

Install the client package. On Ubuntu 24.04:

sudo apt update
sudo apt install freeipa-client libsss-sudo

On Rocky Linux 9:

sudo dnf install -y ipa-client

Run the enrollment. It prompts for the admin password:

sudo ipa-client-install \
  --server=ipa.example.com \
  --domain=example.com \
  --realm=EXAMPLE.COM \
  --principal=admin \
  --mkhomedir
Client configuration complete.
The ipa-client-install command was successful

Verify that the client sees IPA users and can obtain a Kerberos ticket:

id jsmith
kinit jsmith
uid=1234400001(jsmith) gid=1234400001(jsmith) groups=1234400001(jsmith),1234400003(sysadmins)
Password for [email protected]:
Password expired.  You must change it now.

After changing the password, jsmith can log in over SSH, and the home directory is created on first login.

Step 7 - Restricting logins with host-based access control

By default the allow_all HBAC rule lets every user log in to every enrolled host. Replace it with explicit rules. Create the new rule first, so you do not lock yourself out. This rule lets the sysadmins group use every service on every host:

ipa hbacrule-add allow_sysadmins --hostcat=all --servicecat=all
ipa hbacrule-add-user allow_sysadmins --groups=sysadmins

For a narrower rule, group hosts and allow only SSH. The example below assumes a developers group and two web servers that are already enrolled:

ipa hostgroup-add webservers --desc="Web servers"
ipa hostgroup-add-member webservers --hosts=web01.example.com,web02.example.com
ipa hbacrule-add developers_webservers
ipa hbacrule-add-user developers_webservers --groups=developers
ipa hbacrule-add-host developers_webservers --hostgroups=webservers
ipa hbacrule-add-service developers_webservers --hbacsvcs=sshd

Test the rules before you disable the default one:

ipa hbactest --user=jsmith --host=client1.example.com --service=sshd
--------------------
Access granted: True
--------------------
  Matched rules: allow_all
  Matched rules: allow_sysadmins

When the result is what you expect, disable allow_all and test again. jsmith should now match only allow_sysadmins:

ipa hbacrule-disable allow_all
ipa hbactest --user=jsmith --host=client1.example.com --service=sshd

Step 8 - Managing sudo rules centrally

FreeIPA stores sudo rules in the directory and SSSD delivers them to enrolled clients. Register the commands, group them, and grant the group to sysadmins on all hosts:

ipa sudocmd-add /usr/bin/systemctl
ipa sudocmd-add /usr/bin/journalctl
ipa sudocmdgroup-add service_management --desc="Service management commands"
ipa sudocmdgroup-add-member service_management --sudocmds=/usr/bin/systemctl --sudocmds=/usr/bin/journalctl
ipa sudorule-add sysadmins_services --hostcat=all
ipa sudorule-add-user sysadmins_services --groups=sysadmins
ipa sudorule-add-allow-command sysadmins_services --sudocmdgroups=service_management

On the client, clear the SSSD cache and list the rules that apply to jsmith:

sudo sss_cache -E
sudo sudo -l -U jsmith
User jsmith may run the following commands on client1:
    (root) /usr/bin/systemctl, /usr/bin/journalctl

Step 9 - Issuing a service certificate

The built-in CA can issue and automatically renew certificates for services on enrolled hosts through certmonger. On the IPA server, register an HTTP service principal for the client:

ipa service-add HTTP/client1.example.com

On the client, request the certificate. Paths below are for Ubuntu; on Rocky Linux use /etc/pki/tls/certs and /etc/pki/tls/private:

sudo ipa-getcert request \
  -f /etc/ssl/certs/client1.crt \
  -k /etc/ssl/private/client1.key \
  -K HTTP/client1.example.com \
  -D client1.example.com

Check that the request was fulfilled:

sudo ipa-getcert list
Request ID '20260924103512':
	status: MONITORING
	...
	subject: CN=client1.example.com,O=EXAMPLE.COM
	auto-renew: yes

Troubleshooting

ipa-server-install stops with a hostname or IP error. The FQDN must resolve to a non-loopback address. Check /etc/hosts and getent hosts ipa.example.com; remove any line mapping the FQDN to 127.0.0.1 or 127.0.1.1.

kinit: Clock skew too great. Synchronize time on both machines and check with timedatectl. On Ubuntu 24.04 make sure System clock synchronized: yes is reported.

Client enrollment cannot find the server. From the client, check getent hosts ipa.example.com and curl -kI https://ipa.example.com/ipa/ui/. If that fails, the IPA firewall or a provider firewall is blocking ports 80, 443, 88 or 464.

A user cannot log in although the password is correct. Run ipa hbactest for that user, host and service, and read sudo journalctl -u sssd on the client. After changing HBAC or sudo rules, run sudo sss_cache -E on the client.

Services fail after a reboot. Run sudo ipactl status, then sudo ipactl restart, and read the logs of the failing unit, for example sudo journalctl -u krb5kdc or sudo journalctl -u dirsrv@EXAMPLE-COM.

Conclusion

You installed a FreeIPA server with integrated DNS on Rocky Linux 9, enrolled a client, and replaced the permissive default policy with explicit HBAC and sudo rules. Next, add a replica with ipa-replica-install so authentication survives a server failure, enable two-factor authentication with OTP tokens for administrators, and schedule backups with ipa-backup.