keycloak / keycloak

Open Source Identity and Access Management For Modern Applications and Services
https://www.keycloak.org
Apache License 2.0
22.83k stars 6.69k forks source link

Keycloak 25.0.0 in Docker using --proxy-headers=xforwarded: Failed to parse a port from "forwarded"-type headers #30853

Closed baconsplit closed 3 months ago

baconsplit commented 3 months ago

Before reporting an issue

Area

dist/quarkus

Describe the bug

Hey! I am currently using the Keycloak 25.0.0 Docker Image from quay.io and have it configured to use a reverse proxy. I configured Keycloak with parameters --proxy-headers=xforwarded --http-enabled=true --hostname=example.org The reverse proxy is another Docker Container with HAProxy 2.4.0 and uses following configuration in the haproxy.cfg to set xforwarded headers for keyclaok:

    http-request set-header X-Forwarded-Port 443
    http-request set-header X-Forwarded-For %[req.hdr(Host)]
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
    http-request set-header X-Forwarded-Host %[req.hdr(Host)]
    server keycloak keycloak:8080 check

A more detailed confiuration can be seen in "How to Reproduce?"

So I think my HAProxy only sets xforwarded headers but keycloak tries to parse a "forwarded" header all the time. I am

  1. not sure if keycloak really differentiates between a "forwarded" and "xforwarded" header in the log message, or if it means a header that has been forwarded in general.
  2. unsure if the error comes from my proxy configuration, because I tried pretty much every settings possible in there, including not setting any header at all, making my keycloak not reachable but the container still logging that same error message.

If 1. applies, how can I makes sure my HAProxy does not send any forwarded-type headers? If 2. applies, how can I find out where the forwarded-type header comes from or what/which one it is?

Version

25.0.0

Regression

No, in my previous keycloak version 20.0.3 this log also occured, but without the fallback information "... using the default port -1". The HAProxy configuration stayed the same.

Expected behavior

No error logs. Especially not a log trying to parse a port from a "forwarded"-type header, when using the --proxy-headers=xforwarded, so no forwarded-type header should be used or expected.

Actual behavior

Keycloak tries to parse a port from a "forwarded"-type header and fails, resulting in an reoccurring error log.

image

How to Reproduce?

frontend localhost bind *:443 option tcplog mode tcp tcp-request inspect-delay 5s tcp-request content accept if { req_ssl_hello_type 1 } use_backend nodes if { req_ssl_sni -i unrelated.domain.example.org } default_backend bk_tcp_to_https

backend bk_tcp_to_https mode tcp option tcplog server haproxy 0.0.0.0:8443 check

frontend SSL_Termination mode http bind *:8443 ssl crt /path/to/certs/cert.pem use_backend keycloak if { hdr(host) -i keycloak.example.org }

backend keycloak mode http http-request set-header X-Forwarded-Port 443 http-request set-header X-Forwarded-For %[req.hdr(Host)] http-request set-header X-Forwarded-Proto https if { ssl_fc } http-request set-header X-Forwarded-Proto http if !{ ssl_fc } http-request set-header X-Forwarded-Host %[req.hdr(Host)]

server keycloak keycloak:8080 check


- Start both containers and check the logs of the keycloak container as soon as it fully started.

### Anything else?

Sorry if these are a lot of configurations not _directly_ connected to keycloak, but keycloak offers the option to use a reverse proxy to reach it, which I did, and I think that is where the problem comes from.
jonkoops commented 3 months ago

@baconsplit can you confirm this is still an issue in 25.0.1?

baconsplit commented 3 months ago

I just updated the image and can confirm, I see the same logs: image

This is the information I get on /realms/master/hostname-debug: image

The redacted stuff can all be replaced with "keycloak.example.org"

baconsplit commented 3 months ago

I've stopped my HAProxy Container to see if the logs still occur, and unfortunately they still appear. Even when recreating the keycloak container (with same proxy configuration, thus not reachable like that).

So I can only guess these logs result from my combination of start parameters with --proxy-headers=xforwarded etc.

vmuzikar commented 3 months ago

@baconsplit Do you mean the error appears even if you access Keycloak directly without the proxy?

baconsplit commented 3 months ago

@vmuzikar the error appears without accessing Keycloak at all. I don't think I have any service or component left, which tries to access the container. It is one of the first logs that start to appear once Keycloak started a fresh configuration.

vmuzikar commented 3 months ago

@baconsplit Are you able to reproduce it with a fresh Keycloak install?

baconsplit commented 3 months ago

grafik

after getting some sleep and checking my docker-compose configuration again, I noticed the error log comes from my healtchecks within the Docker container. Sorry for the misleading issue, but if I am here already, is there a alternative way I could check within the container if the keycloak service is running (without curl)?

baconsplit commented 3 months ago

test: [ "CMD-SHELL", "if (echo > /dev/tcp/127.0.0.1/8080) &> /dev/null; then echo \"Connection successful\"; fi" ]

Figured this out and seems to work, cheers!

mabartos commented 3 months ago

@baconsplit In Keycloak 25, the management interface was introduced, which is enabled by default and provides the ability to access health checks on it. It means when you have enabled health checks, you can access them on localhost:9000/health. I think it'd be a better solution.