2016-02-14 34 views
3

在GoLang中,我使用NewSingleHostReverseProxy来执行反向代理,但是我需要确认主机站点的SSL证书,以确保我拥有正确的安全证书...任何想法我应该怎么做?我应该在处理程序还是交通工具上做这件事?我是GoLang的新手,并且仍然很喜欢它。谢谢确认TLS证书,同时在GoLang中执行ReverseProxy

proxy := httputil.NewSingleHostReverseProxy(&url.URL{ 
     Scheme: "https", 
     Host: "sha256.badssl.com", 
}) 

http.ListenAndServe("127.0.0.1:80", proxy) 

回答

2

要访问证书,您将有权访问ConnectionState。最简单的方法是提供您自己的DialTLS版本。在那里,您使用net.Dial连接到服务器,执行TLS握手,然后您可以自由验证。

package main 

import (
    "crypto/tls" 
    "log" 
    "net" 
    "net/http" 
    "net/http/httputil" 
    "net/url" 
) 

func main() { 
    proxy := httputil.NewSingleHostReverseProxy(&url.URL{ 
     Scheme: "https", 
     Host: "sha256.badssl.com", 
    }) 

    // Set a custom DialTLS to access the TLS connection state 
    proxy.Transport = &http.Transport{DialTLS: dialTLS} 

    // Change req.Host so badssl.com host check is passed 
    director := proxy.Director 
    proxy.Director = func(req *http.Request) { 
     director(req) 
     req.Host = req.URL.Host 
    } 

    log.Fatal(http.ListenAndServe("127.0.0.1:3000", proxy)) 
} 

func dialTLS(network, addr string) (net.Conn, error) { 
    conn, err := net.Dial(network, addr) 
    if err != nil { 
     return nil, err 
    } 

    host, _, err := net.SplitHostPort(addr) 
    if err != nil { 
     return nil, err 
    } 
    cfg := &tls.Config{ServerName: host} 

    tlsConn := tls.Client(conn, cfg) 
    if err := tlsConn.Handshake(); err != nil { 
     conn.Close() 
     return nil, err 
    } 

    cs := tlsConn.ConnectionState() 
    cert := cs.PeerCertificates[0] 

    // Verify here 
    cert.VerifyHostname(host) 
    log.Println(cert.Subject) 

    return tlsConn, nil 
}