【问题标题】:Trouble getting reverse proxy working with TLS (to proxied server) in Golang with Gin使用 Gin 在 Golang 中使用 TLS(到代理服务器)获取反向代理时遇到问题
【发布时间】:2021-11-23 06:41:26
【问题描述】:

我的任务是创建与代理服务建立 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,我不确定从哪里着手。

【问题讨论】:

    标签: go reverse-proxy tls1.2 go-gin


    【解决方案1】:

    我最终转而直接使用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)
    

    在此之后,一切都在顺利进行。谢谢大家!

    【讨论】:

      【解决方案2】:

      我现在无法完全重现您的设置,但原则上,您应该更改 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 用于验证服务器提供的证书。

      【讨论】:

        【解决方案3】:

        对于 TLS(即 https,即带有 TLS 的 http),您必须连接到正确的服务器端口。它通常是端口 43 或端口 8443。它永远不会与用于 http 的端口相同。所以这意味着要启动,服务器必须为 TLS 提供一个端口,尽管大多数都这样做。

        您共享的唯一代码与与服务器的连接无关。

        由于您没有共享任何向服务器发出请求的代码,因此无法显示错误的位置。

        Here is a sample

        【讨论】:

        • 上面的代码设置了一个在内部发出请求的代理。它有效,代理,我只是不确定 TLS 连接是否正确,因为服务器似乎没有承认它。我会仔细检查端口。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        • 2020-01-07
        • 2022-12-10
        • 2013-04-02
        • 1970-01-01
        • 1970-01-01
        • 2021-01-27
        相关资源
        最近更新 更多