Deployment guide

FreeIPA Identity Management 4.13.4 on AlmaLinux 9

Overview

FreeIPA is the open source identity management server behind Red Hat Identity Management. It gives your Linux fleet one domain with central users and groups, Kerberos single sign-on, host-based access control, sudo rules, SSH public keys and its own certificate authority. You manage it from a web interface, a command line and a JSON-RPC API.

This guide covers launching and using the FreeIPA Identity Management 4.13.4 on AlmaLinux 9 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud identity, secrets and PKI listing on AWS Marketplace. You select it as the software version when you subscribe and launch.

The SecureAnyCloud image is a hardened FreeIPA server that builds your domain on your instance. What you get:

  • Nothing of a domain is in the image. The AMI carries the packages only. On the first boot, the instance runs ipa-server-install itself. It creates its own realm, its own Dogtag certificate authority (the CA signing key is generated on your instance), its own Kerberos master key, keytabs and 389 Directory Server instance. Two instances launched from the same AMI share no key, certificate or password.
  • No default login. First boot generates a random Directory Manager password and a random admin password for your instance and writes them to a root-only file. They are handed to the installer through a terminal, never on a command line. A watcher checks every process's command line and environment throughout the install, and the logs and journal afterwards. The first boot fails if either password appears anywhere.
  • HTTPS from the first boot. The WebUI and API are served by FreeIPA's own Apache over TLS 1.2/1.3 with a server certificate issued by your instance's own CA (an end-entity certificate, not a CA). Port 80 serves only the CA certificate, revocation lists and OCSP, as FreeIPA does by design, and redirects the WebUI to HTTPS.
  • Anonymous LDAP limited to the root DSE. Clients can still discover the server, but an anonymous client cannot list your users, groups or hosts.
  • No DNS server. FreeIPA's integrated DNS (BIND) is not installed, so the instance is never an open resolver. Use Amazon Route 53 private hosted zones (or your own DNS) for the names, as this guide shows.
  • Metadata access blocked. Every FreeIPA service (Apache, the directory server, the KDC and kadmin, Dogtag, Custodia, the OTP daemon, certmonger, SSSD and the first-boot provisioner) is blocked from the instance metadata service, and the AMI requires IMDSv2.
  • Host firewall. firewalld allows exactly 22, 80, 443, 389, 636 and 88/464 (TCP and UDP). Dogtag's own ports (8080, 8443) and kadmin (749) listen by upstream design but are closed by the firewall.
  • Fully patched AlmaLinux 9.8 at build time, SELinux enforcing, and automatic security updates with dnf-automatic.

What is on the image: FreeIPA (ipa-server) 4.13.4 from the AlmaLinux 9 AppStream repository, 389 Directory Server 2.8, MIT Kerberos 1.21, Dogtag PKI 11.7, Apache httpd 2.4 with mod_ssl, SSSD, certmonger, firewalld, AlmaLinux 9.8, cloud-init and the current AWS Systems Manager agent. The AWS CLI is not preinstalled, because the base image's 2023 bundle could never be updated by dnf. If you need it on the server, install the current version with AWS's own installer.

Default user: ec2-user | Architecture: x86_64 | Recommended instance type: m5.large. FreeIPA runs a directory server, a KDC and a Java certificate authority together, so give it at least 8 GiB of memory.

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a subnet in a VPC.
  • A security group that opens only what each audience needs. The rules follow.
  • TCP 22 (SSH) from your administrators' networks only.
  • TCP 443 (WebUI and API) from your administrators and users.
  • From the subnets of the machines that will use the domain (never from the internet): TCP 389 and 636 (LDAP, LDAPS), TCP and UDP 88 (Kerberos), TCP and UDP 464 (password changes) and TCP 80. Clients fetch the CA certificate, revocation lists and OCSP over HTTP on port 80 when they enroll.
  • Never open 749, 8080 or 8443. They are internal, and the host firewall closes them anyway. Nothing listens on 53.
  • A name plan. By default, the instance builds a private domain from its own EC2 host name (for example ip-10-0-1-23.internal, realm IP-10-0-1-23.INTERNAL, server ipa.ip-10-0-1-23.internal). To use your own domain, decide its names before the first launch (Step 1).
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick FreeIPA Identity Management 4.13.4 on AlmaLinux 9 as the software version and select your Region. Then choose Launch through EC2.

Choose m5.large, your key pair and a security group as described above.

To give the domain your own names, add user data that writes /etc/sac/freeipa.conf before the first boot. The realm and server name become part of the CA and of every Kerberos principal. They cannot be changed later without reinstalling the domain:

cat > freeipa-user-data.yaml <<'EOF' #cloud-config write_files: - path: /etc/sac/freeipa.conf owner: root:root permissions: '0644' content: | IPA_DOMAIN=idm.your-domain.example IPA_HOSTNAME=ipa.idm.your-domain.example IPA_REALM=IDM.YOUR-DOMAIN.EXAMPLE IPA_NETBIOS=IDM EOF aws ec2 run-instances --image-id <ami-id-from-the-listing> --instance-type m5.large \
  --key-name <your-key-pair> --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --user-data file://freeipa-user-data.yaml \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=freeipa}]'

Leave the user data out to accept the default private domain. The root volume is 16 GiB. Grow it at launch if you will store many users, hosts or certificates.

2

Connect to your instance

The SSH user on AlmaLinux 9 is ec2-user. Connect with your key pair:

ssh -i <your-key.pem> ec2-user@<public-ip>
3

Wait for the first boot to finish

The first boot builds the whole domain and takes about 10 minutes on m5.large. Generating the certificate authority is the longest part.

You can log in while the first boot runs. systemctl is-active freeipa-firstboot.service prints activating until it is done. When it has finished, run:

systemctl is-active freeipa-firstboot.service
sudo cat /var/lib/sac/data/freeipa-firstboot.done
active provisionedAt=2026-10-30T20:01:25Z realm=IP-172-31-90-177.INTERNAL serverFqdn=ipa.ip-172-31-90-177.internal ipaServerInstallSeconds=535 firstbootTotalSeconds=556

The full log is in /var/log/sac/sac-freeipa-firstboot.log (root only) and ends with FREEIPA_FIRSTBOOT_SUCCESS.

If the first boot fails, freeipa-firstboot.service shows as failed, and the log ends with a FATAL: line that says why. Launch a fresh instance rather than repairing the failed one.

4

Your domain and server name

The instance renames itself to the IdM server name and keeps that name across reboots:

hostname
sudo grep -E '^IPA_(REALM|DOMAIN|SERVER_FQDN|SERVER_PRIVATE_IP|WEB_UI)=' /root/freeipa-credentials.txt
ipa.ip-172-31-90-177.internal IPA_REALM=IP-172-31-90-177.INTERNAL IPA_DOMAIN=ip-172-31-90-177.internal IPA_SERVER_FQDN=ipa.ip-172-31-90-177.internal IPA_SERVER_PRIVATE_IP=172.31.90.177 IPA_WEB_UI=https://ipa.ip-172-31-90-177.internal/ipa/ui/

FreeIPA answers only to that name. Any other host name, or the bare IP address, is redirected to it. Every computer that uses the domain must therefore resolve the name to the instance:

  • Clients in the VPC: Create a Route 53 private hosted zone for the domain (here ip-172-31-90-177.internal) and associate it with the VPC. Add an A record for ipa.<domain> that points at the private address. Add the service records FreeIPA clients look for: _kerberos._udp, _kerberos._tcp, _kerberos-master._tcp, _kpasswd._tcp, _kpasswd._udp and _ldap._tcp (port 88, 88, 88, 464, 464 and 389, target ipa.<domain>). Also add a TXT record _kerberos with the realm.
  • Your own computer (for the WebUI): Add the name to your hosts file with the instance's public address (/etc/hosts on Linux and macOS, C:\Windows\System32\drivers\etc\hosts on Windows), for example <public-ip> ipa.ip-172-31-90-177.internal.
5

Check the services

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

Check what is listening

sudo ss -lntu | awk 'NR>1{print $1, $5}' | sort -u sudo firewall-cmd --list-ports
tcp 0.0.0.0:22 tcp 0.0.0.0:464 tcp 0.0.0.0:749 tcp 0.0.0.0:88 tcp [::1]:8009 tcp [::]:22 tcp *:389 tcp *:443 tcp [::]:464 tcp *:636 tcp [::]:749 tcp *:80 tcp *:8080 tcp *:8443 tcp [::]:88 tcp [::ffff:127.0.0.1]:8005 tcp [::ffff:127.0.0.1]:8009 udp 0.0.0.0:464 udp 0.0.0.0:88 udp 127.0.0.1:323 udp [::1]:323 udp [::]:464 udp [::]:88 22/tcp 80/tcp 88/tcp 389/tcp 443/tcp 464/tcp 636/tcp 88/udp 464/udp

kadmin (749) and Dogtag (8080, 8443) listen on every interface by upstream design. firewalld (second command) does not open them, so other machines cannot reach them even if a security group allows them. Ports 8005 and 8009 are on the loopback address only. Nothing listens on 53 (no DNS server) or 111.

7

Your credentials

/root/freeipa-credentials.txt (mode 0600, root only) holds everything first boot generated. That includes the realm and names, the admin password, the Directory Manager password, and the SHA-256 fingerprints of your CA certificate and of the web server certificate. To print one value, for example the admin password, run:

sudo grep '^IPA_ADMIN_PASSWORD=' /root/freeipa-credentials.txt | cut -d= -f2-

Keep the Directory Manager password for emergencies. It is the directory's root account. Use admin for everything else.

Change the admin password after your first sign-in. In the WebUI, open the admin menu and choose Change password. Alternatively, run ipa passwd admin.

8

Get a Kerberos ticket as admin

sudo grep '^IPA_ADMIN_PASSWORD=' /root/freeipa-credentials.txt | cut -d= -f2- | kinit admin klist
Password for admin@IP-172-31-90-177.INTERNAL: Ticket cache: KCM:1000 Default principal: admin@IP-172-31-90-177.INTERNAL Valid starting Expires Service principal 10/30/2026 20:07:40 10/31/2026 20:06:07 krbtgt/IP-172-31-90-177.INTERNAL@IP-172-31-90-177.INTERNAL

The password goes into kinit on standard input, so it never appears in your shell history or the process list.

9

Add a user

ipa user-add jsmith --first=John --last=Smith --email=jsmith@example.com ipa user-find --sizelimit=10 | grep -E 'User login|Number of entries'
------------------- Added user "jsmith" ------------------- User login: jsmith First name: John Last name: Smith Full name: John Smith Display name: John Smith Initials: JS Home directory: /home/jsmith GECOS: John Smith Login shell: /bin/sh Principal name: jsmith@IP-172-31-90-177.INTERNAL Principal alias: jsmith@IP-172-31-90-177.INTERNAL Email address: jsmith@example.com UID: 1069200004 GID: 1069200004 Password: False Member of groups: ipausers Kerberos keys available: False User login: admin User login: jsmith Number of entries returned 2

Give the user an initial password with ipa passwd jsmith, which prompts twice. FreeIPA marks the password as expired, so the user chooses their own password the first time they run kinit jsmith or sign in to the WebUI.

10

Sign in to the web interface

Add the server name to your hosts file (Step 4) and open TCP 443 to your address. Then browse to https://ipa.<domain>/ipa/ui/ (the IPA_WEB_UI value).

Your browser does not know your instance's private certificate authority, so it warns you the first time. Before you accept, check that the certificate it shows is yours. Its SHA-256 fingerprint must equal IPA_WEB_CERT_SHA256 in the credentials file. On the instance, run:

sudo grep -E '^IPA_(WEB|CA)_CERT_SHA256=' /root/freeipa-credentials.txt openssl s_client -connect localhost:443 -servername "$(hostname)" </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -fingerprint -sha256
IPA_CA_CERT_SHA256=63:86:BE:D1:4C:76:24:D6:F6:EF:1B:BA:28:88:0D:DB:03:E0:2D:0A:61:1A:F5:41:D1:4A:D5:49:4B:2A:CB:DE IPA_WEB_CERT_SHA256=E7:D1:BB:3D:A5:AB:1E:12:08:E1:EA:5B:B3:74:01:02:09:27:91:CC:A2:BB:16:32:7F:EA:2F:1A:E9:ED:99:D9 subject=O=IP-172-31-90-177.INTERNAL, CN=ipa.ip-172-31-90-177.internal issuer=O=IP-172-31-90-177.INTERNAL, CN=Certificate Authority sha256 Fingerprint=E7:D1:BB:3D:A5:AB:1E:12:08:E1:EA:5B:B3:74:01:02:09:27:91:CC:A2:BB:16:32:7F:EA:2F:1A:E9:ED:99:D9

Sign in as admin with the password from Step 7.

After you sign in, the WebUI opens on Identity > Users, with the user you added.

Authentication > Certificates lists the certificates your instance's own CA has issued, including its subsystems and the server certificates.

IPA Server > Configuration holds the domain-wide defaults: search limits, home directory base, default shell and group.

For a CA-issued certificate that browsers trust without a warning, request one for ipa.<domain> from your own CA. Install it with ipa-server-certinstall -w.

11

Anonymous LDAP is limited to the root DSE

Clients find the server's naming contexts anonymously, but an anonymous search of the directory is refused. Test it:

ldapsearch -LLL -x -H ldap://$(hostname) -b '' -s base namingContexts ldapsearch -LLL -x -H ldap://$(hostname) -b "cn=users,cn=accounts,$(awk -F' = ' '$1=="basedn"{print $2}' /etc/ipa/default.conf)" uid; echo "exit code: $?"
dn: namingContexts: dc=ip-172-31-90-177,dc=internal namingContexts: cn=changelog namingContexts: o=ipaca Inappropriate authentication (48) Additional information: Anonymous access is not allowed. exit code: 48

Applications that read the directory should bind with their own account (a FreeIPA system account or a Kerberos keytab) over LDAPS or StartTLS.

12

Enroll a client machine

Run the following as root on each Linux client. Supported clients are AlmaLinux, Rocky Linux, RHEL, Fedora, or Ubuntu with freeipa-client. The client must resolve ipa.<domain> and reach the ports listed in the Prerequisites:

dnf -y install ipa-client ipa-client-install --domain=<IPA_DOMAIN> --server=<IPA_SERVER_FQDN> --realm=<IPA_REALM> --mkhomedir

The installer downloads the CA certificate over HTTP and asks you to confirm it. Compare it with IPA_CA_CERT_SHA256. The installer then joins the host with the admin credentials you type and configures SSSD, Kerberos and SSH.

IdM users can then log in to the client with their own passwords or Kerberos tickets. By design, an enrolled client trusts your instance's CA for its services.

13

Inspect your certificate authority

openssl x509 -in /etc/ipa/ca.crt -noout -subject -dates -fingerprint -sha256 ipa cert-find --sizelimit=5 | grep -E 'Subject|Number of'
subject=O=IP-172-31-90-177.INTERNAL, CN=Certificate Authority notBefore=Oct 30 19:55:32 2026 GMT notAfter=Oct 30 19:55:32 2046 GMT sha256 Fingerprint=63:86:BE:D1:4C:76:24:D6:F6:EF:1B:BA:28:88:0D:DB:03:E0:2D:0A:61:1A:F5:41:D1:4A:D5:49:4B:2A:CB:DE ipa: WARNING: Search result has been truncated: Configured size limit exceeded Subject: CN=Certificate Authority,O=IP-172-31-90-177.INTERNAL Subject: CN=OCSP Subsystem,O=IP-172-31-90-177.INTERNAL Subject: CN=ipa.ip-172-31-90-177.internal,O=IP-172-31-90-177.INTERNAL Subject: CN=CA Subsystem,O=IP-172-31-90-177.INTERNAL Subject: CN=CA Audit,O=IP-172-31-90-177.INTERNAL Number of entries returned 5

The CA's signing key exists only on this instance. /root/cacert.p12 holds a copy of it, encrypted with the Directory Manager password and readable by root only. Keep a copy of that file, and of your backups, somewhere safe.

14

Back up the domain

sudo ipa-backup --data --online sudo ls /var/lib/ipa/backup/
Preparing backup on ipa.ip-172-31-90-177.internal Local roles match globally used roles, proceeding. Backing up ipaca in IP-172-31-90-177-INTERNAL to LDIF Waiting for LDIF to finish Backing up userRoot in IP-172-31-90-177-INTERNAL to LDIF Waiting for LDIF to finish Backing up IP-172-31-90-177-INTERNAL Waiting for BAK to finish Backed up to /var/lib/ipa/backup/ipa-data-2026-10-30-20-05-58 The ipa-backup command was successful ipa-data-2026-10-30-20-05-58

--data --online backs up the directory without stopping the services. A full backup (sudo ipa-backup, without options) also copies the configuration, keys and certificates, but it stops the services for a minute.

Copy /var/lib/ipa/backup/ off the instance, for example to an encrypted S3 bucket. ipa-restore restores it. EBS snapshots of the root volume are a good second layer.

15

Keep the server patched

systemctl is-enabled dnf-automatic.timer grep -E '^(upgrade_type|apply_updates)' /etc/dnf/automatic.conf rpm -q ipa-server 389-ds-base idm-pki-ca krb5-server
enabled upgrade_type = security apply_updates = yes ipa-server-4.13.4-1.el9_8.x86_64 389-ds-base-2.8.0-11.el9_8.x86_64 idm-pki-ca-11.7.1-2.el9_8.noarch krb5-server-1.21.1-10.el9_8.1.x86_64

Security errata from AlmaLinux are installed automatically every day. FreeIPA upgrades its own schema and configuration after a package update, because ipa-server-upgrade runs from the package.

For feature updates, run sudo dnf upgrade in a maintenance window. Reboot if a new kernel was installed.

Security notes

  • Per-instance everything: The realm, the CA and its signing key, the Kerberos master key, every keytab, every TLS key and both passwords are created on your instance at first boot. The AMI contains none of them.
  • Instance metadata: Every FreeIPA service runs with a systemd IPAddressDeny rule for the instance metadata service (169.254.169.254, fd00:ec2::254). A feature that fetches a URL, for example an external identity provider configured with ipa idp-add or a certmonger CA helper, therefore cannot reach instance credentials. The AMI requires IMDSv2.
  • Network exposure: Keep LDAP and Kerberos to your client subnets and the WebUI to the networks that need it. Clients should use Kerberos (GSSAPI), LDAPS or StartTLS. FreeIPA still accepts a simple LDAP bind without TLS on port 389 (upstream default). To refuse passwords in clear text entirely, set nsslapd-require-secure-binds: on on cn=config with ldapmodify -Y EXTERNAL over the LDAPI socket as root.
  • SSH: Password and root logins are off. As on every FreeIPA server, SSH also accepts the public SSH keys stored on IdM users and Kerberos (GSSAPI) logins.
  • DNS: Integrated DNS is not installed. If you add it later with ipa-dns-install, never expose port 53 to the internet.
  • SELinux stays enforcing. No policy was relaxed for FreeIPA.

Support

SecureAnyCloud provides support for this image by email at sales@secureanycloud.com. For FreeIPA itself, see the FreeIPA documentation and the Red Hat Identity Management guides, which apply to the same software.

Deploy on AWS

Launch FreeIPA Identity Management 4.13.4 on AlmaLinux 9 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS