go - 如何在 golang 中做代理和 TLS
问题描述
我正在尝试通过代理路由我的请求,并在 TLS 配置中发送 cert.pem。下面的代码抛出了这个错误 - proxyconnect tcp: tls: first record doesn't look like a TLS handshake。当我将代理 URL 从 https 更改为 HTTP 时,相同的代码可以工作。但是带有 https 的代理 URL 在 python 中有效。以下是我到目前为止的代码
certs := x509.NewCertPool()
pemFile, err := ioutil.ReadFile("cert.pem")
if err != nil {
return
}
certs.AppendCertsFromPEM(pemFile)
tlsConfig := &tls.Config{
RootCAs: certs,
}
proxyUrl, err := url.Parse("https://someproxyurlhere.com:8080")
if err != nil {
return
}
t := &http.Transport{
TLSClientConfig: tlsConfig,
Proxy: http.ProxyURL(proxyUrl),
}
client := http.Client{
Transport: t,
}
reqBody := "some JSON body here"
buff, err := json.Marshal(reqBody)
if err != nil {
return
}
req, err := http.NewRequest(http.MethodPost, "https://someurlhere.com", bytes.NewBuffer(buff))
if err != nil {
return
}
res, err := client.Do(req)
if err != nil {
// Error here - proxyconnect tcp: tls: first record does not look like a TLS handshake
return
}
defer res.Body.Close()
Python代码
import requests
os.environ['HTTPS_PROXY'] = 'https://someproxyurlhere.com:8080'
response = requests.post("https://someurlhere.com",
json={'key': 'value'},
verify='cert.pem')
print(str(response.content))
解决方案
当我将代理 URL 从 https 更改为 HTTP 时,相同的代码可以工作。
这是因为您使用的 HTTP 代理需要通过 HTTP 而不是 HTTPS 访问,即使是https://..
URL。这就是 HTTPS 代理通常的工作方式。请注意,虽然理论上代理可以嗅探它是否获得普通或 TLS 连接,但实际上代理(和服务器)使用不同的端口用于 HTTP 和 HTTPS - 因此,如果它在一个带有 HTTP 的端口上工作,它很可能无法在与 HTTPS 相同的端口。
proxyconnect tcp: tls: first record 看起来不像 TLS 握手。
这是因为代理对奇怪的 HTTP 请求(实际上是 TLS 握手的开始)回答了一个普通的 HTTP 错误。
但是带有 https 的代理 URL 在 python 中有效。
虽然它看起来有效,但实际上并没有。即使https://
以 URL 的形式给出,Python 请求仍将使用纯 HTTP 到代理。
您可以尝试与代理本身建立简单的 TLS 连接,例如使用 Python 或使用openssl s_client
. 它很可能会因一些握手错误而失败,因为代理实际上并不期待 TLS。
推荐阅读
- javascript - 如何在 JavaScript 中向对象添加函数而不会导致内存效率低下
- python - 网状虚拟环境
- reactjs - 将功能组件连接到 redux store
- node.js - 2dsphere 不是路径“索引”中的有效类型
- angular8 - 角度更新 8.1 到 8.2 我得到很多“无法读取未定义的属性 'ngInjectableDef'”
- r - 如何在循环R中创建独立的不同data.frame
- java - 为什么我们需要抽象方法?
- gerrit - 从 gerrit rest 或 ssh api 获取依赖更改的更改 id?
- sql - 替换存储过程的字符串
- c# - 使用图层蒙版进行光线投射