V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
om2mo
V2EX  ›  问与答

Socks 协议为什么不能代理 ICMP?

  •  
  •   om2mo · 335 天前 · 2828 次点击
    这是一个创建于 335 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我看到一篇文章:“SOCKS 是第 5 层协议,它不关心开放系统互连 (OSI) 模型中该层以下的任何内容——这意味着您不能使用它来隧道运行在第 5 层以下的协议。这包括诸如 ping 、地址解析协议( ARP )等。”

    但是传输层和网络层也在 SOCKS 下面,为什么可以代理?
    45 条回复    2023-11-12 13:09:42 +08:00
    iOCZ
        1
    iOCZ  
       335 天前
    代理工作在表示层(4 层)或应用层(7 层),需要 IP 与端口,跟路由、网关工作的传输层还是不一样的。
    ruixue
        2
    ruixue  
       335 天前
    socks 并不能代理网络层,不知道你从哪看的可以,socks5 可以代理任意 tcp 或 udp 流量,但其本身也工作在 tcp 和 udp 上,使用标准的 tcp 或 udp 承载
    om2mo
        3
    om2mo  
    OP
       335 天前
    @ruixue #2 我问的是为什么不能代理 ICMP
    pubby
        4
    pubby  
       335 天前 via iPhone
    因为这个协议就这么设计的啊,只有 tcp 和 udp
    pubby
        5
    pubby  
       335 天前 via iPhone
    Knowazz
        6
    Knowazz  
       335 天前
    其实上面的朋友已经写明白了,SOCKS 代理本身设计的时候就没有支持 ICMP ,同时自身也基于 TCP 、UDP 协议。
    而 TCP 、UDP 是属于传输协议,ICMP 是报文协议,在数据包结构上有本质区别( ICMP 不会携带目的地 IP 和端口)
    kangyue9999
        7
    kangyue9999  
       335 天前 via Android
    @om2mo 楼上说的很清楚啊 ,因为 socks 的包要不然是 tcp 要不然是 udp 人家用的包的 id 就是要不然是 6 要不然是 17 而 ICMP id 是 1 这就不可能实现
    kangyue9999
        8
    kangyue9999  
       335 天前 via Android
    @om2mo 问题在于你把 socks 想成了类似于 vpn 的隧道了,但实际上 socks 仅仅是应用层 7 层的的产品。但是隧道是在 2 或者三层,所以这不是一个概念
    om2mo
        9
    om2mo  
    OP
       335 天前
    @Knowazz #6 ICMP 是 IP 层的一部分可以作为 IP 报文的数据,SOCKS 不是可以代理 IP 吗怎么就不可以代理 ICMP
    leaflxh
        10
    leaflxh  
       335 天前
    你可以了解下 socks2tun 和 tun2socks
    leaflxh
        11
    leaflxh  
       335 天前
    或者你再看看 socks5 协议的通讯过程,或其 RFC
    om2mo
        12
    om2mo  
    OP
       335 天前
    @kangyue9999 #8 VPN 因为虚拟设备 TUN/TAP 更底层所以可以代理上层所有,SOCKS 太高代理不了底层吗?
    Knowazz
        13
    Knowazz  
       335 天前
    @om2mo
    其实倒不是不能代理,问题在于 ICMP 的数据包不携带端口,socks 即便可以帮你发送 ICMP ,却无法如何获取回应,因为回应是以广播的形式下发的。 通讯不能双向,也就没有代理它的必要。
    om2mo
        14
    om2mo  
    OP
       335 天前
    @leaflxh #10 tun2socks 就是虚拟的 3 层转发给 socks 协议啊
    om2mo
        15
    om2mo  
    OP
       335 天前
    @leaflxh #11 看了还是不明白
    Knowazz
        16
    Knowazz  
       335 天前
    VPN 协议工作在数据链层,可以从上级拿到广播,因此可以代理 ICMP 。
    om2mo
        17
    om2mo  
    OP
       335 天前
    @Knowazz #16 还是你专业 有点头绪了但还是不懂
    ruixue
        18
    ruixue  
       335 天前
    @om2mo 都说了啊,socks 代理不了网络层,icmp 属于网络层,ip 也属于网络层,自然都无法代理,这逻辑很难理解吗
    yinmin
        19
    yinmin  
       335 天前 via iPhone
    socks5 是通过 tcp 协议实现传输的。能跑啥协议,要看 socks5 client 和 socks5 server 支持啥协议。通常 socks5 server 只支持 tcp 和 udp ,也有例外,例如 tun2socks
    ZeroClover
        20
    ZeroClover  
       335 天前   ❤️ 2
    因为没什么用处

    如果硬要实现的话,用 tun2socks 拿到 ICMP 包,然后自己写个代理协议把 ICMP 封装成 UDP 里面,发到代理服务器以后再从 UDP 里面拆出来就行。几乎任何东西都可以塞进 UDP 里面,然后你就重新实现了各种传统 VPN
    oldshensheep
        21
    oldshensheep  
       335 天前   ❤️ 1
    4 楼是标准答案,协议只支持 TCP&UDP ,你加一个 ICMP 也是可以的。
    那文章里的解释是错误的,能不能代理与第几层协议无关,发数据包罢了而已管你在第几层。
    om2mo
        22
    om2mo  
    OP
       335 天前
    @oldshensheep #21 但是很多解释总总说它的层次
    oldshensheep
        23
    oldshensheep  
       335 天前
    反正和第几层无关,举个例:OpenVPN 可以使用 TCP 协议代理 ICMP 协议
    这么看他的说法就不正确了
    ysc3839
        24
    ysc3839  
       335 天前 via Android   ❤️ 1
    @om2mo SOCKS 不能传输 ICMP 不是因为它基于 TCP 或 UDP ,而是它设计只能承载 TCP 和 UDP ,协议里就没定义该怎么处理 ICMP ,所以没法支持。你可以想办法自己加上支持,但是你加的这部分就不属于 SOCKS 了。
    testFor
        25
    testFor  
       335 天前
    @oldshensheep 楼上评论你是一个没看啊
    oldshensheep
        26
    oldshensheep  
       335 天前
    @testFor 看了的,然后呢
    julyclyde
        27
    julyclyde  
       335 天前   ❤️ 1
    首先你引用的这句话就有问题
    并不是 *因为* 它工作在某一层,*所以*不支持某功能
    而是它就是很单纯的不支持某功能而已,没设计这个能力

    而且那句话暗示的因为所以关系其实也有问题

    Socks 也不能代理“IP”协议,所以不要按照“既然能代理 IP 为什么不能代理 ICMP”来考虑
    不能!!
    ungrown
        28
    ungrown  
       335 天前
    @oldshensheep #23 通信模型可以嵌套没错,但是嵌套不是自己长出来的,需要实现。VPN 实现了对应的嵌套,因为它这个应用需要这个功能,可这关 socks 什么事呢
    oldshensheep
        29
    oldshensheep  
       335 天前
    所以我说错了什么?
    我有没说 Socks 非要支持 ICMP ,我只是就事论事回答楼主的问题。

    楼主问题:Socks 协议为什么不能代理 ICMP ?
    回答:因为设计上就不支持

    另外的问题,文章里的解释。
    回答:错误的。
    @ungrown
    yestodayHadRain
        30
    yestodayHadRain  
       224 天前
    @ruixue
    @Knowazz
    @oldshensheep
    @ysc3839

    有个地方没想明白,如果按照各位所说,socks 支持代理 tcp/udp 的话:

    我有一台海外的机器 ip 已经被 GFW block 掉了,国内网络是访问不到的,我连接另外一台海外机器的 socks5 代理后 本地去 telnet 被 block 掉的 ip 22 端口,也是打不通的。这个是为什么呢?
    ruixue
        31
    ruixue  
       223 天前   ❤️ 1
    @yestodayHadRain socks5 是明文代理,telnet 也是明文传输,这么搞和裸奔没啥区别,墙依然可以识别到你要访问的真实 ip ,以及传输的所有内容,各种梯子开放的本地 socks5 端口只是用来兼容输入的,真正过墙的还是加密混淆过的翻墙协议,没有人会直接用 socks5 过墙
    yestodayHadRain
        32
    yestodayHadRain  
       223 天前
    @ruixue 好像是因为我没有开 tun 模式的原因,打开 tun 后 就可以打通了。我是用 Dante 搞的,这个 很容易被识别出来吗?
    ruixue
        33
    ruixue  
       223 天前
    @yestodayHadRain 那说明之前压根就没走代理,当然现在能通也不建议这么搞,socks5 基本上就是原样转发流量,在墙面前和裸奔没啥区别,过墙最好用专门的翻墙协议,传统的 VPN 都不太好使,更不用提完全明文的 socks5 了,还有 telnet 也别用了,用 ssh
    yestodayHadRain
        34
    yestodayHadRain  
       223 天前
    @ruixue 比较优雅的方式是什么呢?以前用 vpn 搞过,被封过后来就用 Dante 搞了。还算稳定,其他用 ssr 这种好像封的比较多?
    ruixue
        35
    ruixue  
       223 天前   ❤️ 1
    @yestodayHadRain 你现在怎么上的 V2EX ?直接用手头的翻墙手段不行么

    自己搞的话,reality 、naiveproxy 目前来说比较稳,如果有 ipv6 可以直接跑 ss2022
    Subdue
        36
    Subdue  
       180 天前 via Android
    @ruixue 我有个疑问,本地的 socks5 用来收集数据包,统一全部走加密过墙的,那,TCP 数据包是不是可以都直接转发到加密协议上去,毕竟加密协议也是基于 TCP 的,UDP 数据包除 53 外全部转发到 socks5 上面去,这样所有的数据包是否都走了代理呢?除了乱七八糟的 ICMP ,ARP 之外
    ruixue
        37
    ruixue  
       179 天前
    @Subdue 当然可以啊,只要加密协议也支持 udp 或者 udp over tcp ,这就是所谓的(第 4 层的)全局代理,udp53 也可以让加密协议转发,从远程服务器请求 dns
    Subdue
        38
    Subdue  
       178 天前 via Android
    @ruixue 如果只是为了过墙,udp53 有加密的必要吗?还有 tcp 建立链接后,后续的数据传输是否可以不走代理加密?
    ruixue
        39
    ruixue  
       178 天前
    @Subdue 一般来说全局代理也都是通过代理远程请求 dns ,防止 dns 污染和泄露,socks5 本身就支持代理 dns ,但实际翻墙的时候很少用全局代理,都是用一系列策略进行分流,例如国内网站就直接直连不走代理,openai 和 netflix 单独配置解锁节点,dns 也有专门的处理步骤,比方说国内的域名用国内的 dns ,被墙的域名走加密代理请求远程 dns ,详细说起来就太多了,可以自己搜一下翻墙时 dns 的处理细节

    现在的墙都是多方面的,dns 污染,ban sni ,ban ip ,ban 端口等等。一般来说如果 ip 和端口被墙,就必须要走代理,没有办法直连。有些翻墙协议比如 xtls 是支持加密建立连接后,原样传输 tls 数据流,减少一层加密以提升性能,但大部分实现方案都是全程通过代理服务器转发加密混淆过的流量的。有一些翻墙手段是不需要走代理,只加密一些数据并使用纯净 dns 以绕过墙,比方说域前置,还有 cloudflare 新出的 ech ,前提是目标 ip 端口没有被墙,墙的只是 dns 和 sni 。这些展开说也很多很多,可以自己搜一下相关的信息
    Subdue
        40
    Subdue  
       178 天前 via Android
    @ruixue 建立连接以后就算是过墙的,后续的数据不走加密不会被识别吧,还是墙会监听所有数据包?这样能扛得住这么大流量吗?
    Subdue
        41
    Subdue  
       178 天前 via Android
    @ruixue 这东西确实很多,细说,可以开课了😂
    ruixue
        42
    ruixue  
       178 天前
    @Subdue 墙当然会探测所有的跨境数据包啊(除了物理不过墙的专线和部分逻辑上不入境的借道中转流量),人家用的超算,烧的纳税人的钱,抗不扛得住用不着我们去担心好吧。当然墙也是量力而行的,前几年国际出口带宽一直不提升,很大一方面也是因为墙的算力饱和了,而不是物理层面光缆不够用了,这两年 AI 发展突飞猛进,墙也能处理更高的吞吐量了,这不国际带宽也明显比前几年大了好多
    Subdue
        43
    Subdue  
       177 天前 via Android
    @ruixue 大佬,有研究过安卓手机的实时显示网速是如何实现的吗?我感觉,自从用了透明代理,这个网速和实际下载速度匹配不上了,不知道是不是用 iptables 转发流量的时候弄混了。
    ruixue
        44
    ruixue  
       177 天前
    @Subdue 不敢当,这个我没研究过,帮不了你😅
    libinglong9
        45
    libinglong9  
       137 天前
    不用管第几层,说层级的都是没有理解什么叫代理。
    那我基于 tcp 或者 udp 的 vpn ,不是一样代理 icmp 吗?本质上还是在于设计上有没有提供支持。我用 socks client 在 tcp 里面包装一个 ICMP 的包,让 sockes server 去处理,难道不能?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4816 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 09:56 · PVG 17:56 · LAX 02:56 · JFK 05:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.