如何为Docker部署的Keycloak配置全量传入HTTP请求日志
目前没有专门针对Keycloak的成熟开源蜜罐框架,你可以根据自己的技术栈选以下三种实现方案,都能完整记录所有HTTP请求的头、请求体等全量信息:
- 方案1:前置反向代理层记录(推荐,稳定性最高)
不需要修改Keycloak的代码或原生配置,在现有服务栈前增加一层反向代理,所有流量先经过代理再转发到Keycloak,由代理层完成全量请求信息的记录,不会因为Keycloak版本升级出现兼容性问题。
可选Nginx、Traefik等常用反向代理组件,配置开启全量日志即可记录:请求时间、真实来源IP、请求方法、完整URL、所有请求头、完整请求体、响应状态码、响应内容(按需开启)。
注意需要给Keycloak服务添加环境变量PROXY_ADDRESS_FORWARDING=true,避免代理层转发后Keycloak把代理IP当成访问源IP。
调整后的docker-compose.yml参考:
version: '3'
volumes:
postgres_data:
driver: local
nginx_logs:
driver: local
services:
postgres:
image: postgres
volumes:
- postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: password
keycloak:
image: quay.io/keycloak/keycloak:latest
environment:
DB_VENDOR: POSTGRES
DB_ADDR: postgres
DB_DATABASE: keycloak
DB_USER: keycloak
DB_SCHEMA: public
DB_PASSWORD: password
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
PROXY_ADDRESS_FORWARDING: "true"
entrypoint: /opt/keycloak/bin/kc.sh start-dev
expose:
- "8080"
depends_on:
- postgres
nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- nginx_logs:/var/log/nginx/
depends_on:
- keycloak
同目录下创建nginx.conf配置文件,开启全量日志: ```nginx events {} http { log_format full_log '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "x_forwarded_for: $http_x_forwarded_for" ' 'auth: $http_authorization cookie: $http_cookie ' 'content_type: $http_content_type req_body: $request_body'; server { listen 80; location / { proxy_pass http://keycloak:8080; 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; client_body_buffer_size 10M; client_max_body_size 10M; access_log /var/log/nginx/access.log full_log; } } }
注:原生Nginx没有内置所有请求头的聚合变量,如果需要记录全部请求头,可以将Nginx替换为OpenResty,通过几行Lua代码遍历所有请求头拼接后写入日志。
方案2:Keycloak自定义SPI拦截(记录维度最丰富)
基于Keycloak的SPI扩展机制实现全局请求拦截,除了基础的HTTP请求信息外,还能直接关联Keycloak内部上下文,比如命中的Realm、尝试登录的用户名、访问的客户端ID、触发的认证流程等信息,记录维度比代理层更全。
实现步骤:- 新建Java项目引入Keycloak服务端依赖,编写加了
@PreMatching注解的JAX-RS全局请求过滤器,在过滤器中通过Request Wrapper包裹请求对象读取完整请求体(避免请求体被读取后丢失,影响Keycloak正常处理流程),提取所有需要记录的字段后写入独立日志文件或者专门的蜜罐日志库。 - 按照SPI规范编写
META-INF/services/org.jboss.resteasy.spi.Providers文件注册自定义过滤器,将项目打包为jar包。 - 不需要修改官方Keycloak镜像,启动时将jar包挂载到容器内
/opt/keycloak/providers/目录即可,Keycloak启动时会自动加载该扩展。
- 新建Java项目引入Keycloak服务端依赖,编写加了
方案3:开启Quarkus内置全量日志(部署最快)
你当前使用的latest版本Keycloak基于Quarkus构建,原生支持HTTP全量请求日志开关,不需要额外部署服务也不需要写代码,只需要给Keycloak服务添加对应环境变量即可开启:QUARKUS_HTTP_ACCESS_LOG_ENABLED: "true" QUARKUS_HTTP_ACCESS_LOG_PATTERN: "%h %l %u %t \"%r\" %s %b auth: %{Authorization}i cookie: %{Cookie}i" QUARKUS_HTTP_LOG_BODY: "true" QUARKUS_HTTP_LOG_BODY_SIZE_LIMIT: "10240k"这个方案部署成本最低,但是灵活性最差,日志格式固定,后续如果需要添加自定义告警、行为关联分析的话不如前两个方案方便。
蜜罐部署注意事项
- 你现有配置中的
KEYCLOAK_USER和KEYCLOAK_PASSWORD是旧版WildFly架构Keycloak的环境变量,新版Quarkus架构Keycloak已经不再识别这两个参数,不影响启动可以直接删除。 - 蜜罐环境要和生产业务网络完全隔离,不要存储任何真实业务数据、用户凭证,避免被攻击者拿下后作为内网跳板。
- 所有请求日志要实时同步到独立的存储节点,不要只存在容器本地,防止攻击者入侵后删除日志销毁痕迹。
- 可以提前在Keycloak中创建几个仿真Realm、测试客户端、弱口令测试用户,诱导攻击者进行更多交互,捕获更多攻击payload。
内容的提问来源于stack exchange,提问作者Max S

