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 realmEXAMPLE.COMand the server nameipa.example.com. A subdomain such asipa.corp.example.comworks 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.comat192.0.2.20. - A non-root user with
sudoprivileges on every machine.
NoteUbuntu no longer ships the FreeIPA server packages, which is why the server runs on Rocky Linux 9. Ubuntu 24.04 is fully supported as a client.
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
WarningDo not expose an IPA server to the whole internet unless you have to. On a public VPS, restrict these services to your clients' networks with a firewalld zone, or connect the servers through a private network.
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.
