在使用 Nginx, Apache, Caddy 或 Traefik 等反向代理部署 Gophish 时,许多工程师都遇到过一个经典的拦路虎:登录或进行任何操作时,界面提示 Forbidden - Referer Invalid
。
本文将深入探讨一种快速解决此问题的技术方案——通过在反向代理层移除特定的 HTTP 请求头,从而完全绕过 Gophish 的来源(Referer)安全检查。
问题根源:Gophish 的 CSRF 防护机制
Gophish 内置了一项安全功能,用于防止跨站请求伪造(CSRF)攻击。其工作原理如下:
当 Gophish 运行在反向代理之后时,它会检查
X-Forwarded-Host
或Host
请求头。它会获取这个请求头的值(例如
phishing.yourdomain.com
)。然后,它会拿这个值去和其配置文件
config.json
中的trusted_origins
数组进行比对。如果该值不在
trusted_origins
数组中,Gophish 就认为这是一个来自不受信任来源的非法请求,并返回Forbidden - Referer Invalid
错误。
标准、安全的解决方法(方案A)是在 config.json
中正确配置 trusted_origins
。但如果你需要一个快速的临时解决方案,或者在某些特殊测试场景下,可以选择从源头上“釜底抽薪”。
解决方案:移除触发检查的请求头
既然 Gophish 的检查是基于 X-Forwarded-Host
和 Host
这两个请求头的,那么,如果我们在请求到达 Gophish 之前就把这两个头移除掉,Gophish 的检查逻辑就不会被触发。没有检查,自然也就没有错误。
下面,我们将为各类主流的反向代理软件提供具体配置。
各类反向代理的配置指南
核心思路是:在将请求转发(proxy_pass
)给 Gophish 之前,将 Host
和 X-Forwarded-Host
头的值设置为空字符串或直接移除它们。
1. Nginx
在 Nginx 中,可以通过 proxy_set_header
指令将一个头的值设置为空字符串,这通常等同于移除它。
编辑你的 Nginx 配置文件中 Gophish 相关的 location
块:
location / {
proxy_pass http://127.0.0.1:3333;
# --- 核心修改:移除 Host 和 X-Forwarded-Host 头 ---
# 将 Host 头设置为空,以绕过 Gophish 的检查
proxy_set_header Host "";
# 确保 X-Forwarded-Host 也被移除(或设置为空)
proxy_set_header X-Forwarded-Host "";
# ------------------------------------------------
# 其他必要的头信息,尤其是 X-Forwarded-Proto 必须保留
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_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
说明:proxy_set_header Host "";
是此方案的关键。它向 Gophish 隐藏了原始的 Host 信息。
2. Apache httpd
对于 Apache,需要确保 mod_headers
模块已启用。然后,在 VirtualHost
或 Location
配置块中使用 RequestHeader unset
指令。
<VirtualHost *:443>
ServerName phishing.yourdomain.com
# ... 其他 SSL 配置 ...
# 启用 mod_headers
Header unset Host
Header unset X-Forwarded-Host
ProxyPass / http://127.0.0.1:3333/
ProxyPassReverse / http://127.0.0.1:3333/
ProxyPreserveHost Off
# 保留 X-Forwarded-Proto
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
说明:Header unset Host
和 ProxyPreserveHost Off
共同作用,确保 Gophish 看不到原始的 Host 头。
3. Caddy
Caddy 的配置非常简洁。使用 header_down
指令可以轻松移除请求头。
编辑你的 Caddyfile
:
phishing.yourdomain.com {
# 反向代理到 Gophish
reverse_proxy 127.0.0.1:3333 {
# --- 核心修改:移除请求头 ---
header_down -Host
header_down -X-Forwarded-Host
# ---------------------------
# Caddy 会自动处理 X-Forwarded-For 和 X-Forwarded-Proto,无需手动设置
}
}
说明:-Host
前面的减号 -
代表“移除此头”。这是最直接的实现方式。
4. Traefik
Traefik 可以通过中间件(Middleware)来修改请求头。我们定义一个中间件来移除 Host
头。
使用 Docker Labels:
# 在你的 gophish service 的 labels 中添加:
services:
gophish:
# ... image, network, etc.
labels:
- "traefik.enable=true"
- "traefik.http.routers.gophish.rule=Hostphishing.yourdomain.com)"
- "traefik.http.routers.gophish.entrypoints=websecure"
- "traefik.http.routers.gophish.tls.certresolver=myresolver"
- "traefik.http.services.gophish.loadbalancer.server.port=3333"
# --- 核心修改:定义并应用中间件来移除 Host 头 ---
- "traefik.http.middlewares.remove-host-header.headers.customrequestheaders.Host="
- "traefik.http.routers.gophish.middlewares=remove-host-header"
# ----------------------------------------------------
说明:我们定义了一个名为 remove-host-header
的中间件。customrequestheaders.Host=
将 Host
头的值设置为空,从而实现了移除效果。
使用动态配置文件 (YAML):
# traefik-dynamic-conf.yaml
http:
middlewares:
remove-host-header:
headers:
customRequestHeaders:
Host: "" # 设置为空
X-Forwarded-Host: "" # 同时处理 X-Forwarded-Host
routers:
gophish:
rule: "Hostphishing.yourdomain.com)"
service: gophish
entryPoints:
- websecure
middlewares:
- remove-host-header # 应用中间件
tls:
certResolver: myresolver
services:
gophish:
loadBalancer:
servers:
- url: "http://127.0.0.1:3333"
验证与最终建议
完成上述任一配置修改后,重启你的反向代理服务。然后清理浏览器缓存并重新访问 Gophish 的 Web 界面。此时,Forbidden - Referer Invalid
的错误应该已经消失。
最后,再次强调:
这种方法是一种技术上的妥协,它通过禁用 Gophish 的一项核心安全特性来换取便利。虽然它能有效地解决问题,但也为 CSRF 攻击敞开了大门。
在任何安全性要求较高的环境中,都应采用标准方案:正确配置 Nginx 传递
Host
头,并在 Gophish 的config.json
文件中,将你的域名添加到trusted_origins
数组中。这才是兼顾功能与安全的最佳实践。