Protect your endpoints with Keycloak Security Proxy

Protect your endpoints with Keycloak Security Proxy

When we setup applications in our homelab, there are always some applications do not support authentication or authentication integration.

The solution I was using was Organizr. While it protects your endpoint, it is not the best solution. If you read the source code, it is just matching IP addresses which leads to a lot of problems. Also, it does not redirect you to login page or allow you to setup for remote authentication. It only has limited (admin and user) roles to control access and do not play well with other identity providers, like LDAP.

Requirements

  • Keycloak (Admin privilege)
  • Docker
  • Docker Compose

Keycloak

keycloak

Keycloak is an open source identity and access management application. It has integration with many useful services, including SAML, open ID, LDAP, single sign on, etc.

By using Keycloak, you now only have one place to manage user credentials and users only have to remember one account.

Docker

docker

In this tutorial, we will use Docker to deploy because it is much easier to install and manage applications.

It is still possible to set it up without Docker, but that will not be covered in this tutorial.

Docker Compose

docker compose

Making use of Docker Compose allow us no long need to remember the long docker command. We can even put the file in a version control system.

Let's Start

Configure Keycloak

First, we login to Keycloak with a admin user. Then, we create a client with whoami as Client ID (Any thing you like) and select openid-connect as Client Protocol. We change the Access Type to confidential and add your public url to Valid Redirect URIs, e.g. http://example.com/*. Remember you have to save it. We go to Installation and select Keycloak OIDC JSON as Format Option. We will need it when we configure Keycloak Security Proxy.

{
  "target-url": "http://whoami",
  "bind-address": "0.0.0.0",
  "http-port": "8080",
  "applications": [
    {
      "base-path": "/",
      "adapter-config": {
        "realm": "master",
        "auth-server-url": "http://example.com/auth",
        "ssl-required": "external",
        "resource": "test",
        "credentials": {
          "secret": "6c394787-d92d-46a6-98c9-960a6c2e98c7"
        },
        "confidential-port": 0
      },
      "constraints": [
        {
          "pattern": "/*",
          "roles-allowed": ["user"]
        }
      ]
    }
  ]
}

Configure Keycloak Security Proxy

We will create a configuration file at /home/user/proxy/proxy.json.

All the configuration can be found here.

  • target-url: This the address to proxy. We use whoami because we are going to to deploy a container with a hostname of whoami.
  • bind-address: It needs to be 0.0.0.0 in order to listen request from outside.
  • http-port: The port that it listen to. This does not matter as we have to map it on Docker again.
  • base-path: Base path of the application. Since we only have 1 application, we use /.
  • adapter-config: This is generated from Keycloak. Paste the configuration from previous section.
  • constraints: Constraints for accessing the application. In this example, all paths can only be access if they have have user role.

I have came across a problem that Keycloak is redirecting to HTTP instead of HTTPS which causes mixed content issue. I found an answer on StackOverflow that you can add.

"proxy-address-forwarding" : true

Configure Docker Compose

Then, we create the following docker-compose.yml.

version: "3"

services:
  whoami:
    image: emilevauge/whoami
  proxy:
    image: jboss/keycloak-proxy
    ports:
      - 80:8080
    volumes:
      - /home/user/proxy/proxy.json:/opt/jboss/conf/proxy.json

Run it

We start it up with

docker-compose up -d

When you try to access it without login, it will redirect you to Keycloak login page. If you logined but you do not match the constraints, you will get a 403 response. If you have logged in and you match the constraints, you can just use it normally.