FreeIPA on AlmaLinux 9
Overview
FreeIPA is an open source identity management suite for Linux environments. It combines four services that are usually run separately into one managed domain: an LDAP directory (389 Directory Server) holding users, groups, hosts and services; a Kerberos KDC (MIT Kerberos) issuing tickets for single sign-on; a certificate authority (Dogtag) that issues and renews certificates for every host and service in the domain; and a web interface and CLI for administering all of it, with host-based access control, sudo rules and two-factor authentication.
The SecureAnyCloud image delivers FreeIPA 4.13.1 on AlmaLinux 9, with your entire identity domain built on the first boot of your own VM. It is backed by 24/7 SecureAnyCloud support.
What you get:
- FreeIPA 4.13.1 (
ipa-server) from the AlmaLinux 9 AppStream repository, with 389 Directory Server 2.8.0, MIT Kerberos 1.21.1 and Dogtag PKI 11.7.1 - A complete IdM domain provisioned at first boot: LDAP directory, Kerberos KDC, a certificate authority generated for your VM alone, and the FreeIPA web interface on port 443
- No default login. The IdM
adminpassword and the Directory Manager password are generated on your VM at first boot and written to a root-only file. They exist nowhere else, and they are never passed on a command line or written to the system journal. - A certificate authority whose private key is unique to your VM
firewalldconfigured to the exact port set this appliance needs, with Dogtag's internal ports and the Kerberos administration port closed- SELinux enforcing, with no permissive mode and no custom policy module
- Unattended security updates via
dnf-automatic, proven at build time to actually install a pending update
Nothing is baked into this image, and that is the point. ipa-server-install writes the realm, the server hostname and a freshly generated certificate authority into installed state. If any of that shipped inside a shared marketplace image, every buyer would receive the same CA signing key. That key is enough to mint certificates that every other customer's domain would trust. Every buyer would also share the same Kerberos master key and the same realm.
So the image contains staged packages only: no directory instance, no CA, no Kerberos principals and no realm. All of it is created on your VM, once, at first boot.
FreeIPA is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. This image packages the unmodified open source software, which is distributed under the GNU General Public License v3.0 or later.
Prerequisites
- An Azure subscription.
- A VM size with at least 8 GiB of RAM. FreeIPA runs a directory server, a Kerberos KDC and a Java certificate authority together.
Standard_B2msis the recommended minimum and is what this image is tested on. - An SSH key pair for the
azureuseraccount.
Deploy from the Azure Marketplace
Find FreeIPA Identity Management on AlmaLinux 9 in the Azure Marketplace, select Get It Now, and create a VM of size Standard_B2ms or larger. Allow inbound 22 for administration. Also allow 80, 443, 389, 636, 88 and 464 for the identity services described in Step 6.
Deploy from the Azure CLI
Create the resource group and the VM from your workstation:
az group create --name freeipa-rg --location eastus
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:freeipa-almalinux-9:default:latest
az vm create \
--resource-group freeipa-rg \
--name my-idm \
--image sac1647283583153:freeipa-almalinux-9:default:latest \
--size Standard_B2ms \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardChoose the VM name carefully, because by default your realm is derived from it. A VM named my-idm produces the domain my-idm.internal and the realm MY-IDM.INTERNAL. Step 5 explains how to use your own domain instead.
Connect to your VM
Connect to the VM over SSH:
ssh azureuser@<vm-ip>Wait for first boot to finish
First boot takes about ten minutes, and that is expected. Provisioning an IdM domain means generating a certificate authority from scratch, building a directory instance and creating every Kerberos principal. On a Standard_B2ms this measured 573 seconds end to end, 558 of which were ipa-server-install itself. Nothing times out. The work simply takes that long.
Check whether first boot has finished:
sudo systemctl is-active freeipa-firstboot.serviceWhile first boot is still working, the command reports activating. When it is finished, the command reports active, and the record of what was built is written to a sentinel file:
sudo cat /var/lib/sac/data/freeipa-firstboot.doneprovisionedAt=2026-09-20T08:02:38Z realm=ALMA9-FREEIPA-SMK2-09200650-F7A1C3.INTERNAL serverFqdn=ipa.alma9-freeipa-smk2-09200650-f7a1c3.internal ipaServerInstallSeconds=558 firstbootTotalSeconds=573Confirm every component of the domain is running:
sudo ipactl statusDirectory Service: RUNNING krb5kdc Service: RUNNING kadmin Service: RUNNING httpd Service: RUNNING ipa-custodia Service: RUNNING pki-tomcatd Service: RUNNING ipa-otpd Service: RUNNINGAfter a reboot, the stack takes roughly 90 seconds to come back up fully.
Understand your realm, and use your own domain
FreeIPA is unusually sensitive to host naming. The realm and the server's fully qualified name are written into the CA certificate and into every Kerberos principal. They cannot be changed afterwards without rebuilding the domain.
By default, this image derives a private domain from the name you gave the VM:
VM name Domain Realm Server FQDN
my-idm my-idm.internal MY-IDM.INTERNAL ipa.my-idm.internal
.internal is reserved by ICANN for private use, so this can never collide with a registered name. Deriving it from your VM name keeps your realm distinct. The Azure-supplied <vm>.<id>.bx.internal.cloudapp.net name is deliberately not used as a realm: it lives in Microsoft's namespace and changes shape between virtual networks.
Check which values your VM chose:
sudo ipa env realm domain serverdomain: alma9-freeipa-smk2-09200650-f7a1c3.internal realm: ALMA9-FREEIPA-SMK2-09200650-F7A1C3.INTERNAL server: ipa.alma9-freeipa-smk2-09200650-f7a1c3.internalTo use your own domain, supply it before the VM's first boot by writing /etc/sac/freeipa.conf with cloud-init custom-data at create time:
#cloud-config write_files: - path: /etc/sac/freeipa.conf permissions: '0644' content: | IPA_DOMAIN=idm.example.com IPA_HOSTNAME=ipa.idm.example.com IPA_REALM=IDM.EXAMPLE.COM IPA_NETBIOS=EXAMPLEPass it with --custom-data cloud-init.yaml on az vm create. The first-boot script reads these values instead of deriving its own, sets the hostname to IPA_HOSTNAME, and builds the domain there. IPA_HOSTNAME must sit inside IPA_DOMAIN or provisioning stops with a clear error rather than half-building a domain.
If you realize this only after first boot, you must rebuild the domain. Run sudo ipa-server-install --uninstall -U, remove /var/lib/sac/data/freeipa-firstboot.done and /var/lib/sac/data/freeipa-domain.env, write the file above, and reboot. Deploying a fresh VM is usually quicker.
Check what is listening
List the public listeners and the ports the firewall allows:
ss -lntu | awk 'NR==1 || $5 !~ /127\.0\.0\.1|\[::1\]/' | head -14sudo firewall-cmd --zone=public --list-ports22/tcp 80/tcp 88/tcp 389/tcp 443/tcp 464/tcp 636/tcp 88/udp 464/udpEach open port has a purpose:
Port Why it is open
22/tcp SSH administration
80/tcp CA certificate and CRL distribution. ipa-client-install fetches the CA certificate over plain HTTP before it has anything to trust, and issued certificates carry an HTTP CRL distribution point. Browsers are redirected to HTTPS
443/tcp The web interface and the IdM API that the ipa command and every enrolled client use
389/tcp LDAP with STARTTLS, for enrolled clients and LDAP-aware applications
636/tcp LDAPS, for clients that require implicit TLS
88/tcp, 88/udp The Kerberos KDC. UDP is the default transport; TCP is the fallback for large tickets
464/tcp, 464/udp Kerberos password changes (kpasswd) by enrolled users
Three ports are listening on the VM but deliberately closed by the firewall. Never open them in your network security group:
8080and8443belong to Dogtag, the certificate authority. The web server reaches Dogtag over a loopback-only AJP connection on127.0.0.1:8009, so these ports are purely internal.749is the Kerberos administration port. FreeIPA administers principals through its own API on 443, and Red Hat's documented FreeIPA port list does not include it.
The integrated DNS role is not enabled in this image. FreeIPA can run its own BIND server, but on a VM with a public address that means an internet-reachable recursive resolver, which is a denial-of-service amplification vector and not a safe default.
Azure already provides DNS in every virtual network. Azure Private DNS Zones are the natural place for the _kerberos._tcp and _ldap._tcp service records that clients use for automatic discovery. If you do want the integrated DNS role, add it with sudo ipa-dns-install and restrict recursion to your own network before opening port 53.
Retrieve your credentials
Both passwords were generated on your VM at first boot and written to a root-only file. Check its permissions, then read it:
sudo stat -c '%n %a %U:%G' /root/freeipa-credentials.txt/root/freeipa-credentials.txt 600 root:rootsudo cat /root/freeipa-credentials.txt# sac FreeIPA on AlmaLinux 9 — per-VM credentials
# Generated on this VM at first boot. These values exist nowhere else. IPA_REALM=ALMA9-FREEIPA-SMK2-09200650-F7A1C3.INTERNAL IPA_DOMAIN=alma9-freeipa-smk2-09200650-f7a1c3.internal IPA_SERVER_FQDN=ipa.alma9-freeipa-smk2-09200650-f7a1c3.internal IPA_WEB_UI=https://ipa.alma9-freeipa-smk2-09200650-f7a1c3.internal/ipa/ui/ IPA_ADMIN_USER=admin IPA_ADMIN_PASSWORD=<generated on your VM> DIRECTORY_MANAGER_DN=cn=Directory Manager DIRECTORY_MANAGER_PASSWORD=<generated on your VM>admin is the IdM administrator, used for day-to-day identity management. Directory Manager is the LDAP superuser, used only for low-level directory operations and replica creation. You will rarely need it.
Get a Kerberos ticket
To get a ticket interactively, run sudo kinit admin and type the IPA_ADMIN_PASSWORD value at the prompt. To do it in one step, read the password straight out of the credentials file:
sudo bash -c 'grep ^IPA_ADMIN_PASSWORD= /root/freeipa-credentials.txt | cut -d= -f2- | kinit admin' && echo "ticket granted"Then confirm you hold a ticket in your own realm:
sudo klistsudo ipa pingAdd a user
Create a user account:
sudo ipa user-add awilson --first=Amara --last=Wilson --email=awilson@example.com || sudo ipa user-show awilsonRead the account back:
sudo ipa user-findGive the account a password. The user must change it at first login:
sudo ipa passwd awilsonSign in to the web interface
The web interface is served under the server's own fully qualified name, and FreeIPA redirects any other address there. This is normal for an identity server, because the name is what the Kerberos service principal and the TLS certificate are issued for. Point your browser at the name rather than the IP.
The simplest option is an entry in your workstation's hosts file, mapping your VM's public address to the FQDN from Step 7:
<vm-public-ip> ipa.my-idm.internalFor a shared deployment, create the equivalent record in an Azure Private DNS Zone linked to your virtual network, or in your own DNS.
Then browse to https://ipa.my-idm.internal/ipa/ui/ and sign in as admin. Your browser warns that the certificate is not trusted, because your VM's own certificate authority issued it. Install /etc/ipa/ca.crt as a trusted root to remove the warning.
Enroll a client machine
On another AlmaLinux, Rocky, RHEL or Fedora machine that can resolve your server's name, install the client and enroll it:
sudo dnf -y install ipa-client
sudo ipa-client-install \
--server=ipa.my-idm.internal \
--domain=my-idm.internal \
--realm=MY-IDM.INTERNAL \
--principal=admin \
--mkhomedirBecause the integrated DNS role is not enabled, pass --server, --domain and --realm explicitly instead of relying on SRV-record discovery. Once the machine is enrolled, users in your domain can log in to that machine and sudo rules and host-based access control apply.
Inspect your certificate authority
Your VM generated its own CA at first boot, and its private key exists only on this VM. Inspect the CA certificate:
sudo openssl x509 -in /etc/ipa/ca.crt -noout -subject -issuer -datessubject=O=ALMA9-FREEIPA-SMK2-09200650-F7A1C3.INTERNAL, CN=Certificate Authority issuer=O=ALMA9-FREEIPA-SMK2-09200650-F7A1C3.INTERNAL, CN=Certificate Authority notBefore=Sep 20 07:56:46 2026 GMT notAfter=Sep 20 07:56:46 2046 GMTEvery certificate the domain has issued is listed in the web interface under Authentication, then Certificates. sudo ipa cert-find shows the same list from the CLI.
/root/cacert.p12 holds a backup of the CA signing key, encrypted with the Directory Manager password, and is readable only by root. Copy it somewhere safe, because without it you cannot rebuild a replica of this CA.
Back up the domain
FreeIPA ships its own backup tool, which captures the directory data, the CA and all configuration. Take a backup and list it:
sudo ipa-backup
sudo ls -1 /var/lib/ipa/backup/Restore with sudo ipa-restore <backup-directory>. Back up before any upgrade, and keep /root/cacert.p12 and /root/freeipa-credentials.txt with it.
Keep the VM patched
Unattended security updates are enabled. Confirm the timer and its settings:
systemctl is-enabled dnf-automatic.timergrep -E '^(upgrade_type|apply_updates)' /etc/dnf/automatic.confupgrade_type = default apply_updates = yesupgrade_type is deliberately default rather than security. Security-only mode depends on repository metadata that not every EL-family repository publishes, and getting that judgment wrong produces an image whose automatic updates silently never update anything.
Apply updates by hand at any time:
sudo dnf -y upgrade --refreshReboot after a kernel update. The domain survives reboots, because the hostname is pinned so that Kerberos principals stay valid.
Security notes
- No credential is shared between VMs. The IdM admin password, the Directory Manager password, the CA private key and certificate, the Kerberos master key, the LDAP TLS material, the SSH host keys and the machine ID are all generated on your VM at first boot. Two VMs deployed from this image were compared field by field and had nothing in common.
- No credential is baked into the image. The captured image contains no directory instance, no CA and no realm at all, so there is nothing to leak.
- Passwords never reach the process table or the journal.
ipa-server-installaccepts passwords only on the command line or at an interactive prompt. The command line is visible to every local user throughpsand is echoed into the journal, so the first-boot script drives the installer through a pseudo-terminal and supplies both passwords on standard input instead. - The build account is removed before the image is captured,
rootis locked, and SSH accepts keys only (PermitRootLogin noandPasswordAuthentication no). - SELinux is enforcing, with no custom policy module and no permissive domains.
- The host firewall closes the Dogtag administration ports (
8080,8443) and the Kerberos administration port (749). - Rotate the IdM admin password with
sudo ipa passwd adminonce you have signed in.
Support
SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com.
Deploy on Azure
Launch FreeIPA Identity Management on AlmaLinux 9 on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com