1

使用julienschmidt 的 httprouter 之类的反向代理时,如何对特定主机使用 TLS/SSL 客户端身份验证?

我可以使用http.DefaultTransport.

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

http.DefaultTransport = transport

但只想对特定主机使用客户端证书,例如:

  1. 主机 1 的 cert1
  2. 用于主机 2 的 cert2
  3. 没有客户证书的其他一切

更新

我预计回调GetConfigForClientHandlerGetCertificateHandler将被调用。在这一点上,我可以对info.ServerName. 但只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")
}
4

1 回答 1

4
  1. 创建一个为所有主机共享的 TLS 配置。可能你不需要在那里设置太多。但是你想设置一个Config.GetConfigForClient处理程序。
  2. 在该处理程序中,您检查ClientHelloInfo.ServerName. 那是请求的主机。然后,您修改 TLS 配置以要求客户端身份验证 ( Config.ClientAuth)。
  3. 用你的 net.Listener 包裹起来tls.NewListener
  4. net.Listener使用你的TLS http.Serve(这里是你可以使用 httprouter 的地方)
于 2020-08-02T08:20:34.053 回答