k2

socks5 代理过程

参考资料 SOCKS Protocol Version 5

版本协商和验证

第一阶段

auth_nego_request {
	version(8)=0x05,
	// The auth_method_count field contains the number of method identifier octets that
    // appear in the auth_method_list field.
    auth_method_count(8),
	auth_method_list(auth_method_count),
}

auth_nego_repley {
	version(8)=0x05,
	method(8),
}

rfc 中定义的 method 方法:

值(Hex) 名称
0x00 NO AUTHENTICATION REQUIRED
0x01 GSSAPI
0x02 USERNAME/PASSWORD
0x03–0x7F IANA ASSIGNED
0x80–0xFE RESERVED FOR PRIVATE METHODS
0xFF NO ACCEPTABLE METHODS

如果 reply msg 中的 method 是 0xFF ,说明 socks5 server 无法支持 client 的 auth method,client 要立刻断开连接.

第二阶段

TCP 代理

第一阶段

proxy_request {
    version(8)=0x05,
    cmd(8)=0x01, // CONNECT
    reserved(8)=0x00,
    atyp(8),
    [domain_length(8)],
    dst_addr(..)
    dst_port(16),
}

proxy_reply {
    version(8)=0x05,
    reply(8),
    reserved(8)=0x00,
    atyp(8),
    [domain_length(8)],
    bnd_addr(..),
    bnd_port(..)
}

atyp

reply 的值:

值(Hex) 含义
0x00 succeeded
0x01 general SOCKS server failure
0x02 connection not allowed by ruleset
0x03 Network unreachable
0x04 Host unreachable
0x05 Connection refused
0x06 TTL expired
0x07 Command not supported
0x08 Address type not supported
0x09–0xFF unassigned

第二阶段

1. client ↔ socks: 建立 TCP
2. client → socks: CONNECT
3. socks → target: 建立 TCP
4. socks ↔ target: TCP 建立成功
5. socks → client: 成功响应

6. 开始双向转发:

   client <-> socks <-> target

   (只是复制 TCP payload,不解析、不修改)

UDP 代理

第一阶段

proxy_request {
    version(8)=0x05,
    cmd(8)=0x03, // UDP ASSOCIATE
    reserved(8)=0x00,
    atyp(8),
    [domain_length(8)],
    dst_addr(..)
    dst_port(16),
}

proxy_reply {
    version(8)=0x05,
    reply(8),
    reserved(8)=0x00,
    atyp(8),
    [domain_length(8)],
    bnd_addr(..),
    bnd_port(..)
}

FQA 为什么保留 UDP ASSOCIATE 过程中 atyp 可以是 domain 的这种设计?

我感觉没有必要的,可能是为了方便解析器的实现吧.

第二阶段

relay_udp_header {
    reserved(2)=0x00,
    frag(1),
    atyp(1),
    dst_addr(..),
    dst_port(..),
    payload(..)
}
[udp_header][relay_udp_header][raw_payload]

FRAG

relay udp server 会维护两个东西

// 用于存放待组装的 udp 报文
REASSEMBLY QUEUE
// 计时器
REASSEMBLY TIMER

BIND

这个东西已经被时代淘汰了

所以,没有介绍