我在Go中编写自己的ReverseProxy。ReverseProxy应该连接我的go-webserver和apache2
webserver。但是,当我在另一个IP地址上运行反向代理时,然后在我的Apache2
Web服务器上,当反向代理将请求发送到apache时,我的apache-logfile中出现以下错误。
"Hosname xxxx provided via sni and hostname xxxx2 provided via http are different"
我的反向代理和apache-webserver在https上运行。
这里有一些代码:
func (p *Proxy) directorApache(req *http.Request) {
mainServer := fmt.Sprintf("%s:%d", Config.HostMain, Config.PortMain)
req.URL.Scheme = "https"
req.URL.Host = mainServer
}
func (p *Proxy) directorGo(req *http.Request) {
goServer := fmt.Sprintf("%s:%d", Config.GoHost, Config.GoPort)
req.URL.Scheme = "http"
req.URL.Host = goServer
}
func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
fmt.Println(req.URL.Path)
if p.isGoRequest(req) {
fmt.Println("GO")
p.goProxy.ServeHTTP(rw, req)
return
}
p.httpProxy.ServeHTTP(rw, req)
}
func main() {
var configPath = flag.String("conf", "./configReverse.json", "Path to the Json config file.")
flag.Parse()
proxy := New(*configPath)
cert, err := tls.LoadX509KeyPair(Config.PathCert, Config.PathPrivateKey)
if err != nil {
log.Fatalf("server: loadkeys: %s", err)
}
config := tls.Config{InsecureSkipVerify: true, Certificates: []tls.Certificate{cert}}
listener, err := net.Listen("tcp",
net.JoinHostPort(proxy.Host, strconv.Itoa(proxy.Port)))
if err != nil {
log.Fatalf("server: listen: %s", err)
}
log.Printf("server: listening on %s")
proxy.listener = tls.NewListener(listener, &config)
serverHTTPS := &http.Server{
Handler: proxy.mux,
TLSConfig: &config,
}
if err := serverHTTPS.Serve(proxy.listener); err != nil {
log.Fatal("SERVER ERROR:", err)
}
}
也许有人对此有想法。
假设您正在向发起HTTP请求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所抱怨的。
当您将TLS与服务器名称指示(SNI)一起使用时,请求主机名不仅将用于DNS解析,还将选择用于建立TLS连接的SSL证书。Host
另一方面,HTTP
1.1 标头用于通过Apache区分多个虚拟主机。两个名称 必须匹配 。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
}
在测试我的客户机-服务器分布式系统时,我最初惊讶地得知TLS的默认JSSE实现不进行主机名验证。我在这个问题中尝试了公认的答案,但我的用例有点不同。我使用RabbitMQ的连接工厂,它抽象了SSLSocket的构造。我只是为连接工厂提供了一个SSLContext。我确实找到了很多关于HTTPS的信息,甚至还有一些其他协议,但并不是总能使用的通用协议,即使是自定义协议。 但是,除了使用之外,关于创建
最近有人遇到过这样的错误吗?三个月来,应用程序一直正常运行,但今天okhttp已停止连接任何url。有什么问题吗?我没有更改任何代码,只是更新了依赖项的版本。 这是我的okhttp依赖项: 我还尝试在清单中使用这些设置: 但这没用。 我将不胜感激任何帮助!
我正在esp32上实现一个websocket服务器,并且在android studio Simulator上运行的应用程序上使用okhttp lib。 我正在使用由openssl命令生成的自分配证书:openssl req-newkey rsa:2048-nodes-keyout prvtkey.pem-x509-days 3650-out cacert.pem-subj“/cn=esp32 HT
您可能已经注意到,&字段都为空。原因是,服务器实际上没有域或主机名。在这种情况下我该怎么办? 我有一个记录指向和记录指向 我可以在中使用作为和吗?因为指向另一个具有另一个IP的VPS,它只负责web托管。
我有一个使用Spring Boot实现的应用程序,我在其中使用Spring Security进行身份验证。我已经有了“基于令牌的”身份验证,其中要求客户端检索令牌,然后在后续请求中使用该令牌进行身份验证。 我希望对此进行增强,以便令牌可以被限制为特定主机名,因此只能用于来自该主机的请求。这类似于谷歌地图API对其API密钥所做的操作,可以通过IP或主机名来限制它们。 以下是我实现的代码,用于尝试检