V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
nzhl
V2EX  ›  DNS

在 Linux 上开 clash tun 模式 clash 是怎么劫持 dns 的

  •  
  •   nzhl · 2022-09-16 18:38:07 +08:00 · 7071 次点击
    这是一个创建于 581 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看了下, 感觉它既没有改写 /etc/hosts 也没改写 /etc/resolv.conf , 很好奇怎么做到的

    19 条回复    2024-03-27 10:31:54 +08:00
    aragakiyuii
        1
    aragakiyuii  
       2022-09-16 18:44:43 +08:00 via iPhone
    seers
        2
    seers  
       2022-09-16 18:52:54 +08:00
    好像是 iptables 规则
    nzhl
        3
    nzhl  
    OP
       2022-09-16 19:02:01 +08:00 via iPhone
    @aragakiyuii 有没有更具体的 就是他是怎么监听到 dns 请求的
    nzhl
        4
    nzhl  
    OP
       2022-09-16 19:05:12 +08:00 via iPhone
    @seers 没 我看了 路由表里只有被劫持后的 198 网断
    aragakiyuii
        5
    aragakiyuii  
       2022-09-16 19:07:20 +08:00 via iPhone
    @nzhl 监听的 0.0.0.0:53 你看文档的配置文件
    nzhl
        6
    nzhl  
    OP
       2022-09-16 19:11:42 +08:00 via iPhone
    @aragakiyuii 为啥监听 0000 53 能起作用 不是默认会让访问 etc resolv 文件里面指定的 dns server 吗
    wangyu17455
        7
    wangyu17455  
       2022-09-16 21:33:08 +08:00
    clash 监听流过 tun 设备的一切流量,然后从中筛出你配置了 dns 劫持的目的地址,然后拦截,解析,向你在 clash 配置文件里设置的 dns 服务器发请求,然后收到回复,然后伪造一个源地址和你发送的 dns 查询的目的地址相同的回复
    nzhl
        8
    nzhl  
    OP
       2022-09-16 22:36:25 +08:00
    @wangyu17455 问题从 routing table 来看, 只有已经经过了 DNS 的劫持的流量 (198.18.0.0/16) 才会流入 clash 创建的网卡

    下面是关闭然后开启 tun 模式系统路由表的变化, 只是新增了一条
    198.18.0.0/16 dev utun proto kernel scope link src 198.18.0.1
    看上去这条记录只拦截 198.18 网段, 应该在这之前有一层 DNS 劫持把流量导入到了这个网段

    > ip route
    // tun mode disable
    default via 192.168.50.1 dev wlo1 proto dhcp src 192.168.50.132 metric 20600
    172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
    172.18.0.0/16 dev br-befa72e4dba9 proto kernel scope link src 172.18.0.1 linkdown
    192.168.50.0/24 dev wlo1 proto kernel scope link src 192.168.50.132 metric 600
    > ip route
    # tun mode enable
    default via 192.168.50.1 dev wlo1 proto dhcp src 192.168.50.132 metric 20600
    172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
    172.18.0.0/16 dev br-befa72e4dba9 proto kernel scope link src 172.18.0.1 linkdown
    192.168.50.0/24 dev wlo1 proto kernel scope link src 192.168.50.132 metric 600
    198.18.0.0/16 dev utun proto kernel scope link src 198.18.0.1
    wangyu17455
        9
    wangyu17455  
       2022-09-16 22:43:18 +08:00
    @nzhl 你系统其实有很多张路由表的,用 ip route show table 名字或者数字就能看见,你执行 ip rule 就会发现 clash 让所有流量都查询他自己创建的一张表,然后你用 ip route show table 名字 就能看见那张表的默认路由就是 dev utun ,你也可以用 ip route get 随便写一个 ip 上去来佐证这一点,它会打印出到这个 ip 走了哪条路由
    nzhl
        10
    nzhl  
    OP
       2022-09-16 22:44:50 +08:00
    接上层,我其实好奇的就是这个对 DNS 的拦截是怎么做的, 因为 TUN 是 premium 的功能,只是功能开源了但是代码没开源。

    我理解要拦截 DNS 有几个做法:
    1. cat /etc/hosts

    # Standard host addresses
    127.0.0.1 localhost
    ::1 localhost ip6-localhost ip6-loopback
    ff02::1 ip6-allnodes
    ff02::2 ip6-allrouters
    # This host address
    127.0.1.1 nzhl-manjaro


    2. cat /etc/resolv.conf

    # Generated by NetworkManager
    nameserver 192.168.50.1 # 这是我的华硕路由器


    3. 根据 5 楼的说法以及看他配置似乎确实是在监听 53 端口, 但是首先我发现 53 端口啥也没有

    > sudo netstat -tlunp|grep 53
    tcp 0 0 127.0.0.1:53000 0.0.0.0:* LISTEN 586/clash-core-serv
    udp 0 0 0.0.0.0:34622 0.0.0.0:* 537/avahi-daemon: r
    udp 0 0 224.0.0.251:5353 0.0.0.0:* 405557/chrome --ena
    udp 0 0 224.0.0.251:5353 0.0.0.0:* 405557/chrome --ena
    udp 0 0 224.0.0.251:5353 0.0.0.0:* 405599/chrome --typ
    udp 0 0 224.0.0.251:5353 0.0.0.0:* 405599/chrome --typ
    udp 0 0 0.0.0.0:5353 0.0.0.0:* 537/avahi-daemon: r
    udp6 0 0 :::51972 :::* 537/avahi-daemon: r
    udp6 0 0 :::5353 :::* 537/avahi-daemon: r
    nzhl
        11
    nzhl  
    OP
       2022-09-16 22:49:28 +08:00
    @wangyu17455 兄弟 我试了下 ip rule

    > ip rule
    0: from all lookup local
    9500: from all to 198.18.0.0/16 lookup 1970566510
    9510: from all ipproto icmp goto 9560
    9520: not from all dport 53 lookup main suppress_prefixlength 0
    9530: not from all iif lo lookup 1970566510
    9540: from 0.0.0.0 iif lo uidrange 0-4294967294 lookup 1970566510
    9550: from 198.18.0.1 iif lo uidrange 0-4294967294 lookup 1970566510
    9560: from all nop
    32766: from all lookup main
    32767: from all lookup default

    看着

    9520: not from all dport 53 lookup main suppress_prefixlength 0
    这一行有点像在拦截 53 ?
    wangyu17455
        12
    wangyu17455  
       2022-09-16 22:52:46 +08:00
    @nzhl clash 的配置文件中,dns-hijack 之所以放在 tun 的配置底下而不是放在 dns 的配置底下就是因为 dns-hijack 依赖 tun ,假如你不配置 dns 劫持,只是把 /etc/resolv.conf 设置成 127.0.0.1 ,那么依赖系统进行解析的软件就都走了 clash 的 dns 了,但是不排除有的软件不依赖系统进行解析,走他自己设置的 dns ,这时候你就需要设置 dns-hijack 为 any:53 了,这样你本机发出的任何基于 udp53 端口的 dns 查询都会被 clash 拦截从而走 clash
    nzhl
        13
    nzhl  
    OP
       2022-09-16 22:55:43 +08:00
    感谢兄弟 有点懂了 我好好领悟下
    wangyu17455
        14
    wangyu17455  
       2022-09-16 23:05:39 +08:00
    @nzhl not{不是} (from all dport 53){来自任意来源的,目的端口是 53 的} lookup main{查找 main 路由表} suppress_prefixlength 0 连起来就是说目的端口不是 53 的走 main 路由表
    nzhl
        15
    nzhl  
    OP
       2022-09-16 23:14:13 +08:00
    那应该是下面一条 非闭环的走 1970566510, 然后

    > ip route show table 1970566510
    default dev utun proto unspec

    一旦走到 1970566510 就相当于被 clash 接管了, 这个理解没错把兄弟 @wangyu17455
    wangyu17455
        16
    wangyu17455  
       2022-09-16 23:23:12 +08:00
    @nzhl
    brianyao
        17
    brianyao  
       2022-09-23 12:46:22 +08:00
    based on 官方文档 & 我的理解:

    1. tun 下的 dns-hijack 仅针对 tun 下的 tcp/udp 的请求进行 hijack ,即先匹配,再 hijack ,所以才有了 0.0.0.0:53 和 tcp://any53 的写法(解决某些特定场景下,会直接请求:target ip:port ,如果你不想一条一条加,就全部 hijack )

    2. tun 是一个 L2 协议,所以 tun 本身是不涉及 domain 的操作的(在这一点上,和 socks5 不一样,socks5 的包里可以包裹 domian )在 tun 上的只有 L3 的东西,如 ip 、port 、protocol ,这也解答了 1 中的通配写法

    3. 新版本 clash ,具有 auto-route 、auto- direct- interface 的 feature ,能够自动劫持内核网络栈流量,仅需开启 ipv4-forward 就可以,不需要再配置 iptables 。
    shuiguomayi
        18
    shuiguomayi  
       61 天前 via iPhone
    @brianyao 这里提到的新版本指的是 premium 版本吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2678 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:08 · PVG 23:08 · LAX 08:08 · JFK 11:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.