How do you correctly configure NGINX as a proxy in front of Keycloak?
Asking & answering this as doc because I've had to do it repeatedly now and forget the details after a while.
This is specifically dealing with the case where Keycloak is behind a reverse proxy e.g. nginx and NGINX is terminating SSL and pushing to Keycloak. This is not the same issue as keycloak Invalid parameter: redirect_uri although it produces the same error message.
The key to this is in the docs at https://www.keycloak.org/docs/latest/server_installation/index.html#identifying-client-ip-addresses
The proxy-address-forwarding
must be set as well as the various X-...
headers.
If you're using the Docker image from https://hub.docker.com/r/jboss/keycloak/ then set the env. arg -e PROXY_ADDRESS_FORWARDING=true
.
server {
server_name api.domain.com;
location /auth {
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_pass http://localhost:8080;
proxy_read_timeout 90;
}
location / {
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_pass http://localhost:8081;
proxy_read_timeout 90;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.domain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.domain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = api.domain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name api.domain.com;
listen 80;
return 404; # managed by Certbot
}
If you're using another proxy the important parts of this is the headers that are being set:
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;
Apache, ISTIO and others have their own means of setting these.
The answer above deals with configuration done to the proxy.
In what respects the keycloak container, if you are getting the redirect_uri error when trying to log into the admin console, there are two environment variables that have to be set for Keycloak (as of version 10.0.2) to work behind a reverse proxy.
If the URL of the admin console is https://your.fqdn/auth then you must set:
KEYCLOAK_FRONTEND_URL = https://your.fqdn/auth
along with the above-mentioned:
PROXY_ADDRESS_FORWARDING = true
Below is a minimal docker-compose.yml that will launch keycloak 10 behind a reverse proxy that forwards requests to https://your.fqdn onto the docker hosts's port 8000. Just set the variables KEYCLOAK_ADMIN_PWD
and PG_KC_PASS
in the environment (or .env file) when launching, according to your wishes.
version: '3'
volumes:
pgkeycloak-data:
services:
pg-keycloak:
image: "postgres:12-alpine"
container_name: pg-keycloak
volumes:
- "pgkeycloak-data:/var/lib/postgresql/data"
restart: always
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloakdb
POSTGRES_PASSWORD: ${PG_KC_PASS}
auth:
user: root
privileged: true
image: "quay.io/keycloak/keycloak:10.0.2"
depends_on:
- "pg-keycloak"
restart: always
ports:
- 8000:443
command:
-Djboss.http.port=443
-Djboss.bind.address=0.0.0.0
environment:
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: ${KEYCLOAK_ADMIN_PWD}
KEYCLOAK_FRONTEND_URL: https://your.fqdn/auth
PROXY_ADDRESS_FORWARDING: "true"
DB_USER: keycloakdb
DB_PASSWORD: ${PG_KC_PASS}
DB_ADDR: pg-keycloak
DB_VENDOR: postgres
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With