I am having a lot of difficulties setting up my reverse proxy and reaching the admin console. Can somebody help me or give me any reverse proxy setup that works on their server? Yes, I have looked through other posts here.
I can’t seem to find any example config that adheres to the official recommendations here Using a reverse proxy - Keycloak. I will write down what my tries for a setup that adheres to the official reverse proxy guide, and where my problems are.
This is the summary of what I have observed, and I should note that I use NixOS.
- Everything works fine if I don’t set the headers (
X-Forwarded-*
, etc), but the official recommendations strongly advise to set these headers. - When setting the
proxy_set_header
s (I’ll get to that a bit lower), everything works if I just expose the root directory/
, but obviously that is not very secure. If I put a basic auth infront of the vulnerable locations (which is not an ideal setup anyway), then I also cannot reach the admin console. - If I set the
proxy_set_header
s, and expose only/js/
,/realms/
,/resources/
, and/robots.txt
, and furthermore sethostname-admin
in the keycloak config tolocalhost
, I can’t seem to reach the admin console when I reach it viassh
port forwarding (I usessh -L 8080:localhost:8080 mykeycloak.server
). I get an “invalid parameter: redirect_uri” error. Removing (some of) theproxy_set_header
in the nginx config gives me other problems, like an infinite “Loading the admin console” screen, and when I remove enough of thoseproxy_set_header
s, then it works (as I mentioned in the first bullet point).
I am sorry to say that I am not too knowledgeable about how these headers work.
This is my Keycloak configuration:
db=postgres
db-password=somepassword
db-url-database=keycloak
db-url-host=localhost
db-url-port=5432
db-url-properties=
db-username=keycloak
hostname=mykeycloak.server
hostname-admin=localhost
hostname-strict-backchannel=false
http-host=0.0.0.0
http-port=8080
http-relative-path=/
https-certificate-file=/run/keycloak/ssl/ssl_cert
https-certificate-key-file=/run/keycloak/ssl/ssl_key
https-port=8443
proxy=edge
This is my nginx configuration (yeah sorry I run NixOS so it adds a lot of clutter):
pid /run/nginx/nginx.pid;
error_log stderr;
daemon off;
events {
}
http {
# The mime type definitions included with nginx are very incomplete, so
# we use a list of mime types from the mailcap package, which is also
# used by most other Linux distributions by default.
include /nix/store/<long-nix-store-hash>-mailcap-2.1.53/etc/nginx/mime.types;
# When recommendedOptimisation is disabled nginx fails to start because the mailmap mime.types database
# contains 1026 enries and the default is only 1024. Setting to a higher number to remove the need to
# overwrite it because nginx does not allow duplicated settings.
types_hash_max_size 4096;
include /nix/store/<long-nix-store-hash>-nginx-1.22.1/conf/fastcgi.conf;
include /nix/store/<long-nix-store-hash>-nginx-1.22.1/conf/uwsgi_params;
default_type application/octet-stream;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
proxy_redirect off;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_http_version 1.1;
include /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf;
# $connection_upgrade is used for websocket proxying
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
client_max_body_size 10m;
server_tokens off;
server {
listen 0.0.0.0:443 http2 ssl ;
listen [::0]:443 http2 ssl ;
listen 0.0.0.0:80 ;
listen [::0]:80 ;
server_name mykeycloak.server ;
# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx)
# We use ^~ here, so that we don't check any regexes (which could
# otherwise easily override this intended match accidentally).
location ^~ /.well-known/acme-challenge/ {
root /var/lib/acme/acme-challenge;
auth_basic off;
}
root /var/www/mykeycloak.server;
ssl_certificate /var/lib/acme/mykeycloak.server/fullchain.pem;
ssl_certificate_key /var/lib/acme/mykeycloak.server/key.pem;
ssl_trusted_certificate /var/lib/acme/mykeycloak.server/chain.pem;
location /js/ {
proxy_pass http://localhost:8080/js/;
include /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf;
}
location /realms/ {
proxy_pass http://localhost:8080/realms/;
include /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf;
}
location /resources/ {
proxy_pass http://localhost:8080/resources/;
include /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf;
}
location /robots.txt {
proxy_pass http://localhost:8080/robots.txt;
include /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf;
}
}
}
Important: /nix/store/<long-nix-store-hash>-nginx-recommended-proxy-headers.conf
contains the following:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
Removing the proxy_set_header
s Host
and X-Forwarded-Proto
and X-Real-IP
resolves my issues iirc (removing different ones gives me different issues when trying to reach the admin console), and removing all of it definitely resolves my issues, as mentioned before. But also as mentioned, setting X-Forwarded Proto
was recommended by the official documentation. Also, it recommends setting X-Forwarded-Port
. Furthermore, I have no idea how I would set Forward
as per RFC7239.
Can somebody give me any reverse proxy config that works on their server? I am willing to change the setup, I don’t have any super specific requirements/restrictions.
Any help is appreciated.