Using Keycloak behind Kong proxy - redirection issue

Hello everyone,

I’m trying to setup a Keycloak instance to handle the users of my webapp. This instance would be, like all other microservices, hidden behind my reverse proxy (Kong, it’s a nginx-based proxy).

On my local setup, Kong listens to localhost:443, and keycloak listens to localhost:8082/auth. To achieve that, I used several environment variables on my Keycloak container :

ENV KC_HOSTNAME=localhost
ENV KC_HOSTNAME_PORT=8082
ENV KC_HOSTNAME_STRICT_HTTPS=false
ENV KC_PROXY=edge
ENV PROXY_ADDRESS_FORWARDING=true
ENV KC_HTTP_ENABLED=true
ENV KC_HTTP_PORT=8082
KC_HTTP_RELATIVE_PATH=/auth

The setup of Kong configuration looks fine, and the keycloak endpoints that I need are exposed correctly through Kong (/realms, /js, /resources, /robots.txt, like the doc said). Kong handles the TLS connection, and then speaks to all microservices with HTTP only, thus KC_PROXY=edge. /admin is not exposed, I thought I could access this locally using localhost:8082 on the right machine.
I checked, Kong is accurately sending additionnal headers :

  'x-forwarded-for'
  'x-forwarded-proto'
  'x-forwarded-host'
  'x-forwarded-port'
  'x-forwarded-path'
  'x-forwarded-prefix'

It also leaves the Host untouched.

If I go to https://localhost/auth/realms/master/.well-known/openid-configuration, I get the configuration. However, Keycloak does not know it’s behind Kong, so all endpoints contains localhost:8082. That seems normal, since it’s how I set it up in the first place.

I tried to add a new realm with a different Frontend URL, calling it https://myapp.com Now, my openid configuration contains https://myapp.com:8082/... everywhere. All the workflows get wrongs URLs. What did I miss ? I cannot remove this port that I put in the first place, otherwise I will not be able to access the admin console. I thought I could do something with KC_HOSTNAME_ADMIN, but unfortunately there is no KC_HOSTNAME_ADMIN_PORT… or is there ?

I tried another approach : giving the port 443 instead of 8082. I had to fight all the way to achieve this :

  • Rewriting Kong’s x-forwarded-port thanks to this post
  • add a /conf/quarkus-properties containing quarkus.http.proxy.enable-forwarded-host=true thanks to this post
  • Use 17.0.0 instead of latest tag. This is actually the most important thing.
  • Tested tons of environment variables, proxy modes, etc.

At this point, I don’t even know what made it work, but it seems to work. The probleme is, I was obliged to expose /admin endpoint on Kong, because localhost:8082 does not work anymore (of course :slight_smile:). Maybe this approach is better, but I’m still missing something ?

Thank you for reading :slight_smile:

Hi,

KC_HOSTNAME settings are a way to force keycloak to know that it would be called by external clients using that hostname and port.

In other words, KC_HOSTNAME_* should be set to what your clients use to call keycloak, not what hostname and port keycloak is serving requests. Example:

Keycloak is running on 10.20.30.40:8443, but is behind a reverse proxy. External clients call keycloak using the URL exposed via reverse proxy: https://myapp.com:9090/, so you’ll either:

  • tell keycloak to trust the reverse proxy on checking the host header and handling TLS connections (KC_PROXY=edge and don’t set any KC_HOSTNAME_*) or
  • tell keycloak that it is to be called using that hostname (KC_HOSTNAME=myapp.com) and port (KC_HOSTNAME_PORT=9090) (no need to set KC_HOSTNAME_PORT=443 when port is 443 as that is implied for https).

In your case, the settings you need are:

# to allow http://myapp.com (not https). should not use in production.
ENV KC_HOSTNAME_STRICT_HTTPS=false

#  trust the reverse proxy on hostname, port and TLS termination
ENV KC_PROXY=edge

ENV KC_HTTP_RELATIVE_PATH=/auth

Hello,

Thank you SO MUCH for this response. The thing is, I tried this already so many times, but for whatever reason keycloak was telling me that this variable was mandatory when I went from start-dev to start.
Anyway, now it works perfectly. I even could use 18.0.0 again ! There is something fishy about this.

Again, thank you :slight_smile:

Antoine