/ home-lab

Openldap Keycloak and docker

Some detail documentation on how I have setup almost single sign-on to Gitea, Taiga.io, Grafana, Portainer and Bookstack using Openldap and Keycloak

This post has spun from this reddit post over at r/selfhosted about how to get openldap working with keycloak. While I am no expert it did remind me about the pain it was and so it be a good idea to fully document it somewhere for later reference.

As seen from my previous post https://blog.robrotheram.com/2018/08/11/homelab-version-2-now-with-ldap/ I am running a good number of services that I like to have a single idenity accross all of them and some where near single signon to most.

I am using keycloak as the identity management tool that all the services should hopefully connect to check the identity of the user trying to log in. For the login mechanism I went with openid for 2 reasons one I saw a tutorial about it somewhere and that my first service to try and connect gittea had support for it and not SAML. The problem is that although some of the services listed in that screenshot support openid bookstack and taiga.io and portainer did not but did have LDAP support.

So I will be using LDAP for storing users and then using Keycloak for federating the identity to the services that can support openid. Since I am a fan of docker all of this is in a set of docker containers.

    version: '3'
          driver: local
          driver: local
          image: postgres
            - postgres_data:/var/lib/postgresql/data
            POSTGRES_DB: keycloak
            POSTGRES_USER: keycloak
            POSTGRES_PASSWORD: *********
          image: jboss/keycloak
            DB_ADDR: postgres
            DB_DATABASE: keycloak
            DB_USER: keycloak
            DB_PASSWORD: *********
            KEYCLOAK_USER: admin
            KEYCLOAK_PASSWORD: *********
            #JDBC_PARAMS: "ssl=true"
            - 8081:8080
            - postgres
            - ./themes:/opt/jboss/keycloak/themes/custome/:rw
        image: osixia/openldap
           - ldap:/var/lib/ldap
          LDAP_ORGANISATION: "ExceptionError INC"
          LDAP_DOMAIN: "exceptionerror.io"
          LDAP_BASE_DN: ""
          LDAP_ADMIN_PASSWORD: "admin"
          LDAP_READONLY_USER: "true"
          LDAP_READONLY_USER_USERNAME: "readonly"
          LDAP_READONLY_USER_PASSWORD: "*********"
          - 389:389

So the above the docker-compose will create an openldap container and a keycloak/postgress container.

I am managing Openldap via Apache Directory Studio https://directory.apache.org/studio/ although something like phpMyLdap would also work. I imported this .ldfs file that sets up some basic users and groups. The groups were the bit that was more important. Openldap has some oddities about auto creating fields so that memberof queries work, more on this later

version: 1

dn: ou=groups,dc=exceptionerror,dc=io
objectClass: organizationalUnit
objectClass: top
ou: groups

dn: cn=Ensign,ou=groups,dc=exceptionerror,dc=io
objectClass: top
objectClass: groupOfUniqueNames
cn: Ensign

dn: cn=Crewman,ou=groups,dc=exceptionerror,dc=io
objectClass: top
objectClass: groupOfUniqueNames
cn: Crewman

dn: cn=Engineer,ou=groups,dc=exceptionerror,dc=io
objectClass: top
objectClass: groupOfUniqueNames
cn: Engineer

dn: cn=Commander,ou=groups,dc=exceptionerror,dc=io
objectClass: top
objectClass: groupOfUniqueNames
cn: Commander

dn: cn=Mark Cuban,ou=users,dc=exceptionerror,dc=io
cn: Mark Cuban
gidnumber: 500
givenname: Mark
homedirectory: /home/users/mcuban
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Cuban
uid: mcuban
uidnumber: 1002
userpassword: {MD5}ICy5YqxZB1uWSwcVLSNLcA==

dn: cn=Steve Jobs,ou=users,dc=exceptionerror,dc=io
cn: Steve Jobs
gidnumber: 500
givenname: Steve
homedirectory: /home/users/sjobs
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Jobs
uid: sjobs
uidnumber: 1001
userpassword: {MD5}ICy5YqxZB1uWSwcVLSNLcA==

Now that we have some users and groups time to get ldap connected to keycloak. Below is the settings I have set up for the LDAP adapter. Since I want keycloak to manage LDAP so users can register or edit their passwords


I also wanted to have certain groups do certain things so in the mappings I have added a group mapping


The final is to set a full name mapping to map to the CN attribute.


I also had to set the READ_ONLY Flag on the last name and Frist name to off.

Now if all has gone well users should be able to register and then beable to change their password.

Setting up OpenID

Below is an example for the settings needed to get openid setup for keycloak


In gitea you can add an OAuth2 Source as the keycloak



Services that cant use openid/OAuth2 will have to fall back to using LDAP but I may want certain services such as portainer only allowed to be accessed by users in the admin group. to do this I need some LDAP query magic and was why the groups were set up in LDAP as groupOfUniqueNames was so I can user the ldap query:
To split it up a user must be of type inetOrgPerson and be a memberof the Commander group. In openldap the default setting is to create the memberof mapping for only groupOfUniqueNames.