英文:
go multiple http clients with different tls configs
问题
尝试为调用多个服务的多个HTTP客户端实现不同的TLS配置(有些需要mTLS,有些不需要)。然而,我发现每个新请求都使用之前请求的TLS配置,而不是自己的TLS配置。例如,我有以下两个客户端。当client-1发起第一个请求时,它按预期验证服务器证书。但是当client-2发起下一个请求时,尽管为其配置了InsecureSkipVerify: true,它仍然尝试验证服务器证书。
client-1的配置如下:
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig = &tls.Config{RootCAs: certPool, InsecureSkipVerify: false}
client1 := http.Client{Transport: tr, Timeout: timeout}
client-2的配置如下:
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig = &tls.Config{RootCAs: certPool, InsecureSkipVerify: true}
client2 := http.Client{Transport: tr, Timeout: timeout}
client2请求的响应是x509: certificate signed by unknown authority。这实际上不应该发生,因为InsecureSkipVerify: true意味着不验证服务器证书。
英文:
Trying to implement multiple http clients for calling multiple services, each with their own tls configurations (some need mTLS while some do not). However, I am seeing that the each new request is using the tls config from prior request, and not its own tls config? For example, I have 2 clients as below. When client-1 makes the first request, it verifies the server cert as expected. But when client-2 makes the next request, it is still trying to verify the server cert even though InsecureSkipVerify: true is configured for it.
client-1 has config:
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig = &tls.Config{RootCAs: certPool, InsecureSkipVerify: false}
client1 := http.Client{Transport: tr, Timeout: timeout}
client-2 has config:
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig = &tls.Config{RootCAs: certPool, InsecureSkipVerify: true}
client2 := http.Client{Transport: tr, Timeout: timeout}
response for the client2 request is x509: certificate signed by unknown authority. This shouldn't ideally happen because InsecureSkipVerify: true means the server certs are not verified.
答案1
得分: 2
http.DefaultTransport 是在 http 包中定义的一个变量(这里),如下所示:
var DefaultTransport RoundTripper = &Transport{
Proxy: ProxyFromEnvironment,
DialContext: defaultTransportDialContext(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}),
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
你可以使用 DefaultTransport 来创建多个 http.Client 实例,但需要记住它们都将使用相同的 Transport(即 DefaultTransport)。对 DefaultTransport 的更改将影响使用 DefaultTransport 的所有 http.Client 实例。
要解决这个问题,你可以定义自己的 Transport(可以通过复制上述代码来实现,文档中有相关说明:链接),或者在更改 TLSClientConfig 之前先复制默认的传输方式(tr := http.DefaultTransport.(*http.Transport).Clone())。
英文:
http.DefaultTransport is a variable defined in the http package (here) as:
var DefaultTransport RoundTripper = &Transport{
Proxy: ProxyFromEnvironment,
DialContext: defaultTransportDialContext(&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}),
ForceAttemptHTTP2: true,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
You can use DefaultTransport to create multiple instances of http.Client but need to remember that they will all be using the same Transport (DefaultTransport). Changes to DefaultTransport will have an impact on all instances of http.Client that use DefaultTransport.
To resolve this either define your own Transport (perhaps by copying the above, this is covered in the docs) or make a copy (tr := http.DefaultTransport.(*http.Transport).Clone()) of the default transport before changing TLSClientConfig.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论