我正在尝试将 keycloak 放在 traefik 后面,以确保多项服务和 SPA 的安全。
但是在那之前,我只想通过受 traefik 保护的主机名 tsl 访问 keycloak。
在我下面的 YML 文件中,设置了 keycloak 和 traefik。
keycloak 是使用 dockerfile 创建的,如文档中所述,并且还会生成密钥。
创建的密钥不安全,我知道在生产中我会使用 LetsEncrypt 证书,但我不想每次尝试都请求新证书。
作为别名服务器,我已在撰写文件中指定堆栈主机和 WSL 的 IP。目前我认为可能有错误,但我不知道要更改什么。
在我的 YML 文件中,keycloak 是通过 traefik 使用 https 端口 8443 发布的。但是,如果我只使用
https://stack_host..:8443/admin
502 Bad Gateway 出现,但在我的 Traefik 仪表板中一切看起来都很好。
我现在已经成功了。 Traefik 与 Keycloak 一起运行,TSL 加密是通过 traefik 而不是通过 keycoak 完成的,因此 keycloak 必须只能通过端口 8080 访问,它不需要 keycloak 的密钥对。
我在 /etc/hosts 中添加了另一个主机 auth.stack_host (在 Windows System32/drivers/hosts 下),现在可以在 https:auth.stack_host 下访问它并通向 keycloak。
这里是 keycloak、traefik 和 vue SPA 的样板 YML 文件。 vue 应用程序正在监听 https://stack_host:443 将 stack_host 设置为您计算机的名称或在上面的文件中添加另一个主机。
version: "3"
services:
traefik:
image: traefik:v2.9
command:
- --api.insecure=true
- --providers.file.directory=/configuration/
- --providers.file.watch=true
- --accesslog
- --providers.docker.exposedbydefault=false
- --providers.docker
- --entryPoints.websecure.address=:443
- --entrypoints.web.address=:80
- --entrypoints.gateway.address=:5001
ports:
- "172.17.108.255:8080:8080"
- "80:80"
- "443:443"
- "5001:5001"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /traefik:/configuration/
networks:
- external-network
mem_limit: 200m
mem_reservation: 100m
frontend:
build: gui
container_name: ${STACK_NAME}-frontend
restart: always
networks:
- external-network
command: --brotli --port 8083
labels:
- "traefik.enable=true"
- "traefik.docker.network=${STACK_NAME}-external"
- "traefik.http.routers.frontend.rule=Host(`${STACK_HOST}`)"
- "traefik.http.routers.frontend.entrypoints=websecure"
- "traefik.http.routers.frontend.tls=true"
- "traefik.http.routers.frontend.middlewares=cors_header"
- "traefik.http.middlewares.cors_header.headers.accesscontrolallowmethods=GET,OPTIONS,PUT,POST,DELETE,PATCH"
- "traefik.http.middlewares.cors_header.headers.accesscontrolallowheaders=*"
- "traefik.http.middlewares.cors_header.headers.accesscontrolalloworiginlist=https://${STACK_HOST}"
- "traefik.http.middlewares.cors_header.headers.accesscontrolmaxage=100"
- "traefik.http.middlewares.cors_header.headers.addvaryheader=true"
- "traefik.http.services.frontend.loadbalancer.server.port=8083"
- "traefik.http.services.frontend.loadbalancer.server.scheme=http"
keycloak:
container_name: keycloak
build: KeycloakContainer
restart: always
command: start
environment:
KC_PROXY_ADDRESS_FORWARDING: "true"
KC_HOSTNAME_STRICT: "false"
KC_HOSTNAME_STRICT_HTTPS: "false"
KC_HOSTNAME: auth.${STACK_HOST}
KC_HTTP_ENABLED: "true"
KC_PROXY_HEADERS: xforwarded
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
KC_HEALTH_ENABLED: "true"
labels:
- "traefik.docker.network=${STACK_NAME}-external"
- "traefik.enable=true"
- "traefik.http.routers.keycloak.rule=Host(`auth.${STACK_HOST}`)"
- "traefik.http.routers.keycloak.tls=true"
- "traefik.http.services.keycloak.loadbalancer.server.port=8080"
networks:
- external-network
- internal-network
healthcheck:
test:
[
"CMD-SHELL",
"exec 3<>/dev/tcp/localhost/8080 && echo -e 'GET /health/ready HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && cat <&3 | grep -q '200 OK'"
]
interval: 30s
timeout: 5s
retries: 20
networks:
internal-network:
name: ${STACK_NAME}-internal
internal: true
external-network:
name: ${STACK_NAME}-external
driver: bridge
FROM quay.io/keycloak/keycloak:24.0.1 as builder
WORKDIR /opt/keycloak
RUN /opt/keycloak/bin/kc.sh build
FROM quay.io/keycloak/keycloak:24.0.1
COPY --from=builder /opt/keycloak/ /opt/keycloak/
// load custom theme
COPY ./marvins-theme/ /opt/keycloak/themes/marvins-theme
// import realm
COPY ./realm-config/realm.json /opt/keycloak_import/
RUN /opt/keycloak/bin/kc.sh import --file /opt/keycloak_import/realm.json
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]