简体   繁体   English

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

[英]Using TLS/SSL Client Authentication for specific hosts

How can I use TLS/SSL Client Authentication for specific Hosts when using a reverse proxy like httprouter by julienschmidt ?使用julienschmidt 的 httprouter等反向代理时,如何对特定主机使用 TLS/SSL 客户端身份验证?

I could set a Client Certificate in a global matter with http.DefaultTransport .我可以使用http.DefaultTransport在全局范围内设置客户端证书。

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

http.DefaultTransport = transport

But want to use Client Certificate only for specific hosts , like:但只想对特定主机使用客户端证书,例如:

  1. cert1 for host1 host1 的 cert1
  2. cert2 for host2 host2 的 cert2
  3. everything else with no Client Certificate其他没有客户证书的东西

Update更新

I expected that the callback GetConfigForClientHandler or GetCertificateHandler would be called.我预计会调用回调GetConfigForClientHandlerGetCertificateHandler At this point I could react on the info.ServerName .此时我可以对info.ServerName做出反应。 But only GetClientCertificate get called with no information about the target 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")
}
  1. Create a TLS config which is shared for all hosts.创建一个为所有主机共享的 TLS 配置。 Probably you don't need to set much there.可能你不需要在那里设置太多。 But you want to set a Config.GetConfigForClient handler.但是您想设置一个Config.GetConfigForClient处理程序。
  2. In that handler, you check the ClientHelloInfo.ServerName .在该处理程序中,您检查ClientHelloInfo.ServerName That is the requested host.那就是请求的主机。 You then modify the TLS config to require client auth there ( Config.ClientAuth ).然后,您修改 TLS 配置以要求那里的客户端身份验证 ( Config.ClientAuth )。
  3. Wrap your.net.Listener with tls.NewListenertls.NewListener
  4. Use your TLS net.Listener in http.Serve (here is where you could then use httprouter)http.Serve中使用您的 TLS net.Listener (您可以在此处使用 httprouter)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM