代理 https 时强制客户端主机名
Force client hostname when proxying https
我正在使用 toxiproxy。我有 this exact issue. Both of the curl
solutions mentioned in the issue work (solution a, solution b),但我不能使用 curl。我需要使用 go 标准 net/http
库。
有没有什么方法可以使用 net/http
的方式明确告诉它代理正在使用哪个主机,以便它可以看到证书有效?
我已经尝试在 net/http.Request 上设置 Host
和 Authority
headers,但这没有用。
详情
Toxiproxy 输出:
proxy=[::]:22002 upstream=maps.googleapis.com:443
我的代码:
url := "https://localhost:22002/maps/api/geocode/json..."
req, err := http.NewRequest("GET", url, nil)
req.Host = "maps.googleapis.com"
req.Header.Set("Host", "maps.googleapis.com")
res, err := httpClient.Do(req)
错误:
x509: certificate is valid for *.googleapis.com,
*.clients6.google.com, *.cloudendpointsapis.com, cloudendpointsapis.com, googleapis.com, not localhost
您需要设置 http.Request.Host
字段,以便 http 请求具有正确的 header
req.Host = "maps.googleapis.com"
您还需要在 tls.Config.ServerName
字段中设置主机名以进行 SNI 和主机名验证。
如果您已经为您的 httpClient
配置了传输,您可以这样设置:
httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
ServerName: "maps.googleapis.com",
}
或者对于小程序,您可以覆盖默认值:
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
ServerName: "maps.googleapis.com",
}
或者为您的程序创建自定义传输
var httpTransport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
ServerName: "maps.googleapis.com",
},
}
只需确保重复使用传输,不要为每个请求创建一个新传输。
我正在使用 toxiproxy。我有 this exact issue. Both of the curl
solutions mentioned in the issue work (solution a, solution b),但我不能使用 curl。我需要使用 go 标准 net/http
库。
有没有什么方法可以使用 net/http
的方式明确告诉它代理正在使用哪个主机,以便它可以看到证书有效?
我已经尝试在 net/http.Request 上设置 Host
和 Authority
headers,但这没有用。
详情
Toxiproxy 输出:
proxy=[::]:22002 upstream=maps.googleapis.com:443
我的代码:
url := "https://localhost:22002/maps/api/geocode/json..."
req, err := http.NewRequest("GET", url, nil)
req.Host = "maps.googleapis.com"
req.Header.Set("Host", "maps.googleapis.com")
res, err := httpClient.Do(req)
错误:
x509: certificate is valid for *.googleapis.com, *.clients6.google.com, *.cloudendpointsapis.com, cloudendpointsapis.com, googleapis.com, not localhost
您需要设置 http.Request.Host
字段,以便 http 请求具有正确的 header
req.Host = "maps.googleapis.com"
您还需要在 tls.Config.ServerName
字段中设置主机名以进行 SNI 和主机名验证。
如果您已经为您的 httpClient
配置了传输,您可以这样设置:
httpClient.Transport.(*http.Transport).TLSClientConfig = &tls.Config{
ServerName: "maps.googleapis.com",
}
或者对于小程序,您可以覆盖默认值:
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
ServerName: "maps.googleapis.com",
}
或者为您的程序创建自定义传输
var httpTransport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
TLSClientConfig: &tls.Config{
ServerName: "maps.googleapis.com",
},
}
只需确保重复使用传输,不要为每个请求创建一个新传输。