我正在尝试构建一个网络抓取实用程序,允许任何人运行程序并让他们的计算机充当转发代理,主要是为了绕过 IP 封锁。对此的高级概述如下:
Requester --sends http request--> Centralized server --distributes request to random client-->
Client --sends request to target server--> Target server --responds back down to requester-->
Client --> Centralized server -> Requester
其中棘手的部分是允许客户端充当转发代理,而不实际暴露任何端口(因为我希望这没有棘手的网络设置,例如端口转发)。此外,我认为集中式服务器看起来像请求者的典型转发代理是有意义的,因此它可以使用以下代码:
func main() {
proxyURL, err := url.Parse("http://localhost:8080")
if err != nil {
panic(err)
}
httpClient := &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
response, err := httpClient.Get("https://example.com/")
if err != nil {
panic(err)
}
log.Println("Response status:", response.Status)
}
我最初的设计是让每个客户端打开一个到服务器的 websocket 连接,从而消除了它们暴露端口的需要。然后,原始 HTTP 请求将发送到客户端,客户端将请求/响应转发到目标服务器或从目标服务器转发。然而,我在让它正常工作方面遇到了很多麻烦。这是我的尝试:
// I don't know what the implementation of this would be.
type WSClient interface {
io.Reader
io.Writer
io.Closer
}
func main() {
var wsConn WSClient
proxy := func(w http.ResponseWriter, req *http.Request) {
client, _, err := w.(http.Hijacker).Hijack()
if err != nil {
w.WriteHeader(502)
fmt.Fprint(w, err)
return
}
client.Write([]byte("HTTP/1.0 200 OK\r\n\r\n"))
go func() {
_, err = io.Copy(wsConn, client)
if err != nil {
fmt.Println(err)
return
}
client.Close()
}()
go func() {
_, err := io.Copy(client, wsConn)
if err != nil {
fmt.Println(err)
return
}
wsConn.Close()
}()
}
http.ListenAndServe(":8080", http.HandlerFunc(proxy))
}
我真的不知道从这里该去哪里,这也不是实现我的超级易于设置转发代理目标的正确方法。有人能指出我正确的方向,或者给我一些代码示例来帮助我更接近我想要的功能吗?
除非代理请求源自本地(我的意思是内部与通过任何网络连接,甚至是环回),否则您将拥有侦听器,根据您的定义,我认为这将是“暴露的”。
我认为你的意思是“暴露”端口,因为它监听入站连接,经典的方法是将代理服务器设置为堡垒,一个网络接口位于互联网上,一个网络接口位于内部网上。
您的代理在 Intranet 上侦听,并且仅在 Internet 上进行出站连接。
根据定义,Web 代理(正向或反向)必须侦听请求。