User Tools

Site Tools


linux_server_manuals:docker_keycloak_container_with_local_postgresql

Install Keycloak as Docker Container with Apache Web Server as Reverse Proxy and a local PostgreSQL

Keycloak is an Identity and Access management solution. Which supports SSO (Single Sign on), i.e. if you have several webpages (services) to which you need to authenticate, it is enough if you authenticate only to one of them, and then you are automatically authenticated to all of them. The SSO Identity Providers of keycloak are SAML 2.0 and OpenID Connect, CAS can be added over a plugin. For more details see http://www.keycloak.org/about.html. Since a lot of application which support those protocols, don't support groups or similar stuff, and mostly mail servers won't support the above SS= protocols, we can also install an LDAP server and let Keycloak write to it. But that is part of an other manual.

Keycloak doesn't exist as a package for Debian, and installing and updating it manually is a literal pain in the ass, so that why this manual will first install Docker and then Keycloak as Docker container in Debian Stretch (9). Then connect to a local (not Docker!) Postgresql instance and store all its data there, and finally use Apache as reverse proxy so the internet is able to find our Keycloak instance. If there is a new Version of Keycloak, only the Docker Image needs to be updated and the Docker contrainer recreated, and everything will work as before. Piece of cake. The only thing you don't get like that are automatic security updates for keycloak :-( but still for all the other components of the system.

We assume that the server we install everything on, is available as example.com

Install Docker

First, install Docker.

aptitude install apt-transport-https curl gnupg2 software-properties-common

curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | apt-key add -

add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
   $(lsb_release -cs) \
   stable"

aptitude update

aptitude install docker-ce

Install Keycloak Container

Get the official Keycloak image:

docker pull jboss/keycloak

Mysql Connection

It would be possible to us mysql (Maria db) as database. But the first try didn't succeed. Keycloak failed to create it's tables (or insert some data). As it seems it it is some problem with the UTF8 encoding in MySql… Since I really didn't feel like fighting around with that kind of crap, I just went over to directly use Postgresql which I prefer anyway. Here are just the very rough steps which would be needed to do it with MySql. But it won't work ;-) , at least not on 2018-01-05. Maybe later on somebody does some updates…

aptitude install mysql

Change mysql config to bind to docker nic.

bind-address 172.17.0.1

Connect to mysql and create database:

CREATE USER 'keycloak' IDENTIFIED BY 'keycloak';
create database keycloak;

GRANT ALL PRIVILEGES ON keycloak.* TO 'keycloak';

Then create the container:

docker run --name keycloak -e MYSQL_PORT_3306_TCP_PORT=3306 -e MYSQL_PORT_3306_TCP_ADDR="172.17.0.1" -e MYSQL_DATABASE="keycloak" -e MYSQL_USER="keycloak" -e MYSQL_PASSWORD="keycloak" -e PROXY_ADDRESS_FORWARDING=true jboss/keycloak

Then see the error messages, investigate 3 minutes and give up ;-) .

Keycloak PostgreSQL Connection

We use a locally installed PostgreSQL instance, since I prefer when I can do updates and everything the Debian way. Especially getting automatic security updates. It's also easier since in other programmes I can just write, connect to localhost. Done… As it seems the default ip address the Docker Network interface gets is 172.17.0.1. So that's where we need to make postgresql listen on.

aptitude install postgresql

Edit file /etc/postgresql/9.6/main/pg_hba.conf and add following line to give that subnet permission to connect to postgresql:

host    all             all             172.17.0.1/16        md5

Edit /etc/postgresql/9.6/main/postgresql.conf and change the listening address:

listen_addresses = 'localhost, 172.17.0.1'
systemctl restart postgresql

Connect to postgresql using psql and create database:

create user keycloak password 'myPw';

create database keycloak owner keycloak;

Then create the docker image, and tell it to connect to our local postgresql instance. The following command will make keycloak listen on localhost on port 8081. Change that if you don't like it. The “JAVA_OPTS” settings gives keycloak a bit more memory than the default 512mb. If you are happy with the default settings, leave the parameter away.

docker run --name keycloak --restart=always -p 127.0.0.1:8081:8080 -e JAVA_OPTS="-Xms64m -Xmx1024m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true" -e POSTGRES_PORT_5432_TCP_ADDR=172.17.0.1 -e POSTGRES_PORT_5432_TCP_PORT=5432 -e POSTGRES_DB="keycloak" -e POSTGRES_USER="keycloak" -e POSTGRES_PASSWORD="myPw" -e PROXY_ADDRESS_FORWARDING=true jboss/keycloak

For newer versions of Keycloak we need:

docker run --name keycloak --restart=always -p 127.0.0.1:8081:8080 -e JAVA_OPTS="-Xms64m -Xmx1024m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true" -e KEYCLOAK_HOSTNAME="auth.example.com" -e DB_VENDOR="postgres" -e DB_ADDR=172.17.0.1 -e DB_PASSWORD="myPw" -e PROXY_ADDRESS_FORWARDING=true jboss/keycloak

Check that there are no error messages! (We don't care about warnings (at least not the ones I've got, maybe you have more important ones)).

We need to add a first admin password, do that by executing in another console:

docker exec keycloak keycloak/bin/add-user-keycloak.sh -u admin -p keycloakadminpw

restart container!

docker restart keycloak

Now, the Keycloak container should be working. If there are any problems, you can see the log files of keycloak with:

docker logs keycloak

Before setting a new admin password, or any password at all in keycloak, you probably first want to go to “Authentication/Password Policy” and there add the policy “Hashing Algorithm”, so the passwords will be saved as Hashes to the Database. If you don't know why you should do that, you probably shouldn't be installing an identity management software ;-) .

Test it and immediately change the admin password you've set above over an ssh tunnel to localhost:8081. In your local browser connect to localhost:8081 (or whatever port you are forwarding), go to the administration console, then users. Read the Keycloak manual if you need more infos ;-) . You can skip that step (for example if you don't know what a ssh tunnel is, but I recommend you to learn about it), and first prepare the reverse proxy, as described further down, but latest then you should choose immediately a good password.

Start Postgresql after Docker on boot

Docker and the contrainer Keyclok will be automatically started on boot. But unfortunately after postgresql, so postgresql will not be able to bind to the docker network interface. so we override the template for all postgresql services.

systemctl edit postgresql@

In the editor that was opened enter:

[Unit]
After=docker.service

Exit and save.

Keycloak will now be started on boot of the computer, and is available under:

localhost:8081 and also under it's docker interface 172.17.0.x:8080, which we won't use ;-) .

If you want to integrate Keycloak with a LDAP directory, and want to maintain users in Keycloak, then you should configure the LDAP federation before adding any users to a new realm. See Setup openLDAP and integrate it with Keycloak

Create new Realm with realm admin

This step here is optional. For your users you shouldn't use the master realm, but create a new one, like “example.com”. If you want you can create a user in that realm, which is admin of that realm, that means he can change all the realm settings, create new users, and so on. So you won't need to use the master realm admin, which can do everything in all the realms.

Therefore create a new role with name “realmadmin”. Klick on save, so that all the possible settings appear. Then activate composite roles and choose in the combobox client roles the role realm-management and associate all available roles.

Now you can create a group and add the role realmadmin, all the users which are member of that group, will be realm-admins. You could also just add the role directly to a user.

Install apache as reverse proxy to access Keycloak

Since we need keycloak to be available to the internet. We use a reverse proxy on our host example.com so we can access keycloak from outside.

Setup apache and letsencrypt

We will install apache2, use let's encrypt to get ssl certificate, and then use the reverse proxy to access keycloak.

aptitude install apache2 python-certbot-apache

We copy the default apache config to two new config files. One will be for our main domain example.com, and the other one for the subdomain auth.example.conf which we will use the access keycloak. It is also possible to do it, without using a subdomain for keycloack. Therefore just leave everything away, that has to do with auth.example.com.

cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/auth.example.com.conf

edit those config files, and set the ServerName directive respectively.

ServerName example.com
------
ServerName auth.example.com

Then execute

a2dissite 000-default.conf
a2ensite example.com.conf auth.example.com.conf
systemctl restart apache2

Update your dns entries. (make auth.example.com a cname for example.com).

Execute certbot and choose all domain entries and tell him not to allow http (most propably you don't want that), it will automatically create the correct ssl sites then.

certbot

Setup reverse proxy

Enable necessary modules:

a2enmod proxy_http headers

Edit auth.example.com-le-ssl.conf and add following lines:

        # That exception is needed, so let's encrypt certificate renewal will work
        ProxyPass /.well-known !
        # forward everything else to the docker container.
        ProxyPass / http://localhost:8081/
        ProxyPassReverse / http://localhost:8081/

        #don't change destination server to localhost, otherwise replies from keycloak wont work
        ProxyPreserveHost On
        # so keycloak know it's an https connection
        RequestHeader set X-Forwarded-Proto "https"

If you want to use it without an extra sub domain, but access keycloak directly over example.com/auth, edit the file example.com-le-ssl.conf and add following:

    <Location /auth>
        ProxyPass http://localhost:8081/auth
        ProxyPassReverse http://localhost:8081/auth
        #don't change destination server to localhost, otherwise replies from keycloak wont work
        ProxyPreserveHost On
        RequestHeader set X-Forwarded-Proto "https"
    </Location>
You could leave a comment if you were logged in.
linux_server_manuals/docker_keycloak_container_with_local_postgresql.txt · Last modified: 2019/04/03 17:51 by ronney