对特定主机使用 TLS/SSL 客户端身份验证
Using TLS/SSL Client Authentication for specific hosts
如何在使用像 httprouter by julienschmidt 这样的反向代理时对特定主机使用 TLS/SSL 客户端身份验证?
我可以使用 http.DefaultTransport
在全局事务中设置客户端证书。
transport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
},
}
http.DefaultTransport = transport
但只想对特定主机使用客户端证书,例如:
- host1 的 cert1
- host2 的 cert2
- 其他无客户端证书
更新
我预计回调 GetConfigForClientHandler
或
GetCertificateHandler
将被调用。此时我可以对 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")
}
- 创建一个为所有主机共享的 TLS 配置。可能你不需要在那里设置太多。但是您想设置一个
Config.GetConfigForClient
处理程序。
- 在该处理程序中,您检查
ClientHelloInfo.ServerName
. That is the requested host. You then modify the TLS config to require client auth there (Config.ClientAuth
).
- 用
tls.NewListener
包裹你的net.Listener
- 在
http.Serve
中使用您的 TLS net.Listener
(您可以在此处使用 httprouter)
如何在使用像 httprouter by julienschmidt 这样的反向代理时对特定主机使用 TLS/SSL 客户端身份验证?
我可以使用 http.DefaultTransport
在全局事务中设置客户端证书。
transport := &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{cert},
},
}
http.DefaultTransport = transport
但只想对特定主机使用客户端证书,例如:
- host1 的 cert1
- host2 的 cert2
- 其他无客户端证书
更新
我预计回调 GetConfigForClientHandler
或
GetCertificateHandler
将被调用。此时我可以对 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")
}
- 创建一个为所有主机共享的 TLS 配置。可能你不需要在那里设置太多。但是您想设置一个
Config.GetConfigForClient
处理程序。 - 在该处理程序中,您检查
ClientHelloInfo.ServerName
. That is the requested host. You then modify the TLS config to require client auth there (Config.ClientAuth
). - 用
tls.NewListener
包裹你的net.Listener
- 在
http.Serve
中使用您的 TLSnet.Listener
(您可以在此处使用 httprouter)