仅 IPv6 连接,IPv4 服务:让 SOCKS 代理架起桥梁
SOCKS 代理接受一个连接并打开另一个连接,因此只有 IPv6 的客户端也能访问 IPv4 服务。这是中继,而不是原生 IPv4 访问。
只要路径上有东西愿意中继,你就不需要目标地址族中的地址也能到达目标。应用程序连接到代理,代理再向目标打开第二个连接。这是两个地址族相互独立的套接字,两种协议都不要求它们一致。这是应用层中继,而非原生 IPv4 路径,这一区别决定了什么可行、什么不可行。把两者混为一谈,正是笔记本电脑明明只有一个代理却被描述成具备 IPv4 连接的原因。
两个套接字,两个地址族
SOCKS5 请求用三种形式之一指定目标:字面 v4 地址、字面 v6 地址,或交由代理解析的名字。请求描述的是代理应连接到何处,而不是客户端到代理的连接长什么样。
把这些地址类型读作同一条消息中的三个独立选择。只要可达 IPv6 的代理拥有可用的 IPv4 出口且其策略允许该请求,它就能打开 IPv4 目标套接字。SOCKS5 规范在定义它们时完全没有提及客户端的传输方式。
受控的 SSH 示例
取一个你有权使用的 SSH 主机,它通过 IPv6 应答,并且自身能到达只存在于 v4 的 HTTPS 服务。OpenSSH 的动态转发会在登录会话经由 v6 运行时,在你的机器上放置一个本地 SOCKS 监听器。
ssh -6 -N -D 127.0.0.1:1081 -o ExitOnForwardFailure=yes [email protected]上面的主机和账户只是示例,回环绑定会把监听器留在这台计算机上。不要把它换成通配绑定,好让办公室共用一个无需认证的代理。ExitOnForwardFailure=yes 的存在是为了让失败的转发结束会话,而不是让一条命令在后台无声运行。
会话运行时,请求如下:
curl --proxy socks5h://127.0.0.1:1081 https://v4-only.example/回环连接不是 IPv4 互联网路径。离开你机器的,是经由 v6 的登录会话,打开目标套接字的是远端。socks5h 形式还把名称解析交给那一端,这在客户端没有自己的 IPv4 解析路径时很重要。
目标实际看到什么
目标看到的是中继的出口地址。你的笔记本电脑所属的地址不会出现在那里。该服务的源允许列表必须写中继的地址。它的日志也会把流量记在中继名下。在审计之前把这一点写进变更记录,因为围绕客户端地址建立的允许列表在第一次请求时就会失败。
中继也是对话两半都可见的地方,这在诊断时是有用的性质,若中继在没有策略的情况下共享则是负担。
这不是 DNS64,也不是 NAT64
DNS64 用合成记录来替代 v4 目标,NAT64 沿配置好的路径重写数据包。两者都没有描述这里发生的事:一段传输对话结束、另一段开始,没有任何合成地址能解释结果。因此请求成功并不能说明你的运营商运行了哪些转换服务,代理也可能在自己的出口上运行普通 NAT。
两种机制可以存在于同一网络中,所以请描述你真正验证过的那一种,而不是听起来最接近的那一种。
在承诺之前先弄清范围
OpenSSH 的动态转发承载 TCP 连接,而不是任意 IP 流量,因此 UDP、ICMP 以及任何忽略该代理的协议都需要另一种受支持的设计。请保留 SSH 主机密钥验证、服务器转发限制和 HTTPS 证书验证,因为代理是额外的可信参与者,而不是削弱身份检查的理由。如果目标是通过代理承载 VPN 的外层传输,请验证两端都支持这种传输,而不是假定任何 SOCKS 监听器都能中继它。
这些都不会让客户端变成双栈,也不需要。它只是让一个应用通过一个中继到达一个服务,这是更小的主张,也容易验证得多。