This is a creation in Article, where the information may have evolved or changed.
The last use of Golang to implement the local SOCKS5 proxy, but the use of proxy is certainly for the harmonious Internet, so this time to introduce the use of SSH to implement remote agents, using the official SSH package
Golang.org/x/crypto/ssh
Connecting to SSH with Golang is not difficult
Read the key, set the configuration, connect to the server is OK (not recommended for user name + password to connect ssh)
b, err := ioutil.ReadFile("/home/myml/.ssh/id_rsa")if err != nil {log.Println(err)return}pKey, err := ssh.ParsePrivateKey(b)if err != nil {log.Println(err)return}config := ssh.ClientConfig{User: "userName",Auth: []ssh.AuthMethod{ssh.PublicKeys(pKey),},}client, err = ssh.Dial("tcp", "Host:22", &config)if err != nil {log.Println(err)return}log.Println("连接服务器成功")defer client.Close()
So you get a client, it has a dial () function to create a socket connection, this is created on the server, you can break the network limit, plus the last SOCK5 agent, put net. Dial change to Client.dial, you can have the server to delegate access to the
server, err := client.Dial("tcp", addr)if err != nil {log.Println(err)return}conn.Write([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})go io.Copy(server, conn)io.Copy(conn, server)
Below are the code that runs successfully and remote agents (in Chrome and proxychains tests), and the SSH server and configuration information are modified to their own
Socks5proxyproxy Project main.gopackage mainimport ("bytes" "Encoding/binary" "FMT" "io" "io/ioutil" "Log" "NET" Golang.org/x/crypto/ssh ") func socks5proxy (conn net. Conn) {defer Conn. Close () var b [1024]byten, ERR: = conn. Read (b[:]) if err! = Nil {log. PRINTLN (Err) return}log. Printf ("% x", B[:N]) Conn. Write ([]byte{0x05, 0x00}) N, err = conn. Read (b[:]) if err! = Nil {log. PRINTLN (Err) return}log. Printf ("% x", b[:n]) var addr stringswitch b[3] {case 0X01:SIP: = sockip{}if err: = Binary. Read (bytes. Newreader (B[4:n]), binary. Bigendian, &SIP); Err! = Nil {log. PRINTLN ("Request parsing error") Return}addr = sip.toaddr () case 0x03:host: = String (B[5:n-2]) var port uint16err = binary. Read (bytes. Newreader (B[n-2:n]), binary. Bigendian, &port) if err! = Nil {log. PRINTLN (err) return}addr = FMT. Sprintf ("%s:%d", host, Port)}server, err: = client. Dial ("tcp", addr) if err! = Nil {log. PRINTLN (Err) return}conn. Write ([]byte{0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) go io. Copy (server, conn) io. COPY (conn, server)}type Sockip struct {A, B, C, D byteport uint16}func (IP sockip) toAddr () string {return FMT. Sprintf ("%d.%d.%d.%d:%d", IP. A, IP. B, IP. C, IP. D, IP. PORT)}func Socks5proxystart () {log. SetFlags (log. Ltime | Log. Lshortfile) Server, err: = Net. Listen ("TCP", ": 8080") if err! = Nil {log. Panic (ERR)}defer server. Close () log. Println ("Start accepting connections") for {client, err: = Server. Accept () if err! = Nil {log. PRINTLN (Err) return}log. Println ("A New Connection") go socks5proxy (client)}}var client *ssh. Clientfunc Main () {b, err: = Ioutil. ReadFile ("/home/myml/.ssh/id_rsa") if err! = Nil {log. PRINTLN (Err) Return}pkey, err: = ssh. Parseprivatekey (b) if err! = Nil {log. PRINTLN (err) Return}config: = ssh. Clientconfig{user: "User", Auth: []ssh. Authmethod{ssh. Publickeys (PKey),},}client, err = ssh. Dial ("TCP", "host:22", &config) if err! = Nil {log. PRINTLN (Err) return}log. PRINTLN ("Connection server succeeded") defer client. Close () client. Dial () Socks5proxystart () return}