我遇到的情况是,我在终止安全 (https) 连接的反向代理后面运行 Keycloak 18.0.0。因此我想构建一个 Docker 镜像,将 Keycloak 配置为仅侦听 http(例如端口 8080)。
我已经调整了
Keycloak 文档中的
Dockerfile
。它使用
--proxy=edge
选项(请参阅代理模式)。FROM quay.io/keycloak/keycloak:18.0.0 as builder
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_DB=mariadb
# Install custom providers
RUN curl -sL https://github.com/aerogear/keycloak-metrics-spi/releases/download/2.5.3/keycloak-metrics-spi-2.5.3.jar -o /opt/keycloak/providers/keycloak-metrics-spi-2.5.3.jar
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:18.0.0
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]
然后我使用
构建我的 Docker 镜像docker build --no-cache . -t ghcr.io/saw303/zscsupporter-be/keycloak-18.0.0:0.0.1
并在我的 Docker Composition 中启动镜像。
version: "3.9"
services:
proxy:
image: caddy:2.5.1-alpine
ports:
- "${PROXY_IP}:80:80"
- "${PROXY_IP}:443:443"
volumes:
- ${BASE_PATH:-.}/docker-volume/caddy/Caddyfile:/etc/caddy/Caddyfile:Z
- ${BASE_PATH:-.}/docker-volume/caddy/caddy_data:/data:Z
- ${BASE_PATH:-.}/docker-volume/caddy/caddy_config:/config:Z
keycloak:
image: ghcr.io/saw303/zscsupporter-be/keycloak-18.0.0:0.0.1
ports:
- "127.0.0.1:9001:8080"
- "127.0.0.1:9443:8443"
environment:
KC_HOSTNAME: localhost
KC_HOSTNAME_PORT: 80
KC_HOSTNAME_STRICT_BACKCHANNEL: true
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB_URL: jdbc:mariadb://keycloakdb:3306/keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: secret
KC_LOG_LEVEL: info
KC_PROXY: edge
keycloakdb:
image: mariadb:10.7.3-focal
environment:
MYSQL_ROOT_PASSWORD: root_secret
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: secret
TZ: "Europe/Zurich"
tmpfs:
- /var/lib/mysql:rw
ports:
- "127.0.0.1:3307:3306"
当我使用
启动 Docker 组合时docker compose up -d && docker compose logs -f keycloak
我收到以下日志语句,明确指出它使用严格 HTTPS。
backend-keycloak-1 | 2022-05-29 17:37:46,922 INFO [org.keycloak.quarkus.runtime.hostname.DefaultHostnameProvider] (main) Hostname settings: FrontEnd: localhost, Strict HTTPS: true, Path: <request>, Strict BackChannel: false, Admin: localhost, Port: 8,080, Proxied: true
当我访问管理控制台时
http://localhost:9001/admin/master/console/
我得到一个空白页面,管理控制台仅向
发送一个请求http://localhost:9001/admin/master/console/config
返回错误的 URL
https:
。
{
"realm": "master",
"auth-server-url": "https://localhost:8080/",
"ssl-required": "external",
"resource": "security-admin-console",
"public-client": true,
"confidential-port": 0
}
有没有办法将字段值
auth-server-url
中的协议从https
更改为http
?
更新1:代理配置
我使用 Caddy Server 2.0 作为反向代理。在此测试中,设置 caddy 是 Docker 组合的一部分,只需将端口
80
上的所有请求重定向到端口 keycloak
上的 8080
容器。
{
admin off
}
localhost:80
reverse_proxy /* keycloak:8080
log
请注意,无论我通过反向代理
localhost:80
还是直接localhost:9001
访问Keycloak管理控制台,行为都是相同的。当我通过代理访问时,当然要更改端口值KC_HOSTNAME_PORT: 80
。
更新2:在docker-compose.yml中设置KC_PROXY
KC_PROXY
环境变量现在设置在 docker-compose.yml
中,但行为是相同的。当我跳入正在运行的 keycloak
容器时,我看到以下活动配置
➜ docker compose exec keycloak bash
WARN[0000] The "PROXY_IP" variable is not set. Defaulting to a blank string.
WARN[0000] The "PROXY_IP" variable is not set. Defaulting to a blank string.
bash-4.4$ bin/kc.sh show-config
Current Mode: none
Runtime Configuration:
kc.cache = ispn (PersistedConfigSource)
kc.config.args = show-config (SysPropConfigSource)
kc.db = mariadb (PersistedConfigSource)
kc.db.password = secret (EnvConfigSource)
kc.db.url = jdbc:mariadb://keycloakdb:3306/keycloak (EnvConfigSource)
kc.db.username = keycloak (EnvConfigSource)
kc.health-enabled = true (PersistedConfigSource)
kc.home.dir = /opt/keycloak/bin/../ (SysPropConfigSource)
kc.hostname = localhost (EnvConfigSource)
kc.hostname.port = 80 (EnvConfigSource)
kc.hostname.strict.backchannel = true (EnvConfigSource)
kc.http-enabled = false (PropertiesConfigSource[source=jar:file:///opt/keycloak/lib/lib/main/org.keycloak.keycloak-quarkus-server-18.0.0.jar!/META-INF/keycloak.conf])
kc.http-relative-path = / (PersistedConfigSource)
kc.log-console-output = default (PropertiesConfigSource[source=jar:file:///opt/keycloak/lib/lib/main/org.keycloak.keycloak-quarkus-server-18.0.0.jar!/META-INF/keycloak.conf])
kc.log-file = /opt/keycloak/bin/../data/log/keycloak.log (PropertiesConfigSource[source=jar:file:///opt/keycloak/lib/lib/main/org.keycloak.keycloak-quarkus-server-18.0.0.jar!/META-INF/keycloak.conf])
kc.log.level = info (EnvConfigSource)
kc.metrics-enabled = true (PersistedConfigSource)
kc.provider.file.keycloak-metrics-spi-2.5.3.jar.last-modified = 1653899384311 (PersistedConfigSource)
kc.proxy = edge (EnvConfigSource)
kc.quarkus-properties-enabled = false (PersistedConfigSource)
kc.show.config = none (SysPropConfigSource)
kc.version = 18.0.0 (SysPropConfigSource)
有趣的是,它表明http已禁用。
kc.http-enabled = false (PropertiesConfigSource[source=jar:file:///opt/keycloak/lib/lib/main/org.keycloak.keycloak-quarkus-server-18.0.0.jar!/META-INF/keycloak.conf])
通过将反向代理配置为使用自签名证书,我设法在
localhost
上启动并运行它。
{
admin off
}
localhost:443 {
reverse_proxy keycloak:8080
tls internal
}
log
Caddy 的神奇之处在于声明
tls internal
。
之后我将我的
Dockerfile
更改为这个
FROM quay.io/keycloak/keycloak:18.0.0 as builder
ENV KC_HEALTH_ENABLED=true
ENV KC_METRICS_ENABLED=true
ENV KC_FEATURES=token-exchange
ENV KC_DB=mariadb
RUN curl -sL https://github.com/aerogear/keycloak-metrics-spi/releases/download/2.5.3/keycloak-metrics-spi-2.5.3.jar -o /opt/keycloak/providers/keycloak-metrics-spi-2.5.3.jar
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:18.0.0
COPY --from=builder /opt/keycloak/ /opt/keycloak/
WORKDIR /opt/keycloak
ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]
和我的
docker-compose.yml
相应。
version: "3.9"
services:
proxy:
image: caddy:2.5.1-alpine
ports:
- "${PROXY_IP}:80:80"
- "${PROXY_IP}:443:443"
volumes:
- ${BASE_PATH:-.}/docker-volume/caddy/Caddyfile:/etc/caddy/Caddyfile:Z
- ${BASE_PATH:-.}/docker-volume/caddy/caddy_data:/data:Z
- ${BASE_PATH:-.}/docker-volume/caddy/caddy_config:/config:Z
keycloak:
image: ghcr.io/saw303/zscsupporter-be/keycloak-18.0.0:0.0.1
ports:
- "127.0.0.1:9443:8443"
restart: unless-stopped
environment:
KC_DB_URL: jdbc:mariadb://keycloakdb:3306/keycloak
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_HOSTNAME: localhost
KC_HOSTNAME_STRICT: false
KC_HTTP_ENABLED: true
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: secret
KC_LOG_LEVEL: debug
KC_PROXY: edge
keycloakdb:
image: mariadb:10.7.3-focal
environment:
MYSQL_ROOT_PASSWORD: root_secret
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: secret
TZ: "Europe/Zurich"
tmpfs:
- /var/lib/mysql:rw
ports:
- "127.0.0.1:3307:3306"
deploy:
resources:
limits:
cpus: "1.0"
memory: 200M
完成此配置后,对 Keycloak 管理控制台的访问终于可以使用了。似乎无法使用非安全连接访问管理控制台。
您的 Keycloak 实例似乎未使用
--proxy=edge
配置。
尝试官方文档语法:
--proxy edge
(当然翻译为 Dockerfile 语法)或更简单的选项是设置 Keycloak 容器环境变量 KC_PROXY: edge
使用最新版本导致了我的问题。以下配置在我的 docker-compose 文件中解决了这个问题:
keycloak:
image: quay.io/keycloak/keycloak:22.0
command: start-dev
environment:
KC_CREATE_ADMIN_USER: true
KC_HOSTNAME: localhost
KC_HOSTNAME_DEBUG: true
KC_HOSTNAME_STRICT: false
KC_HOSTNAME_PORT: 8080
KC_HOSTNAME_STRICT_BACKCHANNEL: true
KC_HOSTNAME_ADMIN: localhost
KC_HTTP_ENABLED: true
KC_HOSTNAME_STRICT_HTTPS: false
KC_PROXY: edge
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: admin
KC_DB: postgres
KC_DB_URL_HOST: postgresql
KC_DB_SCHEMA: kc
KC_DB_URL_DATABASE: keycloak
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak
KC_HEALTH_ENABLED: true
healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:8080/health/ready" ]
interval: 15s
timeout: 2s
retries: 15
ports:
- "8080:8080"
networks:
ebills-backend-network:
aliases:
- "keycloak"
depends_on:
postgresql:
condition: service_healthy
正如之前的文章中提到的,以下网址有助于调试:
http://keycloak:8080//realms/master/hostname-debug