从TLS WebSocket连接中剥离SNI信息

时间:2018-07-09 16:30:07

标签: ssl go websocket sni

我发现自己需要在一个敌对的环境中建立WebSocket连接,在该环境中防火墙希望从TLS嗅探TLS中的SNI信息。在我的特定情况下,WebSocket服务器不使用SNI进行请求处理,因此,可以安全地删除握手的SNI部分。

然后我的问题变成了:在golang.org WebSocket软件包golang.org/x/net/websocket中,最简单的剥离SNI信息同时保留对所提供链的验证的方法是什么?

我能想到的最好的办法就是简单地用相应的IP替换要拨打的URL的主机名。这导致crypto/tls永远不会添加有问题的SNI信息,但是,在我能够提出的解决方案中,最终不得不提供一个自定义验证器来验证链:

func dial(url string, origin string) (*websocket.Conn, error) {
    // Use system resolver to get IP of host
    hostRegExp := regexp.MustCompile("//([^/]+)/")
    host := hostRegExp.FindStringSubmatch(url)[1]
    addrs, err := net.LookupHost(host)
    if err != nil {
        return fmt.Errorf("Could not resolve address of %s: %v", host, err)
    }
    ip := addrs[0]

    // Replace the hostname in the given URL with its IP instead
    newURL := strings.Replace(url, host, ip, 1)
    config, _ := websocket.NewConfig(newURL, origin)

    // As we have removed the hostname, the Go TLS package will not know what to
    // validate the certificate DNS names against, so we have to provide a custom
    // verifier based on the hostname we threw away.
    config.TlsConfig = &tls.Config{
        InsecureSkipVerify:    true,
        VerifyPeerCertificate: verifier(host),
    }
    return websocket.DialConfig(config)
}

func verifier(host string) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
    return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
        // For simplicity, let us only consider the case in which the first certificate is the one
        // to validate, and in which it is signed directly by a CA, with no parsing of
        // intermediate certificates required.
        opts := x509.VerifyOptions{
            DNSName: host,
        }
        rawCert := rawCerts[0]
        cert, err := x509.ParseCertificate(rawCert)
        if err != nil {
            return err
        }
        _, err = cert.Verify(opts)
        return err
    }
}

这完全有效,但似乎很笨拙。有没有更简单的方法? (理想情况下,这不是特定于WebSocket应用程序,而是通常适用于TLS;与上述完全相同的想法可以应用于HTTPS。)

0 个答案:

没有答案