Nginx反向代理下HTTPS访问BioTime登录报403错误求助
问题描述
我们有一台ZKTeco MB10考勤设备,已经完成安装并连接到VPS上部署的BioTime 9.5系统。子域名checkin.company.com已指向VPS的IP地址,HTTP协议下通过Nginx反向代理可以正常访问BioTime系统,对应的HTTP配置如下:
server { listen 80; server_name checkin.company.com; location / { proxy_pass http://127.0.0.1:9040; 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; } }
但配置HTTPS后,无法正常登录BioTime网页端,访问地址为https://checkin.company.com,HTTPS的Nginx配置如下:
server { listen 443 ssl; server_name checkin.company.com; ssl_certificate C:\win-acme\certs\checkin.company.com-chain.pem; ssl_certificate_key C:\win-acme\certs\checkin.company.com-key.pem; ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_ciphers HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; location / { proxy_pass http://127.0.0.1:9040; 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; } }
Nginx访问日志显示,HTTPS下访问/base/system_verify/接口时返回403错误:
82.xxx.xx.xxx - - "GET /login/?next=/ HTTP/1.1" 200 11958 82.xxx.xx.xxx - - "PATCH /base/system_verify/ HTTP/1.1" 403 1019
排查思路
- 检查
X-Forwarded-Proto传递是否生效:BioTime系统大概率依赖这个请求头判断当前协议,要是后端没拿到正确的https值,就会认为请求是HTTP协议,拒绝跨协议的验证请求。可以去BioTime的后端日志里查这个头的实际值,确认是不是https。 - 核对CSRF令牌一致性:HTTPS环境下,系统生成的CSRF令牌可能和HTTP环境绑定的协议/域名不同,登录页面生成的令牌和请求
/base/system_verify/时带的令牌必须一致,否则会触发403。 - 确认系统HTTPS信任配置:BioTime 9.5可能有白名单机制,只信任特定协议或域名的请求,得去系统设置里看看有没有把
https://checkin.company.com加入信任列表,或者有没有开启HTTPS支持的开关。 - 检查代理头完整性:除了现有代理头,有些系统需要额外的
X-Forwarded-Host头(虽然Host已经设置,但部分系统会优先读这个),或者确认Host头有没有被后端正确解析。 - 验证SSL兼容性:旧版本应用可能对某些SSL cipher套件不兼容,试试调整
ssl_ciphers为更通用的配置,同时检查SSL证书链是否完整(有没有漏中间证书)。
解决方案
1. 确保BioTime正确识别HTTPS协议
修改Nginx的HTTPS配置,补充必要的代理头,同时在BioTime后台开启信任反向代理的设置:
location / { proxy_pass http://127.0.0.1:9040; 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-Port $server_port; # 要是系统有严格的Referer验证,加上这个头 proxy_set_header Referer $scheme://$host$request_uri; }
登录BioTime后台管理界面,找到「安全设置」或「代理设置」,开启「信任反向代理」,并把信任的代理IP设为VPS本地IP(127.0.0.1)。
2. 调整CSRF信任源
如果系统的CSRF验证绑定了协议,找到BioTime的配置文件(一般是config.py或者类似的配置文件),修改CSRF_TRUSTED_ORIGINS参数,添加HTTPS域名:
CSRF_TRUSTED_ORIGINS = ['https://checkin.company.com']
修改后重启BioTime服务。
3. 修复SSL配置
用openssl s_client -connect checkin.company.com:443验证证书链是否完整,要是缺中间证书,重新生成或补充。同时调整Nginx的SSL协议和cipher配置,提升兼容性:
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
4. 强制HTTP跳转至HTTPS
配置HTTP服务器自动跳转到HTTPS,避免混合协议导致的问题:
server { listen 80; server_name checkin.company.com; return 301 https://$host$request_uri; }
内容的提问来源于stack exchange,提问作者Arbaz Ahmed Mughal
相关产品推荐
相关产品推荐

