Skip to content

Commit c276faa

Browse files
committed
ipa-tuura: add demo for ipa-tuura using IPA and Keycloak
This demo is based on the ipalab-config configuration of Keycloak, which is based on the official Keycloak container image, using a self-signed certificate for HTTPS connection. Keycloak runs in production mode. Helper scripts and playbooks for configuring Keycloak, IPA, and ipa-tuura are provided.
1 parent 234cc50 commit c276faa

File tree

8 files changed

+556
-0
lines changed

8 files changed

+556
-0
lines changed

ipalab-config/ipa-tuura/README.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# FreeIPA integration with Keycloak using ipa-tuura bridge
2+
3+
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.
4+
5+
**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.
6+
7+
8+
## Preparing the environment
9+
10+
Create the configuration:
11+
12+
```
13+
python3 -m venv /tmp/ipalab
14+
. /tmp/ipalab/bin/activate
15+
pip install -r requirements.txt
16+
```
17+
18+
Build the container image and instantiate containers:
19+
20+
```
21+
ipalab-config lab_ipa_tuura.yml
22+
cd ipa-tuura-keycloak
23+
podman-compose build
24+
podman-compose up -d
25+
```
26+
27+
At this stage, the environment consists of three containers:
28+
- A container based on the official Keycloak image
29+
- A container ready for deploying FreeIPA
30+
- The **ipa-tuura** service container, which bridges FreeIPA and Keycloak by integrating them through Keycloak's User Federation storage
31+
32+
Deploy the IPA cluster using
33+
[ansible-freeipa](https://gtihub.com/freeipa/ansible-freeipa):
34+
35+
```
36+
ansible-galaxy collection install \
37+
freeipa.ansible_freeipa \
38+
containers.podman
39+
ansible-playbook -i inventory.yml \
40+
${HOME}/.ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/install-cluster.yml
41+
```
42+
43+
The provided Keycloak container uses a self-signed certificate that is
44+
unkown to the ipa-tuura container. The certificate is found in the container
45+
`keycloak` at the path `/opt/keycloak/conf/cert.pem`. This certificate
46+
must be added to the list of trusted certificates on the ipa-tuura
47+
container. This can be achieved by executing:
48+
49+
```
50+
keycloak/trust_keycloak.sh ipatuura
51+
```
52+
53+
## Using Keycloak web interface
54+
55+
Since the whole environment runs using rootles containers, in a Podman
56+
virtual network, direct access to the host ports is not possible, but
57+
can be achieved using `podman unshare`. For example, to _ssh_ into the
58+
container (if `sshd` is available) or to access the `httpd` server.
59+
60+
When using [Firefox](https://mozilla.org/firefox) a profile is needed
61+
to access the containers URLs, and to ease access the script
62+
`scripts/open-firefox.sh` is provided. This script will manage the
63+
Firefox profile and call `firefox` with the proper configuration for
64+
`podman unshare`, allowing access to Keycloak and WebUI.
65+
66+
Before starting Firefox, add the entries found in the generated `hosts`
67+
file to your machine `/etc/hosts` so the host names can be resolved. The
68+
file `hosts` has all the containers entries needed, add it with:
69+
70+
```
71+
sudo bash -c "cat hosts >> /etc/hosts"
72+
```
73+
74+
Start the Keycloak web interface with:
75+
76+
```
77+
scripts/open-firefox.sh https://keycloak.example.test:8443
78+
```
79+
80+
Start the IPA WebUI with:
81+
82+
```
83+
scripts/open-firefox.sh https://server.ipa.test:443
84+
```
85+
86+
In a similar fashion you can access the Bridge API with:
87+
88+
```
89+
scripts/open-firefox.sh https://ipatuura.ipa.test:443
90+
```
91+
92+
93+
## Setting up Keycloak's User Federation Storage
94+
95+
96+
In order to interconnect both identity management systems, the **ipa-tuura** service must be added as part of Keycloak's *User Federation* storage.
97+
98+
```json
99+
./kcadm.sh create components \
100+
-r master \
101+
-s name=scimipa \
102+
-s providerId=scim \
103+
-s providerType=org.keycloak.storage.UserStorageProvider \
104+
-s 'config.scimurl=["bridge.ipa.test"]' \
105+
-s 'config.loginusername=["scim"]' \
106+
-s 'config.loginpassword=["Secret123"]' \
107+
-s 'config.domain=["ipa.test"]' \
108+
-s 'config.domainname=["ipa.test"]' \
109+
-s 'config.domaindesc=["Bridge_to_ipa"]' \
110+
-s 'config.domainurl=["https://idm.ipa.test"]' \
111+
-s 'config.domainclientid=["admin"]' \
112+
-s 'config.domainclientsecret=["Secret123"]' \
113+
-s 'config.idprovider=["ipa"]' \
114+
-s 'config.cacert=["/etc/ipa/ca.crt"]' \
115+
-s 'config.users_dn=["ou=people,dc=ipa,dc=test"]' \
116+
-s 'config.extraattrs=["mail:mail, sn:sn, givenname:givenname"]' \
117+
-s 'config.addintgdomain=["True"]' \
118+
-s 'config.enabled=["True"]' \
119+
-s 'config.keycloak_hostname=["keycloak.ipa.test"]'
120+
```
121+
122+
CHECK IF WE CAN CREATE A JSON and rely on kcreg:
123+
124+
```json
125+
{
126+
"enabled" : true,
127+
"clientAuthenticatorType" : "client-secret",
128+
"redirectUris" : [ "https://${IPASERVER}/ipa/idp/*" ],
129+
"webOrigins" : [ "https://${IPASERVER}" ],
130+
"protocol" : "openid-connect",
131+
"attributes" : {
132+
"oauth2.device.authorization.grant.enabled" : "true",
133+
"oauth2.device.polling.interval": "5"
134+
}
135+
}
136+
```
137+
138+
139+
To create the OIDC client for Keycloak, you can use the script provided
140+
by `ipalab-config`. The script requires the IPA FQDN, an OIDC client ID
141+
and the OIDC client password. Execute:
142+
143+
```
144+
keycloak/keycloak_add_oidc_client.sh \
145+
server.ipa.test \
146+
ipa_oidc_client \
147+
Secret123
148+
```
149+
150+
Now, we can start adding some users to IPA deploytment, and check if they are automatically provisioned in Keycloak by running:
151+
152+
```
153+
ansible-playbook -i inventory.yml playbooks/add_ipa_users.yml
154+
```
155+
156+
## Testing the setup
157+
158+
To test the setup, create a user on IPA using:
159+
160+
```
161+
ansible-playbook -i inventory.yml playbooks/add_user_auth_idp.yml
162+
```
163+
164+
Perform login with user `jdoe` on Keycloak web interface:
165+
166+
```
167+
scripts/open-firefox.sh https://keycloak.example.test:8443/realms/master/account
168+
```
169+
170+
171+
## Troubleshooting
172+
173+
ADD ipa-tuura troubleshooting
174+
175+
If anything goes wrong, you can search `journalctl` for `ipa-otpd`
176+
entries.
177+
178+
To increase the log level, set the `oidc_child` debug level in
179+
`/etc/ipa/default.conf` by setting:
180+
181+
```
182+
[global]
183+
oidc_child_debug_level=10
184+
```
185+
186+
Valid values are between 0 and 10 and any value above 6 includes debug
187+
output from `libcurl` utility.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
Output out.webm
2+
Set FontSize 16
3+
Set Width 1200
4+
Set Height 800
5+
Require python3
6+
Require podman
7+
Sleep 2s
8+
Hide
9+
Type "export PS1='[\W]$ '"
10+
Enter
11+
Wait /.*[\$#] *$/
12+
Type "command -v deactivate && deactivate"
13+
Enter
14+
Wait /.*[\$#] *$/
15+
Type "rm -rf /tmp/ipalab-ipa-keycloak"
16+
Enter
17+
Wait /.*[\$#] *$/
18+
Ctrl+L
19+
Show
20+
Type "`# Install support software`"
21+
Sleep 500ms
22+
Enter
23+
Sleep 5s
24+
Type "python3 -m venv /tmp/ipalab-ipa-keycloak"
25+
Sleep 500ms
26+
Enter
27+
Wait /.*[\$#] *$/
28+
Type ". /tmp/ipalab-ipa-keycloak/bin/activate"
29+
Sleep 500ms
30+
Enter
31+
Wait /.*[\$#] *$/
32+
Type "pip install -r requirements.txt"
33+
Sleep 500ms
34+
Enter
35+
Wait /.*[\$#] *$/
36+
Sleep 3s
37+
Ctrl+L
38+
Type "`# Create and activate the configuration`"
39+
Sleep 500ms
40+
Enter
41+
Sleep 5s
42+
Type "ipalab-config lab_ipa_keycloak.yml"
43+
Sleep 500ms
44+
Enter
45+
Wait /.*[\$#] *$/
46+
Type "cd ipa-keycloak-idp"
47+
Sleep 500ms
48+
Enter
49+
Wait /.*[\$#] *$/
50+
Type "podman-compose build"
51+
Sleep 500ms
52+
Enter
53+
Wait /.*[\$#] *$/
54+
Type "podman-compose up -d"
55+
Sleep 500ms
56+
Enter
57+
Wait /.*[\$#] *$/
58+
Type "`# Trust Keycloak self-signed certificate`"
59+
Sleep 500ms
60+
Enter
61+
Sleep 5s
62+
Type "keycloak/trust_keycloak.sh server"
63+
Sleep 500ms
64+
Enter
65+
Wait /.*[\$#] *$/
66+
Sleep 3s
67+
Ctrl+L
68+
Type "`# Install containers.podman collection`"
69+
Sleep 500ms
70+
Enter
71+
Sleep 5s
72+
Type "ansible-galaxy collection install containers.podman"
73+
Sleep 500ms
74+
Enter
75+
Wait /.*[\$#] *$/
76+
Type "`# Install freeipa.ansible_freeipa collection`"
77+
Sleep 500ms
78+
Enter
79+
Sleep 5s
80+
Type "ansible-galaxy collection install freeipa.ansible_freeipa"
81+
Sleep 500ms
82+
Enter
83+
Wait /.*[\$#] *$/
84+
Sleep 3s
85+
Ctrl+L
86+
Type "`# Video cut to deploy IPA cluster`"
87+
Sleep 500ms
88+
Enter
89+
Sleep 5s
90+
Type "`# ansible-playbook -i inventory.yml ${ansible_freeipa_collection_path}install-cluster.yml`"
91+
Sleep 500ms
92+
Enter
93+
Sleep 5s
94+
Hide
95+
Type "ansible-playbook -i inventory.yml ~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa/playbooks/install-cluster.yml"
96+
Enter
97+
Wait@10m /.*[\$#] *$/
98+
Show
99+
Type "`# Create Keycloak OIDC client`"
100+
Sleep 500ms
101+
Enter
102+
Sleep 5s
103+
Type "keycloak/keycloak_add_oidc_client.sh server.ipa.test ipa_oidc_client Secret123"
104+
Sleep 500ms
105+
Enter
106+
Wait /.*[\$#] *$/
107+
Type "`# Configure IDP endpoint in IPA`"
108+
Sleep 500ms
109+
Enter
110+
Sleep 5s
111+
Type "ansible-playbook -i inventory.yml playbooks/idp_keycloak.yml"
112+
Sleep 500ms
113+
Enter
114+
Wait /.*[\$#] *$/
115+
Type "`# Test IDP connection with user 'jdoe'`"
116+
Sleep 500ms
117+
Enter
118+
Sleep 5s
119+
Type "`# Create user on Keycloak`"
120+
Sleep 500ms
121+
Enter
122+
Sleep 5s
123+
Type "keycloak/keycloak_add_user.sh jdoe [email protected] userPASS"
124+
Sleep 500ms
125+
Enter
126+
Wait /.*[\$#] *$/
127+
Type "`# Add user to IPA`"
128+
Sleep 500ms
129+
Enter
130+
Sleep 5s
131+
Type "ansible-playbook -i inventory.yml playbooks/add_user_auth_idp.yml"
132+
Sleep 500ms
133+
Enter
134+
Wait /.*[\$#] *$/
135+
Sleep 5s
136+
Ctrl+L
137+
Type "`# kinit user jdoe on IPA server`"
138+
Sleep 500ms
139+
Enter
140+
Sleep 5s
141+
Type "podman exec server kinit -n -c /fast.ccache"
142+
Sleep 500ms
143+
Enter
144+
Wait /.*[\$#] *$/
145+
Type "podman exec server kinit -T /fast.ccache jdoe"
146+
Sleep 500ms
147+
Enter
148+
Wait@5s /.*[\$#] *$/
149+
Type "`# Some issues may be present in this demo, and for a complete execution, access to a browser is needed.`"
150+
Sleep 500ms
151+
Enter
152+
Sleep 5s
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
lab_name: ipa-tuura-keycloak
3+
subnet: "192.168.173.0/24"
4+
# container_fqdn: true
5+
## This is only needed if we want to build
6+
## the ipatuura container
7+
# containerfiles:
8+
# - "ipa-tuura.containerfile"
9+
external:
10+
hosts:
11+
- name: keycloak
12+
hostname: keycloak.external.test
13+
role: keycloak
14+
options:
15+
# admin_username: defaults to "admin"
16+
# admin_password: defaults to "secret123"
17+
- name: ipatuura
18+
hostname: ipatuura.ipa.test
19+
image: "quay.io/freeipa/ipa-tuura:latest"
20+
ipa_deployments:
21+
- name: ipa
22+
domain: ipa.test
23+
admin_password: SomeADMINpassword
24+
dm_password: SomeDMpassword
25+
cluster:
26+
servers:
27+
- name: server
28+
capabilities: ["DNS"]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
- name: Add Keycloak as an external IDP for IPA
3+
hosts: ipaserver
4+
become: false
5+
gather_facts: false
6+
7+
collections:
8+
- freeipa.ansible_freeipa
9+
10+
module_defaults:
11+
group/freeipa.ansible_freeipa.modules:
12+
ipaadmin_password: SomeADMINpassword
13+
14+
tasks:
15+
- name: Ensure Keycloak IDP is present
16+
ipaidp:
17+
name: keycloak-idp
18+
provider: keycloak
19+
organization: master
20+
base_url: "https://keycloak.example.test:8443"
21+
client_id: ipa_oidc_client
22+
secret: Secret123

0 commit comments

Comments
 (0)