luci-app-passwall: sync upstream

last commit: 582e13a15c
This commit is contained in:
gitea-action 2024-12-19 12:18:34 +08:00
parent f6b0177f58
commit b53f44e7f1
23 changed files with 1223 additions and 1066 deletions

View File

@ -6,8 +6,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall PKG_NAME:=luci-app-passwall
PKG_VERSION:=24.12.08 PKG_VERSION:=24.12.17
PKG_RELEASE:=1 PKG_RELEASE:=2
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \

View File

@ -166,13 +166,13 @@ end
function get_now_use_node() function get_now_use_node()
local path = "/tmp/etc/passwall/acl/default" local path = "/tmp/etc/passwall/acl/default"
local e = {} local e = {}
local data, code, msg = nixio.fs.readfile(path .. "/TCP.id") local tcp_node = api.get_cache_var("GLOBAL_TCP_node")
if data then if tcp_node then
e["TCP"] = util.trim(data) e["TCP"] = tcp_node
end end
local data, code, msg = nixio.fs.readfile(path .. "/UDP.id") local udp_node = api.get_cache_var("GLOBAL_UDP_node")
if data then if udp_node then
e["UDP"] = util.trim(data) e["UDP"] = udp_node
end end
luci.http.prepare_content("application/json") luci.http.prepare_content("application/json")
luci.http.write_json(e) luci.http.write_json(e)
@ -269,8 +269,8 @@ function connect_status()
local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct" local chn_list = uci:get(appname, "@global[0]", "chn_list") or "direct"
local gfw_list = uci:get(appname, "@global[0]", "use_gfw_list") or "1" local gfw_list = uci:get(appname, "@global[0]", "use_gfw_list") or "1"
local proxy_mode = uci:get(appname, "@global[0]", "tcp_proxy_mode") or "proxy" local proxy_mode = uci:get(appname, "@global[0]", "tcp_proxy_mode") or "proxy"
local socks_server = luci.sys.exec("[ -f /tmp/etc/passwall/acl/default/TCP_SOCKS_server ] && echo -n $(cat /tmp/etc/passwall/acl/default/TCP_SOCKS_server) || echo -n ''") local socks_server = api.get_cache_var("GLOBAL_TCP_SOCKS_server")
if socks_server ~= "" then if socks_server and socks_server ~= "" then
if (chn_list == "proxy" and gfw_list == "0" and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == "0" and gfw_list == "0" and proxy_mode == "proxy") then if (chn_list == "proxy" and gfw_list == "0" and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == "0" and gfw_list == "0" and proxy_mode == "proxy") then
-- 中国列表+百度 or 全局 -- 中国列表+百度 or 全局
url = "-x socks5h://" .. socks_server .. " " .. url url = "-x socks5h://" .. socks_server .. " " .. url
@ -374,8 +374,8 @@ function clear_all_nodes()
uci:delete(appname, t[".name"]) uci:delete(appname, t[".name"])
end) end)
uci:foreach(appname, "acl_rule", function(t) uci:foreach(appname, "acl_rule", function(t)
uci:set(appname, t[".name"], "tcp_node", "default") uci:set(appname, t[".name"], "tcp_node", "nil")
uci:set(appname, t[".name"], "udp_node", "default") uci:set(appname, t[".name"], "udp_node", "nil")
end) end)
uci:foreach(appname, "nodes", function(node) uci:foreach(appname, "nodes", function(node)
uci:delete(appname, node['.name']) uci:delete(appname, node['.name'])
@ -413,10 +413,20 @@ function delete_select_nodes()
end) end)
uci:foreach(appname, "acl_rule", function(t) uci:foreach(appname, "acl_rule", function(t)
if t["tcp_node"] == w then if t["tcp_node"] == w then
uci:set(appname, t[".name"], "tcp_node", "default") uci:set(appname, t[".name"], "tcp_node", "nil")
end end
if t["udp_node"] == w then if t["udp_node"] == w then
uci:set(appname, t[".name"], "udp_node", "default") uci:set(appname, t[".name"], "udp_node", "nil")
end
end)
uci:foreach(appname, "nodes", function(t)
if t["preproxy_node"] == w then
uci:delete(appname, t[".name"], "preproxy_node")
uci:delete(appname, t[".name"], "chain_proxy")
end
if t["to_node"] == w then
uci:delete(appname, t[".name"], "to_node")
uci:delete(appname, t[".name"], "chain_proxy")
end end
end) end)
uci:delete(appname, w) uci:delete(appname, w)

View File

@ -563,6 +563,10 @@ if api.is_finded("smartdns") then
o:depends({dns_shunt = "smartdns", tcp_proxy_mode = "proxy", chn_list = "direct"}) o:depends({dns_shunt = "smartdns", tcp_proxy_mode = "proxy", chn_list = "direct"})
end end
o = s:taboption("DNS", Flag, "dns_redirect", translate("DNS Redirect"), translate("Force special DNS server to need proxy devices."))
o.default = "1"
o.rmempty = false
if (uci:get(appname, "@global_forwarding[0]", "use_nft") or "0") == "1" then if (uci:get(appname, "@global_forwarding[0]", "use_nft") or "0") == "1" then
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear NFTSET"), translate("Try this feature if the rule modification does not take effect.")) o = s:taboption("DNS", Button, "clear_ipset", translate("Clear NFTSET"), translate("Try this feature if the rule modification does not take effect."))
else else

View File

@ -21,9 +21,8 @@ o.default = 1
o.rmempty = false o.rmempty = false
local auto_switch_tip local auto_switch_tip
local current_node_file = string.format("/tmp/etc/%s/id/socks_%s", appname, arg[1]) local current_node = api.get_cache_var("socks_" .. arg[1])
local current_node = luci.sys.exec(string.format("[ -f '%s' ] && echo -n $(cat %s)", current_node_file, current_node_file)) if current_node then
if current_node and current_node ~= "" and current_node ~= "nil" then
local n = uci:get_all(appname, current_node) local n = uci:get_all(appname, current_node)
if n then if n then
if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then if tonumber(m:get(arg[1], "enable_autoswitch") or 0) == 1 then

View File

@ -646,12 +646,26 @@ o.default = 0
o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay") o = s:option(Flag, option_name("tcpNoDelay"), "tcpNoDelay")
o.default = 0 o.default = 0
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy"))
o.default = ""
o:value("", translate("Close(Not use)")) o:value("", translate("Close(Not use)"))
o:value("1", translate("Preproxy Node"))
o:value("2", translate("Landing Node"))
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then
o:depends({ [option_name("protocol")] = v })
end
end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" })
o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do for k, v in pairs(nodes_table) do
if v.type == "Xray" then if v.type == "Xray" and v.id ~= arg[1] then
o:value(v.id, v.remark) s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark)
end end
end end
@ -659,7 +673,7 @@ for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then if not v:find("_") then
s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v }) s.fields[option_name("tcpMptcp")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v }) s.fields[option_name("tcpNoDelay")]:depends({ [option_name("protocol")] = v })
s.fields[option_name("to_node")]:depends({ [option_name("protocol")] = v }) s.fields[option_name("chain_proxy")]:depends({ [option_name("protocol")] = v })
end end
end end

View File

@ -677,18 +677,27 @@ o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "tuic" }) o:depends({ [option_name("protocol")] = "tuic" })
o:depends({ [option_name("protocol")] = "hysteria2" }) o:depends({ [option_name("protocol")] = "hysteria2" })
o = s:option(ListValue, option_name("to_node"), translate("Landing node"), translate("Only support a layer of proxy.")) o = s:option(ListValue, option_name("chain_proxy"), translate("Chain Proxy"))
o.default = ""
o:value("", translate("Close(Not use)")) o:value("", translate("Close(Not use)"))
for k, v in pairs(nodes_table) do o:value("1", translate("Preproxy Node"))
if v.type == "sing-box" then o:value("2", translate("Landing Node"))
o:value(v.id, v.remark)
end
end
for i, v in ipairs(s.fields[option_name("protocol")].keylist) do for i, v in ipairs(s.fields[option_name("protocol")].keylist) do
if not v:find("_") then if not v:find("_") then
o:depends({ [option_name("protocol")] = v }) o:depends({ [option_name("protocol")] = v })
end end
end end
o = s:option(ListValue, option_name("preproxy_node"), translate("Preproxy Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "1" })
o = s:option(ListValue, option_name("to_node"), translate("Landing Node"), translate("Only support a layer of proxy."))
o:depends({ [option_name("chain_proxy")] = "2" })
for k, v in pairs(nodes_table) do
if v.type == "sing-box" and v.id ~= arg[1] then
s.fields[option_name("preproxy_node")]:value(v.id, v.remark)
s.fields[option_name("to_node")]:value(v.id, v.remark)
end
end
api.luci_types(arg[1], m, s, type_name, option_prefix) api.luci_types(arg[1], m, s, type_name, option_prefix)

View File

@ -16,8 +16,10 @@ OPENWRT_ARCH = nil
DISTRIB_ARCH = nil DISTRIB_ARCH = nil
OPENWRT_BOARD = nil OPENWRT_BOARD = nil
LOG_FILE = "/tmp/log/" .. appname .. ".log"
CACHE_PATH = "/tmp/etc/" .. appname .. "_tmp" CACHE_PATH = "/tmp/etc/" .. appname .. "_tmp"
LOG_FILE = "/tmp/log/" .. appname .. ".log"
TMP_PATH = "/tmp/etc/" .. appname
TMP_IFACE_PATH = TMP_PATH .. "/iface"
function log(...) function log(...)
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ") local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
@ -28,6 +30,16 @@ function log(...)
end end
end end
function set_cache_var(key, val)
sys.call(string.format('/usr/share/passwall/app.sh set_cache_var %s "%s"', key, val))
end
function get_cache_var(key)
local val = sys.exec(string.format('echo -n $(/usr/share/passwall/app.sh get_cache_var %s)', key))
if val == "" then val = nil end
return val
end
function exec_call(cmd) function exec_call(cmd)
local process = io.popen(cmd .. '; echo -e "\n$?"') local process = io.popen(cmd .. '; echo -e "\n$?"')
local lines = {} local lines = {}
@ -97,8 +109,8 @@ end
function curl_proxy(url, file, args) function curl_proxy(url, file, args)
--使用代理 --使用代理
local socks_server = luci.sys.exec("[ -f /tmp/etc/passwall/acl/default/TCP_SOCKS_server ] && echo -n $(cat /tmp/etc/passwall/acl/default/TCP_SOCKS_server) || echo -n ''") local socks_server = get_cache_var("GLOBAL_TCP_SOCKS_server")
if socks_server ~= "" then if socks_server and socks_server ~= "" then
if not args then args = {} end if not args then args = {} end
local tmp_args = clone(args) local tmp_args = clone(args)
tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server tmp_args[#tmp_args + 1] = "-x socks5h://" .. socks_server

View File

@ -688,7 +688,7 @@ function gen_config_server(node)
bind_interface = node.outbound_node_iface, bind_interface = node.outbound_node_iface,
routing_mark = 255, routing_mark = 255,
} }
sys.call("mkdir -p /tmp/etc/passwall/iface && touch /tmp/etc/passwall/iface/" .. node.outbound_node_iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
else else
local outbound_node_t = uci:get_all("passwall", node.outbound_node) local outbound_node_t = uci:get_all("passwall", node.outbound_node)
if node.outbound_node == "_socks" or node.outbound_node == "_http" then if node.outbound_node == "_socks" or node.outbound_node == "_http" then
@ -880,6 +880,7 @@ function gen_config(var)
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name) local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end if not node or not outbound or not outbounds_table then return nil end
local default_outTag = outbound.tag local default_outTag = outbound.tag
local last_insert_outbound
if node.shadowtls == "1" then if node.shadowtls == "1" then
local _node = { local _node = {
@ -896,14 +897,31 @@ function gen_config(var)
} }
local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls") local shadowtls_outbound = gen_outbound(nil, _node, outbound.tag .. "_shadowtls")
if shadowtls_outbound then if shadowtls_outbound then
table.insert(outbounds_table, shadowtls_outbound) last_insert_outbound = shadowtls_outbound
outbound.detour = outbound.tag .. "_shadowtls" outbound.detour = outbound.tag .. "_shadowtls"
outbound.server = nil outbound.server = nil
outbound.server_port = nil outbound.server_port = nil
end end
end end
if node.to_node then if node.chain_proxy == "1" and node.preproxy_node then
if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then
--Ignore
else
local preproxy_node = uci:get_all(appname, node.preproxy_node)
if preproxy_node then
local preproxy_outbound = gen_outbound(nil, preproxy_node)
if preproxy_outbound then
preproxy_outbound.tag = preproxy_node[".name"] .. ":" .. preproxy_node.remarks
outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag
outbound.detour = preproxy_outbound.tag
last_insert_outbound = preproxy_outbound
default_outTag = outbound.tag
end
end
end
end
if node.chain_proxy == "2" and node.to_node then
local to_node = uci:get_all(appname, node.to_node) local to_node = uci:get_all(appname, node.to_node)
if to_node then if to_node then
local to_outbound = gen_outbound(nil, to_node) local to_outbound = gen_outbound(nil, to_node)
@ -921,7 +939,7 @@ function gen_config(var)
end end
end end
end end
return default_outTag return default_outTag, last_insert_outbound
end end
if node.protocol == "_shunt" then if node.protocol == "_shunt" then
@ -1006,8 +1024,11 @@ function gen_config(var)
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil }) local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil })
if _outbound then if _outbound then
_outbound.tag = _outbound.tag .. ":" .. _node.remarks _outbound.tag = _outbound.tag .. ":" .. _node.remarks
rule_outboundTag = set_outbound_detour(_node, _outbound, outbounds, rule_name) rule_outboundTag, last_insert_outbound = set_outbound_detour(_node, _outbound, outbounds, rule_name)
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
if last_insert_outbound then
table.insert(outbounds, last_insert_outbound)
end
end end
end end
elseif _node.protocol == "_iface" then elseif _node.protocol == "_iface" then
@ -1020,7 +1041,7 @@ function gen_config(var)
} }
table.insert(outbounds, _outbound) table.insert(outbounds, _outbound)
rule_outboundTag = _outbound.tag rule_outboundTag = _outbound.tag
sys.call("touch /tmp/etc/passwall/iface/" .. _node.iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, _node.iface))
end end
end end
end end
@ -1197,14 +1218,17 @@ function gen_config(var)
} }
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
COMMON.default_outbound_tag = outbound.tag COMMON.default_outbound_tag = outbound.tag
sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end end
else else
local outbound = gen_outbound(flag, node) local outbound = gen_outbound(flag, node)
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks outbound.tag = outbound.tag .. ":" .. node.remarks
COMMON.default_outbound_tag = set_outbound_detour(node, outbound, outbounds) COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
if last_insert_outbound then
table.insert(outbounds, last_insert_outbound)
end
end end
end end
end end
@ -1452,6 +1476,9 @@ function gen_config(var)
tag = "block" tag = "block"
}) })
for index, value in ipairs(config.outbounds) do for index, value in ipairs(config.outbounds) do
if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and not value.detour and value["_id"] and value.server and value.server_port then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end
for k, v in pairs(config.outbounds[index]) do for k, v in pairs(config.outbounds[index]) do
if k:find("_") == 1 then if k:find("_") == 1 then
config.outbounds[index][k] = nil config.outbounds[index][k] = nil

View File

@ -417,7 +417,7 @@ function gen_config_server(node)
} }
} }
} }
sys.call("mkdir -p /tmp/etc/passwall/iface && touch /tmp/etc/passwall/iface/" .. node.outbound_node_iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.outbound_node_iface))
else else
local outbound_node_t = uci:get_all("passwall", node.outbound_node) local outbound_node_t = uci:get_all("passwall", node.outbound_node)
if node.outbound_node == "_socks" or node.outbound_node == "_http" then if node.outbound_node == "_socks" or node.outbound_node == "_http" then
@ -780,9 +780,30 @@ function gen_config(var)
local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name) local function set_outbound_detour(node, outbound, outbounds_table, shunt_rule_name)
if not node or not outbound or not outbounds_table then return nil end if not node or not outbound or not outbounds_table then return nil end
local default_out_tag = outbound.tag local default_outTag = outbound.tag
local last_insert_outbound
if node.to_node then if node.chain_proxy == "1" and node.preproxy_node then
if outbound["_flag_proxy_tag"] and outbound["_flag_proxy_tag"] ~= "nil" then
--Ignore
else
local preproxy_node = uci:get_all(appname, node.preproxy_node)
if preproxy_node then
local preproxy_outbound = gen_outbound(nil, preproxy_node)
if preproxy_outbound then
preproxy_outbound.tag = preproxy_node[".name"] .. ":" .. preproxy_node.remarks
outbound.tag = preproxy_outbound.tag .. " -> " .. outbound.tag
outbound.proxySettings = {
tag = preproxy_outbound.tag,
transportLayer = true
}
last_insert_outbound = preproxy_outbound
default_outTag = outbound.tag
end
end
end
end
if node.chain_proxy == "2" and node.to_node then
local to_node = uci:get_all(appname, node.to_node) local to_node = uci:get_all(appname, node.to_node)
if to_node then if to_node then
local to_outbound = gen_outbound(nil, to_node) local to_outbound = gen_outbound(nil, to_node)
@ -799,11 +820,11 @@ function gen_config(var)
transportLayer = true transportLayer = true
} }
table.insert(outbounds_table, to_outbound) table.insert(outbounds_table, to_outbound)
default_out_tag = to_outbound.tag default_outTag = to_outbound.tag
end end
end end
end end
return default_out_tag return default_outTag, last_insert_outbound
end end
if node.protocol == "_shunt" then if node.protocol == "_shunt" then
@ -901,12 +922,15 @@ function gen_config(var)
local outbound_tag local outbound_tag
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. _node.remarks outbound.tag = outbound.tag .. ":" .. _node.remarks
outbound_tag = set_outbound_detour(_node, outbound, outbounds, rule_name) outbound_tag, last_insert_outbound = set_outbound_detour(_node, outbound, outbounds, rule_name)
if rule_name == "default" then if rule_name == "default" then
table.insert(outbounds, 1, outbound) table.insert(outbounds, 1, outbound)
else else
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
end end
if last_insert_outbound then
table.insert(outbounds, last_insert_outbound)
end
end end
return outbound_tag, nil return outbound_tag, nil
elseif _node.protocol == "_balancing" then elseif _node.protocol == "_balancing" then
@ -926,7 +950,7 @@ function gen_config(var)
} }
outbound_tag = outbound.tag outbound_tag = outbound.tag
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
sys.call("touch /tmp/etc/passwall/iface/" .. _node.iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, _node.iface))
end end
return outbound_tag, nil return outbound_tag, nil
end end
@ -1075,14 +1099,17 @@ function gen_config(var)
} }
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
COMMON.default_outbound_tag = outbound.tag COMMON.default_outbound_tag = outbound.tag
sys.call("touch /tmp/etc/passwall/iface/" .. node.iface) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface))
end end
else else
local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil }) local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil })
if outbound then if outbound then
outbound.tag = outbound.tag .. ":" .. node.remarks outbound.tag = outbound.tag .. ":" .. node.remarks
COMMON.default_outbound_tag = set_outbound_detour(node, outbound, outbounds) COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds)
table.insert(outbounds, outbound) table.insert(outbounds, outbound)
if last_insert_outbound then
table.insert(outbounds, last_insert_outbound)
end
end end
routing = { routing = {
domainStrategy = "AsIs", domainStrategy = "AsIs",
@ -1369,6 +1396,9 @@ function gen_config(var)
end end
for index, value in ipairs(config.outbounds) do for index, value in ipairs(config.outbounds) do
if (not value["_flag_proxy_tag"] or value["_flag_proxy_tag"] == "nil") and value["_id"] and value.server and value.server_port then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end
for k, v in pairs(config.outbounds[index]) do for k, v in pairs(config.outbounds[index]) do
if k:find("_") == 1 then if k:find("_") == 1 then
config.outbounds[index][k] = nil config.outbounds[index][k] = nil

View File

@ -58,9 +58,10 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color:#8898aa!important; color:#8898aa!important;
line-height: 1.8em; line-height: 1.8em;
min-height: 48px; min-height: 48px;
background-image: linear-gradient(270deg, #dde2ff 0%, #fffeff 100%);
border-radius: 12.375px; border-radius: 12.375px;
background-image: linear-gradient(270deg, #dde2ff 0%, #fffeff 100%);
} }
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
.block h4 { .block h4 {
background-image: none; background-image: none;

View File

@ -1101,7 +1101,7 @@ local api = require "luci.passwall.api"
} }
} }
opt.set(dom_prefix + 'encryption', queryParam.encryption); opt.set(dom_prefix + 'encryption', queryParam.encryption || "none");
if (queryParam.security) { if (queryParam.security) {
if (queryParam.security == "tls") { if (queryParam.security == "tls") {
opt.set(dom_prefix + 'tls', true); opt.set(dom_prefix + 'tls', true);

View File

@ -221,6 +221,10 @@ table td, .table .td {
dom.title = "当前TCP节点"; dom.title = "当前TCP节点";
//var v = "<a style='color: red'>当前TCP节点</a>" + document.getElementById("cbid.passwall." + id + ".remarks").value; //var v = "<a style='color: red'>当前TCP节点</a>" + document.getElementById("cbid.passwall." + id + ".remarks").value;
//document.getElementById("cbi-passwall-" + id + "-remarks").innerHTML = v; //document.getElementById("cbi-passwall-" + id + "-remarks").innerHTML = v;
var tds = dom.getElementsByTagName("td")
for (var j = 0; j < tds.length; j++) {
tds[j].classList.add("_now_use");
}
} }
} }
id = result["UDP"]; id = result["UDP"];
@ -229,6 +233,10 @@ table td, .table .td {
if (dom) { if (dom) {
dom.classList.add("_now_use"); dom.classList.add("_now_use");
dom.title = "当前UDP节点"; dom.title = "当前UDP节点";
var tds = dom.getElementsByTagName("td")
for (var j = 0; j < tds.length; j++) {
tds[j].classList.add("_now_use");
}
} }
} }
} }
@ -296,8 +304,6 @@ table td, .table .td {
} }
} }
get_now_use_node();
/* 自动Ping */ /* 自动Ping */
if (auto_detection_time == "icmp" || auto_detection_time == "tcping") { if (auto_detection_time == "icmp" || auto_detection_time == "tcping") {
var nodes = []; var nodes = [];
@ -418,6 +424,8 @@ table td, .table .td {
} }
} }
get_now_use_node();
if (true) { if (true) {
var str = ""; var str = "";
for (var add_from in node_list) { for (var add_from in node_list) {

View File

@ -223,6 +223,12 @@ msgstr "需要代理的分流规则域名使用 FakeDNS。"
msgid "Redirect" msgid "Redirect"
msgstr "重定向" msgstr "重定向"
msgid "DNS Redirect"
msgstr "DNS 重定向"
msgid "Force special DNS server to need proxy devices."
msgstr "强制需要代理的设备使用专用 DNS 服务器。"
msgid "Clear IPSET" msgid "Clear IPSET"
msgstr "清空 IPSET" msgstr "清空 IPSET"
@ -1714,7 +1720,10 @@ msgstr "延迟ms"
msgid "If is domain name, The requested domain name will be resolved to IP before connect." msgid "If is domain name, The requested domain name will be resolved to IP before connect."
msgstr "如果是域名,域名将在请求发出之前解析为 IP。" msgstr "如果是域名,域名将在请求发出之前解析为 IP。"
msgid "Landing node" msgid "Chain Proxy"
msgstr "链式代理"
msgid "Landing Node"
msgstr "落地节点" msgstr "落地节点"
msgid "Only support a layer of proxy." msgid "Only support a layer of proxy."

View File

@ -12,6 +12,7 @@ config global
list smartdns_remote_dns 'https://1.1.1.1/dns-query' list smartdns_remote_dns 'https://1.1.1.1/dns-query'
option use_default_dns 'direct' option use_default_dns 'direct'
option chinadns_ng_default_tag 'none' option chinadns_ng_default_tag 'none'
option dns_redirect '1'
option use_direct_list '1' option use_direct_list '1'
option use_proxy_list '1' option use_proxy_list '1'
option use_block_list '1' option use_block_list '1'

View File

@ -9,7 +9,6 @@ CONFIG=passwall
TMP_PATH=/tmp/etc/$CONFIG TMP_PATH=/tmp/etc/$CONFIG
TMP_BIN_PATH=$TMP_PATH/bin TMP_BIN_PATH=$TMP_PATH/bin
TMP_SCRIPT_FUNC_PATH=$TMP_PATH/script_func TMP_SCRIPT_FUNC_PATH=$TMP_PATH/script_func
TMP_ID_PATH=$TMP_PATH/id
TMP_ROUTE_PATH=$TMP_PATH/route TMP_ROUTE_PATH=$TMP_PATH/route
TMP_ACL_PATH=$TMP_PATH/acl TMP_ACL_PATH=$TMP_PATH/acl
TMP_IFACE_PATH=$TMP_PATH/iface TMP_IFACE_PATH=$TMP_PATH/iface
@ -373,6 +372,20 @@ get_geoip() {
fi fi
} }
set_cache_var() {
local key="${1}"
shift 1
local val="$@"
[ -n "${key}" ] && [ -n "${val}" ] && echo "${key}=\"${val}\"" >> $TMP_PATH/var
}
get_cache_var() {
local key="${1}"
[ -n "${key}" ] && [ -s "$TMP_PATH/var" ] && {
echo $(cat $TMP_PATH/var | grep "^${key}=" | awk -F '=' '{print $2}' | tail -n 1 | awk -F'"' '{print $2}')
}
}
run_ipt2socks() { run_ipt2socks() {
local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file local flag proto tcp_tproxy local_port socks_address socks_port socks_username socks_password log_file
local _extra_param="" local _extra_param=""
@ -712,6 +725,8 @@ run_socks() {
fi fi
} }
unset http_flag unset http_flag
[ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
} }
run_redir() { run_redir() {
@ -1064,11 +1079,12 @@ run_redir() {
[ "$tcp_node_socks" = "1" ] && { [ "$tcp_node_socks" = "1" ] && {
TCP_SOCKS_server="127.0.0.1:$tcp_node_socks_port" TCP_SOCKS_server="127.0.0.1:$tcp_node_socks_port"
echo "${TCP_SOCKS_server}" > ${GLOBAL_ACL_PATH}/TCP_SOCKS_server set_cache_var "GLOBAL_TCP_SOCKS_server" "${TCP_SOCKS_server}"
} }
;; ;;
esac esac
unset tcp_node_socks_flag tcp_node_http_flag unset tcp_node_socks_flag tcp_node_http_flag
[ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
return 0 return 0
} }
@ -1083,7 +1099,7 @@ start_redir() {
local port=$(echo $(get_new_port $current_port $proto)) local port=$(echo $(get_new_port $current_port $proto))
eval ${proto}_REDIR=$port eval ${proto}_REDIR=$port
run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file run_redir node=$node proto=${proto} bind=0.0.0.0 local_port=$port config_file=$config_file log_file=$log_file
echo $node > ${GLOBAL_ACL_PATH}/${proto}.id set_cache_var "GLOBAL_${proto}_node" "$node"
else else
[ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return [ "${proto}" = "UDP" ] && [ "$TCP_UDP" = "1" ] && return
echolog "${proto}节点没有选择或为空,不代理${proto}" echolog "${proto}节点没有选择或为空,不代理${proto}"
@ -1111,7 +1127,7 @@ start_socks() {
local http_port=$(config_n_get $id http_port 0) local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json" local http_config_file="HTTP2SOCKS_${id}.json"
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
echo $node > $TMP_ID_PATH/socks_${id} set_cache_var "socks_${id}" "$node"
#自动切换逻辑 #自动切换逻辑
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0) local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
@ -1145,7 +1161,9 @@ socks_node_switch() {
local http_config_file="HTTP2SOCKS_${flag}.json" local http_config_file="HTTP2SOCKS_${flag}.json"
LOG_FILE="/dev/null" LOG_FILE="/dev/null"
run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
echo $new_node > $TMP_ID_PATH/socks_${flag} set_cache_var "socks_${flag}" "$new_node"
local USE_TABLES=$(get_cache_var "USE_TABLES")
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
} }
} }
@ -1548,19 +1566,43 @@ start_dns() {
[ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!" [ "$(expr $dnsmasq_version \>= 2.87)" == 0 ] && echolog "Dnsmasq版本低于2.87,有可能无法正常使用!!!"
} }
local RUN_NEW_DNSMASQ=1
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
#The old logic will be removed in the future.
#Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices.
[ "1" = "0" ] && {
DIRECT_DNSMASQ_PORT=$(get_new_port 11400)
DIRECT_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/direct_dnsmasq.conf
lua $APP_PATH/helper_dnsmasq.lua copy_instance -LISTEN_PORT ${DIRECT_DNSMASQ_PORT} -DNSMASQ_CONF ${DIRECT_DNSMASQ_CONF}
ln_run "$(first_type dnsmasq)" "dnsmasq_direct" "/dev/null" -C ${DIRECT_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/direct_dnsmasq.pid
echo "${DIRECT_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/direct_dnsmasq_port
}
#Rewrite the default DNS service configuration
#Modify the default dnsmasq service
lua $APP_PATH/helper_dnsmasq.lua stretch
lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_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 ${DNSMASQ_FILTER_PROXY_IPV6:-0} -NFTFLAG ${nftflag:-0} \
-NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
/etc/init.d/dnsmasq restart >/dev/null 2>&1
else
#Run a copy dnsmasq instance, DNS hijack for that need proxy devices.
GLOBAL_DNSMASQ_PORT=$(get_new_port 11400) GLOBAL_DNSMASQ_PORT=$(get_new_port 11400)
local GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf GLOBAL_DNSMASQ_CONF=${GLOBAL_ACL_PATH}/dnsmasq.conf
local GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d GLOBAL_DNSMASQ_CONF_PATH=${GLOBAL_ACL_PATH}/dnsmasq.d
source $APP_PATH/helper_dnsmasq.sh copy_instance listen_port=$GLOBAL_DNSMASQ_PORT dnsmasq_conf="${GLOBAL_DNSMASQ_CONF}" dnsmasq_conf_path="${GLOBAL_DNSMASQ_CONF_PATH}" lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} -DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} \
lua $APP_PATH/helper_dnsmasq_add.lua -FLAG "default" -TMP_DNSMASQ_PATH ${GLOBAL_DNSMASQ_CONF_PATH} \ -LISTEN_PORT ${GLOBAL_DNSMASQ_PORT} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} -TUN_DNS ${TUN_DNS} \
-DNSMASQ_CONF_FILE ${GLOBAL_DNSMASQ_CONF} -DEFAULT_DNS ${DEFAULT_DNS} -LOCAL_DNS ${LOCAL_DNS} \ -REMOTE_FAKEDNS ${fakedns:-0} -USE_DEFAULT_DNS "${USE_DEFAULT_DNS:-direct}" -CHINADNS_DNS ${china_ng_listen:-0} \
-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}" \ -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 ${DNSMASQ_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} -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid ln_run "$(first_type dnsmasq)" "dnsmasq_default" "/dev/null" -C ${GLOBAL_DNSMASQ_CONF} -x ${GLOBAL_ACL_PATH}/dnsmasq.pid
echo "${GLOBAL_DNSMASQ_PORT}" > ${GLOBAL_ACL_PATH}/var_redirect_dns_port set_cache_var "ACL_default_dns_port" "${GLOBAL_DNSMASQ_PORT}"
DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT} DNS_REDIRECT_PORT=${GLOBAL_DNSMASQ_PORT}
fi
} }
add_ip2route() { add_ip2route() {
@ -1600,7 +1642,7 @@ delete_ip2route() {
start_haproxy() { start_haproxy() {
[ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return [ "$(config_t_get global_haproxy balancing_enable 0)" != "1" ] && return
haproxy_path=${TMP_PATH}/haproxy haproxy_path=$TMP_PATH/haproxy
haproxy_conf="config.cfg" haproxy_conf="config.cfg"
lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS} lua $APP_PATH/haproxy.lua -path ${haproxy_path} -conf ${haproxy_conf} -dns ${LOCAL_DNS}
ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}" ln_run "$(first_type haproxy)" haproxy "/dev/null" -f "${haproxy_path}/${haproxy_conf}"
@ -1751,15 +1793,14 @@ acl_app() {
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1)) dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
local dnsmasq_conf=${acl_path}/dnsmasq.conf local dnsmasq_conf=${acl_path}/dnsmasq.conf
local dnsmasq_conf_path=${acl_path}/dnsmasq.d local dnsmasq_conf_path=${acl_path}/dnsmasq.d
source $APP_PATH/helper_dnsmasq.sh copy_instance listen_port=$dnsmasq_port dnsmasq_conf="${dnsmasq_conf}" dnsmasq_conf_path="${dnsmasq_conf_path}" lua $APP_PATH/helper_dnsmasq.lua add_rule -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} -DNSMASQ_CONF_FILE ${dnsmasq_conf} \
lua $APP_PATH/helper_dnsmasq_add.lua -FLAG ${sid} -TMP_DNSMASQ_PATH ${dnsmasq_conf_path} \ -LISTEN_PORT ${dnsmasq_port} -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS \
-DNSMASQ_CONF_FILE ${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}" \ -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} \ -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 ${dnsmasq_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 -NO_LOGIC_LOG 1
ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid ln_run "$(first_type dnsmasq)" "dnsmasq_${sid}" "/dev/null" -C ${dnsmasq_conf} -x ${acl_path}/dnsmasq.pid
echo "${dnsmasq_port}" > ${acl_path}/var_redirect_dns_port set_cache_var "ACL_${sid}_dns_port" "${dnsmasq_port}"
eval node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)=${dnsmasq_port} eval node_${tcp_node}_$(echo -n "${tcp_proxy_mode}${remote_dns}" | md5sum | cut -d " " -f1)=${dnsmasq_port}
} }
_redir_port=$(eval echo \${node_${tcp_node}_redir_port}) _redir_port=$(eval echo \${node_${tcp_node}_redir_port})
@ -1772,7 +1813,7 @@ acl_app() {
_dns_port=$(eval echo \${node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)}) _dns_port=$(eval echo \${node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)})
run_dns ${_dns_port} run_dns ${_dns_port}
else else
[ -n "${_dnsmasq_port}" ] && echo "${_dnsmasq_port}" > ${acl_path}/var_redirect_dns_port [ -n "${_dnsmasq_port}" ] && set_cache_var "ACL_${sid}_dns_port" "${_dnsmasq_port}"
fi fi
else else
socks_port=$(get_new_port $(expr $socks_port + 1)) socks_port=$(get_new_port $(expr $socks_port + 1))
@ -1810,10 +1851,10 @@ acl_app() {
fi fi
run_dns ${_dns_port} run_dns ${_dns_port}
fi fi
echo "${tcp_node}" > ${acl_path}/var_tcp_node set_cache_var "ACL_${sid}_tcp_node" "${tcp_node}"
} }
fi fi
echo "${tcp_port}" > ${acl_path}/var_tcp_port set_cache_var "ACL_${sid}_tcp_port" "${tcp_port}"
} }
[ "$udp_node" != "nil" ] && { [ "$udp_node" != "nil" ] && {
[ "$udp_node" = "tcp" ] && udp_node=$tcp_node [ "$udp_node" = "tcp" ] && udp_node=$tcp_node
@ -1862,12 +1903,11 @@ acl_app() {
run_ipt2socks flag=acl_${udp_node} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file run_ipt2socks flag=acl_${udp_node} local_port=$redir_port socks_address=127.0.0.1 socks_port=$socks_port log_file=$log_file
fi fi
fi fi
echo "${udp_node}" > ${acl_path}/var_udp_node set_cache_var "ACL_${sid}_udp_node" "${udp_node}"
fi fi
} }
fi fi
echo "${udp_port}" > ${acl_path}/var_udp_port set_cache_var "ACL_${sid}_udp_port" "${udp_port}"
udp_flag=1
} }
unset enabled sid remarks sources interface 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 enabled sid remarks sources interface 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 source_list tcp_port udp_port config_file _extra_param unset _ip _mac _iprange _ipset _ip_or_mac source_list tcp_port udp_port config_file _extra_param
@ -1913,6 +1953,14 @@ start() {
[ "$(expr $dnsmasq_version \>= 2.90)" == 0 ] && echolog "Dnsmasq版本低于2.90建议升级至2.90及以上版本以避免部分情况下Dnsmasq崩溃问题" [ "$(expr $dnsmasq_version \>= 2.90)" == 0 ] && echolog "Dnsmasq版本低于2.90建议升级至2.90及以上版本以避免部分情况下Dnsmasq崩溃问题"
} }
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
[ "$(uci -q get dhcp.@dnsmasq[0].dns_redirect)" == "1" ] && {
uci -q set dhcp.@dnsmasq[0].dns_redirect='0' 2>/dev/null
uci commit dhcp 2>/dev/null
/etc/init.d/dnsmasq restart >/dev/null 2>&1
}
fi
[ "$ENABLED_DEFAULT_ACL" == 1 ] && { [ "$ENABLED_DEFAULT_ACL" == 1 ] && {
mkdir -p ${GLOBAL_ACL_PATH} mkdir -p ${GLOBAL_ACL_PATH}
start_redir TCP start_redir TCP
@ -1920,6 +1968,19 @@ start() {
start_dns start_dns
} }
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start [ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
set_cache_var "USE_TABLES" "$USE_TABLES"
[ -z "$(get_cache_var "ACL_default_dns_port")" ] && lua $APP_PATH/helper_dnsmasq.lua logic_restart -LOG 1
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
set_cache_var "bak_bridge_nf_ipt" "$bridge_nf_ipt"
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
[ "$PROXY_IPV6" == "1" ] && {
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
set_cache_var "bak_bridge_nf_ip6t" "$bridge_nf_ip6t"
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
}
fi
start_crontab start_crontab
echolog "运行完成!\n" echolog "运行完成!\n"
} }
@ -1936,9 +1997,14 @@ stop() {
unset XRAY_LOCATION_ASSET unset XRAY_LOCATION_ASSET
stop_crontab stop_crontab
source $APP_PATH/helper_smartdns.sh del source $APP_PATH/helper_smartdns.sh del
[ -s "$TMP_PATH/bridge_nf_ipt" ] && sysctl -w net.bridge.bridge-nf-call-iptables=$(cat $TMP_PATH/bridge_nf_ipt) >/dev/null 2>&1 rm -rf $GLOBAL_DNSMASQ_CONF
[ -s "$TMP_PATH/bridge_nf_ip6t" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=$(cat $TMP_PATH/bridge_nf_ip6t) >/dev/null 2>&1 rm -rf $GLOBAL_DNSMASQ_CONF_PATH
rm -rf ${TMP_PATH} [ -z "$(get_cache_var "ACL_default_dns_port")" ] && lua $APP_PATH/helper_dnsmasq.lua restart -LOG 0
bak_bridge_nf_ipt=$(get_cache_var "bak_bridge_nf_ipt")
[ -n "${bak_bridge_nf_ipt}" ] && sysctl -w net.bridge.bridge-nf-call-iptables=${bak_bridge_nf_ipt} >/dev/null 2>&1
bak_bridge_nf_ip6t=$(get_cache_var "bak_bridge_nf_ip6t")
[ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1
rm -rf $TMP_PATH
rm -rf /tmp/lock/${CONFIG}_socks_auto_switch* rm -rf /tmp/lock/${CONFIG}_socks_auto_switch*
echolog "清空并关闭相关程序和缓存完成。" echolog "清空并关闭相关程序和缓存完成。"
exit 0 exit 0
@ -2011,13 +2077,28 @@ DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print
LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}" LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}"
IPT_APPEND_DNS=${LOCAL_DNS} IPT_APPEND_DNS=${LOCAL_DNS}
DNSMASQ_CONF_DIR=/tmp/dnsmasq.d
TMP_DNSMASQ_PATH=${DNSMASQ_CONF_DIR}/${CONFIG}
DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')"
if [ -f "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID" ]; then
DNSMASQ_CONF_DIR="$(awk -F '=' '/^conf-dir=/ {print $2}' "/tmp/etc/dnsmasq.conf.$DEFAULT_DNSMASQ_CFGID")"
if [ -n "$DNSMASQ_CONF_DIR" ]; then
DNSMASQ_CONF_DIR=${DNSMASQ_CONF_DIR%*/}
TMP_DNSMASQ_PATH=${DNSMASQ_CONF_DIR}/${CONFIG}
else
DNSMASQ_CONF_DIR="/tmp/dnsmasq.d"
fi
fi
GLOBAL_DNSMASQ_CONF=${DNSMASQ_CONF_DIR}/dnsmasq-${CONFIG}.conf
GLOBAL_DNSMASQ_CONF_PATH=${TMP_DNSMASQ_PATH}
DNS_QUERY_STRATEGY="UseIP" DNS_QUERY_STRATEGY="UseIP"
[ "$FILTER_PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIPv4" [ "$FILTER_PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIPv4"
DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6} DNSMASQ_FILTER_PROXY_IPV6=${FILTER_PROXY_IPV6}
export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/") export V2RAY_LOCATION_ASSET=$(config_t_get global_rules v2ray_location_asset "/usr/share/v2ray/")
export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET export XRAY_LOCATION_ASSET=$V2RAY_LOCATION_ASSET
mkdir -p /tmp/etc $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ID_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_IFACE_PATH $TMP_PATH2 mkdir -p /tmp/etc $TMP_PATH $TMP_BIN_PATH $TMP_SCRIPT_FUNC_PATH $TMP_ROUTE_PATH $TMP_ACL_PATH $TMP_PATH2
arg1=$1 arg1=$1
shift shift
@ -2040,6 +2121,12 @@ socks_node_switch)
echolog) echolog)
echolog $@ echolog $@
;; ;;
get_cache_var)
get_cache_var $@
;;
set_cache_var)
set_cache_var $@
;;
stop) stop)
stop stop
;; ;;

View File

@ -0,0 +1,675 @@
local api = require "luci.passwall.api"
local appname = "passwall"
local uci = api.uci
local sys = api.sys
local fs = api.fs
local datatypes = api.datatypes
local TMP = {}
local function tinsert(table_name, val)
if table_name and type(table_name) == "table" then
if not TMP[table_name] then
TMP[table_name] = {}
end
if TMP[table_name][val] then
return false
end
table.insert(table_name, val)
TMP[table_name][val] = true
return true
end
return false
end
local function backup_servers()
local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server")
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
uci:commit(appname)
end
end
local function restore_servers()
local dns_table = {}
local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server")
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
for k, v in ipairs(DNSMASQ_DNS) do
tinsert(dns_table, v)
end
end
local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers")
if OLD_SERVER and #OLD_SERVER > 0 then
for k, v in ipairs(OLD_SERVER) do
tinsert(dns_table, v)
end
uci:delete(appname, "@global[0]", "dnsmasq_servers")
uci:commit(appname)
end
if dns_table and #dns_table > 0 then
uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table)
uci:commit("dhcp")
end
end
function stretch()
local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server")
local dnsmasq_noresolv = uci:get("dhcp", "@dnsmasq[0]", "noresolv")
local _flag
if dnsmasq_server and #dnsmasq_server > 0 then
for k, v in ipairs(dnsmasq_server) do
if not v:find("/") then
_flag = true
end
end
end
if not _flag and dnsmasq_noresolv == "1" then
uci:delete("dhcp", "@dnsmasq[0]", "noresolv")
local RESOLVFILE = "/tmp/resolv.conf.d/resolv.conf.auto"
local file = io.open(RESOLVFILE, "r")
if not file then
RESOLVFILE = "/tmp/resolv.conf.auto"
else
local size = file:seek("end")
file:close()
if size == 0 then
RESOLVFILE = "/tmp/resolv.conf.auto"
end
end
uci:set("dhcp", "@dnsmasq[0]", "resolvfile", RESOLVFILE)
uci:commit("dhcp")
end
end
function restart(var)
local LOG = var["-LOG"]
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
if LOG == "1" then
api.log("重启 dnsmasq 服务")
end
end
function logic_restart(var)
local LOG = var["-LOG"]
local DEFAULT_DNS = api.get_cache_var("DEFAULT_DNS")
if DEFAULT_DNS then
backup_servers()
--sys.call("sed -i '/list server/d' /etc/config/dhcp >/dev/null 2>&1")
local dns_table = {}
local dnsmasq_server = uci:get("dhcp", "@dnsmasq[0]", "server")
if dnsmasq_server and #dnsmasq_server > 0 then
for k, v in ipairs(dnsmasq_server) do
if v:find("/") then
tinsert(dns_table, v)
end
end
if dns_table and #dns_table > 0 then
uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table)
uci:commit("dhcp")
end
end
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
restore_servers()
else
sys.call("/etc/init.d/dnsmasq restart >/dev/null 2>&1")
end
if LOG == "1" then
api.log("重启 dnsmasq 服务")
end
end
function copy_instance(var)
local LISTEN_PORT = var["-LISTEN_PORT"]
local DNSMASQ_CONF = var["-DNSMASQ_CONF"]
local conf_lines = {}
local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')")
for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do
local filter
if line:find("passwall") then filter = true end
if line:find("ubus") then filter = true end
if line:find("dhcp") then filter = true end
if line:find("server") then filter = true end
if line:find("port") then filter = true end
if not filter then
tinsert(conf_lines, line)
end
end
tinsert(conf_lines, "port=" .. LISTEN_PORT)
if #conf_lines > 0 then
local conf_out = io.open(DNSMASQ_CONF, "a")
conf_out:write(table.concat(conf_lines, "\n"))
conf_out:close()
end
end
function add_rule(var)
local FLAG = var["-FLAG"]
local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"]
local DNSMASQ_CONF_FILE = var["-DNSMASQ_CONF_FILE"]
local LISTEN_PORT = var["-LISTEN_PORT"]
local DEFAULT_DNS = var["-DEFAULT_DNS"]
local LOCAL_DNS = var["-LOCAL_DNS"]
local TUN_DNS = var["-TUN_DNS"]
local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"]
local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"]
local CHINADNS_DNS = var["-CHINADNS_DNS"]
local TCP_NODE = var["-TCP_NODE"]
local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"]
local USE_PROXY_LIST = var["-USE_PROXY_LIST"]
local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"]
local USE_GFW_LIST = var["-USE_GFW_LIST"]
local CHN_LIST = var["-CHN_LIST"]
local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"]
local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"]
local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"]
local NFTFLAG = var["-NFTFLAG"]
local CACHE_PATH = api.CACHE_PATH
local CACHE_FLAG = "dnsmasq_" .. FLAG
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
local USE_CHINADNS_NG = "0"
local list1 = {}
local excluded_domain = {}
local excluded_domain_str = "!"
local function log(...)
if NO_LOGIC_LOG == "1" then
return
end
api.log(...)
end
local function check_dns(domain, dns)
if domain == "" or domain:find("#") then
return false
end
if not dns then
return
end
for k,v in ipairs(list1[domain].dns) do
if dns == v then
return true
end
end
return false
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
return true
end
end
return false
end
local function set_domain_address(domain, address)
if domain == "" or domain:find("#") then
return
end
if not list1[domain] then
list1[domain] = {
dns = {},
ipsets = {}
}
end
if not list1[domain].address then
list1[domain].address = address
end
end
local function set_domain_dns(domain, dns)
if domain == "" or domain:find("#") then
return
end
if not dns then
return
end
if not list1[domain] then
list1[domain] = {
dns = {},
ipsets = {}
}
end
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
if not check_dns(domain, line) then
table.insert(list1[domain].dns, line)
end
end
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] = {
dns = {},
ipsets = {}
}
end
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
if not check_ipset(domain, line) then
table.insert(list1[domain].ipsets, line)
end
end
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
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 = sys.exec("echo -n $(uci show passwall | grep '\\.address') | md5sum")
local new_rules = sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)")
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. USE_DEFAULT_DNS .. CHINADNS_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 .. NFTFLAG
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 .. "*")
end
local dnsmasq_default_dns
if USE_DEFAULT_DNS ~= "nil" then
if USE_DEFAULT_DNS == "direct" then
dnsmasq_default_dns = LOCAL_DNS
end
if USE_DEFAULT_DNS == "remote" then
dnsmasq_default_dns = TUN_DNS
end
if USE_DEFAULT_DNS == "remote" and CHN_LIST == "direct" then
dnsmasq_default_dns = TUN_DNS
end
end
local only_global
if DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0" then
--没有启用中国列表和GFW列表时
dnsmasq_default_dns = TUN_DNS
only_global = 1
end
if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
dnsmasq_default_dns = CHINADNS_DNS
USE_CHINADNS_NG = "1"
end
local setflag_4= (NFTFLAG == "1") and "4#inet#passwall#" or ""
local setflag_6= (NFTFLAG == "1") and "6#inet#passwall#" or ""
if not fs.access(CACHE_DNS_PATH) then
fs.mkdir(CACHE_DNS_PATH)
--屏蔽列表
if USE_CHINADNS_NG == "0" then
if USE_BLOCK_LIST == "1" 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
local fwd_dns
local ipset_flag
local no_ipv6
--始终用国内DNS解析节点域名
if true then
fwd_dns = LOCAL_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
else
uci:foreach(appname, "nodes", function(t)
local function process_address(address)
if address == "engage.cloudflareclient.com" then return end
if datatypes.hostname(address) then
set_domain_dns(address, fwd_dns)
set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6")
end
end
process_address(t.address)
process_address(t.download_address)
end)
log(string.format(" - 节点列表中的域名(vpslist)%s", fwd_dns or "默认"))
end
end
--直连(白名单)列表
if USE_DIRECT_LIST == "1" then
if fs.access("/usr/share/passwall/rules/direct_host") then
fwd_dns = LOCAL_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
--始终用国内DNS解析直连白名单列表
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_dns(line, fwd_dns)
set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6")
end
end
log(string.format(" - 域名白名单(whitelist)%s", fwd_dns or "默认"))
end
end
end
--代理(黑名单)列表
if USE_PROXY_LIST == "1" then
if fs.access("/usr/share/passwall/rules/proxy_host") then
fwd_dns = TUN_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
--始终使用远程DNS解析代理黑名单列表
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 = setflag_4 .. "passwall_blacklist," .. setflag_6 .. "passwall_blacklist6"
if NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
ipset_flag = setflag_4 .. "passwall_blacklist"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 代理域名表(blacklist)%s", fwd_dns or "默认"))
end
end
end
--GFW列表
if USE_GFW_LIST == "1" then
if fs.access("/usr/share/passwall/rules/gfwlist") then
fwd_dns = TUN_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
local ipset_flag = setflag_4 .. "passwall_gfwlist," .. setflag_6 .. "passwall_gfwlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_gfwlist"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(gfwlist_str, "[^\r\n]+") do
if line ~= "" then
if NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
end
if dnsmasq_default_dns == fwd_dns then
fwd_dns = nil
else
set_domain_dns(line, fwd_dns)
end
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 防火墙域名表(gfwlist)%s", fwd_dns or "默认"))
end
end
end
--中国列表
if CHN_LIST ~= "0" then
if fs.access("/usr/share/passwall/rules/chnlist") then
fwd_dns = nil
if CHN_LIST == "direct" then
fwd_dns = LOCAL_DNS
end
if CHN_LIST == "proxy" then
fwd_dns = TUN_DNS
end
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
local ipset_flag = setflag_4 .. "passwall_chnroute," .. setflag_6 .. "passwall_chnroute6"
if CHN_LIST == "proxy" then
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_chnroute"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
end
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
if line ~= "" then
if CHN_LIST == "proxy" and NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
end
if dnsmasq_default_dns == fwd_dns then
fwd_dns = nil
else
set_domain_dns(line, fwd_dns)
end
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 中国域名表(chnroute)%s", fwd_dns or "默认"))
end
end
end
--分流规则
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_CHINADNS_NG == "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)
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
fwd_dns = nil
ipset_flag = nil
no_ipv6 = nil
if _node_id == "_direct" then
fwd_dns = LOCAL_DNS
if USE_DIRECT_LIST == "1" then
ipset_flag = setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6"
else
ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6"
end
else
fwd_dns = TUN_DNS
ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_shuntlist"
no_ipv6 = true
end
if not only_global then
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
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, "::")
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, ipset_flag)
end
end
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s)%s", s.remarks, fwd_dns or "默认"))
end
end
end)
elseif only_global == 1 and NO_PROXY_IPV6 == "1" then
--节点:固定节点
--代理模式:全局模式
--过滤代理域名 IPv6启用
--禁止解析所有IPv6记录
list1["#"] = {
dns = {},
ipsets = {},
address = "::"
}
end
if list1 and next(list1) then
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
local set_name = "ipset"
if NFTFLAG == "1" then
set_name = "nftset"
end
for key, value in pairs(list1) do
if value.address then
local domain = "." .. key
if key == "#" then
domain = key
end
address_out:write(string.format("address=/%s/%s", domain, value.address) .. "\n")
end
if value.dns and #value.dns > 0 then
for i, dns in ipairs(value.dns) do
server_out:write(string.format("server=/.%s/%s", key, dns) .. "\n")
end
end
if value.ipsets and #value.ipsets > 0 then
local ipsets_str = ""
for i, ipset in ipairs(value.ipsets) do
ipsets_str = ipsets_str .. ipset .. ","
end
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
ipset_out:write(string.format("%s=/.%s/%s", set_name, key, ipsets_str) .. "\n")
end
end
address_out:close()
server_out:close()
ipset_out:close()
end
local f_out = io.open(CACHE_TEXT_FILE, "a")
f_out:write(new_text)
f_out:close()
end
if USE_CHINADNS_NG == "0" then
if api.is_install("procd\\-ujail") then
fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
else
api.remove(TMP_DNSMASQ_PATH)
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
end
end
if DNSMASQ_CONF_FILE ~= "nil" then
local conf_lines = {}
if LISTEN_PORT then
--Copy dnsmasq instance
local DEFAULT_DNSMASQ_CFGID = sys.exec("echo -n $(uci -q show dhcp.@dnsmasq[0] | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')")
for line in io.lines("/tmp/etc/dnsmasq.conf." .. DEFAULT_DNSMASQ_CFGID) do
local filter
if line:find("passwall") then filter = true end
if line:find("ubus") then filter = true end
if line:find("dhcp") then filter = true end
if line:find("server") then filter = true end
if line:find("port") then filter = true end
if not filter then
tinsert(conf_lines, line)
end
end
tinsert(conf_lines, "port=" .. LISTEN_PORT)
else
--Modify the default dnsmasq service
end
if USE_CHINADNS_NG == "0" then
tinsert(conf_lines, string.format("conf-dir=%s", TMP_DNSMASQ_PATH))
end
if dnsmasq_default_dns then
for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do
tinsert(conf_lines, string.format("server=%s", s))
end
tinsert(conf_lines, "all-servers")
tinsert(conf_lines, "no-poll")
tinsert(conf_lines, "no-resolv")
if USE_CHINADNS_NG == "0" then
log(string.format(" - 默认:%s", dnsmasq_default_dns))
end
if FLAG == "default" then
api.set_cache_var("DEFAULT_DNS", DEFAULT_DNS)
end
end
if #conf_lines > 0 then
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
conf_out:write(table.concat(conf_lines, "\n"))
conf_out:close()
end
end
if USE_CHINADNS_NG == "0" then
log(" - PassWall必须依赖于Dnsmasq如果你自行配置了错误的DNS流程将会导致域名(直连/代理域名)分流失效!!!")
end
end
_G.stretch = stretch
_G.restart = restart
_G.logic_restart = logic_restart
_G.copy_instance = copy_instance
_G.add_rule = add_rule
if arg[1] then
local func =_G[arg[1]]
if func then
func(api.get_function_args(arg))
end
end

View File

@ -1,27 +0,0 @@
#!/bin/sh
copy_instance() {
local listen_port dnsmasq_conf
eval_set_val $@
[ -s "/tmp/etc/dnsmasq.conf.${DEFAULT_DNSMASQ_CFGID}" ] && {
cp -r /tmp/etc/dnsmasq.conf.${DEFAULT_DNSMASQ_CFGID} $dnsmasq_conf
sed -i "/ubus/d" $dnsmasq_conf
sed -i "/dhcp/d" $dnsmasq_conf
sed -i "/port=/d" $dnsmasq_conf
sed -i "/conf-dir/d" $dnsmasq_conf
sed -i "/no-poll/d" $dnsmasq_conf
sed -i "/no-resolv/d" $dnsmasq_conf
}
echo "port=${listen_port}" >> $dnsmasq_conf
}
DEFAULT_DNSMASQ_CFGID="$(uci -q show "dhcp.@dnsmasq[0]" | awk 'NR==1 {split($0, conf, /[.=]/); print conf[2]}')"
arg1=$1
shift
case $arg1 in
copy_instance)
copy_instance $@
;;
*) ;;
esac

View File

@ -1,506 +0,0 @@
require "luci.sys"
local api = require "luci.passwall.api"
local appname = "passwall"
local var = api.get_args(arg)
local FLAG = var["-FLAG"]
local TMP_DNSMASQ_PATH = var["-TMP_DNSMASQ_PATH"]
local DNSMASQ_CONF_FILE = var["-DNSMASQ_CONF_FILE"]
local DEFAULT_DNS = var["-DEFAULT_DNS"]
local LOCAL_DNS = var["-LOCAL_DNS"]
local TUN_DNS = var["-TUN_DNS"]
local REMOTE_FAKEDNS = var["-REMOTE_FAKEDNS"]
local USE_DEFAULT_DNS = var["-USE_DEFAULT_DNS"]
local CHINADNS_DNS = var["-CHINADNS_DNS"]
local TCP_NODE = var["-TCP_NODE"]
local USE_DIRECT_LIST = var["-USE_DIRECT_LIST"]
local USE_PROXY_LIST = var["-USE_PROXY_LIST"]
local USE_BLOCK_LIST = var["-USE_BLOCK_LIST"]
local USE_GFW_LIST = var["-USE_GFW_LIST"]
local CHN_LIST = var["-CHN_LIST"]
local DEFAULT_PROXY_MODE = var["-DEFAULT_PROXY_MODE"]
local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"]
local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"]
local NFTFLAG = var["-NFTFLAG"]
local CACHE_PATH = api.CACHE_PATH
local CACHE_FLAG = "dnsmasq_" .. FLAG
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
local USE_CHINADNS_NG = "0"
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 function log(...)
if NO_LOGIC_LOG == "1" then
return
end
api.log(...)
end
local function check_dns(domain, dns)
if domain == "" or domain:find("#") then
return false
end
if not dns then
return
end
for k,v in ipairs(list1[domain].dns) do
if dns == v then
return true
end
end
return false
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
return true
end
end
return false
end
local function set_domain_address(domain, address)
if domain == "" or domain:find("#") then
return
end
if not list1[domain] then
list1[domain] = {
dns = {},
ipsets = {}
}
end
if not list1[domain].address then
list1[domain].address = address
end
end
local function set_domain_dns(domain, dns)
if domain == "" or domain:find("#") then
return
end
if not dns then
return
end
if not list1[domain] then
list1[domain] = {
dns = {},
ipsets = {}
}
end
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
if not check_dns(domain, line) then
table.insert(list1[domain].dns, line)
end
end
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] = {
dns = {},
ipsets = {}
}
end
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
if not check_ipset(domain, line) then
table.insert(list1[domain].ipsets, line)
end
end
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
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 = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. USE_DEFAULT_DNS .. CHINADNS_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 .. NFTFLAG
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 .. "*")
end
local dnsmasq_default_dns
if USE_DEFAULT_DNS ~= "nil" then
if USE_DEFAULT_DNS == "direct" then
dnsmasq_default_dns = LOCAL_DNS
end
if USE_DEFAULT_DNS == "remote" then
dnsmasq_default_dns = TUN_DNS
end
if USE_DEFAULT_DNS == "remote" and CHN_LIST == "direct" then
dnsmasq_default_dns = TUN_DNS
end
end
local only_global
if DEFAULT_PROXY_MODE == "proxy" and CHN_LIST == "0" and USE_GFW_LIST == "0" then
--没有启用中国列表和GFW列表时
dnsmasq_default_dns = TUN_DNS
only_global = 1
end
if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
dnsmasq_default_dns = CHINADNS_DNS
USE_CHINADNS_NG = "1"
end
local setflag_4= (NFTFLAG == "1") and "4#inet#passwall#" or ""
local setflag_6= (NFTFLAG == "1") and "6#inet#passwall#" or ""
if not fs.access(CACHE_DNS_PATH) then
fs.mkdir(CACHE_DNS_PATH)
--屏蔽列表
if USE_CHINADNS_NG == "0" then
if USE_BLOCK_LIST == "1" 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
local fwd_dns
local ipset_flag
local no_ipv6
--始终用国内DNS解析节点域名
if true then
fwd_dns = LOCAL_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
else
uci:foreach(appname, "nodes", function(t)
local function process_address(address)
if address == "engage.cloudflareclient.com" then return end
if datatypes.hostname(address) then
set_domain_dns(address, fwd_dns)
set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6")
end
end
process_address(t.address)
process_address(t.download_address)
end)
log(string.format(" - 节点列表中的域名(vpslist)%s", fwd_dns or "默认"))
end
end
--直连(白名单)列表
if USE_DIRECT_LIST == "1" then
if fs.access("/usr/share/passwall/rules/direct_host") then
fwd_dns = LOCAL_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
--始终用国内DNS解析直连白名单列表
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_dns(line, fwd_dns)
set_domain_ipset(line, setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6")
end
end
log(string.format(" - 域名白名单(whitelist)%s", fwd_dns or "默认"))
end
end
end
--代理(黑名单)列表
if USE_PROXY_LIST == "1" then
if fs.access("/usr/share/passwall/rules/proxy_host") then
fwd_dns = TUN_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
--始终使用远程DNS解析代理黑名单列表
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 = setflag_4 .. "passwall_blacklist," .. setflag_6 .. "passwall_blacklist6"
if NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
ipset_flag = setflag_4 .. "passwall_blacklist"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 代理域名表(blacklist)%s", fwd_dns or "默认"))
end
end
end
--GFW列表
if USE_GFW_LIST == "1" then
if fs.access("/usr/share/passwall/rules/gfwlist") then
fwd_dns = TUN_DNS
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
local ipset_flag = setflag_4 .. "passwall_gfwlist," .. setflag_6 .. "passwall_gfwlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_gfwlist"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(gfwlist_str, "[^\r\n]+") do
if line ~= "" then
if NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
end
if dnsmasq_default_dns == fwd_dns then
fwd_dns = nil
else
set_domain_dns(line, fwd_dns)
end
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 防火墙域名表(gfwlist)%s", fwd_dns or "默认"))
end
end
end
--中国列表
if CHN_LIST ~= "0" then
if fs.access("/usr/share/passwall/rules/chnlist") then
fwd_dns = nil
if CHN_LIST == "direct" then
fwd_dns = LOCAL_DNS
end
if CHN_LIST == "proxy" then
fwd_dns = TUN_DNS
end
if USE_CHINADNS_NG == "1" then
fwd_dns = nil
end
if fwd_dns then
local ipset_flag = setflag_4 .. "passwall_chnroute," .. setflag_6 .. "passwall_chnroute6"
if CHN_LIST == "proxy" then
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_chnroute"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
end
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
if line ~= "" then
if CHN_LIST == "proxy" and NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
end
if dnsmasq_default_dns == fwd_dns then
fwd_dns = nil
else
set_domain_dns(line, fwd_dns)
end
set_domain_ipset(line, ipset_flag)
end
end
log(string.format(" - 中国域名表(chnroute)%s", fwd_dns or "默认"))
end
end
end
--分流规则
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_CHINADNS_NG == "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)
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
fwd_dns = nil
ipset_flag = nil
no_ipv6 = nil
if _node_id == "_direct" then
fwd_dns = LOCAL_DNS
if USE_DIRECT_LIST == "1" then
ipset_flag = setflag_4 .. "passwall_whitelist," .. setflag_6 .. "passwall_whitelist6"
else
ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6"
end
else
fwd_dns = TUN_DNS
ipset_flag = setflag_4 .. "passwall_shuntlist," .. setflag_6 .. "passwall_shuntlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = setflag_4 .. "passwall_shuntlist"
no_ipv6 = true
end
if not only_global then
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
end
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, "::")
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, ipset_flag)
end
end
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s)%s", s.remarks, fwd_dns or "默认"))
end
end
end)
elseif only_global == 1 and NO_PROXY_IPV6 == "1" then
--节点:固定节点
--代理模式:全局模式
--过滤代理域名 IPv6启用
--禁止解析所有IPv6记录
list1["#"] = {
dns = {},
ipsets = {},
address = "::"
}
end
if list1 and next(list1) then
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
local set_name = "ipset"
if NFTFLAG == "1" then
set_name = "nftset"
end
for key, value in pairs(list1) do
if value.address then
local domain = "." .. key
if key == "#" then
domain = key
end
address_out:write(string.format("address=/%s/%s\n", domain, value.address))
end
if value.dns and #value.dns > 0 then
for i, dns in ipairs(value.dns) do
server_out:write(string.format("server=/.%s/%s\n", key, dns))
end
end
if value.ipsets and #value.ipsets > 0 then
local ipsets_str = ""
for i, ipset in ipairs(value.ipsets) do
ipsets_str = ipsets_str .. ipset .. ","
end
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
end
end
address_out:close()
server_out:close()
ipset_out:close()
end
local f_out = io.open(CACHE_TEXT_FILE, "a")
f_out:write(new_text)
f_out:close()
end
if USE_CHINADNS_NG == "0" then
if api.is_install("procd\\-ujail") then
fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
else
api.remove(TMP_DNSMASQ_PATH)
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
end
end
if DNSMASQ_CONF_FILE ~= "nil" then
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
if USE_CHINADNS_NG == "0" then
conf_out:write(string.format("conf-dir=%s\n", TMP_DNSMASQ_PATH))
end
if dnsmasq_default_dns then
for s in string.gmatch(dnsmasq_default_dns, '[^' .. "," .. ']+') do
conf_out:write(string.format("server=%s\n", s))
end
conf_out:write("all-servers\n")
conf_out:write("no-poll\n")
conf_out:write("no-resolv\n")
conf_out:close()
if USE_CHINADNS_NG == "0" then
log(string.format(" - 默认:%s", dnsmasq_default_dns))
end
if FLAG == "default" then
local f_out = io.open("/tmp/etc/passwall/default_DNS", "a")
f_out:write(DEFAULT_DNS)
f_out:close()
end
end
end
if USE_CHINADNS_NG == "0" then
log(" - PassWall必须依赖于Dnsmasq如果你自行配置了错误的DNS流程将会导致域名(直连/代理域名)分流失效!!!")
end

View File

@ -2,6 +2,7 @@
DIR="$(cd "$(dirname "$0")" && pwd)" DIR="$(cd "$(dirname "$0")" && pwd)"
MY_PATH=$DIR/iptables.sh MY_PATH=$DIR/iptables.sh
IPSET_LOCALLIST="passwall_locallist"
IPSET_LANLIST="passwall_lanlist" IPSET_LANLIST="passwall_lanlist"
IPSET_VPSLIST="passwall_vpslist" IPSET_VPSLIST="passwall_vpslist"
IPSET_SHUNTLIST="passwall_shuntlist" IPSET_SHUNTLIST="passwall_shuntlist"
@ -11,6 +12,7 @@ IPSET_BLACKLIST="passwall_blacklist"
IPSET_WHITELIST="passwall_whitelist" IPSET_WHITELIST="passwall_whitelist"
IPSET_BLOCKLIST="passwall_blocklist" IPSET_BLOCKLIST="passwall_blocklist"
IPSET_LOCALLIST6="passwall_locallist6"
IPSET_LANLIST6="passwall_lanlist6" IPSET_LANLIST6="passwall_lanlist6"
IPSET_VPSLIST6="passwall_vpslist6" IPSET_VPSLIST6="passwall_vpslist6"
IPSET_SHUNTLIST6="passwall_shuntlist6" IPSET_SHUNTLIST6="passwall_shuntlist6"
@ -212,11 +214,11 @@ load_acl() {
[ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -s "${TMP_ACL_PATH}/${sid}/var_tcp_node" ] && tcp_node=$(cat ${TMP_ACL_PATH}/${sid}/var_tcp_node) [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node")
[ -s "${TMP_ACL_PATH}/${sid}/var_udp_node" ] && udp_node=$(cat ${TMP_ACL_PATH}/${sid}/var_udp_node) [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node")
[ -s "${TMP_ACL_PATH}/${sid}/var_tcp_port" ] && tcp_port=$(cat ${TMP_ACL_PATH}/${sid}/var_tcp_port) [ -n "$(get_cache_var "ACL_${sid}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port")
[ -s "${TMP_ACL_PATH}/${sid}/var_udp_port" ] && udp_port=$(cat ${TMP_ACL_PATH}/${sid}/var_udp_port) [ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_port")
[ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && dns_redirect_port=$(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port) [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
use_shunt_tcp=0 use_shunt_tcp=0
use_shunt_udp=0 use_shunt_udp=0
@ -321,22 +323,22 @@ load_acl() {
fi fi
} }
local dns_redirect
[ $(config_t_get global dns_redirect "1") = "1" ] && dns_redirect=53
if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then
[ -n "$dns_redirect_port" ] && { [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT}
fi
if [ -n "${dns_redirect}" ]; then
$ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN $ipt_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN
$ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null $ip6t_m -A PSW $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
$ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN $ipt_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN
$ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null $ip6t_m -A PSW $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
$ipt_n -A PSW_REDIRECT $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port $ipt_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect}
$ip6t_n -A PSW_REDIRECT $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null $ip6t_n -A PSW_DNS $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null
$ipt_n -A PSW_REDIRECT $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port $ipt_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect}
$ip6t_n -A PSW_REDIRECT $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports $dns_redirect_port 2>/dev/null $ip6t_n -A PSW_DNS $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j REDIRECT --to-ports ${dns_redirect} 2>/dev/null
}
else
$ipt_n -A PSW_REDIRECT $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN
$ip6t_n -A PSW_REDIRECT $(comment "$remarks") -p udp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
$ipt_n -A PSW_REDIRECT $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN
$ip6t_n -A PSW_REDIRECT $(comment "$remarks") -p tcp ${_ipt_source} --dport 53 -j RETURN 2>/dev/null
fi fi
[ -n "$tcp_port" -o -n "$udp_port" ] && { [ -n "$tcp_port" -o -n "$udp_port" ] && {
@ -468,7 +470,7 @@ load_acl() {
unset ipt_tmp ipt_j _ipt_source msg msg2 unset ipt_tmp ipt_j _ipt_source msg msg2
done done
unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface
unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect
done done
} }
@ -499,17 +501,23 @@ load_acl() {
fi fi
} }
local DNS_REDIRECT
[ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53
if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && { [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
fi
if [ -n "${DNS_REDIRECT}" ]; then
$ipt_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN $ipt_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN
$ip6t_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN 2>/dev/null $ip6t_m -A PSW $(comment "默认") -p udp --dport 53 -j RETURN 2>/dev/null
$ipt_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN $ipt_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN
$ip6t_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN 2>/dev/null $ip6t_m -A PSW $(comment "默认") -p tcp --dport 53 -j RETURN 2>/dev/null
$ipt_n -A PSW_REDIRECT $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT $ipt_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT}
$ip6t_n -A PSW_REDIRECT $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null $ip6t_n -A PSW_DNS $(comment "默认") -p udp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} 2>/dev/null
$ipt_n -A PSW_REDIRECT $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT $ipt_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT}
$ip6t_n -A PSW_REDIRECT $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports $DNS_REDIRECT_PORT 2>/dev/null $ip6t_n -A PSW_DNS $(comment "默认") -p tcp --dport 53 -j REDIRECT --to-ports ${DNS_REDIRECT} 2>/dev/null
}
fi fi
[ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && { [ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && {
@ -632,7 +640,6 @@ load_acl() {
} }
echolog " - ${msg2}" echolog " - ${msg2}"
udp_flag=1
} }
fi fi
$ipt_m -A PSW $(comment "默认") -p udp -j RETURN $ipt_m -A PSW $(comment "默认") -p udp -j RETURN
@ -655,113 +662,53 @@ filter_vpsip() {
echolog " - [$?]加入所有IPv6节点到ipset[$IPSET_VPSLIST6]直连完成" echolog " - [$?]加入所有IPv6节点到ipset[$IPSET_VPSLIST6]直连完成"
} }
filter_node() { filter_server_port() {
local proxy_node=${1} local address=${1}
local stream=$(echo ${2} | tr 'A-Z' 'a-z') local port=${2}
local proxy_port=${3} local stream=${3}
stream=$(echo ${3} | tr 'A-Z' 'a-z')
filter_rules() { local _is_tproxy ipt_tmp
local node=${1}
local stream=${2}
local _proxy=${3}
local _port=${4}
local _is_tproxy ipt_tmp msg msg2
if [ -n "$node" ] && [ "$node" != "nil" ]; then
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local address=$(config_n_get $node address)
local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && {
echolog " - 节点配置不正常,略过"
return 1
}
ipt_tmp=$ipt_n ipt_tmp=$ipt_n
_is_tproxy=${is_tproxy} _is_tproxy=${is_tproxy}
[ "$stream" == "udp" ] && _is_tproxy="TPROXY" [ "$stream" == "udp" ] && _is_tproxy="TPROXY"
if [ -n "${_is_tproxy}" ]; then [ -n "${_is_tproxy}" ] && ipt_tmp=$ipt_m
ipt_tmp=$ipt_m
msg="TPROXY"
else
msg="REDIRECT"
fi
else
echolog " - 节点配置不正常,略过"
return 1
fi
local ADD_INDEX=$FORCE_INDEX
for _ipt in 4 6; do for _ipt in 4 6; do
[ "$_ipt" == "4" ] && _ipt=$ipt_tmp && _set_name=$IPSET_VPSLIST [ "$_ipt" == "4" ] && _ipt=$ipt_tmp
[ "$_ipt" == "6" ] && _ipt=$ip6t_m && _set_name=$IPSET_VPSLIST6 [ "$_ipt" == "6" ] && _ipt=$ip6t_m
$_ipt -n -L PSW_OUTPUT | grep -q "${address}:${port}" $_ipt -n -L PSW_OUTPUT | grep -q "${address}:${port}"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
local dst_rule="-j PSW_RULE" $_ipt -I PSW_OUTPUT $(comment "${address}:${port}") -p $stream -d $address --dport $port -j RETURN 2>/dev/null
msg2="按规则路由(${msg})"
[ "$_ipt" == "$ipt_m" -o "$_ipt" == "$ip6t_m" ] || {
dst_rule=$(REDIRECT $_port)
msg2="套娃使用(${msg}:${port} -> ${_port})"
}
[ -n "$_proxy" ] && [ "$_proxy" == "1" ] && [ -n "$_port" ] || {
ADD_INDEX=$(RULE_LAST_INDEX "$_ipt" PSW_OUTPUT "$_set_name" $FORCE_INDEX)
dst_rule=" -j RETURN"
msg2="直连代理"
}
$_ipt -I PSW_OUTPUT $ADD_INDEX $(comment "${address}:${port}") -p $stream -d $address --dport $port $dst_rule 2>/dev/null
else
msg2="已配置过的节点,"
fi fi
done done
msg="[$?]$(echo ${2} | tr 'a-z' 'A-Z')${msg2}使用链${ADD_INDEX},节点(${type}${address}:${port}"
#echolog " - ${msg}"
} }
local proxy_protocol=$(config_n_get $proxy_node protocol) filter_node() {
local proxy_type=$(echo $(config_n_get $proxy_node type nil) | tr 'A-Z' 'a-z') local node=${1}
[ "$proxy_type" == "nil" ] && echolog " - 节点配置不正常,略过!:${proxy_node}" && return 1 local stream=${2}
if [ "$proxy_protocol" == "_balancing" ]; then if [ -n "$node" ] && [ "$node" != "nil" ]; then
#echolog " - 多节点负载均衡(${proxy_type}..." local address=$(config_n_get $node address)
proxy_node=$(config_n_get $proxy_node balancing_node) local port=$(config_n_get $node port)
for _node in $proxy_node; do [ -z "$address" ] && [ -z "$port" ] && {
filter_rules "$_node" "$stream" return 1
done }
elif [ "$proxy_protocol" == "_shunt" ]; then filter_server_port $address $port $stream
#echolog " - 按请求目的地址分流(${proxy_type}..." filter_server_port $address $port $stream
local preproxy_enabled=$(config_n_get $proxy_node preproxy_enabled 0)
[ "$preproxy_enabled" == "1" ] && {
local preproxy_node=$(config_n_get $proxy_node main_node nil)
[ "$preproxy_node" != "nil" ] && {
local preproxy_node_address=$(config_n_get $preproxy_node address)
if [ -n "$preproxy_node_address" ]; then
filter_rules $preproxy_node $stream
else
preproxy_enabled=0
fi fi
} }
}
local default_node=$(config_n_get $proxy_node default_node _direct) filter_direct_node_list() {
if [ "$default_node" != "_direct" ] && [ "$default_node" != "_blackhole" ]; then [ ! -s "$TMP_PATH/direct_node_list" ] && return
local default_proxy_tag=$(config_n_get $proxy_node default_proxy_tag nil) for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do
[ "$default_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && default_proxy_tag="nil" filter_node "$_node_id" TCP
[ "$default_proxy_tag" == "nil" ] && filter_rules $default_node $stream filter_node "$_node_id" UDP
fi unset _node_id
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
for shunt_id in $shunt_ids; do
local shunt_node=$(config_n_get $proxy_node "${shunt_id}" nil)
[ "$shunt_node" == "nil" -o "$shunt_node" == "_default" -o "$shunt_node" == "_direct" -o "$shunt_node" == "_blackhole" ] && continue
local shunt_node_address=$(config_n_get $shunt_node address)
[ -z "$shunt_node_address" ] && continue
local shunt_proxy_tag=$(config_n_get $proxy_node "${shunt_id}_proxy_tag" nil)
[ "$shunt_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && shunt_proxy_tag="nil"
[ "$shunt_proxy_tag" == "nil" ] && filter_rules $shunt_node $stream
done done
else
#echolog " - 普通节点(${proxy_type}..."
filter_rules "$proxy_node" "$stream"
fi
} }
add_firewall_rule() { add_firewall_rule() {
echolog "开始加载防火墙规则..." echolog "开始加载防火墙规则..."
ipset -! create $IPSET_LOCALLIST nethash maxelem 1048576
ipset -! create $IPSET_LANLIST nethash maxelem 1048576 ipset -! create $IPSET_LANLIST nethash maxelem 1048576
ipset -! create $IPSET_VPSLIST nethash maxelem 1048576 ipset -! create $IPSET_VPSLIST nethash maxelem 1048576
ipset -! create $IPSET_SHUNTLIST nethash maxelem 1048576 timeout 172800 ipset -! create $IPSET_SHUNTLIST nethash maxelem 1048576 timeout 172800
@ -771,6 +718,7 @@ add_firewall_rule() {
ipset -! create $IPSET_WHITELIST nethash maxelem 1048576 timeout 172800 ipset -! create $IPSET_WHITELIST nethash maxelem 1048576 timeout 172800
ipset -! create $IPSET_BLOCKLIST nethash maxelem 1048576 timeout 172800 ipset -! create $IPSET_BLOCKLIST nethash maxelem 1048576 timeout 172800
ipset -! create $IPSET_LOCALLIST6 nethash family inet6 maxelem 1048576
ipset -! create $IPSET_LANLIST6 nethash family inet6 maxelem 1048576 ipset -! create $IPSET_LANLIST6 nethash family inet6 maxelem 1048576
ipset -! create $IPSET_VPSLIST6 nethash family inet6 maxelem 1048576 ipset -! create $IPSET_VPSLIST6 nethash family inet6 maxelem 1048576
ipset -! create $IPSET_SHUNTLIST6 nethash family inet6 maxelem 1048576 timeout 172800 ipset -! create $IPSET_SHUNTLIST6 nethash family inet6 maxelem 1048576 timeout 172800
@ -870,6 +818,14 @@ add_firewall_rule() {
fi fi
} }
ipset -! -R <<-EOF
$(ip address show | grep -w "inet" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/^/add $IPSET_LOCALLIST /")
EOF
ipset -! -R <<-EOF
$(ip address show | grep -w "inet6" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/^/add $IPSET_LOCALLIST6 /")
EOF
#局域网IP列表 #局域网IP列表
ipset -! -R <<-EOF ipset -! -R <<-EOF
$(gen_lanlist | sed -e "s/^/add $IPSET_LANLIST /") $(gen_lanlist | sed -e "s/^/add $IPSET_LANLIST /")
@ -943,8 +899,13 @@ add_firewall_rule() {
[ "${USE_DIRECT_LIST}" = "1" ] && $ipt_n -A PSW_OUTPUT $(dst $IPSET_WHITELIST) -j RETURN [ "${USE_DIRECT_LIST}" = "1" ] && $ipt_n -A PSW_OUTPUT $(dst $IPSET_WHITELIST) -j RETURN
$ipt_n -A PSW_OUTPUT -m mark --mark 0xff -j RETURN $ipt_n -A PSW_OUTPUT -m mark --mark 0xff -j RETURN
$ipt_n -N PSW_REDIRECT $ipt_n -N PSW_DNS
$ipt_n -I PREROUTING 1 -j PSW_REDIRECT if [ $(config_t_get global dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
$ipt_n -I PREROUTING $(dst $IPSET_LOCALLIST) -j PSW_DNS
else
$ipt_n -I PREROUTING 1 -j PSW_DNS
fi
$ipt_m -N PSW_DIVERT $ipt_m -N PSW_DIVERT
$ipt_m -A PSW_DIVERT -j MARK --set-mark 1 $ipt_m -A PSW_DIVERT -j MARK --set-mark 1
@ -1011,8 +972,13 @@ add_firewall_rule() {
$ip6t_n -A PSW_OUTPUT -m mark --mark 0xff -j RETURN $ip6t_n -A PSW_OUTPUT -m mark --mark 0xff -j RETURN
} }
$ip6t_n -N PSW_REDIRECT $ip6t_n -N PSW_DNS
$ip6t_n -I PREROUTING 1 -j PSW_REDIRECT if [ $(config_t_get global dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
$ip6t_n -I PREROUTING $(dst $IPSET_LOCALLIST6) -j PSW_DNS
else
$ip6t_n -I PREROUTING 1 -j PSW_DNS
fi
$ip6t_m -N PSW_DIVERT $ip6t_m -N PSW_DIVERT
$ip6t_m -A PSW_DIVERT -j MARK --set-mark 1 $ip6t_m -A PSW_DIVERT -j MARK --set-mark 1
@ -1048,43 +1014,7 @@ add_firewall_rule() {
[ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE [ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE
# 过滤Socks节点
[ "$SOCKS_ENABLED" = "1" ] && {
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
#echolog "分析 Socks 服务所使用节点..."
local id enabled node port msg num
for id in $ids; do
enabled=$(config_n_get $id enabled 0)
[ "$enabled" == "1" ] || continue
node=$(config_n_get $id node nil)
port=$(config_n_get $id port 0)
msg="Socks 服务 [:${port}]"
if [ "$node" == "nil" ] || [ "$port" == "0" ]; then
msg="${msg} 未配置完全,略过"
else
filter_node $node TCP > /dev/null 2>&1 &
filter_node $node UDP > /dev/null 2>&1 &
fi
#echolog " - ${msg}"
done
}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && { [ "$ENABLED_DEFAULT_ACL" == 1 ] && {
# 处理轮换节点的分流或套娃
local node port stream switch
for stream in TCP UDP; do
eval "node=\${${stream}_NODE}"
eval "port=\${${stream}_REDIR_PORT}"
#echolog "分析 $stream 代理自动切换..."
[ "$stream" == "UDP" ] && [ "$node" == "tcp" ] && {
eval "node=\${TCP_NODE}"
eval "port=\${TCP_REDIR_PORT}"
}
if [ "$node" != "nil" ] && [ "$(config_get_type $node nil)" != "nil" ]; then
filter_node $node $stream $port > /dev/null 2>&1 &
fi
done
local ipt_tmp=$ipt_n local ipt_tmp=$ipt_n
if [ -n "${is_tproxy}" ]; then if [ -n "${is_tproxy}" ]; then
ipt_tmp=$ipt_m ipt_tmp=$ipt_m
@ -1287,24 +1217,18 @@ add_firewall_rule() {
# 加载ACLS # 加载ACLS
load_acl load_acl
filter_direct_node_list
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do for iface in $(ls ${TMP_IFACE_PATH}); do
$ipt_n -I PSW_OUTPUT -o $iface -j RETURN $ipt_n -I PSW_OUTPUT -o $iface -j RETURN
$ipt_m -I PSW_OUTPUT -o $iface -j RETURN $ipt_m -I PSW_OUTPUT -o $iface -j RETURN
done done
}
$ipt_n -I PREROUTING $(comment "PSW") -m mark --mark 1 -j RETURN $ipt_n -I PREROUTING $(comment "PSW") -m mark --mark 1 -j RETURN
$ip6t_n -I PREROUTING $(comment "PSW") -m mark --mark 1 -j RETURN $ip6t_n -I PREROUTING $(comment "PSW") -m mark --mark 1 -j RETURN
[ -n "${is_tproxy}" -o -n "${udp_flag}" ] && {
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
echo -n $bridge_nf_ipt > $TMP_PATH/bridge_nf_ipt
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
[ "$PROXY_IPV6" == "1" ] && {
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
echo -n $bridge_nf_ip6t > $TMP_PATH/bridge_nf_ip6t
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
}
}
echolog "防火墙规则加载完成!" echolog "防火墙规则加载完成!"
} }
@ -1316,7 +1240,7 @@ del_firewall_rule() {
$ipt -D $chain $index 2>/dev/null $ipt -D $chain $index 2>/dev/null
done done
done done
for chain in "PSW" "PSW_OUTPUT" "PSW_DIVERT" "PSW_REDIRECT" "PSW_RULE"; do for chain in "PSW" "PSW_OUTPUT" "PSW_DIVERT" "PSW_DNS" "PSW_RULE"; do
$ipt -F $chain 2>/dev/null $ipt -F $chain 2>/dev/null
$ipt -X $chain 2>/dev/null $ipt -X $chain 2>/dev/null
done done
@ -1328,6 +1252,7 @@ del_firewall_rule() {
ip -6 rule del fwmark 1 table 100 2>/dev/null ip -6 rule del fwmark 1 table 100 2>/dev/null
ip -6 route del local ::/0 dev lo table 100 2>/dev/null ip -6 route del local ::/0 dev lo table 100 2>/dev/null
destroy_ipset $IPSET_LOCALLIST
destroy_ipset $IPSET_LANLIST destroy_ipset $IPSET_LANLIST
destroy_ipset $IPSET_VPSLIST destroy_ipset $IPSET_VPSLIST
destroy_ipset $IPSET_SHUNTLIST destroy_ipset $IPSET_SHUNTLIST
@ -1337,6 +1262,7 @@ del_firewall_rule() {
destroy_ipset $IPSET_BLOCKLIST destroy_ipset $IPSET_BLOCKLIST
destroy_ipset $IPSET_WHITELIST destroy_ipset $IPSET_WHITELIST
destroy_ipset $IPSET_LOCALLIST6
destroy_ipset $IPSET_LANLIST6 destroy_ipset $IPSET_LANLIST6
destroy_ipset $IPSET_VPSLIST6 destroy_ipset $IPSET_VPSLIST6
destroy_ipset $IPSET_SHUNTLIST6 destroy_ipset $IPSET_SHUNTLIST6
@ -1498,6 +1424,9 @@ get_wan_ip)
get_wan6_ip) get_wan6_ip)
get_wan6_ip get_wan6_ip
;; ;;
filter_direct_node_list)
filter_direct_node_list
;;
stop) stop)
stop stop
;; ;;

View File

@ -3,6 +3,7 @@
DIR="$(cd "$(dirname "$0")" && pwd)" DIR="$(cd "$(dirname "$0")" && pwd)"
MY_PATH=$DIR/nftables.sh MY_PATH=$DIR/nftables.sh
NFTABLE_NAME="inet passwall" NFTABLE_NAME="inet passwall"
NFTSET_LOCALLIST="passwall_locallist"
NFTSET_LANLIST="passwall_lanlist" NFTSET_LANLIST="passwall_lanlist"
NFTSET_VPSLIST="passwall_vpslist" NFTSET_VPSLIST="passwall_vpslist"
NFTSET_SHUNTLIST="passwall_shuntlist" NFTSET_SHUNTLIST="passwall_shuntlist"
@ -12,6 +13,7 @@ NFTSET_BLACKLIST="passwall_blacklist"
NFTSET_WHITELIST="passwall_whitelist" NFTSET_WHITELIST="passwall_whitelist"
NFTSET_BLOCKLIST="passwall_blocklist" NFTSET_BLOCKLIST="passwall_blocklist"
NFTSET_LOCALLIST6="passwall_locallist6"
NFTSET_LANLIST6="passwall_lanlist6" NFTSET_LANLIST6="passwall_lanlist6"
NFTSET_VPSLIST6="passwall_vpslist6" NFTSET_VPSLIST6="passwall_vpslist6"
NFTSET_SHUNTLIST6="passwall_shuntlist6" NFTSET_SHUNTLIST6="passwall_shuntlist6"
@ -272,11 +274,11 @@ load_acl() {
[ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS [ "$tcp_redir_ports" = "default" ] && tcp_redir_ports=$TCP_REDIR_PORTS
[ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS [ "$udp_redir_ports" = "default" ] && udp_redir_ports=$UDP_REDIR_PORTS
[ -s "${TMP_ACL_PATH}/${sid}/var_tcp_node" ] && tcp_node=$(cat ${TMP_ACL_PATH}/${sid}/var_tcp_node) [ -n "$(get_cache_var "ACL_${sid}_tcp_node")" ] && tcp_node=$(get_cache_var "ACL_${sid}_tcp_node")
[ -s "${TMP_ACL_PATH}/${sid}/var_udp_node" ] && udp_node=$(cat ${TMP_ACL_PATH}/${sid}/var_udp_node) [ -n "$(get_cache_var "ACL_${sid}_udp_node")" ] && udp_node=$(get_cache_var "ACL_${sid}_udp_node")
[ -s "${TMP_ACL_PATH}/${sid}/var_tcp_port" ] && tcp_port=$(cat ${TMP_ACL_PATH}/${sid}/var_tcp_port) [ -n "$(get_cache_var "ACL_${sid}_tcp_port")" ] && tcp_port=$(get_cache_var "ACL_${sid}_tcp_port")
[ -s "${TMP_ACL_PATH}/${sid}/var_udp_port" ] && udp_port=$(cat ${TMP_ACL_PATH}/${sid}/var_udp_port) [ -n "$(get_cache_var "ACL_${sid}_udp_port")" ] && udp_port=$(get_cache_var "ACL_${sid}_udp_port")
[ -s "${TMP_ACL_PATH}/${sid}/var_redirect_dns_port" ] && dns_redirect_port=$(cat ${TMP_ACL_PATH}/${sid}/var_redirect_dns_port) [ -n "$(get_cache_var "ACL_${sid}_dns_port")" ] && dns_redirect_port=$(get_cache_var "ACL_${sid}_dns_port")
use_shunt_tcp=0 use_shunt_tcp=0
use_shunt_udp=0 use_shunt_udp=0
@ -371,22 +373,22 @@ load_acl() {
fi fi
} }
local dns_redirect
[ $(config_t_get global dns_redirect "1") = "1" ] && dns_redirect=53
if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then if ([ -n "$tcp_port" ] && [ -n "${tcp_proxy_mode}" ]) || ([ -n "$udp_port" ] && [ -n "${udp_proxy_mode}" ]); then
[ -n "$dns_redirect_port" ] && { [ -n "${dns_redirect_port}" ] && dns_redirect=${dns_redirect_port}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && dns_redirect=${DIRECT_DNSMASQ_PORT}
fi
if [ -n "${dns_redirect}" ]; then
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp ${_ipt_source} udp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp ${_ipt_source} tcp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp ${_ipt_source} udp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :$dns_redirect_port comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp ${_ipt_source} tcp dport 53 counter redirect to :${dns_redirect} comment \"$remarks\""
}
else
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto udp ${_ipt_source} udp dport 53 counter return comment \"$remarks\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto tcp ${_ipt_source} tcp dport 53 counter return comment \"$remarks\""
fi fi
[ -n "$tcp_port" -o -n "$udp_port" ] && { [ -n "$tcp_port" -o -n "$udp_port" ] && {
@ -524,7 +526,7 @@ load_acl() {
unset nft_chain nft_j _ipt_source msg msg2 unset nft_chain nft_j _ipt_source msg msg2
done done
unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface unset enabled sid remarks sources use_global_config use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode dns_redirect_port tcp_no_redir_ports udp_no_redir_ports tcp_proxy_drop_ports udp_proxy_drop_ports tcp_redir_ports udp_redir_ports tcp_node udp_node interface
unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp unset tcp_port udp_port tcp_node_remark udp_node_remark _acl_list use_shunt_tcp use_shunt_udp dns_redirect
done done
} }
@ -552,17 +554,23 @@ load_acl() {
fi fi
} }
local DNS_REDIRECT
[ $(config_t_get global dns_redirect "1") = "1" ] && DNS_REDIRECT=53
if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then if ([ "$TCP_NODE" != "nil" ] && [ -n "${TCP_PROXY_MODE}" ]) || ([ "$UDP_NODE" != "nil" ] && [ -n "${UDP_PROXY_MODE}" ]); then
[ -n "$DNS_REDIRECT_PORT" ] && { [ -n "${DNS_REDIRECT_PORT}" ] && DNS_REDIRECT=${DNS_REDIRECT_PORT}
else
[ -n "${DIRECT_DNSMASQ_PORT}" ] && DNS_REDIRECT=${DIRECT_DNSMASQ_PORT}
fi
if [ -n "${DNS_REDIRECT}" ]; then
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp udp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol udp udp dport 53 counter return comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp udp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto udp udp dport 53 counter return comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp tcp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE ip protocol tcp tcp dport 53 counter return comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp tcp dport 53 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_MANGLE_V6 meta l4proto tcp tcp dport 53 counter return comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_DNS ip protocol udp udp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT ip protocol tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_DNS ip protocol tcp tcp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto udp udp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto udp udp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\""
nft "add rule $NFTABLE_NAME PSW_REDIRECT meta l4proto tcp tcp dport 53 counter redirect to :$DNS_REDIRECT_PORT comment \"默认\"" nft "add rule $NFTABLE_NAME PSW_DNS meta l4proto tcp tcp dport 53 counter redirect to :${DNS_REDIRECT} comment \"默认\""
}
fi fi
[ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && { [ -n "${TCP_PROXY_MODE}" -o -n "${UDP_PROXY_MODE}" ] && {
@ -694,7 +702,6 @@ load_acl() {
} }
echolog " - ${msg2}" echolog " - ${msg2}"
udp_flag=1
} }
fi fi
} }
@ -724,107 +731,46 @@ filter_vpsip() {
echolog " - [$?]加入所有IPv6节点到nftset[$NFTSET_VPSLIST6]直连完成" echolog " - [$?]加入所有IPv6节点到nftset[$NFTSET_VPSLIST6]直连完成"
} }
filter_node() { filter_server_port() {
local proxy_node=${1} local address=${1}
local stream=$(echo ${2} | tr 'A-Z' 'a-z') local port=${2}
local proxy_port=${3} local stream=${3}
stream=$(echo ${3} | tr 'A-Z' 'a-z')
local _is_tproxy
_is_tproxy=${is_tproxy}
[ "$stream" == "udp" ] && _is_tproxy="TPROXY"
filter_rules() { for _ipt in 4 6; do
[ "$_ipt" == "4" ] && _ip_type=ip
[ "$_ipt" == "6" ] && _ip_type=ip6
nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}"
if [ $? -ne 0 ]; then
nft "insert rule $NFTABLE_NAME $nft_output_chain meta l4proto $stream $_ip_type daddr $address $stream dport $port return comment \"${address}:${port}\"" 2>/dev/null
fi
done
}
filter_node() {
local node=${1} local node=${1}
local stream=${2} local stream=${2}
local _proxy=${3}
local _port=${4}
local _is_tproxy msg msg2
if [ -n "$node" ] && [ "$node" != "nil" ]; then if [ -n "$node" ] && [ "$node" != "nil" ]; then
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local address=$(config_n_get $node address) local address=$(config_n_get $node address)
local port=$(config_n_get $node port) local port=$(config_n_get $node port)
[ -z "$address" ] && [ -z "$port" ] && { [ -z "$address" ] && [ -z "$port" ] && {
echolog " - 节点配置不正常,略过"
return 1 return 1
} }
_is_tproxy=${is_tproxy} filter_server_port $address $port $stream
[ "$stream" == "udp" ] && _is_tproxy="TPROXY" filter_server_port $address $port $stream
if [ -n "${_is_tproxy}" ]; then
msg="TPROXY"
else
msg="REDIRECT"
fi fi
else
echolog " - 节点配置不正常,略过"
return 1
fi
local ADD_INDEX=$FORCE_INDEX
for _ipt in 4 6; do
[ "$_ipt" == "4" ] && _ip_type=ip && _set_name=$NFTSET_VPSLIST
[ "$_ipt" == "6" ] && _ip_type=ip6 && _set_name=$NFTSET_VPSLIST6
nft "list chain $NFTABLE_NAME $nft_output_chain" 2>/dev/null | grep -q "${address}:${port}"
if [ $? -ne 0 ]; then
local dst_rule="jump PSW_RULE"
msg2="按规则路由(${msg})"
[ -n "${is_tproxy}" ] || {
dst_rule=$(REDIRECT $_port)
msg2="套娃使用(${msg}:${port} -> ${_port})"
}
[ -n "$_proxy" ] && [ "$_proxy" == "1" ] && [ -n "$_port" ] || {
ADD_INDEX=$(RULE_LAST_INDEX "$NFTABLE_NAME" $nft_output_chain $_set_name $FORCE_INDEX)
dst_rule="return"
msg2="直连代理"
}
nft "insert rule $NFTABLE_NAME $nft_output_chain position $ADD_INDEX meta l4proto $stream $_ip_type daddr $address $stream dport $port $dst_rule comment \"${address}:${port}\"" 2>/dev/null
else
msg2="已配置过的节点,"
fi
done
msg="[$?]$(echo ${2} | tr 'a-z' 'A-Z')${msg2}使用链${ADD_INDEX},节点(${type}${address}:${port}"
#echolog " - ${msg}"
} }
local proxy_protocol=$(config_n_get $proxy_node protocol) filter_direct_node_list() {
local proxy_type=$(echo $(config_n_get $proxy_node type nil) | tr 'A-Z' 'a-z') [ ! -s "$TMP_PATH/direct_node_list" ] && return
[ "$proxy_type" == "nil" ] && echolog " - 节点配置不正常,略过!:${proxy_node}" && return 1 for _node_id in $(cat $TMP_PATH/direct_node_list | awk '!seen[$0]++'); do
if [ "$proxy_protocol" == "_balancing" ]; then filter_node "$_node_id" TCP
#echolog " - 多节点负载均衡(${proxy_type}..." filter_node "$_node_id" UDP
proxy_node=$(config_n_get $proxy_node balancing_node) unset _node_id
for _node in $proxy_node; do
filter_rules "$_node" "$stream"
done done
elif [ "$proxy_protocol" == "_shunt" ]; then
#echolog " - 按请求目的地址分流(${proxy_type}..."
local preproxy_enabled=$(config_n_get $proxy_node preproxy_enabled 0)
[ "$preproxy_enabled" == "1" ] && {
local preproxy_node=$(config_n_get $proxy_node main_node nil)
[ "$preproxy_node" != "nil" ] && {
local preproxy_node_address=$(config_n_get $preproxy_node address)
if [ -n "$preproxy_node_address" ]; then
filter_rules $preproxy_node $stream
else
preproxy_enabled=0
fi
}
}
local default_node=$(config_n_get $proxy_node default_node _direct)
if [ "$default_node" != "_direct" ] && [ "$default_node" != "_blackhole" ]; then
local default_proxy_tag=$(config_n_get $proxy_node default_proxy_tag nil)
[ "$default_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && default_proxy_tag="nil"
[ "$default_proxy_tag" == "nil" ] && filter_rules $default_node $stream
fi
local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
for shunt_id in $shunt_ids; do
local shunt_node=$(config_n_get $proxy_node "${shunt_id}" nil)
[ "$shunt_node" == "nil" -o "$shunt_node" == "_default" -o "$shunt_node" == "_direct" -o "$shunt_node" == "_blackhole" ] && continue
local shunt_node_address=$(config_n_get $shunt_node address)
[ -z "$shunt_node_address" ] && continue
local shunt_proxy_tag=$(config_n_get $proxy_node "${shunt_id}_proxy_tag" nil)
[ "$shunt_proxy_tag" == "main" ] && [ "$preproxy_enabled" == "0" ] && shunt_proxy_tag="nil"
[ "$shunt_proxy_tag" == "nil" ] && filter_rules $shunt_node $stream
done
else
#echolog " - 普通节点(${proxy_type}..."
filter_rules "$proxy_node" "$stream"
fi
} }
add_firewall_rule() { add_firewall_rule() {
@ -832,6 +778,7 @@ add_firewall_rule() {
gen_nft_tables gen_nft_tables
gen_nftset $NFTSET_VPSLIST ipv4_addr 0 0 gen_nftset $NFTSET_VPSLIST ipv4_addr 0 0
gen_nftset $NFTSET_GFW ipv4_addr "2d" 0 gen_nftset $NFTSET_GFW ipv4_addr "2d" 0
gen_nftset $NFTSET_LOCALLIST ipv4_addr 0 "-1"
gen_nftset $NFTSET_LANLIST ipv4_addr 0 "-1" $(gen_lanlist) gen_nftset $NFTSET_LANLIST ipv4_addr 0 "-1" $(gen_lanlist)
if [ -f $RULES_PATH/chnroute.nft ] && [ -s $RULES_PATH/chnroute.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute.nft) -ge 8 ]; then if [ -f $RULES_PATH/chnroute.nft ] && [ -s $RULES_PATH/chnroute.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute.nft) -ge 8 ]; then
#echolog "使用缓存加载chnroute..." #echolog "使用缓存加载chnroute..."
@ -846,6 +793,7 @@ add_firewall_rule() {
gen_nftset $NFTSET_VPSLIST6 ipv6_addr 0 0 gen_nftset $NFTSET_VPSLIST6 ipv6_addr 0 0
gen_nftset $NFTSET_GFW6 ipv6_addr "2d" 0 gen_nftset $NFTSET_GFW6 ipv6_addr "2d" 0
gen_nftset $NFTSET_LOCALLIST6 ipv6_addr 0 "-1"
gen_nftset $NFTSET_LANLIST6 ipv6_addr 0 "-1" $(gen_lanlist_6) gen_nftset $NFTSET_LANLIST6 ipv6_addr 0 "-1" $(gen_lanlist_6)
if [ -f $RULES_PATH/chnroute6.nft ] && [ -s $RULES_PATH/chnroute6.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute6.nft) -ge 8 ]; then if [ -f $RULES_PATH/chnroute6.nft ] && [ -s $RULES_PATH/chnroute6.nft ] && [ $(awk 'END{print NR}' $RULES_PATH/chnroute6.nft) -ge 8 ]; then
#echolog "使用缓存加载chnroute6..." #echolog "使用缓存加载chnroute6..."
@ -945,6 +893,9 @@ add_firewall_rule() {
fi fi
} }
insert_nftset $NFTSET_LOCALLIST "-1" $(ip address show | grep -w "inet" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/ /\n/g")
insert_nftset $NFTSET_LOCALLIST6 "-1" $(ip address show | grep -w "inet6" | awk '{print $2}' | awk -F '/' '{print $1}' | sed -e "s/ /\n/g")
# 忽略特殊IP段 # 忽略特殊IP段
local lan_ifname lan_ip local lan_ifname lan_ip
lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname) lan_ifname=$(uci -q -p /tmp/state get network.lan.ifname)
@ -999,9 +950,15 @@ add_firewall_rule() {
nft "flush chain $NFTABLE_NAME PSW_DIVERT" nft "flush chain $NFTABLE_NAME PSW_DIVERT"
nft "add rule $NFTABLE_NAME PSW_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept" nft "add rule $NFTABLE_NAME PSW_DIVERT meta l4proto tcp socket transparent 1 mark set 1 counter accept"
nft "add chain $NFTABLE_NAME PSW_REDIRECT" nft "add chain $NFTABLE_NAME PSW_DNS"
nft "flush chain $NFTABLE_NAME PSW_REDIRECT" nft "flush chain $NFTABLE_NAME PSW_DNS"
nft "add rule $NFTABLE_NAME dstnat jump PSW_REDIRECT" if [ $(config_t_get global dns_redirect "1") = "0" ]; then
#Only hijack when dest address is local IP
nft "insert rule $NFTABLE_NAME dstnat ip daddr @${NFTSET_LOCALLIST} jump PSW_DNS"
nft "insert rule $NFTABLE_NAME dstnat ip6 daddr @${NFTSET_LOCALLIST6} jump PSW_DNS"
else
nft "insert rule $NFTABLE_NAME dstnat jump PSW_DNS"
fi
# for ipv4 ipv6 tproxy mark # for ipv4 ipv6 tproxy mark
nft "add chain $NFTABLE_NAME PSW_RULE" nft "add chain $NFTABLE_NAME PSW_RULE"
@ -1122,43 +1079,7 @@ add_firewall_rule() {
[ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE [ "$TCP_UDP" = "1" ] && [ "$UDP_NODE" = "nil" ] && UDP_NODE=$TCP_NODE
# 过滤Socks节点
[ "$SOCKS_ENABLED" = "1" ] && {
local ids=$(uci show $CONFIG | grep "=socks" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}')
#echolog "分析 Socks 服务所使用节点..."
local id enabled node port msg num
for id in $ids; do
enabled=$(config_n_get $id enabled 0)
[ "$enabled" == "1" ] || continue
node=$(config_n_get $id node nil)
port=$(config_n_get $id port 0)
msg="Socks 服务 [:${port}]"
if [ "$node" == "nil" ] || [ "$port" == "0" ]; then
msg="${msg} 未配置完全,略过"
else
filter_node $node TCP > /dev/null 2>&1 &
filter_node $node UDP > /dev/null 2>&1 &
fi
#echolog " - ${msg}"
done
}
[ "$ENABLED_DEFAULT_ACL" == 1 ] && { [ "$ENABLED_DEFAULT_ACL" == 1 ] && {
# 处理轮换节点的分流或套娃
local node port stream switch
for stream in TCP UDP; do
eval "node=\${${stream}_NODE}"
eval "port=\${${stream}_REDIR_PORT}"
#echolog "分析 $stream 代理自动切换..."
[ "$stream" == "UDP" ] && [ "$node" == "tcp" ] && {
eval "node=\${TCP_NODE}"
eval "port=\${TCP_REDIR_PORT}"
}
if [ "$node" != "nil" ] && [ "$(config_get_type $node nil)" != "nil" ]; then
filter_node $node $stream $port > /dev/null 2>&1 &
fi
done
msg="【路由器本机】," msg="【路由器本机】,"
[ "$TCP_NO_REDIR_PORTS" != "disable" ] && { [ "$TCP_NO_REDIR_PORTS" != "disable" ] && {
@ -1354,21 +1275,15 @@ add_firewall_rule() {
# 加载ACLS # 加载ACLS
load_acl load_acl
filter_direct_node_list
[ -d "${TMP_IFACE_PATH}" ] && {
for iface in $(ls ${TMP_IFACE_PATH}); do for iface in $(ls ${TMP_IFACE_PATH}); do
nft "insert rule $NFTABLE_NAME $nft_output_chain oif $iface counter return" nft "insert rule $NFTABLE_NAME $nft_output_chain oif $iface counter return"
nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 oif $iface counter return" nft "insert rule $NFTABLE_NAME PSW_OUTPUT_MANGLE_V6 oif $iface counter return"
done done
}
[ -n "${is_tproxy}" -o -n "${udp_flag}" ] && {
bridge_nf_ipt=$(sysctl -e -n net.bridge.bridge-nf-call-iptables)
echo -n $bridge_nf_ipt > $TMP_PATH/bridge_nf_ipt
sysctl -w net.bridge.bridge-nf-call-iptables=0 >/dev/null 2>&1
[ "$PROXY_IPV6" == "1" ] && {
bridge_nf_ip6t=$(sysctl -e -n net.bridge.bridge-nf-call-ip6tables)
echo -n $bridge_nf_ip6t > $TMP_PATH/bridge_nf_ip6t
sysctl -w net.bridge.bridge-nf-call-ip6tables=0 >/dev/null 2>&1
}
}
echolog "防火墙规则加载完成!" echolog "防火墙规则加载完成!"
} }
@ -1393,6 +1308,7 @@ del_firewall_rule() {
ip -6 rule del fwmark 1 table 100 2>/dev/null ip -6 rule del fwmark 1 table 100 2>/dev/null
ip -6 route del local ::/0 dev lo table 100 2>/dev/null ip -6 route del local ::/0 dev lo table 100 2>/dev/null
destroy_nftset $NFTSET_LOCALLIST
destroy_nftset $NFTSET_LANLIST destroy_nftset $NFTSET_LANLIST
destroy_nftset $NFTSET_VPSLIST destroy_nftset $NFTSET_VPSLIST
destroy_nftset $NFTSET_SHUNTLIST destroy_nftset $NFTSET_SHUNTLIST
@ -1402,6 +1318,7 @@ del_firewall_rule() {
destroy_nftset $NFTSET_BLOCKLIST destroy_nftset $NFTSET_BLOCKLIST
destroy_nftset $NFTSET_WHITELIST destroy_nftset $NFTSET_WHITELIST
destroy_nftset $NFTSET_LOCALLIST6
destroy_nftset $NFTSET_LANLIST6 destroy_nftset $NFTSET_LANLIST6
destroy_nftset $NFTSET_VPSLIST6 destroy_nftset $NFTSET_VPSLIST6
destroy_nftset $NFTSET_SHUNTLIST6 destroy_nftset $NFTSET_SHUNTLIST6
@ -1513,6 +1430,9 @@ get_wan_ip)
get_wan6_ip) get_wan6_ip)
get_wan6_ip get_wan6_ip
;; ;;
filter_direct_node_list)
filter_direct_node_list
;;
stop) stop)
stop stop
;; ;;

View File

@ -82,9 +82,8 @@ test_auto_switch() {
local b_nodes=$1 local b_nodes=$1
local now_node=$2 local now_node=$2
[ -z "$now_node" ] && { [ -z "$now_node" ] && {
local f="/tmp/etc/$CONFIG/id/socks_${id}" if [ -n "$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")" ]; then
if [ -f "${f}" ]; then now_node=$(/usr/share/${CONFIG}/app.sh get_cache_var "socks_${id}")
now_node=$(cat ${f})
else else
#echolog "自动切换检测:未知错误" #echolog "自动切换检测:未知错误"
return 1 return 1

View File

@ -327,6 +327,23 @@ do
} }
end end
else else
--前置代理节点
local currentNode = uci:get_all(appname, node_id) or nil
if currentNode and currentNode.preproxy_node then
CONFIG[#CONFIG + 1] = {
log = true,
id = node_id,
remarks = "节点[" .. node_id .. "]前置代理节点",
currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil,
set = function(o, server)
uci:set(appname, node_id, "preproxy_node", server)
o.newNodeId = server
end,
delete = function(o)
uci:delete(appname, node_id, "preproxy_node")
end
}
end
--落地节点 --落地节点
local currentNode = uci:get_all(appname, node_id) or nil local currentNode = uci:get_all(appname, node_id) or nil
if currentNode and currentNode.to_node then if currentNode and currentNode.to_node then

View File

@ -1,5 +1,5 @@
diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile
index fa1cd41..eac8656 100644 index 2b72468..15c6437 100644
--- a/luci-app-passwall/Makefile --- a/luci-app-passwall/Makefile
+++ b/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile
@@ -144,7 +144,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata @@ -144,7 +144,7 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata
@ -20,7 +20,7 @@ index fa1cd41..eac8656 100644
define Package/$(PKG_NAME)/postrm define Package/$(PKG_NAME)/postrm
diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua
index 02ce26c..83cbafc 100644 index 33c5319..6ddcdfd 100644
--- a/luci-app-passwall/luasrc/controller/passwall.lua --- a/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua
@@ -279,7 +279,7 @@ function connect_status() @@ -279,7 +279,7 @@ function connect_status()
@ -33,7 +33,7 @@ index 02ce26c..83cbafc 100644
if code ~= 0 then if code ~= 0 then
local use_time = luci.sys.exec("echo -n '" .. result .. "' | awk -F ':' '{print $2}'") 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 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 d766646..e5d6a46 100644 index 488cd50..541167f 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -467,6 +467,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)")
@ -49,44 +49,8 @@ index d766646..e5d6a46 100644
o:depends({dns_mode = "dns2socks"}) o:depends({dns_mode = "dns2socks"})
o:depends({dns_mode = "tcp"}) o:depends({dns_mode = "tcp"})
o:depends({dns_mode = "udp"}) o:depends({dns_mode = "udp"})
diff --git a/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm b/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm
index 739c593..3769e7d 100644
--- a/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm
+++ b/luci-app-passwall/luasrc/view/passwall/app_update/app_version.htm
@@ -180,12 +180,12 @@ local version = {}
<div class="cbi-value">
<label class="cbi-value-title">Passwall <%:Version%></label>
<div class="cbi-value-field">
- <div class="cbi-value-description">
+ <!--div class="cbi-value-description"-->
<span>【 <%=api.get_version()%> 】</span>
<input class="btn cbi-button cbi-button-apply" type="button" id="passwall-check_btn"
onclick="onBtnClick(this,'passwall');" value="<%:Check update%>" />
<span id="passwall-check_btn-detail"></span>
- </div>
+ <!--/div-->
</div>
</div>
@@ -196,14 +196,14 @@ local version = {}
<%:Version%>
</label>
<div class="cbi-value-field">
- <div class="cbi-value-description">
+ <!--div class="cbi-value-description"-->
<span>【 <%=version[k] ~="" and version[k] or translate("Null") %> 】</span>
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-check_btn"
onclick="onBtnClick(this,'<%=k%>');" value="<%:Check update%>" />
<input class="btn cbi-button cbi-button-apply" type="button" id="_<%=k%>-force_btn"
onclick="doUpdate(this,'<%=k%>');" value="<%:Force update%>" style="display:none"/>
<span id="_<%=k%>-check_btn-detail"></span>
- </div>
+ <!--/div-->
</div>
</div>
<%end%>
diff --git a/luci-app-passwall/luasrc/view/passwall/global/status.htm b/luci-app-passwall/luasrc/view/passwall/global/status.htm diff --git a/luci-app-passwall/luasrc/view/passwall/global/status.htm b/luci-app-passwall/luasrc/view/passwall/global/status.htm
index 00f79ff..452d369 100644 index e8d76ec..a872950 100644
--- a/luci-app-passwall/luasrc/view/passwall/global/status.htm --- a/luci-app-passwall/luasrc/view/passwall/global/status.htm
+++ b/luci-app-passwall/luasrc/view/passwall/global/status.htm +++ b/luci-app-passwall/luasrc/view/passwall/global/status.htm
@@ -1,5 +1,11 @@ @@ -1,5 +1,11 @@
@ -101,13 +65,13 @@ index 00f79ff..452d369 100644
-%> -%>
<style> <style>
@@ -52,7 +58,29 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md @@ -53,8 +59,30 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
color:#8898aa!important;
line-height: 1.8em; line-height: 1.8em;
min-height: 48px; min-height: 48px;
border-radius: 12.375px;
+ background-image: linear-gradient(270deg, #dde2ff 0%, #fffeff 100%); + background-image: linear-gradient(270deg, #dde2ff 0%, #fffeff 100%);
+ border-radius: 12.375px;
} }
+ @media (prefers-color-scheme: dark) { + @media (prefers-color-scheme: dark) {
+ .block h4 { + .block h4 {
+ background-image: none; + background-image: none;
@ -128,10 +92,11 @@ index 00f79ff..452d369 100644
+ box-shadow: unset; + box-shadow: unset;
+ } + }
+ <% end -%> + <% end -%>
+
.check { .check {
cursor: pointer; cursor: pointer;
@@ -137,7 +165,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md }
@@ -138,7 +166,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
</div> </div>
</div> </div>
</div> </div>
@ -140,7 +105,7 @@ index 00f79ff..452d369 100644
<div class="block pure-g"> <div class="block pure-g">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="img-con"> <div class="img-con">
@@ -149,7 +177,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md @@ -150,7 +178,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
</div> </div>
</div> </div>
</div> </div>
@ -149,7 +114,7 @@ index 00f79ff..452d369 100644
<div class="block pure-g"> <div class="block pure-g">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="img-con"> <div class="img-con">
@@ -161,7 +189,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md @@ -162,7 +190,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
</div> </div>
</div> </div>
</div> </div>
@ -158,7 +123,7 @@ index 00f79ff..452d369 100644
<div class="block pure-g"> <div class="block pure-g">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="img-con"> <div class="img-con">
@@ -173,7 +201,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md @@ -174,7 +202,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
</div> </div>
</div> </div>
</div> </div>
@ -167,37 +132,11 @@ index 00f79ff..452d369 100644
<div class="block pure-g"> <div class="block pure-g">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="img-con"> <div class="img-con">
diff --git a/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
index dfc11d9..0778566 100644
--- a/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
+++ b/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
@@ -26,7 +26,7 @@ table td, .table .td {
}
._now_use {
- background: #94e1ff !important;
+ background: #5e72e445 !important;
}
.ping a:hover{
diff --git a/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
index 24662de..77b6a0b 100644
--- a/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
+++ b/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
@@ -70,7 +70,7 @@ local geosite_update = api.uci_get_type("global_rules", "geosite_update", "1") =
<input class="cbi-input-checkbox" type="checkbox" name="geosite" value="1" <%=geosite_update%> />
geosite
</label>
- <input class="btn cbi-button cbi-button-apply" type="button" id="update_rules_btn" onclick="update_rules(this)" value="<%:Manually update%>" />
+ <br><br><input class="btn cbi-button cbi-button-apply" type="button" id="update_rules_btn" onclick="update_rules(this)" value="<%:Manually update%>" />
</div>
</div>
</div>
diff --git a/luci-app-passwall/root/usr/share/passwall/0_default_config b/luci-app-passwall/root/usr/share/passwall/0_default_config diff --git a/luci-app-passwall/root/usr/share/passwall/0_default_config b/luci-app-passwall/root/usr/share/passwall/0_default_config
index 918aaa4..4b20280 100644 index 8348217..19b16b7 100644
--- a/luci-app-passwall/root/usr/share/passwall/0_default_config --- a/luci-app-passwall/root/usr/share/passwall/0_default_config
+++ b/luci-app-passwall/root/usr/share/passwall/0_default_config +++ b/luci-app-passwall/root/usr/share/passwall/0_default_config
@@ -33,7 +33,7 @@ config global_haproxy @@ -34,7 +34,7 @@ config global_haproxy
config global_delay config global_delay
option auto_on '0' option auto_on '0'
option start_daemon '1' option start_daemon '1'