RHSSO IDP with IDM for Kerberos authentication flow

Tommer Amber
7 min readAug 13, 2020

--

RHSSO & OIDC Intro

I don't like duplications so I’d like to promote my friend’s (and colleague) article about RHSSO, OAuth, and OIDC as an introduction to the topic, and just jump right into the technical guide;

Essentially that guide is intended for those who’d like to install RHSSO/Keycloak (the upstream project) with Kerberos as an authentication mechanism instead of basic auth (username+password).

I found the official project’s documentation a bit lacking and I’d like to make your life easier.

Solution Overview
In our case, the Tomcat container is apart of the RHSSO/Keycloak and the KDC + LDAP is the IdM Server

Architecture Overview

I installed the IDM (FreeIPA — the upstream project) as a container on a docker engine on a VM, and the RHSSO is installed on a VM of its own.

Furthermore, I configured the IDM as a DNS server as well for my environment (GCP).

Our “application” for testing is going to be an API that RHSSO exposes (https://<rhsso-host>:8443/auth/realms/master/account) that initiates the login process of the RHSSO just like any other application.

And finally, a VM client — a VM that is going to be an IDM-client with a Kerberos ticket, which it’ll receive after a successful login using a user that we will create in the IDM itself.

Our final test is going to be:

Now with all of the opening out of the way, let’s get to work;

Install IDM/FreeIPA as a docker container

I really can’t say how much I appreciate good opensource projects, one of them made that specific part of my work much much easier.

I had some configuration issues when I first tried to deploy it. It is quite important that the container will listen on the host’s IP address, and to enable all the ports both in the docker configuration and on the firewall-cmd on the machine itself. Also, some flags/options didn’t work as expected.

Note!! I tried to use podman but it was quite buggy, especially with the “listening on the host’s IP” part, so I used docker instead.

But happily, I manage to make it work as desired, with the following command:

## Prerequisites ##
$ sudo su -
# yum install docker -y
# yum install git -y
# systemctl enable --now docker
# git clone https://github.com/freeipa/freeipa-container.git
# cd freeipa-container
# docker build -t freeipa-server .
## Explanation in the "Note" below ##
# rmdir /var/lib/ipa-data ; mkdir /var/lib/ipa-data
# setsebool -P container_manage_cgroup 1
# docker login docker.io
# docker run --name idm-server-container -ti -e IPA_SERVER_IP=<vm_host_ip> -p 53:53/udp -p 53:53 -p 443:443 -p 80:80 -p 88:88/udp -p 389:389 -p 123:123/udp -p 464:464/udp -p 636:636 -p 88:88 -p 464:464 -h ipa.<your>.<domain> -v /sys/fs/cgroup:/sys/fs/cgroup:ro --tmpfs /run --tmpfs /tmp -v /var/lib/ipa-data:/data:Z freeipa-server --setup-dns

!!! if you have a problem fetching the image — try to fetch it with a specific tag: https://hub.docker.com/r/freeipa/freeipa-server !!!

This deployment has two parts.

In the first one, we install the IDM server interactively (using the command I just mentioned above) — we are doing this in that way because not all the ‘docker run’ command parameters work so it’s better the be safe then sorry I guess. At the end of that part we will make another ssh connection and force-stop the docker container.

Your final output should look like that: (I added the DNS forwarders because of my environment needs, but it’s not at all a must).

Note!! I used the “rmdir” because that is the directory that the IDM will save its data on and if we would like to reinstall it on the same machine it is required to be empty beforehand.

The second part is creating a service that runs the docker container after it has been configured, and enable + start it using systemctl so even if the server will be restarted the container will restart.

# cat > /usr/sbin/run_idm_docker.sh<< EOF
#!/bin/bash
docker start idm-server
EOF
# chmod +x /usr/sbin/run_idm_docker.sh# cat > /etc/systemd/system/idm_docker.service << EOF
[Unit]
Description=run_idm_on_docker
After=network.target
[Service]
Type=idle
ExecStart=/usr/sbin/run_idm_docker.sh
TimeoutStartSec=600
TimeoutStopSec=600
[Install]
WantedBy=multi-user.target
EOF
# chmod a+x /etc/systemd/system/idm_docker.service# systemctl enable --now idm_docker# systemctl status idm_docker

We also need to enable the IDM’s ports in the firewall policy. The IDM container is actually nice enough to tell us just that:

# firewall-cmd --add-port=80/tcp --add-port=443/tcp --add-port=636/tcp --add-port=389/tcp --add-port=88/tcp --add-port=53/tcp --add-port=464/tcp --add-port=88/udp --add-port=464/udp --add-port=53/udp --add-port=123/udp  --permanent# firewall-cmd --reload

Add the IDM as a new nameserver to your /etc/resolv.conf and verify that the DNS resolving functionality works as expected using nslookup.

Install RHSSO/Keycloak

That part is pretty straight-forward; Run the following commands from the RHSSO/Keycloak server.

In that guide, I’m using Keycloak just in order to avoid subscription-manager complications in my environment but the exact same process will work with RHSSO.

Note!! In case you want to install it on a container (Docker/Openshift) you can use the image from official Red Hat Quay registry/Community OperatorHub here: https://www.keycloak.org/downloads.html

$ sudo su - # cd /opt
# wget https://downloads.jboss.org/keycloak/11.0.0/keycloak-11.0.0.tar.gz
# cd rh-sso-7.3/bin/
# yum install java-1.8.0-openjdk.x86_64 -y
# ./standalone.sh
!! Stop it when it finish with the installation !!# cat > /etc/systemd/system/rhsso.service <<EOF
[Unit]
Description=rhsso
After=network.target
[Service]
Type=idle
ExecStart=/opt/rh-sso-7.3/bin/standalone.sh
TimeoutStartSec=600
TimeoutStopSec=600
[Install]
WantedBy=multi-user.target
EOF
# chmod a+x /etc/systemd/system/rhsso.service# systemctl daemon-reload
# systemctl enable --now rhsso.service
# systemctl status rhsso.service
# firewall-cmd — add-port=8443/tcp — permanent
# firewall-cmd — reload

In /etc/resolv.conf: add the IDM realm (domain) to the search options list and the IDM IP itself as the first nameserver. It is required in order to add the RHSSO as ipa-client as I’m about to do.

I advise you to make the /etc/resolv.conf immutable after the changes, just in case. Then add it to the “domain” using the ipa-client toolkit;

# sudo chattr +i /etc/resolv.conf# yum install -y ipa-client
# ipa-client-install
Verify that a host has been created in the IDM with the proper domain.
!! Make sure that user exists in the IDM server and that it has the required permissions!!
# kinit root
# klist !! Verification
Make sure that your user has high permissions — I just gave it all of them because I’m in a demo environment — that’s not supposed to be configured in such a way in an operational environment.
I created a user called “root” for simplicity

Finally, we need to create a keytab in the IDM for the SSO so it’ll be able to authenticate users using Kerberos; Then we will pull it to the RHSSO and configure it in the UI.

Service: HTTP

Host: <rhsso-hostname>.<your domain>

(The @<realm> will be added automatically)

Then in the RHSSO server:

# ipa-getkeytab -p HTTP/vmrhsso-idp01.mtr-gcp.lab@MTR-GCP.LAB -s ipa.mtr-gcp.lab -k /opt/krb5.keytab
  • Notice the output file’s location, we will use it next in the UI

In order to work with the UI we need to create an admin user: (the script is in: /opt/rh-sso-7.3/bin/)

# ./add-user-rhsso.sh -u admin -p admin# systemctl restart rhsso.service

Log in to the UI and add the “User Federation” source — that will be our IDM/FreeIPA.

Configure it

Make sure that you fill it exactly like me in that part.
Change the connection URL to your IDM. Make sure the User DN + Bind DN has the right realm parameters, and that your bind credential is the password of the admin user of your IDM.

Note!! Test the connection + authentication!!!

Notice the Server principal (it should correspond with the IDM service that we created earlier). Also, notice the KeyTab — it needs to be the exact location of the file on the RHSSO server.

Press the “Synchronize all users”

One last thing — make sure the “authentication scheme” in the RHSSO is configured like that:

That’s it with the RHSSO. Let’s test it.

Testing & Verification

From the VMClient (a VM with VNC-Server I installed on it for a nicer experience), make the same changes to the /etc/resolv.conf as we did in the RHSSO (including the “making it immutable” part) and run the following commands:

# sudo su - 
# yum install -y ipa-client
# ipa-client-install
# exit

Create a test user in the IDM, and kinit with it in the VMclient machine:

$ kinit test
$ klist

Now that’s the only tricky part in that guide — make sure to enable Kerberos authentication in your browser. I used Firefox so I did it like this:

Now let’s access the /account API that the RHSSO exposes as a test “application” to make sure that our Kerberos authentication works.

I didn't add the RHSSO certificate to the trusted sources in the VMClient station but it most definitely the best practice to do so.

Accept the risks and continue;

The User is logged in without the need to enter a username+password, using it’s Kerberos authentication parameters, that the browser send to the RHSSO in the background.

We can also see that there is a live session for that connection in the RHSSO, in case it will try to login to other applications using the same mechanism with RHSSO:

--

--