From 7d1fb1a2cac1361ca3832e711e44eb3464aed407 Mon Sep 17 00:00:00 2001 From: xiaorouji <60100640+xiaorouji@users.noreply.github.com> Date: Wed, 13 Sep 2023 15:20:06 +0800 Subject: [PATCH] luci: Adjust FakeDNS logic --- .../model/cbi/passwall/client/global.lua | 40 ++-- .../luasrc/passwall/util_sing-box.lua | 221 +++++++++--------- .../luasrc/passwall/util_xray.lua | 6 +- .../root/usr/share/passwall/app.sh | 44 ++-- 4 files changed, 162 insertions(+), 149 deletions(-) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua index 394b1d59a..f0f2dc1b1 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -281,19 +281,8 @@ dns_mode:value("udp", translatef("Requery DNS By %s", "UDP")) o = s:taboption("DNS", ListValue, "v2ray_dns_mode", " ") o:value("tcp", "TCP") o:value("doh", "DoH") -o:value("fakedns", "FakeDNS") o:depends("dns_mode", "sing-box") o:depends("dns_mode", "xray") -o.validate = function(self, value, t) - if value == "fakedns" then - local _dns_mode = dns_mode:formvalue(t) - local _tcp_node = tcp_node:formvalue(t) - if m:get(_tcp_node, "type"):lower() ~= _dns_mode then - return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode) - end - end - return value -end o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address.")) for k, v in pairs(socks_table) do o:value(v.id, v.remarks) end @@ -345,13 +334,28 @@ o.datatype = "ipaddr" o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"}) o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"}) +o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy.")) +o.default = "0" +o:depends({dns_mode = "sing-box"}) +o:depends({dns_mode = "xray"}) +o.validate = function(self, value, t) + if value and value == "1" then + local _dns_mode = dns_mode:formvalue(t) + local _tcp_node = tcp_node:formvalue(t) + if _dns_mode and _tcp_node and _tcp_node ~= "nil" then + if m:get(_tcp_node, "type"):lower() ~= _dns_mode then + return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode) + end + end + end + return value +end + o = s:taboption("DNS", Flag, "dns_cache", translate("Cache Resolved")) o.default = "1" o:depends({dns_mode = "dns2socks"}) -o:depends({dns_mode = "sing-box", v2ray_dns_mode = "tcp"}) -o:depends({dns_mode = "sing-box", v2ray_dns_mode = "doh"}) -o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"}) -o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"}) +o:depends({dns_mode = "sing-box", remote_fakedns = false}) +o:depends({dns_mode = "xray", remote_fakedns = false}) o.rmempty = false if api.is_finded("chinadns-ng") then @@ -359,10 +363,8 @@ if api.is_finded("chinadns-ng") then o.default = "0" o:depends({dns_mode = "dns2socks"}) o:depends({dns_mode = "dns2tcp"}) - o:depends({dns_mode = "sing-box", v2ray_dns_mode = "tcp"}) - o:depends({dns_mode = "sing-box", v2ray_dns_mode = "doh"}) - o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"}) - o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"}) + o:depends({dns_mode = "sing-box", remote_fakedns = false}) + o:depends({dns_mode = "xray", remote_fakedns = false}) o:depends({dns_mode = "udp"}) end diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua index a5b42d6af..5144dd01d 100644 --- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -1100,109 +1100,104 @@ function gen_config(var) reverse_mapping = true, --在响应 DNS 查询后存储 IP 地址的反向映射以为路由目的提供域名。 fakeip = nil, } - - if true then - local dns_tag = "remote" - - local domain = {} - local domain_suffix = {} - local domain_keyword = {} - local domain_regex = {} - local geosite = {} - for index, value in ipairs(dns_remote_domains) do - if value:find("geosite:") == 1 then - table.insert(geosite, value:sub(1 + #"geosite:")) - elseif value:find("regexp:") == 1 then - table.insert(domain_regex, value:sub(1 + #"regexp:")) - elseif value:find("full:") == 1 then - table.insert(domain, value:sub(1 + #"full:")) - elseif value:find("domain:") == 1 then - table.insert(domain_keyword, value:sub(1 + #"domain:")) - else - table.insert(domain, value) - end + + local dns_tag = "remote" + + local domain = {} + local domain_suffix = {} + local domain_keyword = {} + local domain_regex = {} + local geosite = {} + for index, value in ipairs(dns_remote_domains) do + if value:find("geosite:") == 1 then + table.insert(geosite, value:sub(1 + #"geosite:")) + elseif value:find("regexp:") == 1 then + table.insert(domain_regex, value:sub(1 + #"regexp:")) + elseif value:find("full:") == 1 then + table.insert(domain, value:sub(1 + #"full:")) + elseif value:find("domain:") == 1 then + table.insert(domain_keyword, value:sub(1 + #"domain:")) + else + table.insert(domain, value) end - local remote_rule = { - server = dns_tag, - domain = #domain > 0 and domain or nil, - domain_suffix = #domain_suffix > 0 and domain_suffix or nil, - domain_keyword = #domain_keyword > 0 and domain_keyword or nil, - domain_regex = #domain_regex > 0 and domain_regex or nil, - geosite = #geosite > 0 and geosite or nil, - disable_cache = true, + end + local remote_rule = { + server = dns_tag, + domain = #domain > 0 and domain or nil, + domain_suffix = #domain_suffix > 0 and domain_suffix or nil, + domain_keyword = #domain_keyword > 0 and domain_keyword or nil, + domain_regex = #domain_regex > 0 and domain_regex or nil, + geosite = #geosite > 0 and geosite or nil, + disable_cache = true, + } + + local remote_strategy = "prefer_ipv6" + if remote_dns_query_strategy == "UseIPv4" then + remote_strategy = "ipv4_only" + elseif remote_dns_query_strategy == "UseIPv6" then + remote_strategy = "ipv6_only" + end + + local server = { + tag = dns_tag, + address_strategy = "prefer_ipv4", + strategy = remote_strategy, + address_resolver = "direct", + detour = dns_outTag, + } + + if remote_dns_udp_server then + local server_port = tonumber(remote_dns_port) or 53 + server.address = "udp://" .. remote_dns_udp_server .. ":" .. server_port + end + + if remote_dns_tcp_server then + server.address = remote_dns_tcp_server + end + + if remote_dns_doh_url and remote_dns_doh_host then + server.address = remote_dns_doh_url + end + + if server.address then + table.insert(dns.servers, server) + end + + local fakedns_tag = dns_tag .. "_fakeip" + if remote_dns_fake then + dns.fakeip = { + enabled = true, + inet4_range = "198.18.0.0/16", + inet6_range = "fc00::/18", } - - local remote_strategy = "prefer_ipv6" - if remote_dns_query_strategy == "UseIPv4" then - remote_strategy = "ipv4_only" - elseif remote_dns_query_strategy == "UseIPv6" then - remote_strategy = "ipv6_only" - end - - local server = { - tag = dns_tag, - address_strategy = "prefer_ipv4", + + table.insert(dns.servers, { + tag = fakedns_tag, + address = "fakeip", strategy = remote_strategy, - address_resolver = "direct", - detour = dns_outTag, - } - - local rule_server = dns_tag - - if remote_dns_udp_server then - local server_port = tonumber(remote_dns_port) or 53 - server.address = "udp://" .. remote_dns_udp_server .. ":" .. server_port - end - - if remote_dns_tcp_server then - server.address = remote_dns_tcp_server - end - - if remote_dns_doh_url and remote_dns_doh_host then - server.address = remote_dns_doh_url - end - - if server.address then - table.insert(dns.servers, server) - end - - if remote_dns_fake then - dns.fakeip = { - enabled = true, - inet4_range = "198.18.0.0/16", - inet6_range = "fc00::/18", + }) + + if tags and tags:find("with_clash_api") then + if not experimental then + experimental = {} + end + experimental.clash_api = { + store_fakeip = true, + cache_file = "/tmp/singbox_passwall_" .. flag .. ".db" } - - local fakedns_tag = dns_tag .. "_fakeip" - - if not server.address then - fakedns_tag = dns_tag - end - - table.insert(dns.servers, { - tag = fakedns_tag, - address = "fakeip", - strategy = remote_strategy, - }) - - rule_server = fakedns_tag - - if tags and tags:find("with_clash_api") then - if not experimental then - experimental = {} - end - experimental.clash_api = { - store_fakeip = true, - cache_file = "/tmp/singbox_passwall_" .. flag .. ".db" - } - end end - - if remote_rule.domain or remote_rule.domain_suffix or remote_rule.domain_keyword or remote_rule.domain_regex or remote_rule.geosite then - local rule = api.clone(remote_rule) - rule.server = rule_server - table.insert(dns.rules, rule) + end + + if remote_rule.domain or remote_rule.domain_suffix or remote_rule.domain_keyword or remote_rule.domain_regex or remote_rule.geosite then + local rule = api.clone(remote_rule) + rule.server = dns_tag + if remote_dns_fake then + rule.query_type = { + "A", "AAAA" + } + rule.server = fakedns_tag end + table.insert(dns.rules, rule) end if direct_dns_udp_server then @@ -1266,6 +1261,26 @@ function gen_config(var) tag = "block", address = "rcode://refused", }) + + local default_dns_flag = "remote" + if node_id and (tcp_redir_port or udp_redir_port) then + local node = uci:get_all(appname, node_id) + if node.protocol == "_shunt" then + if node.default_node == "_direct" then + default_dns_flag = "direct" + end + end + else default_dns_flag = "direct" + end + if default_dns_flag == "remote" then + if remote_dns_fake then + table.insert(dns.rules, { + query_type = { "A", "AAAA" }, + server = fakedns_tag + }) + end + end + dns.final = default_dns_flag table.insert(inbounds, { type = "direct", @@ -1285,18 +1300,6 @@ function gen_config(var) }, outbound = "dns-out" }) - - local default_dns_flag = "remote" - if node_id and (tcp_redir_port or udp_redir_port) then - local node = uci:get_all(appname, node_id) - if node.protocol == "_shunt" then - if node.default_node == "_direct" then - default_dns_flag = "direct" - end - end - else default_dns_flag = "direct" - end - dns.final = default_dns_flag end if inbounds or outbounds then diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua index c820915bf..dbca852fc 100644 --- a/luci-app-passwall/luasrc/passwall/util_xray.lua +++ b/luci-app-passwall/luasrc/passwall/util_xray.lua @@ -999,7 +999,6 @@ function gen_config(var) end if remote_dns_fake then - remote_dns_server = "1.1.1.1" fakedns = {} fakedns[#fakedns + 1] = { ipPool = "198.18.0.0/16", @@ -1014,6 +1013,11 @@ function gen_config(var) _remote_dns.address = "fakedns" end + if not remote_dns_server then + remote_dns_server = "1.1.1.1" + remote_dns_port = 53 + end + table.insert(dns.servers, _remote_dns) if dns_listen_port then diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index cda4d6ee7..d521ebbc6 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -327,7 +327,7 @@ run_ipt2socks() { run_singbox() { local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password - local dns_listen_port direct_dns_port direct_dns_udp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port + local dns_listen_port direct_dns_port direct_dns_udp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port local loglevel log_file config_file local _extra_param="" eval_set_val $@ @@ -395,10 +395,8 @@ run_singbox() { [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_server ${_doh_bootstrap}" _extra_param="${_extra_param} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}" ;; - fakedns) - _extra_param="${_extra_param} -remote_dns_fake 1" - ;; esac + [ "$remote_fakedns" = "1" ] && _extra_param="${_extra_param} -remote_dns_fake 1" _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way" lua $UTIL_SINGBOX gen_config ${_extra_param} > $config_file ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" $log_file run -c "$config_file" @@ -406,7 +404,7 @@ run_singbox() { run_xray() { local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password - local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh dns_client_ip dns_query_strategy dns_cache dns_socks_address dns_socks_port + local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_fakedns dns_client_ip dns_query_strategy dns_cache dns_socks_address dns_socks_port local loglevel log_file config_file local _extra_param="" eval_set_val $@ @@ -463,10 +461,8 @@ run_xray() { [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_server ${_doh_bootstrap}" _extra_param="${_extra_param} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}" ;; - fakedns) - _extra_param="${_extra_param} -remote_dns_fake 1" - ;; esac + [ "$remote_fakedns" = "1" ] && _extra_param="${_extra_param} -remote_dns_fake 1" _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way" _extra_param="${_extra_param} -loglevel $loglevel" lua $UTIL_XRAY gen_config ${_extra_param} > $config_file @@ -848,21 +844,25 @@ run_redir() { local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" _args="${_args} dns_listen_port=${dns_listen_port}" + local logout="" case "$v2ray_dns_mode" in tcp) _args="${_args} remote_dns_tcp_server=${REMOTE_DNS}" - echolog " - 域名解析 DNS Over TCP..." + logout=" - 域名解析 DNS Over TCP" ;; doh) remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") _args="${_args} remote_dns_doh=${remote_dns_doh}" - echolog " - 域名解析 DNS Over HTTPS..." - ;; - fakedns) - fakedns=1 - echolog " - 域名解析 Fake DNS..." + logout=" - 域名解析 DNS Over HTTPS" ;; esac + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + fakedns=1 + _args="${_args} remote_fakedns=1" + logout="${logout} + FakeDNS" + } + echolog ${logout} } run_singbox flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args} ;; @@ -896,21 +896,25 @@ run_redir() { local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) _args="${_args} remote_dns_protocol=${v2ray_dns_mode}" _args="${_args} dns_listen_port=${dns_listen_port}" + local logout="" case "$v2ray_dns_mode" in tcp) _args="${_args} remote_dns_tcp_server=${REMOTE_DNS}" - echolog " - 域名解析 DNS Over TCP..." + logout=" - 域名解析 DNS Over TCP" ;; doh) remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") _args="${_args} remote_dns_doh=${remote_dns_doh}" - echolog " - 域名解析 DNS Over HTTPS..." - ;; - fakedns) - fakedns=1 - echolog " - 域名解析 Fake DNS..." + logout=" - 域名解析 DNS Over HTTPS" ;; esac + local remote_fakedns=$(config_t_get global remote_fakedns 0) + [ "${remote_fakedns}" = "1" ] && { + fakedns=1 + _args="${_args} remote_fakedns=1" + logout="${logout} + FakeDNS" + } + echolog ${logout} } run_xray flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args} ;;