vernesong / OpenClash

A Clash Client For OpenWrt
MIT License
16.66k stars 3.08k forks source link

[Bug] DNS劫持选择“使用dnsmasq转发” 但dstnat链上仍有DNS劫持,这似乎与选择“使用防火墙转发”行为一致 #3949

Open Mosney opened 2 months ago

Mosney commented 2 months ago

Verify Steps

OpenClash Version

v0.46.014-beta

Bug on Environment

Immortalwrt

OpenWrt Version

ImmortalWrt 23.05.2, r27625-416c8c5c91

Bug on Platform

Linux-arm64

Describe the Bug

luci界面下,插件设置》DNS设置》本地DNS劫持, 三个选项

选择第二项,使用dnsmasq转发,实际上仍然会在防火墙加入劫持规则

To Reproduce

模式:Fake-IP(TUN-混合)模式【UDP-TUN,TCP-转发】

本地DNS劫持选择使用dnsmasq转发,启动openclash,查看防火墙劫持规则

nft list chain inet fw4 dstnat

root@ImmortalWrt:~# nft list chain inet fw4 dstnat
table inet fw4 {
        chain dstnat {
                type nat hook prerouting priority dstnat; policy accept;
                meta nfproto ipv4 tcp dport 53 counter packets 0 bytes 0 accept comment "OpenClash TCP DNS Hijack"
                udp dport 53 counter packets 0 bytes 0 redirect to :53 comment "OpenClash DNS Hijack"
                tcp dport 53 counter packets 0 bytes 0 redirect to :53 comment "OpenClash DNS Hijack"
                iifname { "eth1", "pppoe-wan" } jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
                ip protocol tcp counter packets 833 bytes 44695 jump openclash
        }
}

OpenClash Log

OpenClash 调试日志

生成时间: 2024-07-08 00:21:55
插件版本: 
隐私提示: 上传此日志前请注意检查、屏蔽公网IP、节点、密码等相关敏感信息

#===================== 系统信息 =====================#

主机型号: N/A
固件版本: ImmortalWrt 23.05.2 r27625-416c8c5c91
LuCI版本: 
内核版本: 5.15.150
处理器架构: aarch64_cortex-a53

#此项有值时,如不使用IPv6,建议到网络-接口-lan的设置中禁用IPV6的DHCP
IPV6-DHCP: 

DNS劫持: Dnsmasq 转发
#DNS劫持为Dnsmasq时,此项结果应仅有配置文件的DNS监听地址
Dnsmasq转发设置: 127.0.0.1#7874

#===================== 内核检查 =====================#

运行状态: 运行中
运行内核:TUN
进程pid: 32552
运行权限: 32552: cap_dac_override,cap_net_bind_service,cap_net_admin,cap_net_raw,cap_sys_ptrace,cap_sys_resource=eip
运行用户: 
已选择的架构: linux-arm64

#下方无法显示内核版本号时请确认您的内核版本是否正确或者有无权限
Tun内核版本: 2023.08.17-13-gdcc8d87
Tun内核文件: 存在
Tun内核运行权限: 正常

Dev内核版本: 
Dev内核文件: 不存在
Dev内核运行权限: 否

Meta内核版本: 
Meta内核文件: 不存在
Meta内核运行权限: 否

#===================== 插件设置 =====================#

当前配置文件: /etc/openclash/config/simple.yaml
启动配置文件: /etc/openclash/simple.yaml
运行模式: fake-ip-mix
默认代理模式: rule
UDP流量转发(tproxy): 停用
自定义DNS: 启用
IPV6代理: 停用
IPV6-DNS解析: 停用
禁用Dnsmasq缓存: 启用
自定义规则: 停用
仅允许内网: 启用
仅代理命中规则流量: 停用
仅允许常用端口流量: 停用
绕过中国大陆IP: 停用
路由本机代理: 停用

#启动异常时建议关闭此项后重试
混合节点: 停用
保留配置: 停用

#启动异常时建议关闭此项后重试
第三方规则: 停用

#===================== 自定义覆写设置 =====================#

#!/bin/sh
. /usr/share/openclash/ruby.sh
. /usr/share/openclash/log.sh
. /lib/functions.sh

# This script is called by /etc/init.d/openclash
# Add your custom overwrite scripts here, they will be take effict after the OpenClash own srcipts

LOG_OUT "Tip: Start Running Custom Overwrite Scripts..."
LOGTIME=$(echo $(date "+%Y-%m-%d %H:%M:%S"))
LOG_FILE="/tmp/openclash.log"
CONFIG_FILE="$1" #config path

#Simple Demo:
    #General Demo
    #1--config path
    #2--key name
    #3--value
    #ruby_edit "$CONFIG_FILE" "['redir-port']" "7892"
    #ruby_edit "$CONFIG_FILE" "['secret']" "123456"
    #ruby_edit "$CONFIG_FILE" "['dns']['enable']" "true"

    #Hash Demo
    #1--config path
    #2--key name
    #3--hash type value
    #ruby_edit "$CONFIG_FILE" "['experimental']" "{'sniff-tls-sni'=>true}"
    #ruby_edit "$CONFIG_FILE" "['sniffer']" "{'sniffing'=>['tls','http']}"

    #Array Demo:
    #1--config path
    #2--key name
    #3--position(start from 0, end with -1)
    #4--value
    #ruby_arr_insert "$CONFIG_FILE" "['dns']['nameserver']" "0" "114.114.114.114"

    #Array Add From Yaml File Demo:
    #1--config path
    #2--key name
    #3--position(start from 0, end with -1)
    #4--value file path
    #5--value key name in #4 file
    #ruby_arr_add_file "$CONFIG_FILE" "['dns']['fallback-filter']['ipcidr']" "0" "/etc/openclash/custom/openclash_custom_fallback_filter.yaml" "['fallback-filter']['ipcidr']"

#Ruby Script Demo:
    #ruby -ryaml -rYAML -I "/usr/share/openclash" -E UTF-8 -e "
    #   begin
    #      Value = YAML.load_file('$CONFIG_FILE');
    #   rescue Exception => e
    #      puts '${LOGTIME} Error: Load File Failed,【' + e.message + '】';
    #   end;

        #General
    #   begin
    #   Thread.new{
    #      Value['redir-port']=7892;
    #      Value['tproxy-port']=7895;
    #      Value['port']=7890;
    #      Value['socks-port']=7891;
    #      Value['mixed-port']=7893;
    #   }.join;

    #   rescue Exception => e
    #      puts '${LOGTIME} Error: Set General Failed,【' + e.message + '】';
    #   ensure
    #      File.open('$CONFIG_FILE','w') {|f| YAML.dump(Value, f)};
    #   end" 2>/dev/null >> $LOG_FILE

exit 0
#===================== 自定义防火墙设置 =====================#

#!/bin/sh
. /usr/share/openclash/log.sh
. /lib/functions.sh

# This script is called by /etc/init.d/openclash
# Add your custom firewall rules here, they will be added after the end of the OpenClash iptables rules

LOG_OUT "Tip: Start Add Custom Firewall Rules..."

exit 0

#===================== NFTABLES 防火墙设置 =====================#

table inet fw4 {
    chain input {
        type filter hook input priority filter; policy drop;
        meta l4proto { tcp, udp } iifname "utun" counter packets 0 bytes 0 accept comment "OpenClash TUN Input"
        iifname "pppoe-wan" ip saddr != @localnetwork counter packets 7478 bytes 4778504 jump openclash_wan_input
        iifname "lo" accept comment "!fw4: Accept traffic from loopback"
        ct state established,related accept comment "!fw4: Allow inbound established and related flows"
        tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
        iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
        iifname { "eth1", "pppoe-wan" } jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
        jump handle_reject
    }
}
table inet fw4 {
    chain forward {
        type filter hook forward priority filter; policy drop;
        meta l4proto { tcp, udp } iifname "utun" counter packets 15 bytes 985 accept comment "OpenClash TUN Forward"
        meta l4proto { tcp, udp } oifname "utun" counter packets 30 bytes 2886 accept comment "OpenClash TUN Forward"
        meta l4proto { tcp, udp } flow add @ft
        ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
        iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
        iifname { "eth1", "pppoe-wan" } jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
        jump handle_reject
    }
}
table inet fw4 {
    chain dstnat {
        type nat hook prerouting priority dstnat; policy accept;
        meta nfproto ipv4 tcp dport 53 counter packets 0 bytes 0 accept comment "OpenClash TCP DNS Hijack"
        udp dport 53 counter packets 0 bytes 0 redirect to :53 comment "OpenClash DNS Hijack"
        tcp dport 53 counter packets 0 bytes 0 redirect to :53 comment "OpenClash DNS Hijack"
        iifname { "eth1", "pppoe-wan" } jump dstnat_wan comment "!fw4: Handle wan IPv4/IPv6 dstnat traffic"
        ip protocol tcp counter packets 289 bytes 15771 jump openclash
    }
}
table inet fw4 {
    chain srcnat {
        type nat hook postrouting priority srcnat; policy accept;
        meta nfproto ipv4 oifname "utun" counter packets 7 bytes 976 return comment "OpenClash TUN Postrouting"
        oifname { "eth1", "pppoe-wan" } jump srcnat_wan comment "!fw4: Handle wan IPv4/IPv6 srcnat traffic"
    }
}
table inet fw4 {
    chain nat_output {
        type nat hook output priority filter - 1; policy accept;
        ip protocol tcp counter packets 606 bytes 36360 jump openclash_output
    }
}
table inet fw4 {
    chain mangle_prerouting {
        type filter hook prerouting priority mangle; policy accept;
        ip protocol udp counter packets 2045 bytes 265944 jump openclash_mangle
        meta nfproto ipv4 tcp dport 53 counter packets 0 bytes 0 jump openclash_dns_hijack
    }
}
table inet fw4 {
    chain mangle_output {
        type route hook output priority mangle; policy accept;
        meta nfproto ipv4 meta l4proto { tcp, udp } counter packets 19860 bytes 15028146 jump openclash_mangle_output
    }
}
table inet fw4 {
    chain openclash {
        ip daddr @localnetwork counter packets 42 bytes 2248 return
        ip protocol tcp counter packets 247 bytes 13523 redirect to :7892
    }
}
table inet fw4 {
    chain openclash_mangle {
        meta nfproto ipv4 udp sport 500 counter packets 0 bytes 0 return
        meta nfproto ipv4 udp sport 68 counter packets 0 bytes 0 return
        meta l4proto { tcp, udp } iifname "utun" counter packets 15 bytes 985 return
        ip daddr @localnetwork counter packets 2000 bytes 262073 return
        ip protocol udp counter packets 30 bytes 2886 jump openclash_upnp
        meta l4proto { tcp, udp } th dport 0-65535 meta mark set 0x00000162 counter packets 30 bytes 2886
    }
}
table inet fw4 {
    chain openclash_mangle_output {
        meta nfproto ipv4 udp sport 500 counter packets 0 bytes 0 return
        meta nfproto ipv4 udp sport 68 counter packets 0 bytes 0 return
        ip daddr @localnetwork counter packets 13196 bytes 13786871 return
        meta skuid != 65534 udp dport 0-65535 ip daddr 198.18.0.0/16 meta mark set 0x00000162 counter packets 0 bytes 0
    }
}
table inet fw4 {
    chain openclash_output {
        ip daddr @localnetwork counter packets 75 bytes 4500 return
        ip protocol tcp ip daddr 198.18.0.0/16 meta skuid != 65534 counter packets 0 bytes 0 redirect to :7892
    }
}
table inet fw4 {
    chain openclash_wan_input {
        udp dport { 7874, 7890, 7891, 7892, 7893, 7895, 9090 } counter packets 0 bytes 0 reject
        tcp dport { 7874, 7890, 7891, 7892, 7893, 7895, 9090 } counter packets 0 bytes 0 reject
    }
}
table inet fw4 {
    chain openclash_dns_hijack {
    }
}

OpenClash Config

No response

Expected Behavior

本地DNS劫持的三个选项按字面意思,第一项不做额外操作,第二项仅将clash dns作为dnsmasq的上游,第三项才会使用iptables/nft劫持所有53端口的流量重定向到clash dns

Additional Context

我注意到luci界面上方有提示

注意: Fake-IP 模式下如需要进行客户端访问控制,请将DNS劫持模式改为防火墙转发

但是我并没有设置过客户端访问控制,且在Fake-IP(TUN-混合)模式【UDP-TUN,TCP-转发模式下似乎也根本没有展示客户端访问控制这个设置tab, 因此我认为也不可能是因为此让启动脚本实际运行时自动切换到第三项使用防火墙劫持DNS。

bcseputetto commented 2 months ago

使用dnsmasq转发,仍然用防火墙重定向了53,是为了防止客户端私自设置DNS。 比如电脑私自设置了 223.5.5.5,openclash的那条防火墙规则可以劫持电脑向223.5.5.5的查询到dnsmasq。 不过我也觉得这个操作最好给个开关,能不要重定向53 @vernesong

FanxJK commented 1 month ago

OpenWrt 的 网络 - DHCP/DNS - 常规 中 取消勾选 “DNS 重定向”

bcseputetto commented 1 month ago

OpenWrt 的 网络 - DHCP/DNS - 常规 中 取消勾选 “DNS 重定向”

这是openclash的行为,而不是dnsmasq的,跟这个选项无关

Aethersailor commented 1 month ago

确实应该加个开关,把选择权交给用户

Shinku-Chen commented 3 weeks ago

使用dnsmasq转发/防火墙转发 这个是clash行为 且目前防火墙转发不支持IPV6 DNS 重定向是路由器行为,劫持所有53请求到dnsmasq,可能会有clash有冲突

目前我对clash的建议: 防火墙转发: 需要增加IPV6防火墙转发(就算防火墙转发后,用户仍然使用到V6的dnsmasq) dns劫持:默认开启劫持,但可以手工关闭,(与dnsmasq联动,或者展示dnsmasq设置并提示),

目前我对用户的建议: IPV6环境下,不要用防火墙转发,建议用dnsmasq转发,确保V4V6都能走到clash 最好关闭dnsmasq劫持