1 回答
TA贡献1820条经验 获得超2个赞
简短示例
假设您正在向https://your-proxy.local
. 您的请求处理程序采用该http.Request
结构并将其URL
字段重写为https://your-apache-backend.local
.
您没有考虑的是,原始 HTTP 请求还包含一个Host
标头 ( Host: your-proxy.local
)。将相同的请求传递给 时http://your-apache-backend.local
,该请求中的Host
标头仍然显示Host: your-proxy.local
. 这就是 Apache 所抱怨的。
解释
当您使用带有服务器名称指示 (SNI) 的 TLS 时,请求主机名不仅会用于 DNS 解析,还会用于选择用于建立 TLS 连接的 SSL 证书。Host
另一方面,Apache 使用HTTP 1.1标头来区分多个虚拟主机。两个名称必须匹配。Apache HTTPD wiki 中也提到了这个问题:
SNI/请求主机名不匹配,或 SNI 提供主机名而请求不提供。
这是浏览器错误。Apache 会以 400 类型的错误拒绝请求。
解决方案
还要重写Host
标题。如果要保留原始Host
标头,可以将其存储在X-Forwarded-Host
标头中(这是一个非标准标头,但它广泛用于反向代理):
func (p *Proxy) directorApache(req *http.Request) {
mainServer := fmt.Sprintf("%s:%d", Config.HostMain, Config.PortMain)
req.URL.Scheme = "https"
req.URL.Host = mainServer
req.Header.Set("X-Forwarded-Host", req.Header().Get("Host"))
req.Host = mainServer
}
- 1 回答
- 0 关注
- 149 浏览
添加回答
举报