我的任务是创建一个反向代理,该代理需要与代理服务建立TLS连接。我拥有的证书对每个请求都是唯一的,并且在内存中。
我运气不好,做对了,我试过很多东西。这就是我现在的处境,希望有人能帮忙:
func proxy(c *gin.Context) {
/* snip: magic here to get the x509 cert strings and remoteUrl */
proxy := httputil.NewSingleHostReverseProxy(remoteUrl)
cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: []byte(signedCertString)})
key:= pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(privateKeyString)})
certificate, err := tls.X509KeyPair(cert, key)
if err != nil {
c.JSON(400, gin.H{"message": "Invalid certificate"})
return
}
proxy.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{certificate},
InsecureSkipVerify: true,
}
}
c.Request.Host = remote.Host
c.Request.URL.Scheme = remote.Scheme
c.Request.URL.Host = remote.Host
c.Request.URL.Path = remote.Path
proxy.ServeHTTP(c.Writer, c.Request)
}
我也试过设置RootCAs
(也许我只是扭曲了现在TLS需要在这种情况下工作):
func proxy(c *gin.Context) {
/* snip: magic here to get the x509 cert strings and remoteUrl */
proxy := httputil.NewSingleHostReverseProxy(remoteUrl)
cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: []byte(signedCertString)})
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(cert)
proxy.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
RootCAs: certPool,
InsecureSkipVerify: true,
}
}
c.Request.Host = remote.Host
c.Request.URL.Scheme = remote.Scheme
c.Request.URL.Host = remote.Host
c.Request.URL.Path = remote.Path
proxy.ServeHTTP(c.Writer, c.Request)
}
在任何情况下,我的目标服务器似乎没有捡起代理请求是TLS,我真的不知道从哪里着手。
对于TLS(即https,它是带有TLS的http),您必须连接到正确的服务器端口。通常是43或8443端口。它永远不会与http使用的端口相同。因此,这意味着要启动,服务器必须为TLS提供端口,尽管大多数服务器都这样做。
您共享的唯一代码与服务器连接无关。
由于您没有共享任何向服务器发出请求的代码,因此无法显示错误的地方。
这是一个示例
我现在无法完全重现您的设置,但原则上,您应该更改ReverseProxy.Director
函数内的请求:
Director必须是一个函数,它将请求修改为使用Transport发送的新请求。
简而言之:
proxy.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{certificate},
RootCAs: certPool,
InsecureSkipVerify: true,
}
}
proxy.Director = func(req *http.Request) {
req.Host = remote.Host
req.URL.Scheme = remote.Scheme
req.URL.Host = remote.Host
req.URL.Path = remote.Path
}
proxy.ServeHTTP(c.Writer, c.Request)
此外,您可能需要在TLS配置中同时使用证书和rootca。证书是您发送给服务器的证书,rootCA用于验证服务器提供的证书。
我最终直接切换到使用ReverseProxy
。但最大的问题是我使用的是RootCAs
而不是ClientCAs
。下面是我最后写的:
clientCAs := x509.NewCertPool()
clientCAs.AppendCertsFromPEM(signedCert)
certificate, err := tls.X509KeyPair(signedCert, privateKey)
proxy := &httputil.ReverseProxy({
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{certificate},
ClientCAs: clientCAs
},
Director: func (req *http.Request) {
// Alter request here
}
},
})
proxy.ServeHTTP(w, r)
在这之后,一切都很顺利。谢谢,!