这是客户端(反向代理)的代码: http://pastebin.com/w3i9cap4 解决方案必须对连接进行配对,以使两个客户端"互相交谈,其中一个充当SOCKS5服务器,一个充当SOCKS5客户端..您可以从位于NAT后的服务器"和连接到位于NAT后的服务器的客户端"这两个公共服务器上接受TCP连接.两个连接都建立后,您可以使用 io.Copy 代理输入并两个连接之间的输出.您将必须保持一组连接,以便对任何新的SOCKS5客户端连接请求都可以使用一个SOCKS5服务器连接. NAT背后的服务器将必须拨打与公共服务器的新连接,然后在该连接上服务SOCKS5请求使用接受io.ReadWriteCloser 的通用SOCKS5服务器.一个未经测试的简化示例: 程序包主要进口 ("io"日志"网")func main(){lnServer,错误:= net.Listen("tcp","1234")如果err!= nil {log.Fatalln(错误)}lnClients,错误:= net.Listen("tcp","1235")如果err!= nil {log.Fatalln(错误)}serverCh:= make(chan net.Conn)转到func(){为了 {conn,err:= lnServer.Accept()如果err!= nil {//处理错误}serverCh<-conn}}()为了 {conn,err:= ln.Accept()如果err!= nil {//处理错误}sc<-serverCh去io.Copy(sc,conn)io.Copy(conn,sc)}} 避免创建自己的连接池和配对的更简单方法是在两台服务器之间创建VPN.公共服务器将所有连接转发到NAT客户端的位置.它将能够接受通过VPN分配的虚拟IP上的连接.进行此设置的一种流行解决方案是 OpenVPN .I have a few problems to understand the theory of exposing clients behind NATs via a public server, for example to use the client as a proxy (preferably SOCKS5).I want to solve this problem using Go and there are some awesome Go libraries out there for SOCKS5 so this is no problem.If a client behind a NAT connects to a public server, how do others users can connect (maybe on a different port) and how should I forward the requests?"C" is the (single) client behind NAT"A" is the public server i want to use to expose the client"U" is a user (or multiple users) which want to connect to C through Ae.g. if A (public server) listens on port 5544 and C (the client behind NAT connects to it while C also has a local SOCKS5 server where the requests are getting forwarded to) how does (U) the user or maybe even multiple users forward the request to C (the first connection made on A:5544)[ U --> A:5544 <--> C <--> C local socks5 server]User connects to A, C is connected to A, the traffic gets forwarded to C (note that C doesn't listen for incoming connections cause C is connected to A and not reverse, because C is behind a NAT)I hope you understand what I mean.Thank you in advance!Edit:To point out what i mean.C - the client behind the NAT does not directly listen on TCP it just opens up a TCP connection (net.Dial() ...) to the public server which soulde expose the client - the socks5 proxy on C is not directly exposed so the dialed TCP connection soulde somehow behave like a TCP listener.I think basically it's the same technique that teamviewer is using.But how exactly? And also it's important that multiple users can connect to the client "C" through "A".Addition: baloo's answer got me a step further but now the problem is that if the answer/traffic from the Client <--> Remote server connection get's copied (on the public server side code) via _, err := io.Copy(usrConn, s.ProxyClient)The data gets streamed/tunneled but if I request a site through the proxy the site is loading and loading this causes also the problem that other "User" connections are blocked. (I get a Site response on the first request so far but the request of the whole site is still pending... I may have a wrong understanding of the SOCKS5 protocol?)Here is my messy prototype code for the public server: http://pastebin.com/7Y2JBVE0And this is the code for the client (reverse proxy): http://pastebin.com/w3i9cap4 解决方案 The connections has to be paired as to make two "clients" talk to each other, where one of them acts as the SOCKS5 server and one as the SOCKS5 client. You accept TCP connections on the public server from both the "server behind NAT" and the "client that connects to server behind NAT".Once both connections are up, you could use io.Copy to proxy the inputs and outputs between the two connections.You will have to keep a pool of connections around, so that there will be one SOCKS5 server connection available to any new SOCKS5 client connection request.The server behind NAT will have to dial a new connection to the public server and then serve SOCKS5 requests on that connection using a generic SOCKS5 server that accepts io.ReadWriteCloser.A simplified and untested example:package mainimport ( "io" "log" "net")func main() { lnServer, err := net.Listen("tcp", "1234") if err != nil { log.Fatalln(err) } lnClients, err := net.Listen("tcp", "1235") if err != nil { log.Fatalln(err) } serverCh := make(chan net.Conn) go func() { for { conn, err := lnServer.Accept() if err != nil { // handle errors } serverCh <- conn } }() for { conn, err := ln.Accept() if err != nil { // handle errors } sc <- serverCh go io.Copy(sc, conn) io.Copy(conn, sc) }}An easier approach to avoid creating your own connection pooling and pairing might be to create a VPN between the two servers. Where the public server forwards all connections towards the NAT'ed client. Which will be able to accept connections on a virtual IP that is assigned through VPN. One popular solution for doing this setup is OpenVPN. 这篇关于使用NAT后面的客户端作为通过公共服务器的代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!