diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index c059c8180..6844e497f 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall -PKG_VERSION:=4.77-1 +PKG_VERSION:=4.77-2 PKG_RELEASE:= PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua index c7f958c44..31a616497 100644 --- a/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua @@ -57,7 +57,7 @@ function index() entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true - entry({"admin", "services", appname, "status"}, call("status")).leaf = true + entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true entry({"admin", "services", appname, "haproxy_status"}, call("haproxy_status")).leaf = true entry({"admin", "services", appname, "socks_status"}, call("socks_status")).leaf = true entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true @@ -201,17 +201,16 @@ function clear_log() luci.sys.call("echo '' > /tmp/log/passwall.log") end -function status() - -- local dns_mode = ucic:get(appname, "@global[0]", "dns_mode") +function index_status() local e = {} e.dns_mode_status = luci.sys.call("netstat -apn | grep ':15353 ' >/dev/null") == 0 e.haproxy_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0 - e["tcp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep 'TCP' >/dev/null") == 0 + e["tcp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'TCP' >/dev/null") == 0 if (ucic:get(appname, "@global[0]", "udp_node") or "nil") == "tcp" then e["udp_node_status"] = e["tcp_node_status"] else - e["udp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep 'UDP' >/dev/null") == 0 + e["udp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'UDP' >/dev/null") == 0 end luci.http.prepare_content("application/json") luci.http.write_json(e) diff --git a/luci-app-passwall/luasrc/controller/passwall.lua.orig b/luci-app-passwall/luasrc/controller/passwall.lua.orig new file mode 100644 index 000000000..bfb8f7961 --- /dev/null +++ b/luci-app-passwall/luasrc/controller/passwall.lua.orig @@ -0,0 +1,445 @@ +-- Copyright (C) 2018-2020 L-WRT Team +-- Copyright (C) 2021-2023 xiaorouji + +module("luci.controller.passwall", package.seeall) +local api = require "luci.passwall.api" +local appname = "passwall" +local ucic = luci.model.uci.cursor() +local http = require "luci.http" +local util = require "luci.util" +local i18n = require "luci.i18n" + +function index() + appname = "passwall" + entry({"admin", "services", appname}).dependent = true + entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true + entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true + entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true + if not nixio.fs.access("/etc/config/passwall") then return end + if nixio.fs.access("/etc/config/passwall_show") then + e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("Pass Wall"), -1) + e.dependent = true + e.acl_depends = { "luci-app-passwall" } + end + --[[ Client ]] + entry({"admin", "services", appname, "settings"}, cbi(appname .. "/client/global"), _("Basic Settings"), 1).dependent = true + entry({"admin", "services", appname, "node_list"}, cbi(appname .. "/client/node_list"), _("Node List"), 2).dependent = true + entry({"admin", "services", appname, "node_subscribe"}, cbi(appname .. "/client/node_subscribe"), _("Node Subscribe"), 3).dependent = true + entry({"admin", "services", appname, "other"}, cbi(appname .. "/client/other", {autoapply = true}), _("Other Settings"), 92).leaf = true + if nixio.fs.access("/usr/sbin/haproxy") then + entry({"admin", "services", appname, "haproxy"}, cbi(appname .. "/client/haproxy"), _("Load Balancing"), 93).leaf = true + end + entry({"admin", "services", appname, "app_update"}, cbi(appname .. "/client/app_update"), _("App Update"), 95).leaf = true + entry({"admin", "services", appname, "rule"}, cbi(appname .. "/client/rule"), _("Rule Manage"), 96).leaf = true + entry({"admin", "services", appname, "rule_list"}, cbi(appname .. "/client/rule_list"), _("Rule List"), 97).leaf = true + entry({"admin", "services", appname, "node_subscribe_config"}, cbi(appname .. "/client/node_subscribe_config")).leaf = true + entry({"admin", "services", appname, "node_config"}, cbi(appname .. "/client/node_config")).leaf = true + entry({"admin", "services", appname, "shunt_rules"}, cbi(appname .. "/client/shunt_rules")).leaf = true + entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true + entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true + entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true + entry({"admin", "services", appname, "log"}, form(appname .. "/client/log"), _("Watch Logs"), 999).leaf = true + + --[[ Server ]] + entry({"admin", "services", appname, "server"}, cbi(appname .. "/server/index"), _("Server-Side"), 99).leaf = true + entry({"admin", "services", appname, "server_user"}, cbi(appname .. "/server/user")).leaf = true + + --[[ API ]] + entry({"admin", "services", appname, "server_user_status"}, call("server_user_status")).leaf = true + entry({"admin", "services", appname, "server_user_log"}, call("server_user_log")).leaf = true + entry({"admin", "services", appname, "server_get_log"}, call("server_get_log")).leaf = true + entry({"admin", "services", appname, "server_clear_log"}, call("server_clear_log")).leaf = true + entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_add_node"}, call("socks_autoswitch_add_node")).leaf = true + entry({"admin", "services", appname, "socks_autoswitch_remove_node"}, call("socks_autoswitch_remove_node")).leaf = true + entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true + entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true + entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true + entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true + entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true + entry({"admin", "services", appname, "index_status"}, call("index_status")).leaf = true + entry({"admin", "services", appname, "haproxy_status"}, call("haproxy_status")).leaf = true + entry({"admin", "services", appname, "socks_status"}, call("socks_status")).leaf = true + entry({"admin", "services", appname, "connect_status"}, call("connect_status")).leaf = true + entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true + entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true + entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true + entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true + entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true + entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true + entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true + + --[[Components update]] + entry({"admin", "services", appname, "check_passwall"}, call("app_check")).leaf = true + local coms = require "luci.passwall.com" + local com + for com, _ in pairs(coms) do + entry({"admin", "services", appname, "check_" .. com}, call("com_check", com)).leaf = true + entry({"admin", "services", appname, "update_" .. com}, call("com_update", com)).leaf = true + end +end + +local function http_write_json(content) + http.prepare_content("application/json") + http.write_json(content or {code = 1}) +end + +function reset_config() + luci.sys.call('/etc/init.d/passwall stop') + luci.sys.call('[ -f "/usr/share/passwall/0_default_config" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall') + luci.http.redirect(api.url()) +end + +function show_menu() + luci.sys.call("touch /etc/config/passwall_show") + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + luci.http.redirect(api.url()) +end + +function hide_menu() + luci.sys.call("rm -rf /etc/config/passwall_show") + luci.sys.call("rm -rf /tmp/luci-*") + luci.sys.call("/etc/init.d/rpcd restart >/dev/null") + luci.http.redirect(luci.dispatcher.build_url("admin", "status", "overview")) +end + +function link_add_node() + local lfile = "/tmp/links.conf" + local link = luci.http.formvalue("link") + luci.sys.call('echo \'' .. link .. '\' > ' .. lfile) + luci.sys.call("lua /usr/share/passwall/subscribe.lua add log") +end + +function socks_autoswitch_add_node() + local id = luci.http.formvalue("id") + local key = luci.http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + for k, e in ipairs(api.get_valid_nodes()) do + if e.node_type == "normal" and e["remark"]:find(key) then + table.insert(new_list, e.id) + end + end + ucic:set_list(appname, id, "autoswitch_backup_node", new_list) + ucic:commit(appname) + end + luci.http.redirect(api.url("socks_config", id)) +end + +function socks_autoswitch_remove_node() + local id = luci.http.formvalue("id") + local key = luci.http.formvalue("key") + if id and id ~= "" and key and key ~= "" then + local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {} + for i = #new_list, 1, -1 do + if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then + table.remove(new_list, i) + end + end + ucic:set_list(appname, id, "autoswitch_backup_node", new_list) + ucic:commit(appname) + end + luci.http.redirect(api.url("socks_config", id)) +end + +function get_now_use_node() + local path = "/tmp/etc/passwall/acl/default" + local e = {} + local data, code, msg = nixio.fs.readfile(path .. "/TCP.id") + if data then + e["TCP"] = util.trim(data) + end + local data, code, msg = nixio.fs.readfile(path .. "/UDP.id") + if data then + e["UDP"] = util.trim(data) + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function get_redir_log() + local name = luci.http.formvalue("name") + local proto = luci.http.formvalue("proto") + local path = "/tmp/etc/passwall/acl/" .. name + proto = proto:upper() + if proto == "UDP" and (ucic:get(appname, "@global[0]", "udp_node") or "nil") == "tcp" and not nixio.fs.access(path .. "/" .. proto .. ".log") then + proto = "TCP" + end + if nixio.fs.access(path .. "/" .. proto .. ".log") then + local content = luci.sys.exec("cat ".. path .. "/" .. proto .. ".log") + content = content:gsub("\n", "
") + luci.http.write(content) + else + luci.http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_socks_log() + local name = luci.http.formvalue("name") + local path = "/tmp/etc/passwall/SOCKS_" .. name .. ".log" + if nixio.fs.access(path) then + local content = luci.sys.exec("cat ".. path) + content = content:gsub("\n", "
") + luci.http.write(content) + else + luci.http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function get_log() + -- luci.sys.exec("[ -f /tmp/log/passwall.log ] && sed '1!G;h;$!d' /tmp/log/passwall.log > /tmp/log/passwall_show.log") + luci.http.write(luci.sys.exec("[ -f '/tmp/log/passwall.log' ] && cat /tmp/log/passwall.log")) +end + +function clear_log() + luci.sys.call("echo '' > /tmp/log/passwall.log") +end + +function index_status() + local e = {} + e.dns_mode_status = luci.sys.call("netstat -apn | grep ':15353 ' >/dev/null") == 0 + e.haproxy_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0 + e["tcp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'TCP' >/dev/null") == 0 + + if (ucic:get(appname, "@global[0]", "udp_node") or "nil") == "tcp" then + e["udp_node_status"] = e["tcp_node_status"] + else + e["udp_node_status"] = luci.sys.call("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep 'default' | grep 'UDP' >/dev/null") == 0 + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function haproxy_status() + local e = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null", appname)) == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function socks_status() + local e = {} + local index = luci.http.formvalue("index") + local id = luci.http.formvalue("id") + e.index = index + e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep '%s' | grep 'SOCKS_' > /dev/null", id)) == 0 + local use_http = ucic:get(appname, id, "http_port") or 0 + e.use_http = 0 + if tonumber(use_http) > 0 then + e.use_http = 1 + e.http_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '/tmp/etc/passwall/bin/' | grep -v '_acl_' | grep '%s' | grep -E 'HTTP_|HTTP2SOCKS' > /dev/null", id)) == 0 + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function connect_status() + local e = {} + e.use_time = "" + local url = luci.http.formvalue("url") + local result = luci.sys.exec('curl --connect-timeout 3 -o /dev/null -I -sk -w "%{http_code}:%{time_appconnect}" ' .. url) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + if use_time:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + e.ping_type = "curl" + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function ping_node() + local index = luci.http.formvalue("index") + local address = luci.http.formvalue("address") + local port = luci.http.formvalue("port") + local type = luci.http.formvalue("type") or "icmp" + local e = {} + e.index = index + if type == "tcping" and luci.sys.exec("echo -n $(command -v tcping)") ~= "" then + if api.is_ipv6(address) then + address = api.get_ipv6_only(address) + end + e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, address)) + else + e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % address) + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function urltest_node() + local index = luci.http.formvalue("index") + local id = luci.http.formvalue("id") + local e = {} + e.index = index + local result = luci.sys.exec(string.format("/usr/share/passwall/test.sh url_test_node %s %s", id, "urltest_node")) + local code = tonumber(luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $1}'") or "0") + if code ~= 0 then + local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") + if use_time:find("%.") then + e.use_time = string.format("%.2f", use_time * 1000) + else + e.use_time = string.format("%.2f", use_time / 1000) + end + end + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end + +function set_node() + local protocol = luci.http.formvalue("protocol") + local section = luci.http.formvalue("section") + ucic:set(appname, "@global[0]", protocol .. "_node", section) + ucic:commit(appname) + luci.sys.call("/etc/init.d/passwall restart > /dev/null 2>&1 &") + luci.http.redirect(api.url("log")) +end + +function copy_node() + local section = luci.http.formvalue("section") + local uuid = api.gen_short_uuid() + ucic:section(appname, "nodes", uuid) + for k, v in pairs(ucic:get_all(appname, section)) do + local filter = k:find("%.") + if filter and filter == 1 then + else + xpcall(function() + ucic:set(appname, uuid, k, v) + end, + function(e) + end) + end + end + ucic:delete(appname, uuid, "add_from") + ucic:set(appname, uuid, "add_mode", 1) + ucic:commit(appname) + luci.http.redirect(api.url("node_config", uuid)) +end + +function clear_all_nodes() + ucic:set(appname, '@global[0]', "enabled", "0") + ucic:set(appname, '@global[0]', "tcp_node", "nil") + ucic:set(appname, '@global[0]', "udp_node", "nil") + ucic:foreach(appname, "socks", function(t) + ucic:delete(appname, t[".name"]) + ucic:set_list(appname, t[".name"], "autoswitch_backup_node", {}) + end) + ucic:foreach(appname, "haproxy_config", function(t) + ucic:delete(appname, t[".name"]) + end) + ucic:foreach(appname, "acl_rule", function(t) + ucic:set(appname, t[".name"], "tcp_node", "default") + ucic:set(appname, t[".name"], "udp_node", "default") + end) + ucic:foreach(appname, "nodes", function(node) + ucic:delete(appname, node['.name']) + end) + + ucic:commit(appname) + luci.sys.call("/etc/init.d/" .. appname .. " stop") +end + +function delete_select_nodes() + local ids = luci.http.formvalue("ids") + string.gsub(ids, '[^' .. "," .. ']+', function(w) + if (ucic:get(appname, "@global[0]", "tcp_node") or "nil") == w then + ucic:set(appname, '@global[0]', "tcp_node", "nil") + end + if (ucic:get(appname, "@global[0]", "udp_node") or "nil") == w then + ucic:set(appname, '@global[0]', "udp_node", "nil") + end + ucic:foreach(appname, "socks", function(t) + if t["node"] == w then + ucic:delete(appname, t[".name"]) + end + local auto_switch_node_list = ucic:get(appname, t[".name"], "autoswitch_backup_node") or {} + for i = #auto_switch_node_list, 1, -1 do + if w == auto_switch_node_list[i] then + table.remove(auto_switch_node_list, i) + end + end + ucic:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list) + end) + ucic:foreach(appname, "haproxy_config", function(t) + if t["lbss"] == w then + ucic:delete(appname, t[".name"]) + end + end) + ucic:foreach(appname, "acl_rule", function(t) + if t["tcp_node"] == w then + ucic:set(appname, t[".name"], "tcp_node", "default") + end + if t["udp_node"] == w then + ucic:set(appname, t[".name"], "udp_node", "default") + end + end) + ucic:delete(appname, w) + end) + ucic:commit(appname) + luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &") +end + +function update_rules() + local update = luci.http.formvalue("update") + luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &") + http_write_json() +end + +function server_user_status() + local e = {} + e.index = luci.http.formvalue("index") + e.status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/bin/' | grep -i '%s' >/dev/null", appname .. "_server", luci.http.formvalue("id"))) == 0 + http_write_json(e) +end + +function server_user_log() + local id = luci.http.formvalue("id") + if nixio.fs.access("/tmp/etc/passwall_server/" .. id .. ".log") then + local content = luci.sys.exec("cat /tmp/etc/passwall_server/" .. id .. ".log") + content = content:gsub("\n", "
") + luci.http.write(content) + else + luci.http.write(string.format("", i18n.translate("Not enabled log"))) + end +end + +function server_get_log() + luci.http.write(luci.sys.exec("[ -f '/tmp/log/passwall_server.log' ] && cat /tmp/log/passwall_server.log")) +end + +function server_clear_log() + luci.sys.call("echo '' > /tmp/log/passwall_server.log") +end + +function app_check() + local json = api.to_check_self() + http_write_json(json) +end + +function com_check(comname) + local json = api.to_check("",comname) + http_write_json(json) +end + +function com_update(comname) + local json = nil + local task = http.formvalue("task") + if task == "extract" then + json = api.to_extract(comname, http.formvalue("file"), http.formvalue("subfix")) + elseif task == "move" then + json = api.to_move(comname, http.formvalue("file")) + else + json = api.to_download(comname, http.formvalue("url"), http.formvalue("size")) + end + + http_write_json(json) +end diff --git a/luci-app-passwall/luasrc/view/passwall/global/status.htm b/luci-app-passwall/luasrc/view/passwall/global/status.htm index 46c50d494..452d369af 100644 --- a/luci-app-passwall/luasrc/view/passwall/global/status.htm +++ b/luci-app-passwall/luasrc/view/passwall/global/status.htm @@ -221,7 +221,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md document.getElementsByTagName('img')[i].setAttribute("oncontextmenu","return false;"); document.getElementsByTagName('img')[i].setAttribute("ondragstart","return false;"); } - XHR.poll(5, '<%=api.url("status")%>', null, + XHR.poll(5, '<%=api.url("index_status")%>', null, function (x, data) { var status_dns = document.getElementById('status_dns'); var status_haproxy = document.getElementById('status_haproxy'); diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh index 4fafae7a1..6300b6674 100755 --- a/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/luci-app-passwall/root/usr/share/passwall/app.sh @@ -480,13 +480,8 @@ run_dns2socks() { } run_chinadns_ng() { - local _flag _listen_port _dns_china _dns_trust _use_direct_list _use_proxy_list _chnlist _gfwlist _no_ipv6_dns _no_logic_log + local _flag _listen_port _dns_china _dns_trust _use_direct_list _use_proxy_list _chnlist _gfwlist _no_ipv6_dns eval_set_val $@ - - [ -n "$_no_logic_log" ] && { - local ORIGIN_LOG_FILE=$LOG_FILE - LOG_FILE="/dev/null" - } local _CONF_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.conf local _LOG_FILE=$TMP_ACL_PATH/$_flag/chinadns_ng.log @@ -499,7 +494,6 @@ run_chinadns_ng() { china-dns ${_dns_china} trust-dns ${_dns_trust} filter-qtype 65 - EOF [ "${_use_direct_list}" = "1" ] && [ -s "${RULES_PATH}/direct_host" ] && { @@ -574,9 +568,6 @@ run_chinadns_ng() { [ -n "$_default_tag" ] && [ "$_default_tag" != "smart" ] && echo "default-tag ${_default_tag}" >> ${_CONF_FILE} ln_run "$(first_type chinadns-ng)" chinadns-ng "${_LOG_FILE}" -C ${_CONF_FILE} - echolog " | - 过滤服务:ChinaDNS-NG(127.0.0.1#${_listen_port}):国内DNS:${_dns_china},可信DNS:${_dns_trust}" - - [ -n "${ORIGIN_LOG_FILE}" ] && LOG_FILE=${ORIGIN_LOG_FILE} } run_socks() { @@ -862,30 +853,28 @@ run_redir() { resolve_dns=1 config_file=$(echo $config_file | sed "s/.json/_DNS.json/g") _args="${_args} remote_dns_query_strategy=${DNS_QUERY_STRATEGY}" - FILTER_PROXY_IPV6=0 + DNSMASQ_FILTER_PROXY_IPV6=0 [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" 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}" - logout=" - 域名解析 DNS Over TCP (${REMOTE_DNS})" + resolve_dns_log="Sing-Box DNS(127.0.0.1#${dns_listen_port}) -> tcp://${REMOTE_DNS}" ;; 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}" - logout=" - 域名解析 DNS Over HTTPS (${remote_dns_doh})" + resolve_dns_log="Sing-Box DNS(127.0.0.1#${dns_listen_port}) -> ${remote_dns_doh}" ;; esac local remote_fakedns=$(config_t_get global remote_fakedns 0) [ "${remote_fakedns}" = "1" ] && { fakedns=1 _args="${_args} remote_fakedns=1" - logout="${logout} + FakeDNS" + resolve_dns_log="${resolve_dns_log} + FakeDNS" } - echolog ${logout} } run_singbox flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args} ;; @@ -913,17 +902,20 @@ run_redir() { resolve_dns=1 config_file=$(echo $config_file | sed "s/.json/_DNS.json/g") _args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}" - FILTER_PROXY_IPV6=0 + DNSMASQ_FILTER_PROXY_IPV6=0 local _dns_client_ip=$(config_t_get global dns_client_ip) [ -n "${_dns_client_ip}" ] && _args="${_args} dns_client_ip=${_dns_client_ip}" [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" _args="${_args} dns_listen_port=${dns_listen_port}" _args="${_args} remote_dns_tcp_server=${REMOTE_DNS}" local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) - [ "$v2ray_dns_mode" = "tcp+doh" ] && { + if [ "$v2ray_dns_mode" = "tcp+doh" ]; then 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}" - } + resolve_dns_log="Xray DNS(127.0.0.1#${dns_listen_port}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}" + else + resolve_dns_log="Xray DNS(127.0.0.1#${dns_listen_port}) -> tcp://${REMOTE_DNS}" + fi } run_xray flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args} ;; @@ -1216,7 +1208,7 @@ stop_crontab() { start_dns() { TUN_DNS="127.0.0.1#${dns_listen_port}" - echolog "过滤服务配置:准备接管域名解析..." + echolog "DNS域名解析:" [ "$ENABLED_ACLS" == 1 ] && { local items=$(uci show ${CONFIG} | grep "=acl_rule" | cut -d '.' -sf 2 | cut -d '=' -sf 1) [ -n "$items" ] && { @@ -1231,7 +1223,7 @@ start_dns() { local dns2socks_socks_server=$(echo $(config_t_get global socks_server 127.0.0.1:1080) | sed "s/#/:/g") local dns2socks_forward=$(get_first_dns REMOTE_DNS 53 | sed 's/#/:/g') run_dns2socks socks=$dns2socks_socks_server listen_address=127.0.0.1 listen_port=${dns_listen_port} dns=$dns2socks_forward cache=$DNS_CACHE - echolog " - 域名解析:dns2socks(127.0.0.1:${dns_listen_port}),${dns2socks_socks_server} -> ${dns2socks_forward}" + echolog " - dns2socks(${TUN_DNS}),${dns2socks_socks_server} -> tcp://${dns2socks_forward}" ;; sing-box) [ "${resolve_dns}" == "0" ] && { @@ -1241,7 +1233,7 @@ start_dns() { local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file" [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" _args="${_args} remote_dns_query_strategy=${DNS_QUERY_STRATEGY}" - FILTER_PROXY_IPV6=0 + DNSMASQ_FILTER_PROXY_IPV6=0 use_tcp_node_resolve_dns=1 local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) _args="${_args} dns_listen_port=${dns_listen_port}" @@ -1249,7 +1241,7 @@ start_dns() { case "$v2ray_dns_mode" in tcp) _args="${_args} remote_dns_tcp_server=${REMOTE_DNS}" - echolog " - 域名解析 DNS Over TCP (${REMOTE_DNS})" + echolog " - Sing-Box DNS(${TUN_DNS}) -> tcp://${REMOTE_DNS}" ;; doh) remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query") @@ -1265,7 +1257,7 @@ start_dns() { [ "${_is_ip}" = "true" ] && _doh_bootstrap=${_doh_host} [ -n "${_doh_bootstrap}" ] && REMOTE_DNS=${_doh_bootstrap}:${_doh_port} unset _doh_url _doh_host_port _doh_host _is_ip _doh_port _doh_bootstrap - echolog " - 域名解析 DNS Over HTTPS (${remote_dns_doh})" + echolog " - Sing-Box DNS(${TUN_DNS}) -> ${remote_dns_doh}" ;; esac _args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}" @@ -1280,17 +1272,20 @@ start_dns() { local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file" [ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0" _args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}" - FILTER_PROXY_IPV6=0 + DNSMASQ_FILTER_PROXY_IPV6=0 local _dns_client_ip=$(config_t_get global dns_client_ip) [ -n "${_dns_client_ip}" ] && _args="${_args} dns_client_ip=${_dns_client_ip}" use_tcp_node_resolve_dns=1 _args="${_args} dns_listen_port=${dns_listen_port}" _args="${_args} remote_dns_tcp_server=${REMOTE_DNS}" local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp) - [ "$v2ray_dns_mode" = "tcp+doh" ] && { + if [ "$v2ray_dns_mode" = "tcp+doh" ]; then 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 " - Xray DNS(${TUN_DNS}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}" + else + echolog " - Xray DNS(${TUN_DNS}) -> tcp://${REMOTE_DNS}" + fi _args="${_args} dns_socks_address=127.0.0.1 dns_socks_port=${tcp_node_socks_port}" run_xray ${_args} } @@ -1298,14 +1293,16 @@ start_dns() { dns2tcp) use_tcp_node_resolve_dns=1 ln_run "$(first_type dns2tcp)" dns2tcp "/dev/null" -L "${TUN_DNS}" -R "$(get_first_dns REMOTE_DNS 53)" -v - echolog " - 域名解析:dns2tcp + 使用(TCP节点)解析域名..." + echolog " - dns2tcp(${TUN_DNS}) -> tcp://$(get_first_dns REMOTE_DNS 53 | sed 's/#/:/g')" ;; udp) use_udp_node_resolve_dns=1 TUN_DNS="$(echo ${REMOTE_DNS} | sed 's/#/:/g' | sed -E 's/\:([^:]+)$/#\1/g')" - echolog " - 域名解析:使用UDP协议请求DNS($TUN_DNS)..." + echolog " - udp://${TUN_DNS}" ;; esac + + [ -n "${resolve_dns_log}" ] && echolog " - ${resolve_dns_log}" [ "${use_tcp_node_resolve_dns}" = "1" ] && echolog " * 请确认上游 DNS 支持 TCP 查询,如非直连地址,确保 TCP 代理打开,并且已经正确转发!" [ "${use_udp_node_resolve_dns}" = "1" ] && echolog " * 要求代理 DNS 请求,如上游 DNS 非直连地址,确保 UDP 代理打开,并且已经正确转发!" @@ -1313,7 +1310,7 @@ start_dns() { [ "$CHINADNS_NG" = "1" ] && [ -n "$(first_type chinadns-ng)" ] && ([ "${CHN_LIST}" = "direct" ] || [ "${USE_GFW_LIST}" = "1" ]) && { [ "$FILTER_PROXY_IPV6" = "1" ] && { local _no_ipv6_dns="trust" - FILTER_PROXY_IPV6=0 + DNSMASQ_FILTER_PROXY_IPV6=0 } local china_ng_listen_port=$(expr $dns_listen_port + 1) local china_ng_listen="127.0.0.1#${china_ng_listen_port}" @@ -1327,6 +1324,8 @@ start_dns() { _chnlist="${CHN_LIST}" \ _gfwlist="${USE_GFW_LIST}" \ _no_ipv6_dns="${_no_ipv6_dns}" + + echolog " - ChinaDNS-NG(127.0.0.1#${china_ng_listen_port}):国内DNS:$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2) | tr " " ","),可信DNS:${TUN_DNS}" USE_DEFAULT_DNS="chinadns_ng" } @@ -1340,7 +1339,7 @@ start_dns() { -DNSMASQ_CONF_FILE "/tmp/dnsmasq.d/dnsmasq-passwall.conf" -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} \ -TUN_DNS ${TUN_DNS} -REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \ -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} \ + -TCP_NODE ${TCP_NODE} -DEFAULT_PROXY_MODE "${TCP_PROXY_MODE}" -NO_PROXY_IPV6 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \ -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} } @@ -1437,6 +1436,7 @@ acl_app() { tcp_proxy_mode=${tcp_proxy_mode:-proxy} udp_proxy_mode=${udp_proxy_mode:-proxy} filter_proxy_ipv6=${filter_proxy_ipv6:-0} + dnsmasq_filter_proxy_ipv6=${filter_proxy_ipv6} dns_mode=${dns_mode:-dns2socks} remote_dns=${remote_dns:-1.1.1.1} chinadns_ng=${chinadns_ng:-0} @@ -1469,7 +1469,7 @@ acl_app() { [ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query} local type=${dns_mode} [ "${dns_mode}" = "sing-box" ] && type="singbox" - filter_proxy_ipv6=0 + dnsmasq_filter_proxy_ipv6=0 run_${type} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns_doh}" remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY} config_file=$config_file fi eval node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)=${_dns_port} @@ -1478,7 +1478,7 @@ acl_app() { [ "$chinadns_ng" = "1" ] && [ -n "$(first_type chinadns-ng)" ] && ([ "${chn_list}" = "direct" ] || [ "${use_gfw_list}" = "1" ]) && { [ "$filter_proxy_ipv6" = "1" ] && { local _no_ipv6_dns="trust" - filter_proxy_ipv6=0 + dnsmasq_filter_proxy_ipv6=0 } chinadns_port=$(expr $chinadns_port + 1) _china_ng_listen="127.0.0.1#${chinadns_port}" @@ -1492,8 +1492,7 @@ acl_app() { _use_proxy_list="${use_proxy_list}" \ _chnlist=${chn_list} \ _gfwlist=${use_gfw_list} \ - _no_ipv6_dns="${_no_ipv6_dns}" \ - _no_logic_log=1 + _no_ipv6_dns="${_no_ipv6_dns}" use_default_dns="chinadns_ng" } @@ -1518,7 +1517,7 @@ acl_app() { -DNSMASQ_CONF_FILE $TMP_ACL_PATH/$sid/dnsmasq.conf -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_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}" \ -TUN_DNS "127.0.0.1#${_dns_port}" -REMOTE_FAKEDNS 0 -USE_DEFAULT_DNS "${use_default_dns:-direct}" -CHINADNS_DNS ${_china_ng_listen:-0} \ - -TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \ + -TCP_NODE $tcp_node -DEFAULT_PROXY_MODE ${tcp_proxy_mode} -NO_PROXY_IPV6 ${dnsmasq_filter_proxy_ipv6:-0} -NFTFLAG ${nftflag:-0} \ -NO_LOGIC_LOG 1 ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C $TMP_ACL_PATH/$sid/dnsmasq.conf -x $TMP_ACL_PATH/$sid/dnsmasq.pid eval node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)=${dnsmasq_port} @@ -1551,7 +1550,7 @@ acl_app() { _dns_port=$dns_port config_file=$(echo $config_file | sed "s/TCP_/DNS_${_dns_port}_TCP_/g") remote_dns_doh=${remote_dns} - filter_proxy_ipv6=0 + dnsmasq_filter_proxy_ipv6=0 [ "$dns_mode" = "xray" ] && [ "$v2ray_dns_mode" = "tcp+doh" ] && remote_dns_doh=${remote_dns_doh:-https://1.1.1.1/dns-query} _extra_param="dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh=${remote_dns_doh} remote_dns_query_strategy=${DNS_QUERY_STRATEGY} dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY}" fi @@ -1633,7 +1632,7 @@ acl_app() { [ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port unset enabled sid remarks sources use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip unset _ip _mac _iprange _ipset _ip_or_mac rule_list tcp_port udp_port config_file _extra_param - unset _china_ng_listen _china_ng_chn _china_ng_gfw _gfwlist_file _chnlist_file _china_ng_log_file _no_ipv6_dns _china_ng_extra_param + unset _china_ng_listen _china_ng_chn _china_ng_gfw _gfwlist_file _chnlist_file _china_ng_log_file _no_ipv6_dns _china_ng_extra_param dnsmasq_filter_proxy_ipv6 unset redirect_dns_port done unset socks_port redir_port dns_port dnsmasq_port chinadns_port @@ -1730,6 +1729,7 @@ ENABLED_ACLS=$(config_t_get global acl_enable 0) } tcp_proxy_way=$(config_t_get global_forwarding tcp_proxy_way redirect) +PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0) TCP_REDIR_PORTS=$(config_t_get global_forwarding tcp_redir_ports '80,443') UDP_REDIR_PORTS=$(config_t_get global_forwarding udp_redir_ports '1:65535') TCP_NO_REDIR_PORTS=$(config_t_get global_forwarding tcp_no_redir_ports 'disable') @@ -1772,9 +1772,9 @@ DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print [ -z "${DEFAULT_DNS}" ] && [ "$(echo $ISP_DNS | tr ' ' '\n' | wc -l)" -le 2 ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | head -2 | tr '\n' ',') LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}" -PROXY_IPV6=$(config_t_get global_forwarding ipv6_tproxy 0) -DNS_QUERY_STRATEGY="UseIPv4" -[ "$PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIP" +DNS_QUERY_STRATEGY="UseIP" +[ "$FILTER_PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIPv4" +DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6} export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/") export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET