How to proxy https requests using Go, http requests work fine?

huangapple go评论92阅读模式
英文:

How to proxy https requests using Go, http requests work fine?

问题

我会尽力解释一切,对服务器的东西还不太熟悉!所有的代码都是用Go语言编写的,主要问题出在ServeHTTP函数上。

问题

我正在处理通过(http.server).ListenAndServe()接收到的请求,并将其通过(http.ReverseProxy).ServeHTTP(http.ResponseWriter, *http.Request)发送到另一个代理服务器。我使用Python的requests库提交GET请求,并通过第一个服务器和第二个服务器代理到实际目标。我已经能够提交和接收HTTP请求,但是无法提交HTTPS请求。

错误信息

我不断收到来自Python请求库的502 bad gateway错误,很可能是由于在使用https://httpbin.org或任何其他https网站时,ServeHTTP()返回了http: proxy error: unsupported protocol scheme ""。使用http时,会将HTML返回给我。

响应的差异

对于http,*http.Response的差异是

&{GET http://httpbin.org HTTP/1.0 1 0 map[] <nil> <nil> 0 [] true http://httpbin.org map[] map[] <nil> map[] [我的IP地址] http://httpbin.org <nil> <nil> <nil> 0xc000050fc0}

而对于https,差异是

&{CONNECT //httpbin.org:443 HTTP/1.0 1 0 map[] <nil> <nil> 0 [] true httpbin.org:443 map[] map[] <nil> map[] [我的IP地址] httpbin.org:443 <nil> <nil> <nil> 0xc0000503c0}

这是*http.Request的文档链接:链接

我之前尝试过的方法

我尝试修改ReverseProxy.Director属性,并让函数修改*http.Request。我尝试过删除":443"并添加"https://"或"http://"。但是这样做会导致错误的请求。我还尝试将CONNECT请求更改为GET或POST,但两者都产生了奇怪的结果,包括无效的方法或错误的请求。

需要帮助吗?

英文:

I'm going to try my best to explain everything, new to server stuff! Everything is in Go and the main issue is with the ServeHTTP.

Problem

I'm working on forwarding requests received by (http.server).ListenAndServe() to be sent to another proxy server via (http.ReverseProxy).ServeHTTP(http.ResponseWriter, *http.Request). I'm using the python requests to submit a GET request and proxy it through the first server and the second server, to the actual target. I have been able to submit and receive http requests, but I cannot submit https requests.

Error

I constantly receive 502 bad gateway from the python request library, likely a result of http: proxy error: unsupported protocol scheme &quot;&quot; from ServeHTTP() when I use https://httpbin.org or any other https site. Using http results in the html being returned to me.

Response differences

The difference in *http.Response is for http is

&amp;{GET http://httpbin.org HTTP/1.0 1 0 map[] &lt;nil&gt; &lt;nil&gt; 0 [] true http://httpbin.org map[] map[] &lt;nil&gt; map[] [my ip address] http://httpbin.org &lt;nil&gt; &lt;nil&gt; &lt;nil&gt; 0xc000050fc0}

and https is

&amp;{CONNECT //httpbin.org:443 HTTP/1.0 1 0 map[] &lt;nil&gt; &lt;nil&gt; 0 [] true httpbin.org:443 map[] map[] &lt;nil&gt; map[] [my ip address] httpbin.org:443 &lt;nil&gt; &lt;nil&gt; &lt;nil&gt; 0xc0000503c0}

Here is a link to the documentation for *http.Request

What I've previously tried

I've tried modifying ReverseProxy.Director attribute and having the function modify the *http.Request. I've done everything from removing the ":443" and adding "https://" or even "http://". Doing this results in a bad request error. I've also tried changing the CONNECT request to a GET or POST, both of which had strange results including invalid method or bad request.

Any help?

答案1

得分: 1

客户端发出了错误的请求。它应该是CONNECT httpbin.org:443 HTTP/1.0,即只包含目标服务器的域名和端口。鉴于标准的Python工具可以正确处理代理的HTTPS请求,问题很可能是由某些(未知的)自定义代码发出了错误的代理请求。

英文:

> ... CONNECT //httpbin.org:443 HTTP/1.0 ...

The client is doing the wrong request. It needs to be CONNECT httpbin.org:443 HTTP/1.0, i.e. just domain and port of the target server. Given that standard Python tools properly handle HTTPS for proxies, the problem is likely caused by some (unknown) self-made code issuing the wrong proxy requests.

答案2

得分: 1

我认为问题在于你无法正常地代理一个https请求。根据你的描述,我猜你正在尝试将服务器作为另一个代理的代理,所以看起来你需要进行中间人攻击,以欺骗被代理的请求将其发送到实际的代理服务器。

请注意,这可能是一个不太好的主意,请确保如果是这种情况,所有的请求都是安全的,因为中间服务器可以读取未加密的https信息。

不幸的是,我想不到一个快速的解决方案。相反,你需要深入研究这个,修改特定的中间人请求,并设置一个https.go分发每个请求到的进一步代理服务器的池。

祝你好运!

英文:

I think the issue is that you can't really proxy an https request normally. I assume you're trying to use the server as a proxy to another proxy based on your description, so it looks like you're going to have to Man in the middle it to trick the proxied request to send it along to the actual proxy server.

NOTE this can be kind of a bad idea, make sure that if this is the case all the requests are secure as what'll happen is the intermediate server can read the unencrypted https info.

Unfortunately there's no quick solution I could think of. Instead you have to dive deep into this library and modify the specific MITM request and set up a pool of the further proxy servers that https.go distributes each request to.

Best of luck!

huangapple
  • 本文由 发表于 2021年8月28日 06:00:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/68959729.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定