### Create and Run a Basic SOCKS5 Server in Go Source: https://github.com/things-go/go-socks5/blob/master/README.md This example shows how to create a SOCKS5 server using the go-socks5 package and start it listening on a specific TCP port. It includes basic logger configuration for output. ```go package main import ( "log" "os" "github.com/things-go/go-socks5" ) func main() { // Create a SOCKS5 server server := socks5.NewServer( socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Create SOCKS5 proxy on localhost port 8000 if err := server.ListenAndServe("tcp", ":8000"); err != nil { panic(err) } } ``` -------------------------------- ### Enable TLS/SSL for Secure SOCKS5 Connections (Go) Source: https://context7.com/things-go/go-socks5/llms.txt Provides an example of configuring and starting a SOCKS5 server with TLS encryption. It covers loading X.509 certificates and keys, setting up TLS configurations including cipher suites and minimum TLS version, and listening for secure connections. Clients would need to connect using TLS. ```go package main import ( "crypto/tls" "log" "os" "github.com/things-go/go-socks5" ) func main() { // Load TLS certificate and key cert, err := tls.LoadX509KeyPair("server.crt", "server.key") if err != nil { log.Fatal(err) } tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, }, } server := socks5.NewServer( socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Start TLS listener if err := server.ListenAndServeTLS("tcp", ":1443", tlsConfig); err != nil { log.Fatal(err) } // Clients must connect using TLS: // Example with curl: curl --proxy-insecure -x socks5://localhost:1443 http://example.com } ``` -------------------------------- ### Install go-socks5 Package Source: https://github.com/things-go/go-socks5/blob/master/README.md This snippet shows the command to install the go-socks5 package using Go modules. It's a prerequisite for importing and using the package in your Go projects. ```bash go get github.com/things-go/go-socks5 ``` -------------------------------- ### Go SOCKS5 Production Server Setup Source: https://context7.com/things-go/go-socks5/llms.txt This Go code sets up a production-ready SOCKS5 server. It includes custom authentication, IP/port filtering rules, request logging middleware, custom dialer with timeouts, and optional TLS support. It uses the 'github.com/things-go/go-socks5' library. ```go package main import ( "context" "crypto/tls" "io" "log" "net" "os" "time" "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/bufferpool" "github.com/things-go/go-socks5/statute" ) // Production-ready credentials with IP filtering type ProductionCredentials struct { users map[string]string } func (c *ProductionCredentials) Valid(user, password, userAddr string) bool { expectedPass, exists := c.users[user] if !exists { log.Printf("Authentication failed: unknown user %s from %s", user, userAddr) return false } if password != expectedPass { log.Printf("Authentication failed: invalid password for user %s from %s", user, userAddr) return false } log.Printf("Authentication successful: user %s from %s", user, userAddr) return true } // Production rules with comprehensive filtering type ProductionRules struct{} func (r *ProductionRules) Allow(ctx context.Context, req *socks5.Request) (context.Context, bool) { // Only allow CONNECT and ASSOCIATE if req.Command != statute.CommandConnect && req.Command != statute.CommandAssociate { log.Printf("Blocked: unsupported command %d", req.Command) return ctx, false } // Block private IPs if req.DestAddr.IP.IsPrivate() || req.DestAddr.IP.IsLoopback() { log.Printf("Blocked: private/loopback destination %s", req.DestAddr.String()) return ctx, false } // Block dangerous ports dangerousPorts := []int{22, 23, 25, 3389} for _, port := range dangerousPorts { if req.DestAddr.Port == port { log.Printf("Blocked: dangerous port %d", port) return ctx, false } } return ctx, true } // Request logging middleware func requestLogger(ctx context.Context, writer io.Writer, request *socks5.Request) error { username := "anonymous" if request.AuthContext != nil { if user, ok := request.AuthContext.Payload["username"]; ok { username = user } } log.Printf("[REQUEST] user=%s dest=%s from=%s", username, request.DestAddr.String(), request.RemoteAddr.String()) return nil } func main() { // Setup credentials creds := &ProductionCredentials{ users: map[string]string{ "admin": "secure_password_123", "user1": "another_password_456", }, } // Custom resolver with timeout customResolver := &struct { socks5.DNSResolver }{} // Custom buffer pool (64KB buffers) bufPool := bufferpool.NewPool(64 * 1024) // Create server with all production settings server := socks5.NewServer( // Authentication socks5.WithCredential(creds), // Access control socks5.WithRule(&ProductionRules{}), // DNS resolution socks5.WithResolver(customResolver), // Connection settings socks5.WithDial(func(ctx context.Context, network, addr string) (net.Conn, error) { dialer := &net.Dialer{ Timeout: 30 * time.Second, KeepAlive: 30 * time.Second, } return dialer.DialContext(ctx, network, addr) }), // UDP settings socks5.WithBindIP(net.ParseIP("0.0.0.0")), // Performance socks5.WithBufferPool(bufPool), // Logging socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), // Middleware socks5.WithConnectMiddleware(requestLogger), socks5.WithAssociateMiddleware(requestLogger), ) // Optional: Start with TLS useTLS := os.Getenv("USE_TLS") == "true" if useTLS { cert, err := tls.LoadX509KeyPair("server.crt", "server.key") if err != nil { log.Fatal("Failed to load TLS certificate:", err) } tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, } log.Println("Starting SOCKS5 server with TLS on :1443") if err := server.ListenAndServeTLS("tcp", ":1443", tlsConfig); err != nil { log.Fatal("Server error:", err) } } else { log.Println("Starting SOCKS5 server on :1080") if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal("Server error:", err) } } } ``` -------------------------------- ### Import go-socks5 Package in Go Source: https://github.com/things-go/go-socks5/blob/master/README.md This snippet demonstrates how to import the go-socks5 server package into your Go source code after installation. This allows you to use its functionalities to build a SOCKS5 server. ```go import "github.com/things-go/go-socks5" ``` -------------------------------- ### SOCKS5 Server with Username/Password Auth (Go) Source: https://context7.com/things-go/go-socks5/llms.txt This code configures a SOCKS5 server to enforce username and password authentication for all incoming connections. It uses a static map of credentials for validation. An example `curl` command is provided to show how a client would connect. ```go package main import ( "log" "os" "github.com/things-go/go-socks5" ) func main() { // Define static credentials (username -> password mapping) credentials := socks5.StaticCredentials{ "alice": "password123", "bob": "secret456", "charlie": "pass789", } // Create server with username/password authentication server := socks5.NewServer( socks5.WithCredential(credentials), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } // Example client connection with authentication: // Using curl: curl -x socks5://alice:password123@localhost:1080 http://example.com ``` -------------------------------- ### Go: Implement Middleware Chain for Request Processing Source: https://context7.com/things-go/go-socks5/llms.txt This Go code illustrates how to create and chain multiple middleware functions for the go-socks5 server to process requests. Each middleware can perform actions like logging, collecting metrics, rate limiting, or validation before the request is handled. This example shows middlewares for CONNECT and ASSOCIATE commands. ```go package main import ( "context" "fmt" "io" "log" "os" "time" "github.com/things-go/go-socks5" ) func loggingMiddleware(ctx context.Context, writer io.Writer, request *socks5.Request) error { username := "anonymous" if request.AuthContext != nil { if user, ok := request.AuthContext.Payload["username"]; ok { username = user } } log.Printf("CONNECT request: user=%s, dest=%s, from=%s", username, request.DestAddr.String(), request.RemoteAddr.String()) return nil } func metricsMiddleware(ctx context.Context, writer io.Writer, request *socks5.Request) error { // Record start time in context for duration tracking start := time.Now() // Store in request (you could also use context.WithValue) log.Printf("Request started at %s for destination %s", start, request.DestAddr.String()) return nil } func rateLimitMiddleware(ctx context.Context, writer io.Writer, request *socks5.Request) error { // Implement rate limiting logic username := "anonymous" if request.AuthContext != nil { if user, ok := request.AuthContext.Payload["username"]; ok { username = user } } // Check rate limit (pseudo-code) // if exceedsRateLimit(username) { // return fmt.Errorf("rate limit exceeded for user %s", username) // } log.Printf("Rate limit check passed for user %s", username) return nil } func validationMiddleware(ctx context.Context, writer io.Writer, request *socks5.Request) error { // Validate destination if request.DestAddr.Port == 0 { return fmt.Errorf("invalid destination port: 0") } // Block certain IP ranges if request.DestAddr.IP.IsLoopback() { return fmt.Errorf("connections to loopback addresses are not allowed") } return nil } func main() { server := socks5.NewServer( // Add multiple middlewares - they execute in order socks5.WithConnectMiddleware(loggingMiddleware), socks5.WithConnectMiddleware(rateLimitMiddleware), socks5.WithConnectMiddleware(validationMiddleware), socks5.WithConnectMiddleware(metricsMiddleware), // Middleware can also be added for ASSOCIATE (UDP) commands socks5.WithAssociateMiddleware(loggingMiddleware), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Custom IP-Filtered Credentials for SOCKS5 Server (Go) Source: https://context7.com/things-go/go-socks5/llms.txt This Go example implements a custom credential store for a SOCKS5 server that validates both username/password and restricts access based on the client's IP address. The `IPFilteredCredentials` type checks user credentials and an associated list of allowed IPs. ```go package main import ( "log" "os" "strings" "github.com/things-go/go-socks5" ) // IPFilteredCredentials allows limiting user access by IP address type IPFilteredCredentials struct { users map[string]string // username -> password allowedIPs map[string][]string // username -> allowed IPs } func (c *IPFilteredCredentials) Valid(user, password, userAddr string) bool { // Check if user exists and password matches expectedPass, exists := c.users[user] if !exists || password != expectedPass { return false } // Extract IP from address (format: "IP:Port") ip := strings.Split(userAddr, ":")[0] // Check if IP is allowed for this user allowedIPs, hasRestriction := c.allowedIPs[user] if !hasRestriction { return true // No IP restriction } for _, allowedIP := range allowedIPs { if ip == allowedIP { return true } } return false } func main() { creds := &IPFilteredCredentials{ users: map[string]string{ "admin": "admin123", "user": "user123", }, allowedIPs: map[string][]string{ "admin": {"127.0.0.1", "192.168.1.100"}, // Admin only from specific IPs // "user" has no restrictions }, } server := socks5.NewServer( socks5.WithCredential(creds), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Create Basic SOCKS5 Server (Go) Source: https://context7.com/things-go/go-socks5/llms.txt This snippet demonstrates how to create a minimal SOCKS5 server using the go-socks5 library with default settings. It listens on a specified TCP port and does not require any authentication. The server is configured with a logger for output. ```go package main import ( "log" "os" "github.com/things-go/go-socks5" ) func main() { // Create server with default settings (no authentication) server := socks5.NewServer( socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Listen on port 1080 if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Custom SOCKS5 Command Handlers (Go) Source: https://context7.com/things-go/go-socks5/llms.txt This snippet demonstrates how to override default SOCKS5 command handlers for CONNECT and ASSOCIATE commands. It shows custom logic for establishing connections and handling UDP associate requests, including sending success/failure replies and implementing bidirectional data copying. Dependencies include the 'github.com/things-go/go-socks5' package. ```go package main import ( "context" "fmt" "io" "log" "net" "os" "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/statute" ) func customConnectHandler(ctx context.Context, writer io.Writer, request *socks5.Request) error { log.Printf("Custom CONNECT handler: connecting to %s", request.DestAddr.String()) // Establish custom connection conn, err := net.Dial("tcp", request.DestAddr.String()) if err != nil { // Send failure response socks5.SendReply(writer, statute.RepHostUnreachable, nil) return fmt.Errorf("connection failed: %w", err) } defer conn.Close() // Send success response if err := socks5.SendReply(writer, statute.RepSuccess, conn.LocalAddr()); err != nil { return fmt.Errorf("failed to send reply: %w", err) } // Custom proxying logic here // For example, inject headers, transform data, etc. log.Printf("Connection established to %s, starting proxy", request.DestAddr.String()) // Use server's proxy method or implement custom bidirectional copy errCh := make(chan error, 2) go func() { _, err := io.Copy(conn, request.Reader) errCh <- err }() go func() { _, err := io.Copy(writer, conn) errCh <- err }() // Wait for one direction to finish err = <-errCh return err } func customAssociateHandler(ctx context.Context, writer io.Writer, request *socks5.Request) error { log.Printf("Custom ASSOCIATE handler: UDP relay for %s", request.DestAddr.String()) // Implement custom UDP relay logic // For example, add packet filtering, transformation, or logging return fmt.Errorf("UDP associate not implemented in custom handler") } func main() { server := socks5.NewServer( socks5.WithConnectHandle(customConnectHandler), socks5.WithAssociateHandle(customAssociateHandler), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Implement Custom Buffer Pool for Memory Optimization (Go) Source: https://context7.com/things-go/go-socks5/llms.txt Demonstrates creating a custom buffer pool that implements the bufferpool.BufPool interface for memory management optimization. It allows reusing byte slices to reduce garbage collection overhead. This is useful for high-performance network applications. ```go package main import ( "log" "os" "sync" "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/bufferpool" ) // CustomBufferPool implements bufferpool.BufPool interface type CustomBufferPool struct { pool sync.Pool size int } func NewCustomBufferPool(bufferSize int) *CustomBufferPool { return &CustomBufferPool{ size: bufferSize, pool: sync.Pool{ New: func() interface{} { buf := make([]byte, 0, bufferSize) return &buf }, }, } } func (p *CustomBufferPool) Get() []byte { buf := p.pool.Get().(*[]byte) // Reset buffer length to 0, keep capacity *buf = (*buf)[:0] return *buf } func (p *CustomBufferPool) Put(buf []byte) { // Only return to pool if capacity matches expected size if cap(buf) == p.size { p.pool.Put(&buf) } } func main() { // Use custom buffer pool with 64KB buffers customPool := NewCustomBufferPool(64 * 1024) server := socks5.NewServer( socks5.WithBufferPool(customPool), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Or use the built-in pool with custom size // builtinPool := bufferpool.NewPool(128 * 1024) // 128KB buffers // socks5.WithBufferPool(builtinPool) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Go: Implement Request-Aware Dialer for Logging Source: https://context7.com/things-go/go-socks5/llms.txt This Go code snippet demonstrates how to create a custom dialer for the go-socks5 server that intercepts connection requests. It logs user details, the requested network address, and connection status. This allows for detailed logging, custom routing, or rate limiting based on request information. ```go package main import ( "context" "log" "net" "os" "time" "github.com/things-go/go-socks5" ) func main() { server := socks5.NewServer( socks5.WithDialAndRequest( func(ctx context.Context, network, addr string, request *socks5.Request) (net.Conn, error) { // Log connection details username := "anonymous" if request.AuthContext != nil { if user, ok := request.AuthContext.Payload["username"]; ok { username = user } } log.Printf("User %s connecting to %s via %s from %s", username, addr, network, request.RemoteAddr) // Implement per-user routing or rate limiting here dialer := &net.Dialer{ Timeout: 15 * time.Second, } conn, err := dialer.DialContext(ctx, network, addr) if err != nil { log.Printf("Connection failed for %s to %s: %v", username, addr, err) return nil, err } log.Printf("Connection established for %s to %s", username, addr) return conn, nil }, ), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Integrate Goroutine Pool for Concurrency Control (Go) Source: https://context7.com/things-go/go-socks5/llms.txt Shows how to integrate a custom goroutine pool to manage concurrent connection handling in the SOCKS5 server. This limits the number of active goroutines, preventing resource exhaustion. It includes a basic pool implementation with submit and shutdown methods. ```go package main import ( "fmt" "log" "os" "sync" "github.com/things-go/go-socks5" ) // SimpleGoroutinePool implements a basic worker pool type SimpleGoroutinePool struct { workers int taskQueue chan func() wg sync.WaitGroup } func NewGoroutinePool(workers, queueSize int) *SimpleGoroutinePool { pool := &SimpleGoroutinePool{ workers: workers, taskQueue: make(chan func(), queueSize), } // Start worker goroutines for i := 0; i < workers; i++ { pool.wg.Add(1) go pool.worker() } return pool } func (p *SimpleGoroutinePool) worker() { defer p.wg.Done() for task := range p.taskQueue { task() } } func (p *SimpleGoroutinePool) Submit(task func()) error { select { case p.taskQueue <- task: return nil default: return fmt.Errorf("task queue full") } } func (p *SimpleGoroutinePool) Shutdown() { close(p.taskQueue) p.wg.Wait() } func main() { // Create pool with 100 workers and queue size of 1000 pool := NewGoroutinePool(100, 1000) defer pool.Shutdown() server := socks5.NewServer( socks5.WithGPool(pool), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Can also integrate third-party pools like: // - github.com/panjf2000/ants // - gopkg.in/go-playground/pool.v3 if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Filter SOCKS5 Commands with Custom Rules in Go Source: https://context7.com/things-go/go-socks5/llms.txt Implement fine-grained access control for SOCKS5 commands (CONNECT, BIND, ASSOCIATE) using custom rules. This Go code defines a CustomRuleSet that blocks loopback and private IP addresses, specific ports like SSH (22), and certain domains, while only allowing CONNECT commands. It integrates with the go-socks5 server using the WithRule option. ```go package main import ( "context" "log" "os" "strings" "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/statute" ) // CustomRuleSet implements fine-grained access control type CustomRuleSet struct{} func (r *CustomRuleSet) Allow(ctx context.Context, req *socks5.Request) (context.Context, bool) { // Block connections to localhost if req.DestAddr.IP.IsLoopback() { return ctx, false } // Block connections to private networks if req.DestAddr.IP.IsPrivate() { return ctx, false } // Block specific ports (e.g., SSH) if req.DestAddr.Port == 22 { return ctx, false } // Only allow CONNECT commands if req.Command != statute.CommandConnect { return ctx, false } // Block specific domains by checking auth context destStr := req.DestAddr.String() blockedDomains := []string{"blocked.com", "malicious.org"} for _, domain := range blockedDomains { if strings.Contains(destStr, domain) { return ctx, false } } return ctx, true } func main() { server := socks5.NewServer( socks5.WithRule(&CustomRuleSet{}), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) // Alternatively, use built-in rules: // socks5.NewPermitAll() - Allow all commands // socks5.NewPermitNone() - Deny all commands // socks5.NewPermitConnAndAss() - Allow CONNECT and ASSOCIATE only if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Address Rewriting for SOCKS5 Proxy (Go) Source: https://context7.com/things-go/go-socks5/llms.txt This snippet shows how to implement address rewriting for a SOCKS5 proxy server using the 'github.com/things-go/go-socks5' package. It defines a struct 'AddressRewriter' that intercepts destination addresses and redirects traffic to alternative destinations based on a predefined map. This allows for transparently changing where client requests are sent. ```go package main import ( "context" "log" "net" "os" "github.com/things-go/go-socks5" "github.com/things-go/go-socks5/statute" ) // AddressRewriter redirects traffic to different destinations type AddressRewriter struct { redirects map[string]string // original -> new destination } func (r *AddressRewriter) Rewrite(ctx context.Context, request *socks5.Request) (context.Context, *statute.AddrSpec) { originalDest := request.DestAddr.String() // Check if this destination should be rewritten if newDest, exists := r.redirects[originalDest]; exists { log.Printf("Rewriting destination from %s to %s", originalDest, newDest) // Parse new destination host, port, _ := net.SplitHostPort(newDest) ip := net.ParseIP(host) portNum := 0 fmt.Sscanf(port, "%d", &portNum) return ctx, &statute.AddrSpec{ IP: ip, Port: portNum, AddrType: statute.ATYPIPv4, } } // No rewrite needed return ctx, request.DestAddr } func main() { rewriter := &AddressRewriter{ redirects: map[string]string{ "oldserver.com:80": "newserver.com:80", "api.example.com:443": "192.168.1.100:8443", }, } server := socks5.NewServer( socks5.WithRewriter(rewriter), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Customize Outbound Connections with Custom Dialer in Go Source: https://context7.com/things-go/go-socks5/llms.txt Customize how the SOCKS5 proxy establishes outbound connections. This Go code demonstrates using a custom dialer with a specified timeout and binding outbound connections to a particular local IP address (e.g., 192.168.1.10). This is useful for specific routing or transport requirements. It's configured using the WithDial option in go-socks5. ```go package main import ( "context" "log" "net" "os" "time" "github.com/things-go/go-socks5" ) func main() { // Configure custom dialer with timeout and local address binding server := socks5.NewServer( socks5.WithDial(func(ctx context.Context, network, addr string) (net.Conn, error) { dialer := &net.Dialer{ Timeout: 10 * time.Second, // Bind to specific local IP for outbound connections LocalAddr: &net.TCPAddr{ IP: net.ParseIP("192.168.1.10"), }, } return dialer.DialContext(ctx, network, addr) }), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Implement Custom DNS Resolution in Go Source: https://context7.com/things-go/go-socks5/llms.txt Override default system DNS behavior by implementing a custom DNS resolver. This Go code defines a CustomResolver that supports domain-to-IP overrides and can direct DNS queries to a specified custom DNS server (e.g., 8.8.8.8). It integrates with the go-socks5 server using the WithResolver option. ```go package main import ( "context" "log" "net" "os" "github.com/things-go/go-socks5" ) // CustomResolver redirects specific domains or uses custom DNS servers type CustomResolver struct { overrides map[string]string // domain -> IP mapping } func (r *CustomResolver) Resolve(ctx context.Context, name string) (context.Context, net.IP, error) { // Check for manual overrides first if ip, exists := r.overrides[name]; exists { return ctx, net.ParseIP(ip), nil } // Use custom DNS server (e.g., 8.8.8.8) resolver := &net.Resolver{ PreferGo: true, Dial: func(ctx context.Context, network, address string) (net.Conn, error) { d := net.Dialer{} return d.DialContext(ctx, "udp", "8.8.8.8:53") }, } addrs, err := resolver.LookupIPAddr(ctx, name) if err != nil { return ctx, nil, err } if len(addrs) == 0 { return ctx, nil, net.ErrClosed } return ctx, addrs[0].IP, nil } func main() { resolver := &CustomResolver{ overrides: map[string]string{ "internal.company.com": "10.0.1.50", "api.local": "192.168.1.100", }, } server := socks5.NewServer( socks5.WithResolver(resolver), socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } } ``` -------------------------------- ### Configure SOCKS5 UDP Association with Custom Bind IP in Go Source: https://context7.com/things-go/go-socks5/llms.txt This Go code snippet configures a SOCKS5 server to enable the UDP ASSOCIATE command. It allows specifying a custom bind IP for UDP relay and uses rules to permit UDP traffic. The server listens on TCP port 1080. ```go package main import ( "log" "net" "os" "github.com/things-go/go-socks5" ) func main() { // Set bind IP for UDP associations bindIP := net.ParseIP("0.0.0.0") // Listen on all interfaces server := socks5.NewServer( socks5.WithBindIP(bindIP), // Use bind IP for resolving UDP address socks5.WithUseBindIpBaseResolveAsUdpAddr(true), // Enable UDP ASSOCIATE command via rules socks5.WithRule(socks5.NewPermitAll()), // Allows CONNECT, BIND, and ASSOCIATE socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))), ) if err := server.ListenAndServe("tcp", ":1080"); err != nil { log.Fatal(err) } // UDP ASSOCIATE command allows UDP traffic relay through the proxy // Client sends ASSOCIATE request, server responds with UDP relay address // Client then sends UDP packets to relay address, which forwards to destination } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.