FreeIPA is the full-weight open source identity stack: 389 Directory Server for LDAP, MIT Kerberos for single sign-on, Dogtag for an internal certificate authority, optional BIND for integrated DNS, and a web UI plus CLI on top. If you need Kerberos tickets, host-based access control, centralized sudo rules, machine enrollment, and an internal CA that issues host and service certificates, FreeIPA is the only open source project that ships all of it as one integrated product.
It is also the heaviest option. Plan the deployment before you type the first command, because the realm name, domain name, and server hostname cannot be changed after installation.
This guide covers a single-server FreeIPA deployment on a RamNode KVM VPS, then enrolling clients and adding a replica.
Verified against FreeIPA 4.12.x on AlmaLinux 10. The same steps apply to Rocky Linux 10 and RHEL 10. On EL10 the server packages are plain AppStream RPMs; the idm:DL1 module dance from EL9 and earlier is gone.
1. Pick the right RamNode instance
FreeIPA runs Java (Dogtag), a directory server, a KDC, and Apache on one box. Undersized instances install fine and then fall over under real load.
| Deployment size | vCPU | RAM | Disk |
|---|---|---|---|
| Absolute minimum, lab only | 2 | 4 GB | 20 GB |
| Recommended production baseline | 2 to 4 | 8 GB | 40 GB |
| Larger realm or AD trust | 4+ | 16 GB | 80 GB+ |
Do not attempt this on 2 GB. The Dogtag CA installation alone will exhaust it and ipa-server-install will fail partway through, leaving you to uninstall and start over.
Order a Standard or Premium KVM plan with an AlmaLinux 10 or Rocky Linux 10 template. Build this on a clean instance. FreeIPA expects to own ports 80, 443, 389, 636, 88, and 464. If a web server, another LDAP, or a reverse proxy is already listening, the install will conflict.
2. Plan the names before you install
Write these down and do not change them later:
| Item | Example | Rule |
|---|---|---|
| Server FQDN | ipa.example.com | Must be a real A record, not a CNAME. Permanent. |
| Kerberos realm | EXAMPLE.COM | Uppercase. Conventionally matches the domain. Permanent. |
| IPA domain | example.com | Lowercase. Permanent. |
Use a subdomain you control and are not already serving other things from. Many admins deploy into ipa.corp.example.com with realm CORP.EXAMPLE.COM to keep the identity zone separate from the public website zone.
Renaming a FreeIPA server or realm after the fact means building a new realm and migrating. There is no rename tool.
3. Prepare the server
dnf -y update
rebootSet the hostname to the full FQDN:
hostnamectl set-hostname ipa.example.comFreeIPA resolves its own name during install. Pin it in /etc/hosts with the public IP, not 127.0.0.1:
echo "203.0.113.10 ipa.example.com ipa" >> /etc/hostsCreate the public DNS records at your registrar or DNS provider:
ipa.example.com. A 203.0.113.10
ipa.example.com. AAAA 2001:db8::10Set the PTR record for the instance in the RamNode control panel so reverse lookup returns ipa.example.com. Kerberos is sensitive to name mismatches and a wrong PTR produces authentication failures that look like clock problems.
Verify all three directions before continuing:
dig +short ipa.example.com
dig +short -x 203.0.113.10
hostname -fTime must be correct. Kerberos rejects tickets outside a five-minute skew.
dnf -y install chrony
systemctl enable --now chronyd
chronyc sourcesKeep SELinux enforcing. FreeIPA is developed and tested with SELinux on, and disabling it causes more problems than it solves.
getenforce4. Decide on integrated DNS
FreeIPA can install its own BIND instance with an LDAP-backed zone. It manages SRV records for the realm automatically, which makes client discovery painless. On a public VPS it also means running a nameserver on a public IP, and a misconfigured one becomes an open resolver used for DNS amplification attacks. RamNode will notice that traffic and so will you.
Option A, integrated DNS with recursion locked down. Best if you want automatic SRV management and you are careful.
Option B, external DNS. Skip --setup-dns and create the SRV records yourself at your existing DNS provider. Fewer moving parts, one more manual step per service.
This guide uses Option A with recursion restricted. If you choose Option B, drop the --setup-dns flags and add the SRV records from section 6.
5. Open the firewall
firewall-cmd --permanent --add-service=freeipa-4
firewall-cmd --permanent --add-service=freeipa-ldap
firewall-cmd --permanent --add-service=freeipa-ldaps
firewall-cmd --permanent --add-service=dns
firewall-cmd --permanent --add-service=ntp
firewall-cmd --reload
firewall-cmd --list-allfreeipa-4 covers Kerberos on 88 and 464 plus the HTTP and HTTPS ports. freeipa-ldap and freeipa-ldaps open 389 and 636. dns opens TCP and UDP 53 for the embedded BIND.
If your clients are all in known networks, scope the LDAP and Kerberos ports to those sources instead of leaving them world-open:
firewall-cmd --permanent --new-zone=idmclients
firewall-cmd --permanent --zone=idmclients --add-source=198.51.100.0/24
firewall-cmd --permanent --zone=idmclients --add-service=freeipa-4
firewall-cmd --reload6. Install the server
dnf -y install ipa-server ipa-server-dns
rpm -q ipa-server ipa-server-dnsRun the installer. This is the interactive form, which is the right choice the first time:
ipa-server-install --setup-dnsAnswer as follows:
- Configure integrated DNS:
yes - Server host name:
ipa.example.com - Domain name:
example.com - Realm name:
EXAMPLE.COM - Directory Manager password: strong, stored in your password manager, used for direct LDAP administration
- IPA admin password: strong, this is the realm administrator
- DNS forwarders: enter your preferred upstream resolvers, or answer no to use root hints
- Reverse zone: decline unless you actually control the reverse zone for your IP block, which you do not on a shared VPS range
The unattended equivalent, useful once you have done it and want it repeatable:
ipa-server-install \
--realm=EXAMPLE.COM \
--domain=example.com \
--hostname=ipa.example.com \
--ds-password='DIRECTORY_MANAGER_PASSWORD' \
--admin-password='IPA_ADMIN_PASSWORD' \
--setup-dns \
--forwarder=9.9.9.9 \
--no-reverse \
--no-ntp \
--unattendedInstallation takes 10 to 25 minutes on a 2 vCPU instance. Do not interrupt it.
Lock down the resolver immediately
If you installed integrated DNS, restrict recursion to your own networks before you walk away:
ipa dnsconfig-mod --allow-sync-ptr=falseThen edit /etc/named/ipa-options-ext.conf:
allow-recursion { localhost; 198.51.100.0/24; };
allow-query-cache { localhost; 198.51.100.0/24; };
rate-limit { responses-per-second 10; };systemctl restart namedTest from an outside host that recursion is refused:
dig @203.0.113.10 example.orgYou want REFUSED for anything outside your allowed ranges.
If you skipped integrated DNS
Create these SRV records in your external zone so clients can discover the realm:
_kerberos._tcp.example.com. SRV 0 100 88 ipa.example.com.
_kerberos._udp.example.com. SRV 0 100 88 ipa.example.com.
_kerberos-master._tcp.example.com. SRV 0 100 88 ipa.example.com.
_kerberos-master._udp.example.com. SRV 0 100 88 ipa.example.com.
_kpasswd._tcp.example.com. SRV 0 100 464 ipa.example.com.
_kpasswd._udp.example.com. SRV 0 100 464 ipa.example.com.
_ldap._tcp.example.com. SRV 0 100 389 ipa.example.com.
_kerberos.example.com. TXT "EXAMPLE.COM"7. First login and smoke test
kinit admin
klist
ipa user-find admin
ipa config-showIf kinit fails, check clock skew and DNS first. Those are the cause roughly nine times out of ten.
Open the web UI at https://ipa.example.com and log in as admin. The certificate is issued by the realm's internal CA, so your browser will warn until you either trust that CA or replace the web certificate (section 10).
Run the health check:
dnf -y install ipa-healthcheck
ipa-healthcheck --failures-only8. Create users, groups, and policy
ipa user-add anguyen --first=Alice --last=Nguyen --email=alice@example.com --password
ipa group-add sysadmins --desc="Server administrators"
ipa group-add-member sysadmins --users=anguyenSet a sane default shell and password policy:
ipa config-mod --defaultshell=/bin/bash
ipa pwpolicy-mod --minlength=12 --maxlife=365 --history=5 --minclasses=3
ipa pwpolicy-add sysadmins --priority=1 --minlength=16 --maxlife=180Host-based access control decides who may log into which machine. FreeIPA ships an allow_all rule. Disable it once you have your own rules, not before:
ipa hbacrule-add sysadmins_all --desc="Sysadmins to all hosts"
ipa hbacrule-add-user sysadmins_all --groups=sysadmins
ipa hbacrule-mod sysadmins_all --hostcat=all --servicecat=all
ipa hbacrule-disable allow_allTest the rule before you rely on it:
ipa hbactest --user=anguyen --host=web01.example.com --service=sshdCentralized sudo:
ipa sudorule-add sysadmins_sudo
ipa sudorule-add-user sysadmins_sudo --groups=sysadmins
ipa sudorule-mod sysadmins_sudo --hostcat=all --cmdcat=all
ipa sudorule-add-option sysadmins_sudo --sudooption='!authenticate'Enable two-factor for administrators:
ipa user-mod anguyen --user-auth-type=otp --user-auth-type=password
ipa otptoken-add --owner=anguyen --type=totp9. Enroll a client
On another RamNode instance, EL family:
dnf -y install ipa-client
ipa-client-install --mkhomedir --enable-dns-updatesDebian or Ubuntu clients:
apt install -y freeipa-client
ipa-client-install --mkhomedir --enable-dns-updatesPoint the client's resolver at the IPA server first, or pass --server=ipa.example.com --domain=example.com explicitly when discovery is not available.
Verify:
id anguyen
kinit anguyen
klistUbuntu note. The client packages are fine, but recent Ubuntu releases default to sudo-rs, which does not support the sudoers plugin interface that SSSD uses. FreeIPA sudo rules silently do not apply. Check with sudo --version and switch back if needed:
update-alternatives --set sudo /usr/bin/sudo.wsThere is no freeipa-server package on Ubuntu at all, only client tooling. If you must host the server on a Debian or Ubuntu VPS, run the official freeipa/freeipa-server container image with a bind-mounted /data volume and --sysctl net.ipv6.conf.all.disable_ipv6=0, and accept that in-place upgrades only work within the same base OS major version.
10. Replace the web certificate with Let's Encrypt
The internal CA is correct for host and service certificates inside the realm. For the web UI, a publicly trusted certificate saves everyone a browser warning.
Use DNS-01 validation, since FreeIPA owns port 80:
dnf -y install certbot
certbot certonly --manual --preferred-challenges dns -d ipa.example.comInstall it into both Apache and the directory server:
ipa-server-certinstall -w -d \
/etc/letsencrypt/live/ipa.example.com/fullchain.pem \
/etc/letsencrypt/live/ipa.example.com/privkey.pem
systemctl restart httpd dirsrv@EXAMPLE-COM.service-w installs for the web server and -d for the directory server. Repeat this after every renewal, or script it in a certbot deploy hook. Keep the internal CA intact; it still issues everything else.
11. Add a replica
A single FreeIPA server is a single point of failure for every login in the realm. Once you depend on it, add a second instance, ideally in a different RamNode location.
On the primary, authorize the new host:
kinit admin
ipa host-add ipa2.example.com --ip-address=198.51.100.20
ipa hostgroup-add-member ipaservers --hosts=ipa2.example.comOn the replica, after setting hostname, hosts file, DNS, and PTR the same way:
dnf -y install ipa-server ipa-server-dns ipa-client
ipa-client-install --domain=example.com --server=ipa.example.com --mkhomedir
ipa-replica-install --setup-ca --setup-dns --forwarder=9.9.9.9 --no-reverseVerify replication:
ipa-replica-manage list
ipa-csreplica-manage list
ipa topologysegment-find domainBoth servers now accept writes and replicate to each other. Point clients at both by listing both in DNS SRV records, which integrated DNS handles automatically.
12. Backups
ipa-backup is the only supported backup method. File-level copies of the directory server are not restorable.
ipa-backup
ls -lh /var/lib/ipa/backup/Full backups require the services to be stopped briefly. Data-only backups run online:
ipa-backup --data --onlineAutomate it and ship the result off the VPS:
cat > /etc/cron.daily/ipa-backup <<'EOF'
#!/bin/bash
set -e
/usr/sbin/ipa-backup --data --online --quiet
find /var/lib/ipa/backup -maxdepth 1 -type d -mtime +14 -exec rm -rf {} +
rsync -az /var/lib/ipa/backup/ backup@backup.example.com:/srv/backups/ipa/
EOF
chmod +x /etc/cron.daily/ipa-backupRestore with ipa-restore /var/lib/ipa/backup/ipa-full-2026-08-31-03-00-00. Restores must go back to the same hostname and realm, which is another reason those names are permanent.
Take a RamNode snapshot before every ipa-server-upgrade or major package update.
13. Maintenance
ipactl status
ipa-healthcheck --failures-only
dnf -y update && ipa-server-upgradeWatch certificate expiry. The internal CA certificates renew automatically through certmonger, but a server that was powered off past an expiry date needs manual intervention:
getcert list | grep -E 'status|expires'Directory server logs live in /var/log/dirsrv/slapd-EXAMPLE-COM/, Kerberos in /var/log/krb5kdc.log, and the framework in /var/log/httpd/error_log plus /var/log/ipa/.
14. Troubleshooting
ipa-server-install fails during the CA step. Almost always insufficient RAM or a hostname that does not resolve. Run ipa-server-install --uninstall, fix the cause, and start clean.
kinit returns clock skew too great. Fix chrony on whichever side is drifting.
Clients enroll but id user fails. SSSD cannot reach LDAP. Check firewall scoping on 389 and 636 and read /var/log/sssd/sssd_example.com.log.
Web UI returns a 500 after an update. Run ipa-server-upgrade, which completes migrations that a plain package update leaves pending.
Locked out of the admin account. Reset it as root on the server with kadmin.local and change_password admin.
DNS queries from strangers in your logs. Your recursion restriction is not applied. Fix allow-recursion and restart named immediately.
Where to go next
Add the replica before you add users. Then look at Vault for secret storage, RADIUS proxying for network device authentication, and an Active Directory trust if you have a Windows domain to interoperate with. If FreeIPA feels heavier than your environment needs, and you do not need Kerberos or an internal CA, Kanidm covers the OIDC and Unix login cases on a fraction of the resources.
