EX362 Exam Prep

This page contains the necessary resources to help you prepare for the Red Hat Certified Specialist in Identity Management exam, EX362. This follows loosely the youtube playlist as much as possible with various examples and ideas. At the bottom, you will also find our own example practice exam for you to try your hand at to test your knowledge.

The list of objectives can be found here. Note that the exam objectives can change at any time. It is the responsibility of the reader to always review the objectives prior to studying and taking the exam to ensure success.

Please note that we are not affiliated with Red Hat. The materials and examples used are our own and do not reflect the training programs provided by Red Hat and are educational only. We do not disclose any of the tasks, questions, or material on the exam as it would violate the NDA. Any questions sent to us about anything directly related to the exam will not be answered. We also do not provide any one-on-one tutoring or online teaching courses.
If exam objectives have changed to where the videos and this material are missing information, we can add on at any time upon request. If there are things about FreeIPA that you’d like to see in the videos that may fit into objective, we can add it also upon request. However, it is likely those extra things would be better suited in the separate FreeIPA section on this site.


The video series goes over setting up FreeIPA in a lab/VM environment by following the objectives as outlined by Red Hat. The list of objectives can be found here.

Exam Information

The EX362 exam tests your knowledge in a real world format style test - Meaning just like any Red Hat exam, it is performance-based and you perform tasks as if you were on the job. You are evaluated on the tasks you perform and if they meet the objective criteria. The EX362 is related to FreeIPA or Red Hat Identity Management and counts toward the RHCA (Red Hat Certified Architect).

To take the exam, you must have at least an RHCSA. If you are attempting to become a Red Hat Certified Architect, you must have an RHCE.

Hardware Recommendations

The minimum requirements for IdM are fairly low. 2GB of RAM, 1 core, and a 10GB disk. However, we believe that’s too low, especially if we plan on scaling out. And during upgrades, you would need at least 4GB of RAM for the operations to be successful. Below are our minimum recommendations:

  • 2 (virtual) CPU Core
  • 4 GB of RAM
  • 10GB+ disk or partition for /var/lib/dirsrv

Per the Red Hat documentation, consider that with at least 10k users and 100 groups, you would need at least 3GB of RAM and 1GB swap. If you end up having 100k users and 50k groups, then 16GB of RAM and 4GB of swap is recommended. In fact, in larger deployments, it’s more effective to increase RAM than disk, as most data is stored in cache.

View the resources above in the previous section for directory server tuning information.

Installing FreeIPA/Red Hat IdM with replicas for growth and scale

Server Name IP Address
IPA Servers should either have a DHCP reservation or a static address. In the event that you have either, DNS should always be pointing at, especially if your replica serves DNS. Both of our replicas serve DNS, so loopback is sufficient and recommended for our name server.
In later versions of FreeIPA, there is support to force network manager to ensure resolv.conf is loopback without the need to set it by hand with nmcli.
# Set a static address - It's important for your IdM servers
# to have static addresses or a DHCP reservation.
% nmcli con mod eth0 ipv4.address
% nmcli con mod eth0 ipv4.gateway
% nmcli con mod eth0 ipv4.method manual
% nmcli con mod eth0 ipv4.dns-search example.com

# You should set this if your replica serves DNS! If not, set it to
# one or more of your IdM replicas that do.
% nmcli con mod eth0 ipv4.dns
% nmcli con up eth0
# Examples of using ipa-server-install
# RHEL 7
% yum install ipa-server ipa-server-dns ipa-server-trust-ad
# RHEL 8
% yum module enable idm:DL1/{server,dns,adtrust,client,common}
% yum install ipa-server ipa-server-dns ipa-server-trust-ad
# Installation, interactive, does not setup specific components
% ipa-server-install

# Installation, mostly automatic (recommended)
# This will setup DNS and the necessary pieces for an AD trust
# Optionally, you can use the --netbios-name switch to set your forest netbios name
% ipa-server-install --domain example.com --realm EXAMPLE.COM \
    --reverse-zone=15.168.192.in-addr.arpa. \
    --no-forwarders \
    --no-ntp \
    --setup-dns \
    --setup-adtrust \
    -p Passw0rd! \
    -a Passw0rd!
% kinit admin
# We need to make sure that any A records get a corresponding PTR record, otherwise you're making them manually.
% ipa dnsconfig-mod --allow-sync-ptr=True
# Adding a replica
% ipa-replica-install --setup-dns \
    --setup-ca \

# Adding a replica unattended without forwarders
% ipa-client-install --realm EXAMPLE.COM
% kinit admin
% ipa hostgroup-add-member --hosts=ipa02.example.com ipaservers
% ipa-replica-install --setup-dns \
    --setup-ca \
    --no-forwarders \

Creating Users, Groups, and Policies

Users Login Name Type Group Role UID/GID
John Smith jsmith Normal admins   Auto
Bob Rufus brufus Normal corp   Auto
Larry Dufus ldufus Normal helpdesk   Auto
Robert Cole rcole Staged     Auto
Thomas Snyder tsnyder Preserved     Auto
SysHost Management syshostmgt Normal   Host Manager 10000
Groups Policy
HelpDesk helpdesk
enrollers Enrollment Administrator
Roles Privilege
Host Manager Host administrators
  Host group administrators
  Netgroups administrators
  Host enrollment
Custom UID/GID

It is possible to create the users with a custom uid/gid with the switches –uid and –gidnumber which you will see below. It is also possible to set random passwords with –random.

See ipa user-add –help for more switches.

Password Expiration
When you make a user with the –password switch or use ipa passwd to set a password, it is automatically expired and must be changed on next login. If you want to avoid this from happening, you will need to set a random password via –password or –random, and then use kpasswd username to change it to the desired password. This does not make the account non-expiring.
# Creating users with a password, create all the accounts from the table (except from syshost)
% ipa user-add --first="John" --last="Smith" --password jsmith

# Create the system account with a password of Sup3R$ecre7! and a UID of 10000
% ipa user-add --first="SysHost" --last="Management" --uid=10000 --gidnumber=10000 --password syshostmgt

# Stage a user
% ipa stageuser-add --first="Robert" --last="Cole" rcole

# Preserve a user
% ipa user-del tsynder --preserve

# Create a regular (POSIX) group
% ipa group-add corp

# Create a member only group
% ipa group-add --nonposix HelpDesk
% ipa group-add --nonposix enrollers

# Add the HelpDesk group to the helpdesk policy
# Add the enrollers group to the Enrollment Administrator role
% ipa role-add-member "helpdesk" --groups=HelpDesk
% ipa role-add-member "Enrollment Administrator" --groups=enrollers

# Create a role with privileges
% ipa role-add "Host Manager"
% ipa role-add-privilege "Host Manager" \
    --privileges="Host administrators" \
    --privileges="Host group administrators" \
    --privileges="Netgroups administrators" \
    --privileges="Host enrollment"

# Add the syshostmgt user as a member of the role
% ipa role-add-member "Host Manager" --users="syshostmgt"

# Set our user passwords to CentOS123!$ so that way we don't have to change them later
% kpasswd jsmith

# If we already set the password we want but we don't want it to expire without making a policy or prompt for a password change (NOT RECOMMENDED)
% ldapmodify -x -w 'Passw0rd!' -D 'cn=Directory Manager'
dn: uid=syshostmgt,cn=users,cn=accounts,dc=ipa,dc=chotel,dc=com
changetype: modify
delete: krbLastPwdChange

(Press CTRL+D)

New Passwords Expired

The common question we receive (and even the #freeipa IRC receive) is “Why can’t we just set the password to not be expired right away?” See this page for information on why this is. You may also look at the pagure page and the Red Hat bugzilla related bug.

Install and configure IdM Clients

Client Name IP Address
Depending on your architecture and setup, IdM clients should either be pointing directly at the IdM servers for DNS (at least two of them) or pointing at the DNS server in the environment that is delegating that domain to the IdM domain controllers.
In our lab, our IdM servers are our only DNS servers, thus it makes sense that our clients should point to them. In that scenario, you would configure your DHCP server to use the IdM servers as the name servers and/or configure them in a static manner depending on your environment.
# If your client is not pointing at the IdM DNS and you
# don't have another DNS server that's performing delegation,
# change your name servers.
% nmcli con mod eth0 ipv4.dns
% nmcli con mod eth0 +ipv4.dns
% nmcli con mod eth0 ipv4.dns-search example.com

# Optionally, if your clients don't have DHCP
# reservations, set a static address.
% nmcli con mod eth0 ipv4.address
% nmcli con mod eth0 ipv4.gateway
% nmcli con mod eth0 ipv4.method manual

# It might be a good idea to set your hostname if you haven't already
% hostnamectl set-hostname client.example.com
% hostname client.example.com

# Install the ipa-client packages
% yum install ipa-client -y
% ipa-client-install --realm EXAMPLE.COM --domain example.com
. . .
% id admin
uid=686600000(admin) gid=686600000(admins) groups=686600000(admins)

Configure roaming/automounted home directories

You will need to configure your NFS server to serve up roaming home directories for users and then your client should have automouting enabled.

Client Kerberos Service
It may not be required to create an nfs kerberos service for the client. The ipa-client-automount command may already handle this but it does not hurt to create one. In fact, the host keytab is used on the client side anyway. Creating an NFS client keytab may have been required back in the EL6 days.
# IDM Steps
% kinit admin
% ipa service-add nfs/nfs.example.com
% ipa service-add nfs/client.example.com

# Setup the automounting locations
% ipa automountmap-add default auto.home
% ipa automountkey-add default --key "/home" --info auto.home auto.master
% ipa automountkey-add default --key "*" --info "-fstype=nfs4,rw,sec=krb5,soft nfs.example.com:/exports/home/&" auto.home

# NFS Server Steps
% yum install nfs-utils -y
% mkdir /exports/home
% vi /etc/exports
/exports/home *(rw,sec=sys:krb5:krb5i:krb5p)

% vi /etc/sysconfig/nfs

# Make the home directories for all users and move them to /export/home
% mkhomedir_helper jsmith
% mv /home/jsmith /export/home/

# Create the necessary keytabs
% kinit admin
% ipa-getkeytab -s idm1.example.com -p nfs/nfs.example.com -k /etc/krb5.keytab

# Verify keytab
% klist -ket /etc/krb5.keytab

# Enable and start nfs
% systemctl enable nfs-server --now

# Open the necessary firewall ports
% firewall-cmd --add-service=nfs --permanent
% firewall-cmd --complete-reload

# Client steps
% kinit admin
% ipa-getkeytab -s idm1.example.com -p nfs/client.example.com -k /etc/krb5.keytab
% ipa-client-automount --location=default

# Verify keytab
% klist -ket /etc/krb5.keytab

To test, login to the system via ssh or console and verify the home directory has mounted. /var/log/messages and secure will display errors in case of failure.

Use the REST api to query IdM

When you invoke the ipa command, you are actually communicating with the API that runs on the IdM replicas. Operations done are sent via a POST with JSON data. The return data is also in JSON and translated to be readable in the terminal. Because it’s JSON, custom scripts can be made with say perl or python that communicates with the API to send the calls, perhaps for specific tasks, jobs, or other operations that could be automated. You can also use curl to do this also if you so choose.

The question becomes, “well, how do I know the right data to send?” You can issue the -vv switch to see the request being sent.

% ipa -vv ping
ipa: INFO: trying https://idm1.example.com/ipa/json
ipa: INFO: [try 1]: Forwarding 'schema' to json server 'https://idm1.example.com/ipa/json'
ipa: INFO: trying https://idm1.example.com/ipa/session/json
ipa: INFO: [try 1]: Forwarding 'ping/1' to json server 'https://idm1.example.com/ipa/session/json'
ipa: INFO: Request: {
    "id": 0,
    "method": "ping/1",
    "params": [
            "version": "2.230"
ipa: INFO: Response: {
    "error": null,
    "id": 0,
    "principal": "admin@EXAMPLE.COM",
    "result": {
        "summary": "IPA server version 4.6.4. API version 2.230"
    "version": "4.6.4"
IPA server version 4.6.4. API version 2.230

If you look at the ‘request’ section, you can see the data that is sent. Each request has a method and params, where method is a command to be excuted and params is simply an array that contains positional arguments and a dictionary of options. If you take a look at say, group-show, you would see a different request.

% ipa -vv group-show admins
ipa: INFO: trying https://idm1.example.com/ipa/session/json
ipa: INFO: [try 1]: Forwarding 'group_show/1' to json server 'https://idm1.example.com/ipa/session/json'
ipa: INFO: Request: {
    "id": 0,
    "method": "group_show/1",
    "params": [
            "version": "2.230"
### Lots of output ###

Let’s say I wanted to perform that in a simple bash script that uses curl. I would perform a kinit and then run the script below to have it login for me via kerberos and do the work.


# Login with Kerberos
curl -v \
  -H referer:https://$ipaReplica/ipa \
  -c $cookieJar -b $cookieJar \
  --cacert /etc/ipa/ca.crt \
  --negotiate -u : \
  -X POST \

# Send user_find method request
curl -v \
  -H referer:https://$ipaReplica/ipa \
  -H "Content-Type:application/json" \
  -H "Accept:applicaton/json"\
  -c $cookieJar -b $cookieJar \
  --cacert /etc/ipa/ca.crt \
  -d  '{"method":"group_show/1","params":[["admins"],{}],"id":0}' \
  -X POST \

Any of the commands ran via ipa can be reviewed with the -vv switch so you can see what kind of call it’s making and how it’s making it. Thus, making it easier to tie into your own scripts. On the Web UI, you can go to IPA Server -> API Browser to find more information on the specific API calls.

Configure Kerberized services

One of the things that you may end up doing, whether by hand or in an automated fashion, is creating kerberized services. In a previous section, we addressed creating an NFS service for both a server and a client for the purpose of automating home directory mounts on a client when a user logs in. So you already have the idea of what this entails.

# Create kerberos service
% ipa service-add HTTP/http.example.com

Not only that, it’s probably a good idea to actually get the keytab.

% kinit admin
% ipa-getkeytab -s idm1.example.com -p HTTP/http.example.com -k /etc/krb5.keytab

For an example of automating keytab creation and retrieval, see the CentOS/FreeIPA page on this site.

Create a trust with Active Directory

Server Name IP Address

For our trust, the AD server will need to be configured to be the example.net domain with the hostname of ad.example.net. This way, we are not colliding in DNS and both AD and IdM should be able to communicate with each other as two separate forests. It is recommended to use Windows Server 2016 (with the same domain functional level) for this setup, as experience with that product is a recommended prerequisite for the exam.

Configure and manage a certificate authority

By default FreeIPA stands up its own CA. And because of this, this allows you or your workplace to be able to issue certificates, that can be used in a wide variety of services, the most common or obvious one would be for Apache httpd.

There’s a couple of ways you can get a certificate signed by FreeIPA. One method is to generate your own CSR and request it to be signed by FreeIPA. Another way is you can do it all from one command, ipa-getcert, and optionally, either have the certificate in PEM format or an NSS database. We’ll address these examples.

# Creating an SSL certificate in the PEM format
% ipa service-add HTTP/http.example.com
% ipa-getcert request -f /etc/pki/tls/certs/http.pem -k /etc/pki/tls/private/http.key -K HTTP/http.example.com -D http.example.com
New signing request "20190902000318" added.
# Verify
% ipa-getcert list
Number of certificates and requests being tracked: 1.
Request ID '20190902000318':
        status: MONITORING
        stuck: no
        key pair storage: type=FILE,location='/etc/pki/tls/private/http.key'
        certificate: type=FILE,location='/etc/pki/tls/certs/http.pem'
        CA: IPA
        issuer: CN=Certificate Authority,O=EXAMPLE.COM
        subject: CN=http.example.com,O=EXAMPLE.COM
        expires: 2021-09-02 00:03:19 UTC
        dns: http.example.com
        principal name: HTTP/http.example.com@EXAMPLE.COM
        key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
        eku: id-kp-serverAuth,id-kp-clientAuth
        pre-save command:
        post-save command:
        track: yes
        auto-renew: yes

# Create an SSL certificate in the NSS format
% ipa-getcert request -d /etc/pki/tls/certs/nss -n 'Test' -K HTTP/http.example.com -D http.example.com
New signing request "20190902000756" added.
# Verify
% ipa-getcert list
. . .
Request ID '20190902000756':
        status: MONITORING
        stuck: no
        key pair storage: type=NSSDB,location='/etc/pki/tls/certs/nss',nickname='Test',token='NSS Certificate DB'
        certificate: type=NSSDB,location='/etc/pki/tls/certs/nss',nickname='Test',token='NSS Certificate DB'
        CA: IPA
        issuer: CN=Certificate Authority,O=EXAMPLE.COM
        subject: CN=http.example.com,O=EXAMPLE.COM
        expires: 2021-09-02 00:07:57 UTC
        dns: http.example.com
        principal name: HTTP/http.example.com@EXAMPLE.COM
        key usage: digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment
        eku: id-kp-serverAuth,id-kp-clientAuth
        pre-save command:
        post-save command:
        track: yes
        auto-renew: yes

By default, when a certificate request is performed (and succeeds to be signed by the IPA CA), it is typically tracked and auto-renewed by default. This is done by the certmonger service, which eliminates the need to have to renew anything by hand.

Back up an IdM infrastructure

There are multiple ways you can backup IPA.

  • Full backup: Default, shuts down IPA before performing a backup. This backs up with raw files. As such, it must be done offline.
  • Data backup: Backs up a copy of the ldap data and the changelog (the IPA-REALM instance, DogTag, IPA backend). This can be done online.
# Turns off IPA completely and perform a backup
% ipa-backup
# Backs up data only and doesn't take down IPA
% ipa-backup --data --online
# Backs up data only and gpg encrypts
% ipa-backup --gpg --gpg-keyring=/root/keys --data --online

To restore a backup, the ipa-restore command is available.

% ipa-restore /var/lib/ipa/backup/

Configure IdM as an LDAP backend for external services

Most services and applications that authenticate users do typically have LDAP support. IdM can be used as an LDAP backend. You typically need only a few things to authenticate users from IdM to an application.

  • Base DN, this always ends up being the top level of your domain: dc=example,dc=com - All accounts share this common base.
  • Bind DN, this is a system account that binds to the directory to assist with searches and authentication
  • Attribute mappings
  • Groups, depending on the application

Below is a table of common DN’s you may specify in an application:

DN’s Path Filter (if applicable)
Base DN dc=example,dc=com  
User DN cn=users,cn=accounts,dc=example,dc=com uid=…
Group DN cn=groups,cn=accounts,dc=example,dc=com (objectClass=groupOfNames)
Bind DN uid=account,cn=sysaccounts,cn=etc,dc=example,dc=com  
% ipa user-show admin --all | grep '^dn'
  dn: uid=admin,cn=users,cn=accounts,dc=example,dc=com

Below is a table of common attributes that may be used to map user information in the application.

Type Attribute
Login Name uid
First Name givenName
Surname sn
Email mail
Groups memberOf
Full Name cn

Below are two ways to create a bind account (bind DN). The first way is the LDAP way. The second way is the ipa-ldap-updater.

% kinit admin
% ldapadd -Y GSSAPI
. . .
dn: uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com
objectclass: account
objectclass: simplesecurityobject
uid: binder
userPassword: password123
passwordExpirationTime: 20380119031407Z
nsIdleTimeout: 0
# Press CTRL+d
adding new entry "uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com"
% kinit admin
% cat << EOF > binder.update
dn: uid=binder,cn=sysaccounts,cn=etc,dc=example,dc=com
% ipa-ldap-updater binder.update

When this account is created, you can then specify the full DN for that object into a bind DN field, along with it’s password into an accompanying bind password field.

If you’d like an example of setting up Ansible Tower (or AWX, the open source version of tower) against IdM, you can click here.


On some applications, it is possible to use kerberos authentication rather than a straight bind account. The general idea is the same when picking out the base dn, attributes, and the like. However, instead you would create an account with an accompanying LDAP/… service principal to do the authentication.