Revel 框架本身不支持 HTTPS,必须由 Nginx 反向代理终结 TLS;其底层基于 Go net/http,无 RunTLS 接口,生产环境须监听 127.0.0.1:8089 并由 Nginx 在 443 端口处理 SSL 终止、透传 X-Forwarded-Proto,并配置 cookie.secure = true 以保障安全。

Revel 框架本身不监听 HTTPS,必须由 Nginx 反代终结 SSL
Revel 是一个 Go Web 框架,它底层完全基于 Go 标准库的 http.Server,而该类型**不支持在运行时动态启用 TLS**。你无法像 Flask 那样传入 ssl_context,也不能像 Gin 那样调用 RunTLS —— Revel 没有提供任何内置的 TLS 启动入口。
所有生产环境部署 Revel 应用的正确路径是:让 Revel 进程只监听本地回环地址(如 127.0.0.1:8089),不暴露到公网;再由 Nginx 作为反向代理,在 443 端口接收 HTTPS 请求、终止 TLS、解密后以 HTTP 转发给 Revel。这是唯一被验证可行、且符合安全最佳实践的方式。
- 直接用
revel run -p 443或修改源码强行加ListenAndServeTLS属于 hack 行为,会破坏进程管理、健康检查和日志统一性 - Revel 的
app.conf中没有https.port或ssl.cert这类配置项,试图添加无效 - 若你在开发机上想快速测试 HTTPS,应单独起一个 Nginx 容器或本地实例,而非折腾 Revel 本身
Nginx 配置 SSL 证书的三个硬性条件
Nginx 要成功加载证书并响应 HTTPS 请求,必须同时满足以下三点,缺一不可:
-
ssl_certificate必须指向一个 PEM 文件,且内容顺序为:域名证书 + 中间 CA 证书(例如 Let’s Encrypt 的fullchain.pem);只放cert.pem会导致 Android/iOS/Java 客户端握手失败,报错SSL routines:tls_process_server_certificate:certificate verify failed -
ssl_certificate_key必须是未加密的私钥(生成时用了-nodes),带密码的私钥会让 Nginx 启动时报SSL_CTX_use_PrivateKey_file("...") failed (SSL: error:0906406D:PEM routines:PEM_def_callback:problems getting password) - 私钥文件权限必须为
0600(Linux/macOS),Nginx 主进程以 root 启动但 worker 以www-data或nginx用户运行,若权限为0644,worker 读取时会静默失败或报Permission denied
验证命令:openssl x509 -in /path/to/fullchain.pem -text -noout | head -20 看是否含两个 Certificate 块;openssl rsa -in /path/to/key.pem -check -noout 确认私钥有效。
HTTP 强制跳转 HTTPS 必须在 Nginx server 块中完成
Revel 应用收不到原始请求的协议信息(除非你透传 X-Forwarded-Proto),所以不能靠 Revel 的中间件或 FilterConfig 做 301 跳转 —— 那样既慢又不可靠,还可能引发重定向循环或混合内容警告。
标准做法是在 Nginx 中开两个 server 块:
- 一个监听
80端口,仅做跳转:return 301 https://$host$request_uri; - 另一个监听
443 ssl,加载证书,并通过proxy_pass http://127.0.0.1:8089转发到 Revel
关键细节:return 指令比 rewrite ... redirect 更高效;$request_uri 保留完整路径和 query string,避免丢失参数;不要在 HTTPS server 块里再写跳转逻辑,否则可能触发循环。
Revel 应用需适配反代后的 HTTPS 环境
虽然 TLS 终止在 Nginx,但 Revel 仍需知道当前请求是 HTTPS,否则生成的 URL(如 AssetUrl、UrlFor)、Cookie 的 Secure 标志、CSRF Token 传输都可能出错。
- 在 Nginx 的
location块中加入:proxy_set_header X-Forwarded-Proto $scheme; - 在 Revel 的
app.conf中设置:http.addr = "127.0.0.1"(绑定回环)、http.port = "8089",并确保app.mode = prod - Revel 默认不校验
X-Forwarded-Proto,你需要在自定义 Filter 或init.go中手动检查该 header 并设置req.TLS != nil或改写req.URL.Scheme;更稳妥的做法是使用revel.Intercept在BEFORE阶段统一处理
最容易被忽略的是:Revel 的 Cookie.Secure 默认为 false,即使 Nginx 传了 HTTPS header,它也不会自动设为 true —— 必须显式在 app.conf 中写 cookie.secure = true,否则登录态可能被 HTTP 页面窃取。











