猿问

使用Gin在戈朗中使用TLS(代理服务器)进行反向代理时出现问题

我的任务是创建一个反向代理,该代理是与代理服务建立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)

}

我也尝试过设置(也许我只是扭曲了现在TLS需要在这种情况下工作):RootCAs



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,我真的不确定在哪里继续。


慕无忌1623718
浏览 199回答 3
3回答

慕后森

对于 TLS(即具有 TLS 的 https),您必须连接到正确的服务器端口。它通常是端口 43 或端口 8443。它与用于 http 的端口永远不会相同。因此,这意味着要启动,服务器必须为TLS提供端口,尽管大多数服务器都这样做。您共享的唯一代码与与服务器的连接无关。由于您尚未共享向服务器发出请求的任何代码,因此无法显示错误所在。下面是一个示例

富国沪深

我现在无法完全重现您的设置,但原则上,您应该在反向代理.Director函数中更改请求:控制器必须是一个函数,它将请求修改为要使用传输发送的新请求。简而言之:  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 配置中的证书和根 CA。证书是您发送到服务器的证书,而 rootCA 用于验证服务器提供的证书。

繁花不似锦

我最终切换到直接使用。但最大的问题是我正在使用而不是.以下是我最终得到的结果:ReverseProxyRootCAsClientCAsclientCAs := 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)在此之后,一切都在游泳中工作。谢谢大家!
随时随地看视频慕课网APP

相关分类

Go
我要回答