Centralized Authentication on Linux with FreeIPA: A Production Guide to User and Group Management

Security tutorial - IT technology blog
Security tutorial - IT technology blog

Why Manual User Management Breaks Down (And What I Did About It)

After my server got hit by SSH brute-force attacks at midnight, I started treating authentication as a first-class concern from day one of every new deployment. But locking down SSH turned out to be the easy part. The real mess was structural: each Linux box had its own /etc/passwd, its own local users, and SSH keys scattered across the team’s laptops. When someone left, we’d spend two or three hours tracking down which servers they had accounts on — and hoping we hadn’t missed one.

That experience pushed me to evaluate centralized authentication properly. Here’s what I found after running these solutions in production.

Comparing the Main Approaches

At the small-to-midsize scale, three options are actually realistic:

1. LDAP + PAM (DIY stack)

You stand up OpenLDAP and wire it with pam_ldap and nss_ldap. Flexible in theory, painful in practice. Schema migrations, replication lag, and expiring TLS certs have a way of consuming entire afternoons. I’ve watched teams sink more engineering time into keeping the LDAP server alive than into their actual product.

2. Active Directory (Samba or Microsoft AD)

If your org already runs Windows AD, joining Linux machines via sssd and realmd works well enough. The catch: you’re anchored to Windows infrastructure, and AD was never designed with Linux-native workflows in mind. Sudo rules and host-based access control require plugins or Group Policy hacks that feel bolted on.

3. FreeIPA

FreeIPA ships Kerberos, LDAP (389 Directory Server), DNS, NTP, and a CA in a single integrated stack. It was built for Linux and Unix from the start — not retrofitted. The web UI is clean, SSH public key management is built in, and you get native support for sudo policies and host-based access control without touching a single LDIF file.

Pros and Cons of FreeIPA

What FreeIPA does well

  • Integrated Kerberos SSO — Authenticate once, get tickets for services. SSH, HTTP via GSSAPI, and more — no repeated password prompts.
  • HBAC rules — Restrict which users can reach which hosts. Junior devs on staging only, senior engineers on prod — one policy, enforced everywhere.
  • Centralized sudo rules — Define them once in FreeIPA. SSSD pushes them to every client automatically. No more syncing /etc/sudoers across 20 machines by hand.
  • SSH public key storage — Store keys in FreeIPA, clients fetch via SSSD. Adding or revoking a key takes under 10 seconds and takes effect across the entire fleet immediately.
  • Built-in CA — Issues service certs and handles renewal. Much cleaner than running a standalone CA or littering your infrastructure with self-signed certificates.
  • Web UI + CLI — Most day-to-day tasks (add user, reset password, change group membership) take under a minute in the browser.

What to watch out for

  • Resource footprint — Plan for at least 2 vCPUs and 4 GB RAM for the server. A $5 VPS won’t cut it.
  • DNS dependency — Kerberos is unforgiving about name resolution. Broken DNS means broken auth. FreeIPA manages its own DNS zone, which helps — but plan your zone delegation before the installer runs.
  • Learning curve — Realms, principals, keytabs — these concepts are unfamiliar the first time. Budget a few hours of reading before things click.
  • HA needs planning — One FreeIPA server is one point of failure. Run at least one replica for anything production.

Recommended Setup for Small Teams

For a team of 5–50 people managing 10–100 Linux servers, this setup hits the right balance of simplicity and resilience:

  • 1 FreeIPA primary + 1 replica — both on a private network or dedicated management VLAN
  • All production machines joined as FreeIPA clients via sssd
  • Internal DNS managed by FreeIPA (e.g., internal.example.com)
  • SSH keys stored in FreeIPA, fetched dynamically — no more authorized_keys files to synchronize
  • HBAC rules separating dev, staging, and prod access

Implementation Guide

Step 1: Install FreeIPA Server

RHEL 9, Rocky Linux 9, or AlmaLinux 9 are the best-supported targets. Set a proper FQDN before running anything else:

# Set hostname
hostnamectl set-hostname ipa.internal.example.com

# Update /etc/hosts
echo "192.168.1.10 ipa.internal.example.com ipa" >> /etc/hosts

# Install
dnf install -y freeipa-server freeipa-server-dns

# Run installer
ipa-server-install \
  --domain=internal.example.com \
  --realm=INTERNAL.EXAMPLE.COM \
  --ds-password=YourDirManagerPass \
  --admin-password=YourAdminPass \
  --setup-dns \
  --auto-forwarders \
  --unattended

Expect 5–10 minutes for the installer to finish. Verify the result:

ipactl status

Step 2: Create Users and Groups

Once the server is up, log in and create your first users. The web UI at https://ipa.internal.example.com works fine, but the CLI is faster for scripting:

# Authenticate as admin
kinit admin

# Create a user
ipa user-add jdoe \
  --first=John \
  --last=Doe \
  [email protected] \
  --shell=/bin/bash

# Set initial password
ipa passwd jdoe

# Create a group
ipa group-add devops --desc="DevOps Engineers"

# Add user to group
ipa group-add-member devops --users=jdoe

Step 3: Store SSH Keys in FreeIPA

This is the feature that gets the most surprised reactions from sysadmins seeing it for the first time. Upload a key once — it’s available everywhere:

# Upload SSH public key for a user
ipa user-mod jdoe --sshpubkey="$(cat /home/jdoe/.ssh/id_ed25519.pub)"

SSSD on client machines fetches the key automatically at login time. No file to sync, no cron job, no drift.

Step 4: Join Linux Clients to FreeIPA

Run this on each server you want to bring under central management:

# Install client tools
dnf install -y freeipa-client

# Join the domain
ipa-client-install \
  --domain=internal.example.com \
  --server=ipa.internal.example.com \
  --realm=INTERNAL.EXAMPLE.COM \
  --principal=admin \
  --password=YourAdminPass \
  --mkhomedir \
  --unattended

After enrollment, any FreeIPA user can SSH into the machine with their centrally managed credentials — no local account needed.

Step 5: Configure HBAC Rules

Fresh installs allow all FreeIPA users to reach all enrolled hosts. Disable that immediately:

# Disable the permissive default rule
ipa hbacrule-disable allow_all

# Create a rule: devops group can access prod servers
ipa hbacrule-add allow_devops_prod \
  --desc="DevOps access to production hosts"

ipa hbacrule-add-user allow_devops_prod --groups=devops
ipa hbacrule-add-host allow_devops_prod --hosts=prod-web-01.internal.example.com
ipa hbacrule-add-service allow_devops_prod --hbacsvcs=sshd

# Simulate access before relying on the rule
ipa hbactest \
  --user=jdoe \
  --host=prod-web-01.internal.example.com \
  --service=sshd

Step 6: Centralize Sudo Rules

No more distributing sudoers snippets by hand. Define the rule once, let SSSD handle propagation:

# Create a sudo rule for devops
ipa sudorule-add devops_all_commands \
  --desc="DevOps can run all commands as root"

ipa sudorule-add-user devops_all_commands --groups=devops
ipa sudorule-add-host devops_all_commands --hostgroups=ipaservers
ipa sudorule-mod devops_all_commands --cmdcat=all
ipa sudorule-mod devops_all_commands --runasusercat=all

SSSD picks this up on the next cache refresh — typically under 60 seconds. No visudo, no SSH-ing into 20 boxes.

Step 7: Set Up a Replica

A single FreeIPA server should never be your only authentication server in production. On a second machine, the replica install is straightforward:

# Install FreeIPA server package
dnf install -y freeipa-server

# Join as a replica
ipa-replica-install \
  --setup-ca \
  --setup-dns \
  --principal=admin \
  --admin-password=YourAdminPass

Replication is synchronous by default and typically settles in under a second. If the primary goes down, SSSD on clients automatically fails over to the replica — no manual intervention needed.

Lessons from Running FreeIPA in Production

  • Always test HBAC rules with ipa hbactest first. I locked myself out of a server once by disabling allow_all before the replacement rule was in place. The simulation command exists for exactly this reason — use it.
  • Watch Kerberos ticket expiry. The default lifetime is 24 hours. Long-running jobs that rely on Kerberos auth will break when the ticket expires. Use k5start or a keytab for service accounts.
  • Don’t skip DNS validation. Run ipa dns-check and fix every warning before joining clients. DNS problems produce cryptic Kerberos errors that are miserable to debug under pressure.
  • Tune SSSD’s offline cache. If the FreeIPA server is temporarily unreachable, SSSD falls back on cached credentials — but they expire. Set cache_credentials = True and krb5_store_password_if_offline = True in /etc/sssd/sssd.conf for machines that might lose connectivity.
  • Offboarding becomes trivial. One command disables a user’s access across every enrolled machine instantly: ipa user-disable jdoe. That single capability often justifies the entire FreeIPA setup.
Share: