-
Notifications
You must be signed in to change notification settings - Fork 6
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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: | ||
|
||
``` | ||
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: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
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 |
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"] |
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 .."
There was a problem hiding this comment.
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: