Skip to content

WIP ipa-tuura: add demo for ipa-tuura using IPA and Keycloak #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 187 additions & 0 deletions ipalab-config/ipa-tuura/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# FreeIPA integration with Keycloak using ipa-tuura bridge

This lab sets up an environment that integrates [FreeIPA](https://freeipa.org) and [Keycloak](https://keycloak.org) identity management deployments using the **ipa-tuura** bridge via Keycloak's User Federation feature.

**ipa-tuura** is a service that exposes identity and authentication domains through a set of Django applications, enabling centralized management of users, groups, and authentication methods.


## Preparing the environment

Create the configuration:

```
python3 -m venv /tmp/ipalab
. /tmp/ipalab/bin/activate
pip install -r requirements.txt
```

Build the container image and instantiate containers:

```
ipalab-config lab_ipa_tuura.yml
cd ipa-tuura-keycloak
podman-compose build
podman-compose up -d
```

At this stage, the environment consists of three containers:
- A container based on the official Keycloak image
- A container ready for deploying FreeIPA
- The **ipa-tuura** service container, which bridges FreeIPA and Keycloak by integrating them through Keycloak's User Federation storage

Deploy the IPA cluster using
[ansible-freeipa](https://gtihub.com/freeipa/ansible-freeipa):

```
ansible-galaxy collection install \
freeipa.ansible_freeipa \
containers.podman
ansible-playbook -i inventory.yml \
${HOME}/.ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/install-cluster.yml
```

The provided Keycloak container uses a self-signed certificate that is
unkown to the ipa-tuura container. The certificate is found in the container
`keycloak` at the path `/opt/keycloak/conf/cert.pem`. This certificate
must be added to the list of trusted certificates on the ipa-tuura
container. This can be achieved by executing:

```
keycloak/trust_keycloak.sh ipatuura
```

## Using Keycloak web interface

Since the whole environment runs using rootles containers, in a Podman
virtual network, direct access to the host ports is not possible, but
can be achieved using `podman unshare`. For example, to _ssh_ into the
container (if `sshd` is available) or to access the `httpd` server.

When using [Firefox](https://mozilla.org/firefox) a profile is needed
to access the containers URLs, and to ease access the script
`scripts/open-firefox.sh` is provided. This script will manage the
Firefox profile and call `firefox` with the proper configuration for
`podman unshare`, allowing access to Keycloak and WebUI.

Before starting Firefox, add the entries found in the generated `hosts`
file to your machine `/etc/hosts` so the host names can be resolved. The
file `hosts` has all the containers entries needed, add it with:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (typo): Consider rephrasing 'containers entries'.

Change “containers entries” to “container entries” for clarity.

Suggested change
file `hosts` has all the containers entries needed, add it with:
file `hosts` has all the container entries needed, add it with:

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to ".. has the entries for all containers .."

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good—“hosts” has the entries for all containers needed. I’ll update the README to:

Before starting Firefox, add the entries found in the generated `hosts` file to your machine’s `/etc/hosts` so the host names can be resolved. The `hosts` file has the entries for all containers needed, add it with:


```
sudo bash -c "cat hosts >> /etc/hosts"
```

Start the Keycloak web interface with:

```
scripts/open-firefox.sh https://keycloak.example.test:8443
```

Start the IPA WebUI with:

```
scripts/open-firefox.sh https://server.ipa.test:443
```

In a similar fashion you can access the Bridge API with:

```
scripts/open-firefox.sh https://ipatuura.ipa.test:443
```


## Setting up Keycloak's User Federation Storage


In order to interconnect both identity management systems, the **ipa-tuura** service must be added as part of Keycloak's *User Federation* storage.

```json
./kcadm.sh create components \
-r master \
-s name=scimipa \
-s providerId=scim \
-s providerType=org.keycloak.storage.UserStorageProvider \
-s 'config.scimurl=["bridge.ipa.test"]' \
-s 'config.loginusername=["scim"]' \
-s 'config.loginpassword=["Secret123"]' \
-s 'config.domain=["ipa.test"]' \
-s 'config.domainname=["ipa.test"]' \
-s 'config.domaindesc=["Bridge_to_ipa"]' \
-s 'config.domainurl=["https://idm.ipa.test"]' \
-s 'config.domainclientid=["admin"]' \
-s 'config.domainclientsecret=["Secret123"]' \
-s 'config.idprovider=["ipa"]' \
-s 'config.cacert=["/etc/ipa/ca.crt"]' \
-s 'config.users_dn=["ou=people,dc=ipa,dc=test"]' \
-s 'config.extraattrs=["mail:mail, sn:sn, givenname:givenname"]' \
-s 'config.addintgdomain=["True"]' \
-s 'config.enabled=["True"]' \
-s 'config.keycloak_hostname=["keycloak.ipa.test"]'
```

CHECK IF WE CAN CREATE A JSON and rely on kcreg:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Developer note found in documentation.

Remove or address the 'CHECK IF WE CAN...' developer note and update the documentation accordingly.


```json
{
"enabled" : true,
"clientAuthenticatorType" : "client-secret",
"redirectUris" : [ "https://${IPASERVER}/ipa/idp/*" ],
"webOrigins" : [ "https://${IPASERVER}" ],
"protocol" : "openid-connect",
"attributes" : {
"oauth2.device.authorization.grant.enabled" : "true",
"oauth2.device.polling.interval": "5"
}
}
```


To create the OIDC client for Keycloak, you can use the script provided
by `ipalab-config`. The script requires the IPA FQDN, an OIDC client ID
and the OIDC client password. Execute:

```
keycloak/keycloak_add_oidc_client.sh \
server.ipa.test \
ipa_oidc_client \
Secret123
```

Now, we can start adding some users to IPA deploytment, and check if they are automatically provisioned in Keycloak by running:

```
ansible-playbook -i inventory.yml playbooks/add_ipa_users.yml
```

## Testing the setup

To test the setup, create a user on IPA using:

```
ansible-playbook -i inventory.yml playbooks/add_user_auth_idp.yml
```

Perform login with user `jdoe` on Keycloak web interface:

```
scripts/open-firefox.sh https://keycloak.example.test:8443/realms/master/account
```


## Troubleshooting

ADD ipa-tuura troubleshooting
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Placeholder comment in Troubleshooting section.

Please replace the placeholder with the actual ipa-tuura troubleshooting steps or remove it.


If anything goes wrong, you can search `journalctl` for `ipa-otpd`
entries.

To increase the log level, set the `oidc_child` debug level in
`/etc/ipa/default.conf` by setting:

```
[global]
oidc_child_debug_level=10
```

Valid values are between 0 and 10 and any value above 6 includes debug
output from `libcurl` utility.
152 changes: 152 additions & 0 deletions ipalab-config/ipa-tuura/ipa-keycloak-idp.tape
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
Output out.webm
Set FontSize 16
Set Width 1200
Set Height 800
Require python3
Require podman
Sleep 2s
Hide
Type "export PS1='[\W]$ '"
Enter
Wait /.*[\$#] *$/
Type "command -v deactivate && deactivate"
Enter
Wait /.*[\$#] *$/
Type "rm -rf /tmp/ipalab-ipa-keycloak"
Enter
Wait /.*[\$#] *$/
Ctrl+L
Show
Type "`# Install support software`"
Sleep 500ms
Enter
Sleep 5s
Type "python3 -m venv /tmp/ipalab-ipa-keycloak"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type ". /tmp/ipalab-ipa-keycloak/bin/activate"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "pip install -r requirements.txt"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Sleep 3s
Ctrl+L
Type "`# Create and activate the configuration`"
Sleep 500ms
Enter
Sleep 5s
Type "ipalab-config lab_ipa_keycloak.yml"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "cd ipa-keycloak-idp"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "podman-compose build"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "podman-compose up -d"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "`# Trust Keycloak self-signed certificate`"
Sleep 500ms
Enter
Sleep 5s
Type "keycloak/trust_keycloak.sh server"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Sleep 3s
Ctrl+L
Type "`# Install containers.podman collection`"
Sleep 500ms
Enter
Sleep 5s
Type "ansible-galaxy collection install containers.podman"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "`# Install freeipa.ansible_freeipa collection`"
Sleep 500ms
Enter
Sleep 5s
Type "ansible-galaxy collection install freeipa.ansible_freeipa"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Sleep 3s
Ctrl+L
Type "`# Video cut to deploy IPA cluster`"
Sleep 500ms
Enter
Sleep 5s
Type "`# ansible-playbook -i inventory.yml ${ansible_freeipa_collection_path}install-cluster.yml`"
Sleep 500ms
Enter
Sleep 5s
Hide
Type "ansible-playbook -i inventory.yml ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/install-cluster.yml"
Enter
Wait@10m /.*[\$#] *$/
Show
Type "`# Create Keycloak OIDC client`"
Sleep 500ms
Enter
Sleep 5s
Type "keycloak/keycloak_add_oidc_client.sh server.ipa.test ipa_oidc_client Secret123"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "`# Configure IDP endpoint in IPA`"
Sleep 500ms
Enter
Sleep 5s
Type "ansible-playbook -i inventory.yml playbooks/idp_keycloak.yml"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "`# Test IDP connection with user 'jdoe'`"
Sleep 500ms
Enter
Sleep 5s
Type "`# Create user on Keycloak`"
Sleep 500ms
Enter
Sleep 5s
Type "keycloak/keycloak_add_user.sh jdoe [email protected] userPASS"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "`# Add user to IPA`"
Sleep 500ms
Enter
Sleep 5s
Type "ansible-playbook -i inventory.yml playbooks/add_user_auth_idp.yml"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Sleep 5s
Ctrl+L
Type "`# kinit user jdoe on IPA server`"
Sleep 500ms
Enter
Sleep 5s
Type "podman exec server kinit -n -c /fast.ccache"
Sleep 500ms
Enter
Wait /.*[\$#] *$/
Type "podman exec server kinit -T /fast.ccache jdoe"
Sleep 500ms
Enter
Wait@5s /.*[\$#] *$/
Type "`# Some issues may be present in this demo, and for a complete execution, access to a browser is needed.`"
Sleep 500ms
Enter
Sleep 5s
28 changes: 28 additions & 0 deletions ipalab-config/ipa-tuura/lab_ipa_tuura.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
lab_name: ipa-tuura-keycloak
subnet: "192.168.173.0/24"
# container_fqdn: true
## This is only needed if we want to build
## the ipatuura container
# containerfiles:
# - "ipa-tuura.containerfile"
external:
hosts:
- name: keycloak
hostname: keycloak.external.test
role: keycloak
options:
# admin_username: defaults to "admin"
# admin_password: defaults to "secret123"
- name: ipatuura
hostname: ipatuura.ipa.test
image: "quay.io/freeipa/ipa-tuura:latest"
ipa_deployments:
- name: ipa
domain: ipa.test
admin_password: SomeADMINpassword
dm_password: SomeDMpassword
cluster:
servers:
- name: server
capabilities: ["DNS"]
22 changes: 22 additions & 0 deletions ipalab-config/ipa-tuura/playbooks/add_ipa_users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- name: Add Keycloak as an external IDP for IPA
hosts: ipaserver
become: false
gather_facts: false

collections:
- freeipa.ansible_freeipa

module_defaults:
group/freeipa.ansible_freeipa.modules:
ipaadmin_password: SomeADMINpassword

tasks:
- name: Ensure Keycloak IDP is present
ipaidp:
name: keycloak-idp
provider: keycloak
organization: master
base_url: "https://keycloak.example.test:8443"
client_id: ipa_oidc_client
secret: Secret123
Loading