From 7b412bdb340aae07d7c9dbba6c83e6861e78241e Mon Sep 17 00:00:00 2001 From: gitea-action Date: Fri, 22 Nov 2024 01:30:18 +0800 Subject: [PATCH] luci-app-passwall: sync upstream last commit: https://github.com/xiaorouji/openwrt-passwall/commit/849a638eb905bc3632d4bf55006c5c7b71eec962 --- .../model/cbi/passwall/client/global.lua | 7 +- .../root/usr/share/passwall/app.sh | 3 +- .../share/passwall/helper_chinadns_add.lua | 8 +- .../share/passwall/helper_smartdns_add.lua | 711 +++++++++--------- patch-luci-app-passwall.patch | 4 +- 5 files changed, 381 insertions(+), 352 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 67e0768eb..b2a564b0c 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -396,10 +396,6 @@ if api.is_finded("smartdns") then end return DynamicList.write(self, section, t) end - - o = s:taboption("DNS", Flag, "smartdns_exclude_default_group", translate("Exclude Default Group"), translate("Exclude DNS Server from default group.")) - o.default = "0" - o:depends("dns_shunt", "smartdns") end ---- DNS Forward Mode @@ -563,6 +559,9 @@ o:value("remote", translate("Remote DNS")) o:value("direct", translate("Direct DNS")) o.description = desc .. "" o:depends({dns_shunt = "dnsmasq", tcp_proxy_mode = "proxy", chn_list = "direct"}) +if api.is_finded("smartdns") then + o:depends({dns_shunt = "smartdns", tcp_proxy_mode = "proxy", chn_list = "direct"}) +end o = s:taboption("DNS", Flag, "dns_redirect", "DNS " .. translate("Redirect"), translate("Force Router DNS server to all local devices.")) o.default = "0" diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index 6d4179539..80c8fcdd9 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -1361,9 +1361,8 @@ start_dns() { else smartdns_remote_dns="tcp://1.1.1.1" fi - local smartdns_exclude_default_group=$(config_t_get global smartdns_exclude_default_group 0) lua $APP_PATH/helper_smartdns_add.lua -FLAG "default" -SMARTDNS_CONF "/tmp/etc/smartdns/$CONFIG.conf" \ - -LOCAL_GROUP ${group_domestic:-nil} -REMOTE_GROUP "passwall_proxy" -REMOTE_PROXY_SERVER ${TCP_SOCKS_server} -REMOTE_EXCLUDE "${smartdns_exclude_default_group}" \ + -LOCAL_GROUP ${group_domestic:-nil} -REMOTE_GROUP "passwall_proxy" -REMOTE_PROXY_SERVER ${TCP_SOCKS_server} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" \ -TUN_DNS ${smartdns_remote_dns} \ -USE_DIRECT_LIST "${USE_DIRECT_LIST}" -USE_PROXY_LIST "${USE_PROXY_LIST}" -USE_BLOCK_LIST "${USE_BLOCK_LIST}" -USE_GFW_LIST "${USE_GFW_LIST}" -CHN_LIST "${CHN_LIST}" \ -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE "${TCP_PROXY_MODE}" -NO_PROXY_IPV6 ${FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ 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 361d29bec..42ddc1286 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 @@ -84,7 +84,7 @@ local function insert_array_after(array1, array2, target) --将array2插入到ar end if not fs.access(TMP_ACL_PATH) then - fs.mkdir(TMP_ACL_PATH, 493) + fs.mkdir(TMP_ACL_PATH) end local setflag = (NFTFLAG == "1") and "inet@passwall@" or "" @@ -345,7 +345,9 @@ if CHNLIST == "proxy" then DEFAULT_TAG = "chn" end --全局模式,默认使用远程DNS if DEFAULT_MODE == "proxy" and CHNLIST == "0" and GFWLIST == "0" then DEFAULT_TAG = "gfw" - if NO_IPV6_TRUST == "1" then table.insert(config_lines, "no-ipv6") end + if NO_IPV6_TRUST == "1" and uci:get(appname, TCP_NODE, "protocol") ~= "_shunt" then + table.insert(config_lines, "no-ipv6") + end end --是否接受直连 DNS 空响应 @@ -368,7 +370,7 @@ if DEFAULT_TAG == "chn" then elseif DEFAULT_TAG == "gfw" then log(string.format(" - 默认:%s", DNS_TRUST)) else - log(string.format(" - 默认:%s", "127.0.0.1#" .. LISTEN_PORT)) + log(string.format(" - 默认:%s", "智能匹配")) end --输出配置文件 diff --git a/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua index 06aae68a3..4c2bbf593 100644 --- a/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua +++ b/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua @@ -8,7 +8,7 @@ local SMARTDNS_CONF = var["-SMARTDNS_CONF"] local LOCAL_GROUP = var["-LOCAL_GROUP"] local REMOTE_GROUP = var["-REMOTE_GROUP"] local REMOTE_PROXY_SERVER = var["-REMOTE_PROXY_SERVER"] -local REMOTE_EXCLUDE = var["-REMOTE_EXCLUDE"] +local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"] local TUN_DNS = var["-TUN_DNS"] local TCP_NODE = var["-TCP_NODE"] local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"] @@ -24,16 +24,17 @@ local CACHE_PATH = api.CACHE_PATH local CACHE_FLAG = "smartdns_" .. FLAG local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG local CACHE_DNS_FILE = CACHE_DNS_PATH .. ".conf" -local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt" local uci = api.uci local sys = api.sys local fs = api.fs local datatypes = api.datatypes -local list1 = {} -local excluded_domain = {} -local excluded_domain_str = "!" +local TMP_PATH = "/tmp/etc/" .. appname +local TMP_ACL_PATH = TMP_PATH .. "/acl" +local RULES_PATH = "/usr/share/" .. appname .. "/rules" +local config_lines = {} +local tmp_lines = {} local function log(...) if NO_LOGIC_LOG == "1" then @@ -42,124 +43,63 @@ local function log(...) api.log(...) end -local function check_ipset(domain, ipset) - if domain == "" or domain:find("#") then - return false - end - if not ipset then - return - end - for k,v in ipairs(list1[domain].ipsets) do - if ipset == v then +local function is_file_nonzero(path) + if path and #path > 1 then + if sys.exec('[ -s "%s" ] && echo -n 1' % path) == "1" then return true end end - return false + return nil end -local function set_domain_extra_param(domain, param) - if domain == "" or domain:find("#") then - return - end - if not list1[domain] then - list1[domain] = { - params = {} - } - end - if not list1[domain].params then - list1[domain].params = {} - end - if not list1[domain].params[param] then - list1[domain].params[param] = param +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 set_domain_address(domain, address) - if domain == "" or domain:find("#") then - return - end - if not list1[domain] then - list1[domain] = {} - end - if not list1[domain].address then - list1[domain].address = address +local function merge_array(array1, array2) + for i, line in ipairs(array2) do + table.insert(array1, #array1 + 1, line) end end -local function set_domain_group(domain, group) - if domain == "" or domain:find("#") then - return - end - if not group then - return - end - if not list1[domain] then - list1[domain] = {} - end - if not list1[domain].group then - list1[domain].group = group - if group == REMOTE_GROUP then - list1[domain].speed_check_mode = "none" +local function insert_array_before(array1, array2, target) --将array2插入到array1的target前面,target不存在则追加 + for i, line in ipairs(array1) do + if line == target then + for j = #array2, 1, -1 do + table.insert(array1, i, array2[j]) + end + return end end + merge_array(array1, array2) end -local function set_domain_ipset(domain, ipset) - if domain == "" or domain:find("#") then - return - end - if not ipset then - return - end - if not list1[domain] then - list1[domain] = {} - end - if not list1[domain].ipsets then - list1[domain].ipsets = {} - end - for line in string.gmatch(ipset, '[^' .. "," .. ']+') do - if not check_ipset(domain, line) then - table.insert(list1[domain].ipsets, line) +local function insert_array_after(array1, array2, target) --将array2插入到array1的target后面,target不存在则追加 + for i, line in ipairs(array1) do + if line == target then + for j = 1, #array2 do + table.insert(array1, i + j, array2[j]) + end + return end end + merge_array(array1, array2) end -local function add_excluded_domain(domain) - if domain == "" or domain:find("#") then - return - end - table.insert(excluded_domain, domain) - excluded_domain_str = excluded_domain_str .. "|" .. domain +if not fs.access(TMP_ACL_PATH) then + fs.mkdir(TMP_ACL_PATH) end -local function check_excluded_domain(domain) - if domain == "" or domain:find("#") then - return false - end - for k,v in ipairs(excluded_domain) do - if domain:find(v) then - return true - end - end - return false -end - -local cache_text = "" -local nodes_address_md5 = luci.sys.exec("echo -n $(uci show passwall | grep '\\.address') | md5sum") -local new_rules = luci.sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)") -local new_text = SMARTDNS_CONF .. LOCAL_GROUP .. REMOTE_GROUP .. REMOTE_PROXY_SERVER .. REMOTE_EXCLUDE .. TUN_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. nodes_address_md5 .. new_rules -if fs.access(CACHE_TEXT_FILE) then - for line in io.lines(CACHE_TEXT_FILE) do - cache_text = line - end -end - -if cache_text ~= new_text then - api.remove(CACHE_DNS_PATH .. "*") +if not fs.access(CACHE_PATH) then + fs.mkdir(CACHE_PATH) end if LOCAL_GROUP == "nil" then LOCAL_GROUP = nil + log(" * 注意:国内分组名未设置,可能会导致 DNS 解析异常!") end if not REMOTE_GROUP or REMOTE_GROUP == "nil" then @@ -170,263 +110,352 @@ if not REMOTE_GROUP or REMOTE_GROUP == "nil" then sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1') end -if not fs.access(CACHE_DNS_FILE) then - sys.exec(string.format('echo "server %s -bootstrap-dns" >> %s', "114.114.114.114", CACHE_DNS_FILE)) - local proxy_server_name = "passwall-proxy-server" - sys.call(string.format('echo "proxy-server socks5://%s -name %s" >> %s', REMOTE_PROXY_SERVER, proxy_server_name, CACHE_DNS_FILE)) - if true then - string.gsub(TUN_DNS, '[^' .. "|" .. ']+', function(w) - local server_dns = w - local server_param = string.format("server %s -group %s -proxy %s", "%s", REMOTE_GROUP, proxy_server_name) +local proxy_server_name = "passwall-proxy-server" +config_lines = { + "force-qtype-SOA 65", + "server 114.114.114.114 -bootstrap-dns", + string.format("proxy-server socks5://%s -name %s", REMOTE_PROXY_SERVER, proxy_server_name) +} +if true then + string.gsub(TUN_DNS, '[^' .. "|" .. ']+', function(w) + local server_dns = w + local server_param = string.format("server %s -group %s -proxy %s", "%s", REMOTE_GROUP, proxy_server_name) - if REMOTE_EXCLUDE == "1" then - server_param = server_param .. " -exclude-default-group" - end - - local isHTTPS = w:find("https://") - if isHTTPS and isHTTPS == 1 then - local http_host = nil - local url = w - local port = 443 - local s = api.split(w, ",") - if s and #s > 1 then - url = s[1] - local dns_ip = s[2] - local host_port = api.get_domain_from_url(s[1]) - if host_port and #host_port > 0 then - http_host = host_port - local s2 = api.split(host_port, ":") - if s2 and #s2 > 1 then - http_host = s2[1] - port = s2[2] - end - url = url:gsub(http_host, dns_ip) - end - end - server_dns = url - if http_host then - server_dns = server_dns .. " -http-host " .. http_host + local isHTTPS = w:find("https://") + if isHTTPS and isHTTPS == 1 then + local http_host = nil + local url = w + local port = 443 + local s = api.split(w, ",") + if s and #s > 1 then + url = s[1] + local dns_ip = s[2] + local host_port = api.get_domain_from_url(s[1]) + if host_port and #host_port > 0 then + http_host = host_port + local s2 = api.split(host_port, ":") + if s2 and #s2 > 1 then + http_host = s2[1] + port = s2[2] + end + url = url:gsub(http_host, dns_ip) end end - server_param = string.format(server_param, server_dns) - sys.exec(string.format('echo "%s" >> %s', server_param, CACHE_DNS_FILE)) - end) + server_dns = url + if http_host then + server_dns = server_dns .. " -http-host " .. http_host + end + end + server_param = string.format(server_param, server_dns) + table.insert(config_lines, server_param) + end) +end + +--设置默认 DNS 分组(托底组) +local DEFAULT_DNS_GROUP = (USE_DEFAULT_DNS == "direct" and LOCAL_GROUP) or + (USE_DEFAULT_DNS == "remote" and REMOTE_GROUP) +local only_global = (DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0") and 1 --没有启用中国列表和GFW列表时(全局) +if only_global == 1 then + DEFAULT_DNS_GROUP = REMOTE_GROUP +end +if DEFAULT_DNS_GROUP then + local domain_rules_str = "domain-rules /./ -nameserver " .. DEFAULT_DNS_GROUP + if DEFAULT_DNS_GROUP == REMOTE_GROUP then + domain_rules_str = domain_rules_str .. " -speed-check-mode none -d no -no-serve-expired" + if NO_PROXY_IPV6 == "1" and only_global == 1 and uci:get(appname, TCP_NODE, "protocol") ~= "_shunt" then + domain_rules_str = domain_rules_str .. " -address #6" + end end + table.insert(config_lines, domain_rules_str) +end - local setflag= (NFTFLAG == "1") and "inet#passwall#" or "" - local set_type= (NFTFLAG == "1") and "-nftset" or "-ipset" +local setflag = (NFTFLAG == "1") and "inet#passwall#" or "" +local set_type = (NFTFLAG == "1") and "-nftset" or "-ipset" - --始终用国内DNS解析节点域名 +--预设排序标签(越往后优先级越高) +for i = 1, 8 do + table.insert(config_lines, "#--" .. i) +end + +--屏蔽列表 +local file_block_host = TMP_ACL_PATH .. "/block_host" +if USE_BLOCK_LIST == "1" and not fs.access(file_block_host) then --对自定义列表进行清洗 + local block_domain, lookup_block_domain = {}, {} + for line in io.lines(RULES_PATH .. "/block_host") do + line = api.get_std_domain(line) + if line ~= "" and not line:find("#") then + insert_unique(block_domain, line, lookup_block_domain) + end + end + if #block_domain > 0 then + local f_out = io.open(file_block_host, "w") + for i = 1, #block_domain do + f_out:write(block_domain[i] .. "\n") + end + f_out:close() + end +end +if USE_BLOCK_LIST == "1" and is_file_nonzero(file_block_host) then + local domain_set_name = "passwall-block" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_block_host), + string.format("domain-rules /domain-set:%s/ -a #", domain_set_name) + } + insert_array_after(config_lines, tmp_lines, "#--7") +end + +--始终用国内DNS解析节点域名 +local file_vpslist = TMP_ACL_PATH .. "/vpslist" +if not is_file_nonzero(file_vpslist) then + 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 - set_domain_group(address, LOCAL_GROUP) - set_domain_ipset(address, "#4:" .. setflag .. "passwall_vpslist,#6:" .. setflag .. "passwall_vpslist6") + f_out:write(address .. "\n") end end) - log(string.format(" - 节点列表中的域名(vpslist)使用分组:%s", LOCAL_GROUP or "默认")) - - --屏蔽列表 - if USE_BLOCK_LIST == "1" then - if fs.access("/usr/share/passwall/rules/block_host") then - for line in io.lines("/usr/share/passwall/rules/block_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - set_domain_address(line, "-") - end - end - end - end - - --直连(白名单)列表 - if USE_DIRECT_LIST == "1" then - if fs.access("/usr/share/passwall/rules/direct_host") then - for line in io.lines("/usr/share/passwall/rules/direct_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - add_excluded_domain(line) - set_domain_group(line, LOCAL_GROUP) - set_domain_ipset(line, "#4:" .. setflag .. "passwall_whitelist,#6:" .. setflag .. "passwall_whitelist6") - end - end - log(string.format(" - 域名白名单(whitelist)使用分组:%s", LOCAL_GROUP or "默认")) - end - end - - --代理(黑名单)列表 - if USE_PROXY_LIST == "1" then - if fs.access("/usr/share/passwall/rules/proxy_host") then - for line in io.lines("/usr/share/passwall/rules/proxy_host") do - line = api.get_std_domain(line) - if line ~= "" and not line:find("#") then - add_excluded_domain(line) - local ipset_flag = "#4:" .. setflag .. "passwall_blacklist,#6:" .. setflag .. "passwall_blacklist6" - if NO_PROXY_IPV6 == "1" then - set_domain_address(line, "#6") - ipset_flag = "#4:" .. setflag .. "passwall_blacklist" - end - set_domain_group(line, REMOTE_GROUP) - set_domain_ipset(line, ipset_flag) - set_domain_extra_param(line, "-no-serve-expired") - end - end - log(string.format(" - 代理域名表(blacklist)使用分组:%s", REMOTE_GROUP or "默认")) - end - end - - --GFW列表 - if USE_GFW_LIST == "1" then - if fs.access("/usr/share/passwall/rules/gfwlist") then - local domain_set_name = "passwall-gfwlist" - local domain_file = CACHE_DNS_PATH .. "_gfwlist.list" - sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '" > ' .. domain_file) - sys.exec(string.format('echo "domain-set -name %s -file %s" >> %s', domain_set_name, domain_file, CACHE_DNS_FILE)) - local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) - domain_rules_str = domain_rules_str .. " -speed-check-mode none" - domain_rules_str = domain_rules_str .. " -no-serve-expired" - if NO_PROXY_IPV6 == "1" then - domain_rules_str = domain_rules_str .. " -address #6" - domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_gfwlist" - else - domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_gfwlist" .. ",#6:" .. setflag .. "passwall_gfwlist6" - end - sys.exec(string.format('echo "%s" >> %s', domain_rules_str, CACHE_DNS_FILE)) - log(string.format(" - 防火墙域名表(gfwlist)使用分组:%s", REMOTE_GROUP or "默认")) - end - end - - --中国列表 - if CHN_LIST ~= "0" then - if fs.access("/usr/share/passwall/rules/chnlist") then - local domain_set_name = "passwall-chnlist" - local domain_file = CACHE_DNS_PATH .. "_chnlist.list" - sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '" > ' .. domain_file) - sys.exec(string.format('echo "domain-set -name %s -file %s" >> %s', domain_set_name, domain_file, CACHE_DNS_FILE)) - - if CHN_LIST == "direct" then - local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") - domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_chnroute,#6:" .. setflag .. "passwall_chnroute6" - sys.exec(string.format('echo "%s" >> %s', domain_rules_str, CACHE_DNS_FILE)) - log(string.format(" - 中国域名表(chnroute)使用分组:%s", LOCAL_GROUP or "默认")) - end - if CHN_LIST == "proxy" then - local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) - domain_rules_str = domain_rules_str .. " -speed-check-mode none" - domain_rules_str = domain_rules_str .. " -no-serve-expired" - if NO_PROXY_IPV6 == "1" then - domain_rules_str = domain_rules_str .. " -address #6" - domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_chnroute" - else - domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_chnroute" .. ",#6:" .. setflag .. "passwall_chnroute6" - end - sys.exec(string.format('echo "%s" >> %s', domain_rules_str, CACHE_DNS_FILE)) - log(string.format(" - 中国域名表(chnroute)使用分组:%s", REMOTE_GROUP or "默认")) - end - end - end - - --分流规则 - if uci:get(appname, TCP_NODE, "protocol") == "_shunt" 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) - 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 fwd_group = nil - local ipset_flag = nil - local no_ipv6 = nil - - if _node_id == "_direct" then - fwd_group = LOCAL_GROUP - ipset_flag = "#4:" .. setflag .. "passwall_whitelist,#6:" .. setflag .. "passwall_whitelist6" - else - fwd_group = REMOTE_GROUP - ipset_flag = "#4:" .. setflag .. "passwall_shuntlist,#6:" .. setflag .. "passwall_shuntlist6" - if NO_PROXY_IPV6 == "1" then - ipset_flag = "#4:" .. setflag .. "passwall_shuntlist" - no_ipv6 = true - end - 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) - add_excluded_domain(line) - - if no_ipv6 then - set_domain_address(line, "#6") - end - set_domain_group(line, fwd_group) - set_domain_ipset(line, ipset_flag) - if fwd_group == REMOTE_GROUP then - set_domain_extra_param(line, "-no-serve-expired") - end - end - end - if _node_id ~= "_direct" then - log(string.format(" - Sing-Box/Xray分流规则(%s)使用分组:%s", s.remarks, fwd_group or "默认")) - end - end - end) - end - - local f_out = io.open(CACHE_DNS_FILE, "a") - for key, value in pairs(list1) do - local group_str = "" - local ipset_str = "" - local speed_check_mode_str = "" - local address_str = "" - local extra_param_str = "" - if value.group and #value.group > 0 then - group_str = group_str .. value.group - end - if group_str ~= "" then - group_str = " -n " .. group_str - end - if value.ipsets and #value.ipsets > 0 then - for i, ipset in ipairs(value.ipsets) do - ipset_str = ipset_str .. ipset .. "," - end - ipset_str = ipset_str:sub(1, #ipset_str - 1) - end - if ipset_str ~= "" then - ipset_str = " " .. set_type .. " " .. ipset_str - end - if value.address and #value.address > 0 then - address_str = address_str .. value.address - end - if address_str ~= "" then - address_str = " -a " .. address_str - end - if value.speed_check_mode and #value.speed_check_mode > 0 then - speed_check_mode_str = value.speed_check_mode - end - if speed_check_mode_str ~= "" then - speed_check_mode_str = " -c " .. speed_check_mode_str - end - if value.params then - for k2, v2 in pairs(value.params) do - extra_param_str = extra_param_str .. " " .. v2 - end - end - local str = string.format("domain-rules /%s/ %s%s%s%s%s\n", key, group_str, ipset_str, address_str, speed_check_mode_str, extra_param_str) - f_out:write(str) - end - f_out:close() - - f_out = io.open(CACHE_TEXT_FILE, "a") - f_out:write(new_text) f_out:close() end +if is_file_nonzero(file_vpslist) then + local domain_set_name = "passwall-vpslist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_vpslist) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_vpslist,#6:" .. setflag .. "passwall_vpslist6" + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--8") + log(string.format(" - 节点列表中的域名(vpslist)使用分组:%s", LOCAL_GROUP 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, 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 + insert_unique(direct_domain, line, lookup_direct_domain) + end + end + if #direct_domain > 0 then + local f_out = io.open(file_direct_host, "w") + for i = 1, #direct_domain do + f_out:write(direct_domain[i] .. "\n") + end + f_out:close() + end +end +if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then + local domain_set_name = "passwall-directlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_direct_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_whitelist,#6:" .. setflag .. "passwall_whitelist6" + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--6") + log(string.format(" - 域名白名单(whitelist)使用分组:%s", LOCAL_GROUP 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, 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 + insert_unique(proxy_domain, line, lookup_proxy_domain) + end + end + if #proxy_domain > 0 then + local f_out = io.open(file_proxy_host, "w") + for i = 1, #proxy_domain do + f_out:write(proxy_domain[i] .. "\n") + end + f_out:close() + end +end +if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then + local domain_set_name = "passwall-proxylist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_proxy_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_blacklist" + else + domain_rules_str = domain_rules_str .. " -d no " .. set_type .. " #4:" .. setflag .. "passwall_blacklist" .. ",#6:" .. setflag .. "passwall_blacklist6" + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--5") + log(string.format(" - 代理域名表(blacklist)使用分组:%s", REMOTE_GROUP or "默认")) +end + +--GFW列表 +if USE_GFW_LIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then + local domain_set_name = "passwall-gfwlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/gfwlist") + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_gfwlist" + else + domain_rules_str = domain_rules_str .. " -d no " .. set_type .. " #4:" .. setflag .. "passwall_gfwlist" .. ",#6:" .. setflag .. "passwall_gfwlist6" + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--1") + log(string.format(" - 防火墙域名表(gfwlist)使用分组:%s", REMOTE_GROUP or "默认")) +end + +--中国列表 +if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then + local domain_set_name = "passwall-chnlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/chnlist") + } + + if CHN_LIST == "direct" then + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_chnroute,#6:" .. setflag .. "passwall_chnroute6" + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--2") + log(string.format(" - 中国域名表(chnroute)使用分组:%s", LOCAL_GROUP or "默认")) + end + + --回中国模式 + if CHN_LIST == "proxy" then + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_chnroute" + else + domain_rules_str = domain_rules_str .. " -d no " .. set_type .. " #4:" .. setflag .. "passwall_chnroute" .. ",#6:" .. setflag .. "passwall_chnroute6" + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--2") + log(string.format(" - 中国域名表(chnroute)使用分组:%s", REMOTE_GROUP or "默认")) + end +end + +--分流规则 +if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then + local white_domain, lookup_white_domain = {}, {} + local shunt_domain, 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, REMOTE_GROUP 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 + local domain_set_name = "passwall-whitehost" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_white_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "") + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_whitelist,#6:" .. setflag .. "passwall_whitelist6" + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--3") + end + + if is_file_nonzero(file_shunt_host) then + local domain_set_name = "passwall-shuntlist" + tmp_lines = { + string.format("domain-set -name %s -file %s", domain_set_name, file_shunt_host) + } + local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP) + domain_rules_str = domain_rules_str .. " -speed-check-mode none" + domain_rules_str = domain_rules_str .. " -no-serve-expired" + if NO_PROXY_IPV6 == "1" then + domain_rules_str = domain_rules_str .. " -address #6" + domain_rules_str = domain_rules_str .. " " .. set_type .. " #4:" .. setflag .. "passwall_shuntlist" + else + domain_rules_str = domain_rules_str .. " -d no " .. set_type .. " #4:" .. setflag .. "passwall_shuntlist" .. ",#6:" .. setflag .. "passwall_shuntlist6" + end + table.insert(tmp_lines, domain_rules_str) + insert_array_after(config_lines, tmp_lines, "#--4") + end + +end + +if #config_lines > 0 then + local f_out = io.open(CACHE_DNS_FILE, "w") + for i = 1, #config_lines do + line = config_lines[i] + if line ~= "" and not line:find("^#--") then + f_out:write(line .. "\n") + end + end + f_out:close() +end + +if DEFAULT_DNS_GROUP then + log(string.format(" - 默认分组:%s", DEFAULT_DNS_GROUP)) +end + fs.symlink(CACHE_DNS_FILE, SMARTDNS_CONF) sys.call(string.format('echo "conf-file %s" >> /etc/smartdns/custom.conf', string.gsub(SMARTDNS_CONF, appname, appname .. "*"))) log(" - 请让SmartDNS作为Dnsmasq的上游或重定向!") diff --git a/patch-luci-app-passwall.patch b/patch-luci-app-passwall.patch index f44c5c21c..48bd3d647 100644 --- a/patch-luci-app-passwall.patch +++ b/patch-luci-app-passwall.patch @@ -24,10 +24,10 @@ index 8cc5965..add2a56 100644 if code ~= 0 then local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") 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 6fa2cf9..67e0768 100644 +index a63c1af..b2a564b 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua -@@ -471,6 +471,12 @@ o:value("9.9.9.9", "9.9.9.9 (Quad9)") +@@ -467,6 +467,12 @@ o:value("9.9.9.9", "9.9.9.9 (Quad9)") o:value("149.112.112.112", "149.112.112.112 (Quad9)") o:value("208.67.220.220", "208.67.220.220 (OpenDNS)") o:value("208.67.222.222", "208.67.222.222 (OpenDNS)")