package main import "github.com/armon/go-socks5" func main(){ conf := &socks5.Config{} server, err := socks5.New(conf) if err != nil { panic(err) } // Create SOCKS5 proxy on localhost port 8000 if err := server.ListenAndServe("tcp", "127.0.0.1:8000"); err != nil { panic(err) } }
lib ตัวนี้เป็น SOCKS5 อย่างเดียวเวลา connect ให้ตั้ง type เป็น SOCKS5 ด้วยนะเวลาจะทดสอบ
ตามรูปตัวอย่างบรรทัดด้านบนเป็นการลองส่ง request จาก client ที่ set SOCKS 4 มาจะเห็นว่า connect ไม่ได้ ถ้า set ถูกจะเห็นตามบรรทัดล่างๆคือ มีการส่งข้อมูลไปกลับระหว่าตัว client กับ target
แค่นี้ยังไม่พอเรามา hack เพิ่มอีกนิดหน่อยดีกว่า จริงๆผมอยาก print log มากกว่านี้แต่ ไปอ่านdoc มันแล้วไม่มี function พวกนี้เลย เรามาเขียน ความสามารถที่เราอยากได้เพิ่มให้กับ lib มันเลยดีกว่า
โดยเข้าไปแก้ file ที่อยู่ใน path src/github.com/armon/go-socks5/request.go
หรือถ้าต้องการ monitor อะไรเพิ่มเติมก็ไปเขียน hook เพิ่มเอาได้เลย
func (s *Server) handleConnect(conn conn, bufConn io.Reader, dest, realDest *AddrSpec) error { // Check if this is allowed client := conn.RemoteAddr().(*net.TCPAddr) if !s.config.Rules.AllowConnect(realDest.IP, realDest.Port, client.IP, client.Port) { if err := sendReply(conn, ruleFailure, nil); err != nil { return fmt.Errorf("Failed to send reply: %v", err) } return fmt.Errorf("Connect to %v blocked by rules", dest) } // Attempt to connect addr := net.TCPAddr{IP: realDest.IP, Port: realDest.Port} target, err := net.DialTCP("tcp", nil, &addr) if err != nil { msg := err.Error() resp := hostUnreachable if strings.Contains(msg, "refused") { resp = connectionRefused } else if strings.Contains(msg, "network is unreachable") { resp = networkUnreachable } if err := sendReply(conn, resp, nil); err != nil { return fmt.Errorf("Failed to send reply: %v", err) } return fmt.Errorf("Connect to %v failed: %v", dest, err) } defer target.Close() // Send success local := target.LocalAddr().(*net.TCPAddr) bind := AddrSpec{IP: local.IP, Port: local.Port} if err := sendReply(conn, successReply, &bind); err != nil { return fmt.Errorf("Failed to send reply: %v", err) } // Start proxying errCh := make(chan error, 2) go proxy("target", target, bufConn, errCh,realDest.IP) go proxy("client", conn, target, errCh,local.IP) // Wait select { case e := <-errCh: return e } }
function handleConnection เพิ่งตรงให้ go routine เรียก function โดยเพิ่มตัวแปร IP เข้าไปด้วย
func proxy(name string, dst io.Writer, src io.Reader, errCh chan error,ip1 net.IP) { // Copy n, err := io.Copy(dst, src) // Log, and sleep. This is jank but allows the otherside // to finish a pending copy log.Printf("[DEBUG] socks: Copied %d bytes to %s[%v]", n, name,ip1) time.Sleep(10 * time.Millisecond) // Send any errors errCh <-err }และที่ function proxy ให้รับตัวแปรเพิ่มอีก 1 ตัวและ print log IP ออกมาแสดง
จะได้ผลตามนี้
แค่ code ไม่กี่บรรทัดก็ได้ SOCKS server แล้ว
ไม่มีความคิดเห็น:
แสดงความคิดเห็น