FreeIPA Identity Management 4.13.4 on AWS User Guide
Overview
This guide covers launching and using the FreeIPA Identity Management 4.13.4 on AlmaLinux 9 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg identity, secrets and PKI listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
FreeIPA is the open source identity management server behind Red Hat Identity Management: one domain that gives your Linux fleet central users and groups, Kerberos single sign-on, host-based access control, sudo rules, SSH public keys and its own certificate authority, managed from a web interface, a command line and a JSON-RPC API.
The cloudimg image is a hardened FreeIPA server that builds your domain on your instance:
- Nothing of a domain is in the image. The AMI carries the packages only. On the first boot the instance runs
ipa-server-installitself: 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
adminpassword 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, and 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, 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 (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; 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. Open only what each audience needs:
- 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 when they enrol).
- Never open 749, 8080 or 8443: they are internal and the host firewall closes them anyway. There is nothing 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, realmIP-10-0-1-23.INTERNAL, serveripa.ip-10-0-1-23.internal). To use your own domain, decide its names before the first launch (Step 1).
Step 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 your Region, then Launch through EC2. Choose m5.large, your key pair, and a security group as above.
To give the domain your own names, add user data that writes /etc/cloudimg/freeipa.conf before the first boot. The realm and server name become part of the CA and of every Kerberos principal, so they cannot be changed later without reinstalling the domain:
cat > freeipa-user-data.yaml <<'EOF'
#cloud-config
write_files:
- path: /etc/cloudimg/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.
Step 2: Connect to your instance
| Operating system | SSH user |
|---|---|
| AlmaLinux 9 | ec2-user |
ssh -i <your-key.pem> ec2-user@<public-ip>
Step 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 it runs; systemctl is-active freeipa-firstboot.service prints activating until it is done. When it has finished:
systemctl is-active freeipa-firstboot.service
sudo cat /var/lib/cloudimg/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/cloudimg-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 that one.
Step 4: Your domain and server name
The instance has renamed 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 only answers to that name (any other host name, or the bare IP address, is redirected to it), so every computer that uses the domain must resolve it to the instance:
- Clients in the VPC: create a Route 53 private hosted zone for the domain (here
ip-172-31-90-177.internal) associated with the VPC, with an A record foripa.<domain>pointing at the private address, and the service records FreeIPA clients look for:_kerberos._udp,_kerberos._tcp,_kerberos-master._tcp,_kpasswd._tcp,_kpasswd._udpand_ldap._tcp(port 88, 88, 88, 464, 464 and 389, targetipa.<domain>), plus a TXT record_kerberoswith the realm. - Your own computer (for the WebUI): add the name to your hosts file with the instance's public address (
/etc/hostson Linux and macOS,C:\Windows\System32\drivers\etc\hostson Windows), for example<public-ip> ipa.ip-172-31-90-177.internal.
Step 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
Step 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 they are unreachable from other machines even if a security group allowed them. 8005 and 8009 are on the loopback address only. Nothing listens on 53 (no DNS server) or 111.
Step 7: Your credentials
/root/freeipa-credentials.txt (mode 0600, root only) holds everything first boot generated: 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:
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 (WebUI: admin menu > Change password, or ipa passwd admin).
Step 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.
Step 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 (it prompts twice). FreeIPA marks it as expired, so the user chooses their own password the first time they run kinit jsmith or sign in to the WebUI.
Step 10: Sign in to the web interface
With the server name in your hosts file (Step 4) and TCP 443 open to your address, 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 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:
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 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 (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 and install it with ipa-server-certinstall -w.
Step 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:
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.
Step 12: Enrol a client machine
On each Linux client (AlmaLinux, Rocky Linux, RHEL, Fedora, or Ubuntu with freeipa-client) that can resolve ipa.<domain> and reach the ports from the Prerequisites, as root:
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, asks you to confirm it (compare it with IPA_CA_CERT_SHA256), 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, and an enrolled client trusts your instance's CA for its services by design.
Step 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, readable by root only); keep a copy of it, and of your backups, somewhere safe.
Step 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 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.
Step 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 (ipa-server-upgrade runs from the package). For feature updates, run sudo dnf upgrade in a maintenance window and 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
IPAddressDenyrule for the instance metadata service (169.254.169.254, fd00:ec2::254), so a feature that fetches a URL (for example an external identity provider configured withipa idp-add, or a certmonger CA helper) 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), so to refuse passwords in clear text entirely, set
nsslapd-require-secure-binds: ononcn=configwithldapmodify -Y EXTERNALover 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
cloudimg provides support for this image by email at support@cloudimg.co.uk. For FreeIPA itself, see the FreeIPA documentation and the Red Hat Identity Management guides, which apply to the same software.