英文:
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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论