使用 Nginx 反向代理 Docker 版 Keycloak 并配置 SSL
前提条件:
- Keycloak 已在 Docker 中运行,端口映射为
8080:8080
- 域名
auth.yourdomain.com
已解析到服务器 IP
- 服务器已安装 Docker 和 Docker Compose
完整步骤:
1. 创建 Nginx 配置文件
1
| sudo nano /etc/nginx/conf.d/keycloak.conf
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| server { listen 80; server_name auth.yourdomain.com; return 301 https://$host$request_uri; }
server { listen 443 ssl http2; server_name auth.yourdomain.com;
ssl_certificate /etc/nginx/ssl/self.crt; ssl_certificate_key /etc/nginx/ssl/self.key; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; location / { proxy_pass http://localhost: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; proxy_set_header X-Forwarded-Host $host; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ { proxy_pass http://localhost:8080; proxy_cache static_assets; proxy_cache_valid 200 30d; add_header X-Cache-Status $upstream_cache_status; } location ~ ^/(keycloak\.json|theme-resources|resources|auth/admin) { deny all; return 404; } }
|
2. 创建临时自签名证书(用于初始测试)
1 2 3 4 5
| sudo mkdir -p /etc/nginx/ssl sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/nginx/ssl/self.key \ -out /etc/nginx/ssl/self.crt \ -subj "/CN=auth.yourdomain.com"
|
3. 测试并启动 Nginx
1 2
| sudo nginx -t sudo systemctl restart nginx
|
4. 配置 Keycloak 容器适应反向代理
修改 Keycloak 的 Docker 启动命令(或 docker-compose.yml):
1 2 3 4 5 6 7 8 9 10
| docker run -d \ --name keycloak \ -e KEYCLOAK_ADMIN=admin \ -e KEYCLOAK_ADMIN_PASSWORD=ChangeMe123 \ -e KC_PROXY=edge \ -e KC_HOSTNAME=auth.yourdomain.com \ -e KC_HTTP_ENABLED=false \ -p 8080:8080 \ quay.io/keycloak/keycloak:22.0.5 \ start --optimized
|
5. 获取 Let’s Encrypt SSL 证书
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| sudo yum install epel-release sudo yum install certbot python3-certbot-nginx
sudo certbot --nginx \ -d auth.yourdomain.com \ --email admin@yourdomain.com \ --agree-tos \ --no-eff-email \ --redirect
echo "0 3 * * * /usr/bin/certbot renew --quiet --post-hook 'systemctl reload nginx'" | sudo tee -a /etc/crontab > /dev/null
|
6. 更新 Nginx 配置使用新证书
Certbot 会自动修改 Nginx 配置,将:
1 2
| ssl_certificate /etc/nginx/ssl/self.crt; ssl_certificate_key /etc/nginx/ssl/self.key;
|
替换为:
1 2
| ssl_certificate /etc/letsencrypt/live/auth.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/auth.yourdomain.com/privkey.pem;
|
7. 重启服务
1 2
| sudo systemctl reload nginx docker restart keycloak
|
8. 配置防火墙
1 2 3
| sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
|
验证配置:
访问测试:
1 2 3 4 5
| curl -I https://auth.yourdomain.com
curl -k http://localhost:8080
|
SSL 验证:
1 2
| openssl s_client -connect auth.yourdomain.com:443 -servername auth.yourdomain.com | grep "Verify"
|
Keycloak 日志检查:
1 2
| docker logs keycloak | grep KC_PROXY
|
高级配置选项:
1. 自定义 Nginx 代理头
1 2 3 4
| 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-Port $server_port;
|
2. 启用 HTTP/2 和 Brotli 压缩
1 2 3 4 5 6
| listen 443 ssl http2;
brotli on; brotli_comp_level 6; brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
3. 安全加固配置
1 2 3 4 5 6 7 8 9 10 11
| server_tokens off;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
|
故障排除:
问题1:Keycloak 重定向循环
解决:确保容器设置了正确的代理类型:
1
| docker exec -it keycloak /opt/keycloak/bin/kc.sh build --proxy edge
|
问题2:Nginx 502 Bad Gateway
解决:
- 检查 Keycloak 容器是否运行:
docker ps
- 检查端口映射:
docker port keycloak
- 测试本地访问:
curl http://localhost:8080
问题3:混合内容警告
解决:在 Keycloak 管理控制台设置正确的 URL:
- 登录 Keycloak 管理控制台
- 进入 Realm Settings → General
- 设置 Frontend URL:
https://auth.yourdomain.com
问题4:WebSocket 连接失败
解决:确保 Nginx 包含以下配置:
1 2 3 4
| proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400;
|
最终架构:
1 2 3 4
| 用户 -> HTTPS(443) -> Nginx -> HTTP(8080) -> Keycloak 容器 ↳ SSL 终止 ↳ 请求头重写 ↳ 安全加固
|
通过以上配置,您已实现:
- Docker 版 Keycloak 的安全 HTTPS 访问
- Nginx 反向代理 + SSL 终止
- Let’s Encrypt 自动证书管理
- 安全加固和性能优化
- WebSocket 支持