I wanted to test setting up an on premise identity provider and see if I can build my own SSO solution.
Found that the easiest way to do this is to use Keycloak.
Keycloak is a feature rich identity access management system that supports various integration protocols, among those, SAML 2.0 and OpenID connect.
Keycloak can also connect to existing IDPs and LDAP user directories to allow more flexible setups.
To install Keycloak using you can download it from its official download page: https://www.keycloak.org/downloads or use a docker image.
To use docker, we need to pull the official image from the official docker repo:
docker pull jboss/keycloak
Once we have the image, you can run keycloak using below simple docker run:
This will start keycloak and expose port 8080 and 8443 to the docker host, then using docker exec, we run the script add-user-keycloak.sh to add an admin user.
In our use case here, we will start keycloak using a bigger set of options to allow it to interact with a docker network, import a realm, that was saved from a previous setup, add admin user directly from docker run command and add reverse proxy forwarding options.
But first, we create a docker bridge network:
[root@Fingon ~]# docker network create --subnet=172.28.0.0/16 --gateway=172.28.0.1 dcnet
And then the docker run script looks like this:
docker run \
-e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin \
-e PROXY_ADDRESS_FORWARDING=true \
-e KEYCLOAK_IMPORT=/tmp/realm-export.json \
-v /tmp/realm-export.json:/tmp/realm-export.json \
--network dcnet \
--hostname keycloak2 \
--ip 172.28.0.13 \
--add-host fingon:172.17.0.1 \
--add-host fingon:172.28.0.1 \
--add-host dcnode2:172.28.0.12 \
--add-host dcnode1:172.28.0.11 \
--add-host keycloak2:172.28.0.13 \
--dns 8.8.4.4 \
--dns 8.8.8.8 \
--dns 172.28.0.1 \
--name="keycloak2" -d -p 8181:8080 -p 9443:8443 jboss/keycloak
And once the container us up, we can see it with docker ps:
[root@Fingon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3402c1b4163e jboss/keycloak "/opt/jboss/tools/do…" 21 hours ago Up 3 seconds 0.0.0.0:8181->8080/tcp, 0.0.0.0:9443->8443/tcp keycloak2
[root@Fingon ~]#
We can now access keycloak from host machine using the URL http://localhost:8181/auth/ or https://localhost:9443/auth/
To expose keycloak to outside network and use proper SSL configuration, we then need to use a reverse proxy, in this case we use Nginx.
The Nigix configuration will look like this:
[root@Fingon nginx]# cat nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_authorization"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://fingon$request_uri;
}
# Settings for a TLS enabled server.
#
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/root/cert.crt";
ssl_certificate_key "/root/key.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
location /auth/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8181/auth/;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@Fingon nginx]#
Now the UI looks like below:

You can access keycloak on https only using the URL https://fingon/auth.
Any requests to http will be redirected to https.
On Nginx, we need to set the host, x-forwarded-for and x-forwarded-proto headers so that keycloak identifies it is working behind a reverse proxy and does a proper redirection.
More information can be found in keycloak documentation.
Now we are ready to do more keycloak configurations ☺
Found that the easiest way to do this is to use Keycloak.
Keycloak is a feature rich identity access management system that supports various integration protocols, among those, SAML 2.0 and OpenID connect.
Keycloak can also connect to existing IDPs and LDAP user directories to allow more flexible setups.
To install Keycloak using you can download it from its official download page: https://www.keycloak.org/downloads or use a docker image.
To use docker, we need to pull the official image from the official docker repo:
docker pull jboss/keycloak
Once we have the image, you can run keycloak using below simple docker run:
docker run -p 8080:8080 -p 8443:8443 jboss/keycloak
docker exec <CONTAINER> /opt/jboss/keycloak/bin/add-user-keycloak.sh -u <USERNAME> -p <PASSWORD>
This will start keycloak and expose port 8080 and 8443 to the docker host, then using docker exec, we run the script add-user-keycloak.sh to add an admin user.
In our use case here, we will start keycloak using a bigger set of options to allow it to interact with a docker network, import a realm, that was saved from a previous setup, add admin user directly from docker run command and add reverse proxy forwarding options.
But first, we create a docker bridge network:
[root@Fingon ~]# docker network create --subnet=172.28.0.0/16 --gateway=172.28.0.1 dcnet
And then the docker run script looks like this:
docker run \
-e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin \
-e PROXY_ADDRESS_FORWARDING=true \
-e KEYCLOAK_IMPORT=/tmp/realm-export.json \
-v /tmp/realm-export.json:/tmp/realm-export.json \
--network dcnet \
--hostname keycloak2 \
--ip 172.28.0.13 \
--add-host fingon:172.17.0.1 \
--add-host fingon:172.28.0.1 \
--add-host dcnode2:172.28.0.12 \
--add-host dcnode1:172.28.0.11 \
--add-host keycloak2:172.28.0.13 \
--dns 8.8.4.4 \
--dns 8.8.8.8 \
--dns 172.28.0.1 \
--name="keycloak2" -d -p 8181:8080 -p 9443:8443 jboss/keycloak
And once the container us up, we can see it with docker ps:
[root@Fingon ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3402c1b4163e jboss/keycloak "/opt/jboss/tools/do…" 21 hours ago Up 3 seconds 0.0.0.0:8181->8080/tcp, 0.0.0.0:9443->8443/tcp keycloak2
[root@Fingon ~]#
We can now access keycloak from host machine using the URL http://localhost:8181/auth/ or https://localhost:9443/auth/
To expose keycloak to outside network and use proper SSL configuration, we then need to use a reverse proxy, in this case we use Nginx.
The Nigix configuration will look like this:
[root@Fingon nginx]# cat nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$http_authorization"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://fingon$request_uri;
}
# Settings for a TLS enabled server.
#
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/root/cert.crt";
ssl_certificate_key "/root/key.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
location /auth/ {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8181/auth/;
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
[root@Fingon nginx]#
Now the UI looks like below:

You can access keycloak on https only using the URL https://fingon/auth.
Any requests to http will be redirected to https.
On Nginx, we need to set the host, x-forwarded-for and x-forwarded-proto headers so that keycloak identifies it is working behind a reverse proxy and does a proper redirection.
More information can be found in keycloak documentation.
Now we are ready to do more keycloak configurations ☺
No comments:
Post a Comment