如何在Golang中执行代理和TLS [英] How to do proxy and TLS in golang

查看:479
本文介绍了如何在Golang中执行代理和TLS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过代理路由我的请求,并且还在TLS配置中发送cert.pem.下面的代码引发了此错误- proxyconnect tcp:tls:第一条记录看起来不像TLS握手.当我将代理URL从https更改为HTTP时,相同的代码有效.但是,带有https的代理URL在python中有效.下面是到目前为止的代码

I am trying to route my requests through a proxy and also sending cert.pem in TLS config. Below code is throwing this error - proxyconnect tcp: tls: first record does not look like a TLS handshake. When I change the proxy URL from https to HTTP, the same code works. However proxy URL with https works in python. Below is my code so far

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时,相同的代码有效.

When I change the proxy URL from https to HTTP, the same code works.

这是因为您使用的是HTTP代理,即使对于 https://. URL,也需要通过HTTP而不是HTTPS进行访问.这就是HTTPS代理通常的工作方式.请注意,虽然从理论上讲,代理在实践中可能会嗅探它是否获得普通连接或TLS连接,但是代理(和服务器)对HTTP和HTTPS使用不同的端口-因此,如果它在使用HTTP的一个端口上工作,则很可能无法在与HTTPS相同的端口.

This is because you are using a HTTP proxy which need to be accessed by HTTP and not HTTPS even for https://.. URLs. This is how HTTPS proxying usually works. Note that while in theory a proxy could sniff if it gets a plain or a TLS connection in practice proxies (and servers) use different ports for HTTP and HTTPS - thus if it works on one port with HTTP it will very likely not work on the same port with HTTPS.

proxyconnect tcp:tls:第一条记录看起来不像TLS握手.

proxyconnect tcp: tls: first record does not look like a TLS handshake.

这是因为代理使用简单的HTTP错误来响应奇怪的HTTP请求(这实际上是TLS握手的开始).

This is because the proxy answers with an plain HTTP error to the strange HTTP request (which is actually the start of the TLS handshake).

带https的代理URL在python中有效.

However proxy URL with https works in python.

虽然看起来有效,但实际上不起作用.即使将 https://指定为URL,Python请求仍将使用纯HTTP代理.

While it looks that it works it actually doesn't. Python requests will still use plain HTTP to the proxy even if https:// was given as URL.

您可以尝试与代理本身建立简单的TLS连接,例如使用Python或 openssl s_client .由于代理实际上并不期望使用TLS,因此很可能会由于一些握手错误而失败.

You can try to do a simple TLS connection to the proxy itself, for example with Python or with openssl s_client. It will very likely fail with some handshake error because the proxy isn't actually expecting TLS.

这篇关于如何在Golang中执行代理和TLS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆