Review permissions of volume mounts to ensure file permissions are at least 644.
#Ensure files are executeable
#-rwxr-xr-x openldap/service/z_kadmind/process.sh
#-rwxr-xr-x openldap/service/z_krb5kdc/process.sh
chmod 0755 openldap/service/z_kadmind/process.sh openldap/service/z_krb5kdc/process.sh
#ls -la openldap/service/z_kadmind/process.sh openldap/service/z_krb5kdc/process.sh
# Start services using Docker Compose
docker-compose up
# Verify valid keytab file generated
docker exec keycloak-openldap kinit HTTP/[email protected] -k -t /etc/keytabs/keycloak.keytab
# List and destroy Kerberos ticket
docker exec keycloak-openldap klist
docker exec keycloak-openldap kdestroy
# Verify permissions of shared keytab file to ensure it can be read by Keycloak
docker exec --user root keycloak chmod 644 /tmp/keytabs/keycloak.keytab
-
Username:
admin
-
Password:
password
-
OIDC Endpoint:
http://keycloak.127.0.0.1.nip.io:8080/auth/realms/{realm}/.well-known/openid-configuration
-
Authorization Endpoint:
http://keycloak.127.0.0.1.nip.io:8080/auth/realms/{realm}/protocol/openid-connect/auth
-
Account Management:
http://keycloak.127.0.0.1.nip.io:8080/auth/realms/{realm}/account
Credentials:
[email protected]
/password
,[email protected]
/password
-
js-console
login -
OIDC Debugger
loginOpen
Send Request
using InPrivate / Cognito Window-
Authorization Endpoint:
http://keycloak.127.0.0.1.nip.io:8080/ auth/realms/dev/protocol/openid-connect/auth
-
Redirect URL:
https://oidcdebugger.com/debug
-
Client ID:
oidc-debugger
-
# Cleanup
docker-compose rm -f
docker volume rm keycloak_vol-mariadb keycloak_vol-openldap-ldap keycloak_vol-openldap-slapd
Creating users is now a two-step process:
-
Create new user with ldapadd (if KeyCloak Kerberos configured to be backed by an LDAP server).
-
Create new KDC entry using
addprinc
(for Kerberos Authentication) and link it to the DN. E.g.:kadmin.local kadmin.local: addprinc -pw password -x dn=uid=charlie,ou=People, dc=example,dc=org charlie
Run the following commands in
keycloak-openldap
container:docker exec -it keycloak-openldap bash
Default password forldapsearch
command is provided using-w
flag. Use-W
for interactive password prompt.
# Verify LDAP credentials
ldapwhoami -x -D "cn=admin,dc=example,dc=org" -w admin
ldapwhoami -x -D "uid=alice,ou=People,dc=example,dc=org" -w password
# Verify krbContainer container exists (numEntries: 1)
ldapsearch -L -x -D cn=admin,dc=example,dc=org -b dc=example,dc=org -w admin cn=krbContainer
# Verify ACL for kdc-service and kadmin-service (numEntries: 12)
ldapsearch -L -x -D uid=kdc-service,dc=example,dc=org -b cn=krbContainer,dc=example,dc=org -w password
ldapsearch -L -x -D uid=kadmin-service,dc=example,dc=org -b cn=krbContainer,dc=example,dc=org -w password
# Verify Kerberos services are started
service krb5-kdc status
service krb5-admin-server status
# Validate Kerberos token can be obtained using keytab file
kinit HTTP/[email protected] -k -t /etc/keytabs/keycloak.keytab
klist
kdestroy
# Login using SPNEGO
# 302 returned with access code: # http://js-console.127.0.0.1.nip.io:8000/?session_state=...&code=...
# To use existing ticket, use curl -I --negotiate -u : http://....
curl -I --negotiate -u [email protected]:password "http://keycloak.127.0.0.1.nip.io:8080/auth/realms/dev/protocol/openid-connect/auth?client_id=js-console&redirect_uri=http%3A%2F%2Fjs-console.127.0.0.1.nip.io%3A8000%2F&response_type=code&scope=openid"
To generate a keytab
file for Active Directory, create a service account / user e.g. keycloak
.
REM Set service principal name
setspn -s HTTP/myapp.example.org keycloak
REM Generate keytab
ktpass -princ HTTP/myapp.example.org ^
-mapuser keycloak@dev.pc8.dsta -crypto ALL ^
-ptype KRB5_NT_PRINCIPAL -pass * -out C:\keycloak.keytab
Create a principal for Windows Client
# Remember the password for the principal (e.g. `password`)
# IMPORTANT: Value of %COMPUTERNAME% has to be lower case
docker exec -it keycloak-openldap kadmin.local -q "addprinc host/%COMPUTERNAME%.example.org"
# Run the following commands as Administrator
# Set domain (computername and workgroup of computer will change)
ksetup /setdomain EXAMPLE.ORG
# Update KDC for domain (where 172.30.160.1 is the IP of OpenLDAP)
# To verify windows client can reach the OpenLDAP via IP, use `openssl s_client -connect localhost:636`
ksetup /AddKdc EXAMPLE.ORG 172.30.160.1
# ksetup /DelKdc EXAMPLE.ORG X.X.X.X
# Set the machine password to be the same as the principal created above (`password` in this example)
ksetup /setmachpassword password
# Optional: ksetup /AddRealmFlags EXAMPLE.ORG delegate
# Map domain user to local user
ksetup /mapuser [email protected] %USERNAME%
Verify Windows Client can authenticate using Kerberos:
# For logs see `/var/log/krb5kdc.log` in OpenLDAP container (logging is configured in krb5.conf file)
runas /user:[email protected] cmd
Common Errors:
-
1787: The security database on the server does not have a computer account for this workstation trust relationship.
Principal for Windows Client not added: The principal name has to be lowercase.
-
SPNEGO login failed: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP-REQ - RC4 with HMAC)
Keytab not found (check for typo in Keycloak settings).
-
SPNEGO login failed: java.security.PrivilegedActionException: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
Check the FQDN or keycloak server (e.g. domain CNAME alias). To verify use wireshark to inspect
TGS_REQ
inreq-body
.Regenerate the keytab file:
docker exec keycloak-openldap kadmin.local -q "ktadd -k /etc/keytabs/keycloak.keytab HTTP/[email protected]" docker exec --user root keycloak chmod 644 /tmp/keytabs/keycloak.keytab
# Generate CA key and cert
openssl req -x509 -nodes -newkey rsa:2048 -keyout rootCA.key \
-days 3650 -out rootCA.crt \
-subj "/C=SG/OU=www.org/O=MyOrg, Inc./CN=My Org Root CA"
# Generate CSR for keycloak
openssl req -newkey rsa:2048 -nodes -keyout keycloak.key \
-new -out keycloak.csr \
-subj "/C=SG/L=Singapore/O=MyOrg, Inc./CN=keycloak" \
-addext "subjectAltName=DNS:localhost,DNS:keycloak.127.0.0.1.nip.io" \
-addext "keyUsage=digitalSignature,keyEncipherment"
# Generate CA signed cert for keycloak
openssl x509 -in keycloak.csr \
-CA rootCA.crt -CAkey rootCA.key -CAcreateserial \
-req -days 3650 -out keycloak.crt \
-extfile <(printf "subjectAltName=DNS:localhost,DNS:keycloak,DNS:keycloak.127.0.0.1.nip.io")
# Generate CSR for openldap
openssl req -newkey rsa:2048 -nodes -keyout ldap.key \
-new -out ldap.csr \
-subj "/C=SG/L=Singapore/O=MyOrg, Inc./CN=openldap" \
-addext "subjectAltName=DNS:localhost,DNS:openldap,DNS:openldap.127.0.0.1.nip.io" \
-addext "keyUsage=digitalSignature,keyEncipherment"
# Generate CA signed cert for openldap (using previous CA serial file rootCA.srl)
openssl x509 -in ldap.csr \
-CA rootCA.crt -CAkey rootCA.key -CAserial rootCA.srl \
-req -days 3650 -out ldap.crt \
-extfile <(printf "subjectAltName=DNS:localhost,DNS:openldap,DNS:openldap.127.0.0.1.nip.io")
# Verify certs
openssl verify -verbose -CAfile rootCA.crt keycloak.crt
openssl verify -verbose -CAfile rootCA.crt ldap.crt
SSL / TLS debugging
openssl s_client -connect localhost:636
openssl s_client -connect localhost:8443
- MIT Kerberos Documentation
- Ubuntu Docs: Kerberos and LDAP
- Kerberos Environment Setup
- Configuring a Master KDC on an OpenLDAP Directory Server
- All About Kerberos “The Three Headed Dog” with respect to IIS and Sql
- Kerberos and Windows Security: Kerberos v5 Protocol
- Performing Kerberoasting without SPNs
- Kerberos Wireshark Captures
- Using Kerberos in NAT and DHCP Environments
- Keycloak Kerberos