diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index 406ccab92..5a8c27dd4 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -543,7 +543,7 @@ run_dns2socks() { } run_chinadns_ng() { - local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag + local _flag _listen_port _dns_local _dns_trust _no_ipv6_trust _use_direct_list _use_proxy_list _gfwlist _chnlist _default_mode _default_tag _no_logic_log _tcp_node local _extra_param="" eval_set_val $@ @@ -554,6 +554,7 @@ run_chinadns_ng() { _extra_param="-FLAG ${_flag} -LISTEN_PORT ${_listen_port} -DNS_LOCAL ${_dns_local} -DNS_TRUST ${_dns_trust}" _extra_param="${_extra_param} -USE_DIRECT_LIST ${_use_direct_list} -USE_PROXY_LIST ${_use_proxy_list} -GFWLIST ${_gfwlist} -CHNLIST ${_chnlist}" _extra_param="${_extra_param} -NO_IPV6_TRUST ${_no_ipv6_trust} -DEFAULT_MODE ${_default_mode} -DEFAULT_TAG ${_default_tag} -NFTFLAG ${nftflag}" + _extra_param="${_extra_param} -NO_LOGIC_LOG ${_no_logic_log} -TCP_NODE ${_tcp_node}" lua $APP_PATH/helper_chinadns_add.lua ${_extra_param} > ${_CONF_FILE} ln_run "$(first_type chinadns-ng)" chinadns-ng "${_LOG_FILE}" -C ${_CONF_FILE} @@ -1470,6 +1471,8 @@ start_dns() { local china_ng_listen="127.0.0.1#${china_ng_listen_port}" [ -z "${china_ng_trust_dns}" ] && local china_ng_trust_dns=${TUN_DNS} + echolog " - ChinaDNS-NG(${china_ng_listen}):直连DNS:${china_ng_local_dns},可信DNS:${china_ng_trust_dns}" + run_chinadns_ng \ _flag="default" \ _listen_port=${china_ng_listen_port} \ @@ -1481,9 +1484,9 @@ start_dns() { _gfwlist=${USE_GFW_LIST} \ _chnlist=${CHN_LIST} \ _default_mode=${TCP_PROXY_MODE} \ - _default_tag=$(config_t_get global chinadns_ng_default_tag smart) - - echolog " - ChinaDNS-NG(${china_ng_listen}):直连DNS:${china_ng_local_dns},可信DNS:${china_ng_trust_dns}" + _default_tag=$(config_t_get global chinadns_ng_default_tag smart) \ + _no_logic_log=0 \ + _tcp_node=${TCP_NODE} USE_DEFAULT_DNS="chinadns_ng" } @@ -1677,7 +1680,9 @@ acl_app() { _gfwlist=${use_gfw_list} \ _chnlist=${chn_list} \ _default_mode=${tcp_proxy_mode} \ - _default_tag=${chinadns_ng_default_tag:-smart} + _default_tag=${chinadns_ng_default_tag:-smart} \ + _no_logic_log=1 \ + _tcp_node=${tcp_node} use_default_dns="chinadns_ng" } diff --git a/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua index e4a735420..a9c4d2f1f 100644 --- a/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua +++ b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua @@ -14,6 +14,8 @@ local CHNLIST = var["-CHNLIST"] local NO_IPV6_TRUST = var["-NO_IPV6_TRUST"] local DEFAULT_MODE = var["-DEFAULT_MODE"] local DEFAULT_TAG = var["-DEFAULT_TAG"] +local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"] +local TCP_NODE = var["-TCP_NODE"] local NFTFLAG = var["-NFTFLAG"] local uci = api.uci @@ -27,6 +29,13 @@ local RULES_PATH = "/usr/share/" .. appname .. "/rules" local config_lines = {} local tmp_lines = {} +local function log(...) + if NO_LOGIC_LOG == "1" then + return + end + api.log(...) +end + local function is_file_nonzero(path) if path and #path > 1 then if sys.exec('[ -s "%s" ] && echo -n 1' % path) == "1" then @@ -36,6 +45,13 @@ local function is_file_nonzero(path) return nil end +local function insert_unique(dest_table, value, lookup_table) + if not lookup_table[value] then + table.insert(dest_table, value) + lookup_table[value] = true + end +end + local function merge_array(lines1, lines2) for i, line in ipairs(lines2) do table.insert(lines1, #lines1 + 1, line) @@ -60,15 +76,15 @@ config_lines = { --始终用国内DNS解析节点域名 local file_vpslist = TMP_ACL_PATH .. "/vpslist" if not is_file_nonzero(file_vpslist) then - local vpslist_out = io.open(file_vpslist, "w") + local f_out = io.open(file_vpslist, "w") uci:foreach(appname, "nodes", function(t) local address = t.address if address == "engage.cloudflareclient.com" then return end if datatypes.hostname(address) then - vpslist_out:write(address .. "\n") + f_out:write(address .. "\n") end end) - vpslist_out:close() + f_out:close() end if is_file_nonzero(file_vpslist) then tmp_lines = { @@ -78,24 +94,26 @@ if is_file_nonzero(file_vpslist) then "group-ipset " .. setflag .. "passwall_vpslist," .. setflag .. "passwall_vpslist6" } merge_array(config_lines, tmp_lines) + log(string.format(" - 节点列表中的域名(vpslist):%s", DNS_LOCAL or "默认")) end --直连(白名单)列表 local file_direct_host = TMP_ACL_PATH .. "/direct_host" if USE_DIRECT_LIST == "1" and not fs.access(file_direct_host) then --对自定义列表进行清洗 local direct_domain = {} + local lookup_direct_domain = {} for line in io.lines(RULES_PATH .. "/direct_host") do line = api.get_std_domain(line) if line ~= "" and not line:find("#") then - table.insert(direct_domain, line) + insert_unique(direct_domain, line, lookup_direct_domain) end end if #direct_domain > 0 then - local direct_out = io.open(file_direct_host, "w") + local f_out = io.open(file_direct_host, "w") for i = 1, #direct_domain do - direct_out:write(direct_domain[i] .. "\n") + f_out:write(direct_domain[i] .. "\n") end - direct_out:close() + f_out:close() end end if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then @@ -106,24 +124,26 @@ if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then "group-ipset " .. setflag .. "passwall_whitelist," .. setflag .. "passwall_whitelist6" } merge_array(config_lines, tmp_lines) + log(string.format(" - 域名白名单(whitelist):%s", DNS_LOCAL or "默认")) end --代理(黑名单)列表 local file_proxy_host = TMP_ACL_PATH .. "/proxy_host" if USE_PROXY_LIST == "1" and not fs.access(file_proxy_host) then --对自定义列表进行清洗 local proxy_domain = {} + local lookup_proxy_domain = {} for line in io.lines(RULES_PATH .. "/proxy_host") do line = api.get_std_domain(line) if line ~= "" and not line:find("#") then - table.insert(proxy_domain, line) + insert_unique(proxy_domain, line, lookup_proxy_domain) end end if #proxy_domain > 0 then - local proxy_out = io.open(file_proxy_host, "w") + local f_out = io.open(file_proxy_host, "w") for i = 1, #proxy_domain do - proxy_out:write(proxy_domain[i] .. "\n") + f_out:write(proxy_domain[i] .. "\n") end - proxy_out:close() + f_out:close() end end if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then @@ -135,6 +155,7 @@ if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then } merge_array(config_lines, tmp_lines) if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:proxylist") end + log(string.format(" - 代理域名表(blacklist):%s", DNS_TRUST or "默认")) end --GFW列表 @@ -145,6 +166,7 @@ if GFWLIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then } merge_array(config_lines, tmp_lines) if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:gfw") end + log(string.format(" - 防火墙域名表(gfwlist):%s", DNS_TRUST or "默认")) end --中国列表 @@ -158,6 +180,7 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then "chnlist-first" } merge_array(config_lines, tmp_lines) + log(string.format(" - 中国域名表(chnroute):%s", DNS_LOCAL or "默认")) end --回中国模式 @@ -170,6 +193,92 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then } merge_array(config_lines, tmp_lines) if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:chn_proxy") end + log(string.format(" - 中国域名表(chnroute):%s", DNS_TRUST or "默认")) + end +end + +--分流规则 +if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then + local white_domain = {} + local shunt_domain = {} + local lookup_white_domain = {} + local lookup_shunt_domain = {} + local file_white_host = TMP_ACL_PATH .. "/white_host" + local file_shunt_host = TMP_ACL_PATH .. "/shunt_host" + + local t = uci:get_all(appname, TCP_NODE) + local default_node_id = t["default_node"] or "_direct" + uci:foreach(appname, "shunt_rules", function(s) + local _node_id = t[s[".name"]] or "nil" + if _node_id ~= "nil" and _node_id ~= "_blackhole" then + if _node_id == "_default" then + _node_id = default_node_id + end + + local domain_list = s.domain_list or "" + for line in string.gmatch(domain_list, "[^\r\n]+") do + if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then + if line:find("domain:") or line:find("full:") then + line = string.match(line, ":([^:]+)$") + end + line = api.get_std_domain(line) + if _node_id == "_direct" then + if line ~= "" and not line:find("#") then + insert_unique(white_domain, line, lookup_white_domain) + end + else + if line ~= "" and not line:find("#") then + insert_unique(shunt_domain, line, lookup_shunt_domain) + end + end + end + end + + if _node_id ~= "_direct" then + log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, DNS_TRUST or "默认")) + end + end + end) + + if is_file_nonzero(file_white_host) == nil then + if #white_domain > 0 then + local f_out = io.open(file_white_host, "w") + for i = 1, #white_domain do + f_out:write(white_domain[i] .. "\n") + end + f_out:close() + end + end + + if is_file_nonzero(file_shunt_host) == nil then + if #shunt_domain > 0 then + local f_out = io.open(file_shunt_host, "w") + for i = 1, #shunt_domain do + f_out:write(shunt_domain[i] .. "\n") + end + f_out:close() + end + end + + if is_file_nonzero(file_white_host) then + tmp_lines = { + "group whitelist", + "group-dnl " .. file_white_host, + "group-upstream " .. DNS_LOCAL, + "group-ipset " .. setflag .. "passwall_whitelist," .. setflag .. "passwall_whitelist6" + } + merge_array(config_lines, tmp_lines) + end + + if is_file_nonzero(file_shunt_host) then + tmp_lines = { + "group shuntlist", + "group-dnl " .. file_shunt_host, + "group-upstream " .. DNS_TRUST, + "group-ipset " .. setflag .. "passwall_shuntlist," .. setflag .. "passwall_shuntlist6" + } + merge_array(config_lines, tmp_lines) + if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6 tag:shuntlist") end end end diff --git a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua index f062657cf..991f744cf 100644 --- a/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua +++ b/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq_add.lua @@ -221,8 +221,8 @@ if not fs.access(CACHE_DNS_PATH) then set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6") end end) + log(string.format(" - 节点列表中的域名(vpslist):%s", fwd_dns or "默认")) end - log(string.format(" - 节点列表中的域名(vpslist):%s", fwd_dns or "默认")) end --直连(白名单)列表 @@ -242,8 +242,8 @@ if not fs.access(CACHE_DNS_PATH) then set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6") end end + log(string.format(" - 域名白名单(whitelist):%s", fwd_dns or "默认")) end - log(string.format(" - 域名白名单(whitelist):%s", fwd_dns or "默认")) end end @@ -272,8 +272,8 @@ if not fs.access(CACHE_DNS_PATH) then set_domain_ipset(line, ipset_flag) end end + log(string.format(" - 代理域名表(blacklist):%s", fwd_dns or "默认")) end - log(string.format(" - 代理域名表(blacklist):%s", fwd_dns or "默认")) end end @@ -306,8 +306,8 @@ if not fs.access(CACHE_DNS_PATH) then set_domain_ipset(line, ipset_flag) end end + log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认")) end - log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认")) end end @@ -348,13 +348,13 @@ if not fs.access(CACHE_DNS_PATH) then set_domain_ipset(line, ipset_flag) end end + log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认")) end - log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认")) end end --分流规则 - if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then + if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_DEFAULT_DNS ~= "chinadns_ng" and CHINADNS_DNS == "0" then local t = uci:get_all(appname, TCP_NODE) local default_node_id = t["default_node"] or "_direct" uci:foreach(appname, "shunt_rules", function(s) @@ -391,6 +391,7 @@ if not fs.access(CACHE_DNS_PATH) then if line:find("domain:") or line:find("full:") then line = string.match(line, ":([^:]+)$") end + line = api.get_std_domain(line) add_excluded_domain(line) if no_ipv6 then @@ -401,7 +402,7 @@ if not fs.access(CACHE_DNS_PATH) then end end if _node_id ~= "_direct" then - log(string.format(" - V2ray/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认")) + log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认")) end end end) diff --git a/luci-app-passwall/root/usr/share/passwall/iptables.sh b/luci-app-passwall/root/usr/share/passwall/iptables.sh index 8ecfd233e..069271524 100755 --- a/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -745,6 +745,8 @@ add_firewall_rule() { #分流规则的IP列表 local node_protocol=$(config_n_get $TCP_NODE protocol) if [ "$node_protocol" = "_shunt" ]; then + USE_DIRECT_LIST = "1" + USE_BLOCK_LIST = "1" local default_node_id=$(config_n_get $TCP_NODE default_node "_direct") local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') for shunt_id in $shunt_ids; do diff --git a/luci-app-passwall/root/usr/share/passwall/nftables.sh b/luci-app-passwall/root/usr/share/passwall/nftables.sh index 55a631e36..630a438a2 100755 --- a/luci-app-passwall/root/usr/share/passwall/nftables.sh +++ b/luci-app-passwall/root/usr/share/passwall/nftables.sh @@ -830,6 +830,8 @@ add_firewall_rule() { #分流规则的IP列表 local node_protocol=$(config_n_get $TCP_NODE protocol) if [ "$node_protocol" = "_shunt" ]; then + USE_DIRECT_LIST = "1" + USE_BLOCK_LIST = "1" local default_node_id=$(config_n_get $TCP_NODE default_node "_direct") local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') for shunt_id in $shunt_ids; do