借助Varnish与Hitch代理部署Discourse论坛及多站点的问题排查
问题解决:Discourse在Varnish+Hitch架构下的资源加载与登录异常
问题根源分析
- 资源(Logo/附件)加载失败:Discourse未正确识别前端的HTTPS协议,生成的资源链接为
http://,被浏览器的混合内容安全策略拦截。 - 强制HTTPS后无法登录:Discourse会话Cookie未标记
Secure属性,且X-Forwarded-Proto头未正确传递,导致登录请求出现重定向循环或Cookie无法在HTTPS环境下生效。
解决方案
1. 修正Varnish的default.vcl配置
原配置中对Discourse请求直接使用pipe会跳过后续头处理逻辑,导致X-Forwarded-Proto无法传递给后端,需调整如下:
vcl 4.1; import std; backend default { .host = "192.168.1.103"; .port = "8080"; } backend discourse { .host = "192.168.1.103"; .port = "8081"; } sub vcl_recv { # 优先处理HTTP转HTTPS重定向,所有非443端口请求强制跳转 if (std.port(server.ip) != 443) { set req.http.location = "https://" + req.http.host + req.url; return(synth(301)); } # 设置X-Forwarded-Proto头,告知后端当前使用HTTPS协议 if (!req.http.X-Forwarded-Proto) { set req.http.X-Forwarded-Proto = "https"; } # 路由到对应后端,Discourse使用pass而非pipe以保留头处理逻辑 if (req.http.host == "discourse.example.com") { set req.backend_hint = discourse; return (pass); } else { set req.backend_hint = default; } } sub vcl_backend_response { # 强制给Discourse的Cookie添加Secure属性,确保HTTPS环境下正常传输 if (bereq.http.host == "discourse.example.com") { set beresp.http.Set-Cookie = regsuball(beresp.http.Set-Cookie, "(; )?(Secure)?", "; Secure"); } } sub vcl_synth { if (resp.status == 301 || resp.status == 302) { set resp.http.location = req.http.location; return (deliver); } }
2. 配置Discourse识别反向代理的HTTPS
修改Discourse的app.yml,添加反向代理信任配置,让Discourse正确识别前端的HTTPS环境:
expose: - "8081:80" # http # - "443:443" # https ## 添加反向代理相关环境变量 env: DISCOURSE_FORCE_HTTPS: true DISCOURSE_TRUSTED_PROXIES: 192.168.1.103 # 填写Varnish服务器的IP地址 DISCOURSE_X_FORWARDED_PROTO: https ## Uncomment these two lines if you wish to add Lets Encrypt (https) # - "templates/web.ssl.template.yml" # - "templates/web.letsencrypt.ssl.template.yml" ## If you added the Lets Encrypt template, uncomment below to get a free SSL certificate # LETSENCRYPT_ACCOUNT_EMAIL: me@example.com
3. 验证Hitch配置
确保Hitch将解密后的HTTPS请求转发到Varnish的监听端口(默认6081),检查Hitch配置文件中是否存在:
backend = "[127.0.0.1]:6081"
4. 重启服务使配置生效
- 重启Varnish:
systemctl restart varnish - 重建并重启Discourse:
cd /var/discourse && ./launcher rebuild app - 重启Hitch:
systemctl restart hitch
内容的提问来源于stack exchange,提问作者Umair Suraj
相关产品推荐
相关产品推荐

