go - 对特定主机使用 TLS/SSL 客户端身份验证

标签 go ssl reverse-proxy client-certificates httprouter

当使用像 httprouter by julienschmidt 这样的反向代理时,如何对特定主机使用 TLS/SSL 客户端身份验证?
我可以使用 http.DefaultTransport 在全局事务中设置客户端证书.

transport := &http.Transport{
    TLSClientConfig: &tls.Config{
        Certificates: []tls.Certificate{cert},
    },
}

http.DefaultTransport = transport
但只想将客户端证书用于 特定主机 , 喜欢:
  • 用于主机 1 的证书 1
  • 用于主机 2 的证书 2
  • 的所有其他内容没有客户证书

  • 更新
    我预计回调 GetConfigForClientHandler或者GetCertificateHandler会被调用。在这一点上,我可以对 info.ServerName 使用react.但只有 GetClientCertificate在没有关于目标的信息的情况下被调用 info.ServerName .
    func main() {
        transport := &http.Transport{
            TLSClientConfig: &tls.Config{
                GetConfigForClient:   GetConfigForClientHandler,
                GetClientCertificate: GetClientCertificateHandler,
                GetCertificate:       GetCertificateHandler,
            },
        }
    
        http.DefaultTransport = transport
    
        // Host which enforce client certificate authentication
        resp, err := http.Get("https://example.com")
        if err != nil {
            fmt.Println("Error", err)
        }
        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)
        fmt.Println(string(body))
    }
    
    func GetClientCertificateHandler(info *tls.CertificateRequestInfo) (*tls.Certificate, error) {
        fmt.Println("GetClientCertificateHandler")
        panic("GetClientCertificateHandler")
    }
    
    func GetConfigForClientHandler(info *tls.ClientHelloInfo) (*tls.Config, error) {
        fmt.Println("GetConfigForClientHandler for:", info.ServerName)
        panic("GetConfigForClientHandler")
    }
    
    func GetCertificateHandler(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
        fmt.Println("GetCertificateHandler for:", info.ServerName)
        panic("GetCertificateHandler")
    }
    

    最佳答案

  • 创建一个为所有主机共享的 TLS 配置。可能你不需要在那里设置太多。但是你想设置一个 Config.GetConfigForClient 处理程序。
  • 在该处理程序中,您检查 ClientHelloInfo.ServerName .那是请求的主机。然后修改 TLS 配置以要求客户端身份验证 ( Config.ClientAuth )。
  • tls.NewListener 包裹你的 net.Listener
  • 使用您的 TLS net.Listener http.Serve (这里是你可以使用 httprouter 的地方)
  • 关于go - 对特定主机使用 TLS/SSL 客户端身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63213638/

    相关文章:

    go - 以 C 类型作为参数导出函数 [不能在 package.Func 的参数中使用 x (type *C.ctype) 作为类型 *package.C.ctype]

    mongodb - 按给定示例中的字段名称更新 mongo 事务

    Apache 没有将 .co.uk 重定向到 .com

    apache - Tomcat 服务 URLs mod_proxy 和 apache 错误

    redirect - 在代理后面运行非标准端口的 nginx 机器上的 301 重定向

    docker - Nginx Plus无法使用Docker嵌入式DNS服务器解析服务

    go - Go 中 Print 和 print 的区别

    xml - Response.Return_ 标签中的名称 "return"与 *Result.XMLName 中的名称 "Result"冲突

    html - 在我的浏览器中删除 "NON SECURE"消息的任何技巧?

    java - 在 Java 中获取 SSLHandshakeException