You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何建立并维护带身份认证的SOCKS5代理服务器连接

Go语言获取带身份认证的SOCKS5代理服务器连接方案

核心实现逻辑:标准库golang.org/x/net/proxy的SOCKS5方法封装了完整的代理转发流程,如果你只需要和代理本身完成认证后的原始连接,手动实现SOCKS5的认证握手步骤即可,不需要走后续的目标地址CONNECT请求。

可直接使用的实现代码

package main

import (
	"errors"
	"net"
)

// SOCKS5认证相关常量,符合RFC 1928/RFC 1929规范
const (
	socks5Version = 0x05
	authMethodPassword = 0x02
	authMethodNone = 0x00
	authMethodNoAcceptable = 0xFF
	authPasswordVersion = 0x01
	authStatusSuccess = 0x00
)

// DialSocks5WithAuth 直接返回和SOCKS5代理完成认证后的net.Conn连接
func DialSocks5WithAuth(proxyAddr string, username, password string) (net.Conn, error) {
	// 第一步:先建立和代理服务器的基础TCP连接
	conn, err := net.Dial("tcp", proxyAddr)
	if err != nil {
		return nil, err
	}

	// 第二步:发送认证方法协商请求
	// 包结构:版本号+支持的认证方法数量+支持的认证方法列表
	authMethods := []byte{authMethodNone, authMethodPassword}
	negotiateReq := make([]byte, 2+len(authMethods))
	negotiateReq[0] = socks5Version
	negotiateReq[1] = byte(len(authMethods))
	copy(negotiateReq[2:], authMethods)

	if _, err = conn.Write(negotiateReq); err != nil {
		conn.Close()
		return nil, err
	}

	// 第三步:读取代理返回的认证方法选择响应
	negotiateResp := make([]byte, 2)
	if _, err = conn.Read(negotiateResp); err != nil {
		conn.Close()
		return nil, err
	}
	if negotiateResp[0] != socks5Version {
		conn.Close()
		return nil, errors.New("invalid SOCKS5 version")
	}
	chosenMethod := negotiateResp[1]
	if chosenMethod == authMethodNoAcceptable {
		conn.Close()
		return nil, errors.New("proxy does not support any offered auth methods")
	}

	// 第四步:如果代理要求用户名密码认证,发送认证凭证
	if chosenMethod == authMethodPassword {
		authReq := make([]byte, 3+len(username)+len(password))
		authReq[0] = authPasswordVersion
		authReq[1] = byte(len(username))
		copy(authReq[2:], []byte(username))
		authReq[2+len(username)] = byte(len(password))
		copy(authReq[3+len(username):], []byte(password))

		if _, err = conn.Write(authReq); err != nil {
			conn.Close()
			return nil, err
		}

		// 读取认证结果
		authResp := make([]byte, 2)
		if _, err = conn.Read(authResp); err != nil {
			conn.Close()
			return nil, err
		}
		if authResp[1] != authStatusSuccess {
			conn.Close()
			return nil, errors.New("SOCKS5 authentication failed")
		}
	}

	// 到这里连接已经完成认证,直接返回即可
	return conn, nil
}

func main() {
	// 使用示例
	proxyConn, err := DialSocks5WithAuth("11.11.11.11:1111", "your_username", "your_password")
	if err != nil {
		panic("connect to proxy failed: " + err.Error())
	}
	defer proxyConn.Close()

	// 后续可以直接使用这个proxyConn和代理服务器交互
}

注意事项

  • 上述代码严格遵循SOCKS5协议规范,兼容无认证和用户名密码认证两种场景
  • 返回的proxyConn就是和代理服务器完成认证后的原生net.Conn对象,完全符合预期调用效果
  • 如果后续需要用这个代理连接转发请求到目标地址,只需要继续按照SOCKS5协议发送CONNECT请求即可,不需要重复走认证流程

内容的提问来源于stack exchange,提问作者PitaHat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 00:54:03