update 2026-08-24 00:17:56
marry-jell / merge (push) Canceled after 0s

This commit is contained in:
action committed 2026-08-24 00:17:56 +08:00
1 parent 2029d6e764
commit 77391c5efa
13 files changed
+97 -114

No files matched your search

@@ -172,6 +172,7 @@ o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")") o:value("", translate("Use global config") .. "(" .. UDP_NO_REDIR_PORTS .. ")")
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("1:52,54:442,444:65535", translatef("Forward only %s", "53, 443"))
o:depends("mode", "1") o:depends("mode", "1")
o.validate = port_validate o.validate = port_validate
@@ -74,6 +74,7 @@ o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
o.default = "disable" o.default = "disable"
o:value("disable", translate("No patterns are used")) o:value("disable", translate("No patterns are used"))
o:value("1:65535", translate("All")) o:value("1:65535", translate("All"))
o:value("1:52,54:442,444:65535", translatef("Forward only %s", "53, 443"))
o.validate = port_validate o.validate = port_validate
---- TCP Proxy Drop Ports ---- TCP Proxy Drop Ports
@@ -30,6 +30,16 @@ for i, v in ipairs(user_list) do
end end
o:depends({ auth = true }) o:depends({ auth = true })
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0"
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ firewall_allow = true })
o = s:option(Flag, "log", translate("Log")) o = s:option(Flag, "log", translate("Log"))
o.default = "1" o.default = "1"
@@ -456,9 +456,16 @@ if singbox_tags:find("with_wireguard") then
o:depends({ protocol = "wireguard" }) o:depends({ protocol = "wireguard" })
end end
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0" o.default = "0"
o:depends({ custom = false, is_endpoint = "" }) o:depends({ custom = false })
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ custom = false, firewall_allow = true })
o = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) o = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0" o.default = "0"
@@ -468,10 +468,17 @@ o = s:option(DummyValue, "gen_wireguard_key")
o.template = m:template_path("/server/gen_wireguard_key") o.template = m:template_path("/server/gen_wireguard_key")
o:depends({ protocol = "wireguard" }) o:depends({ protocol = "wireguard" })
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost.")) o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0" o.default = "0"
o:depends({ custom = false }) o:depends({ custom = false })
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ custom = false, firewall_allow = true })
o = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!")) o = s:option(Flag, "accept_lan", translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0" o.default = "0"
o:depends({ custom = false }) o:depends({ custom = false })
@@ -72,6 +72,17 @@ o = s:option(Flag, "tcp_fast_open", "TCP " .. translate("Fast Open"))
o.default = "0" o.default = "0"
o:depends({ custom = false }) o:depends({ custom = false })
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0"
o:depends({ custom = false })
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ custom = false, firewall_allow = true })
o = s:option(Flag, "log", translate("Log")) o = s:option(Flag, "log", translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
@@ -103,6 +103,17 @@ o = s:option(Flag, "udp_forward", translate("UDP Forward"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0"
o:depends({ custom = false })
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ custom = false, firewall_allow = true })
o = s:option(Flag, "log", translate("Log")) o = s:option(Flag, "log", translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
@@ -147,6 +147,17 @@ o.validate = function(self, value, t)
end end
o:depends({ custom = false }) o:depends({ custom = false })
o = s:option(Flag, "firewall_allow", translate("Firewall Allow"))
o.default = "0"
o:depends({ custom = false })
o = s:option(Value, "firewall_allow_src", translate("Source zone"))
o.nocreate = true
o.allowany = true
o.default = "wan"
o.template = "cbi/firewall_zonelist"
o:depends({ custom = false, firewall_allow = true })
o = s:option(Flag, "log", translate("Log")) o = s:option(Flag, "log", translate("Log"))
o.default = "1" o.default = "1"
o.rmempty = false o.rmempty = false
@@ -8,16 +8,10 @@ local jsonc = api.jsonc
local CONFIG = api.s_config local CONFIG = api.s_config
local CONFIG_PATH = api.S_TMP_PATH local CONFIG_PATH = api.S_TMP_PATH
local NFT_INCLUDE_FILE = CONFIG_PATH .. "/" .. CONFIG .. ".nft"
local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log" local LOG_APP_FILE = "/tmp/log/" .. CONFIG .. ".log"
local TMP_BIN_PATH = CONFIG_PATH .. "/bin" local TMP_BIN_PATH = CONFIG_PATH .. "/bin"
local require_dir = "luci.passwall." local require_dir = "luci.passwall."
local ipt_bin = sys.exec("echo -n $(/usr/share/passwall/iptables.sh get_ipt_bin)")
local ip6t_bin = sys.exec("echo -n $(/usr/share/passwall/iptables.sh get_ip6t_bin)")
local nft_flag = api.is_finded("fw4") and "1" or "0"
local function log(...) local function log(...)
local f, err = io.open(LOG_APP_FILE, "a") local f, err = io.open(LOG_APP_FILE, "a")
if f and err == nil then if f and err == nil then
@@ -31,18 +25,6 @@ local function cmd(cmd)
sys.call(cmd) sys.call(cmd)
end end
local function ipt(arg)
if ipt_bin and #ipt_bin > 0 then
cmd(ipt_bin .. " -w " .. arg)
end
end
local function ip6t(arg)
if ip6t_bin and #ip6t_bin > 0 then
cmd(ip6t_bin .. " -w " .. arg)
end
end
local function ln_run(s, d, command, output) local function ln_run(s, d, command, output)
if not output then if not output then
output = "/dev/null" output = "/dev/null"
@@ -52,37 +34,6 @@ local function ln_run(s, d, command, output)
return string.format("%s >%s 2>&1 &", d .. " " .. command, output) return string.format("%s >%s 2>&1 &", d .. " " .. command, output)
end end
local function gen_include()
cmd(string.format("echo '#!/bin/sh' > %s.include", CONFIG_PATH))
local function extract_rules(n, a)
local _ipt = ipt_bin
if n == "6" then
_ipt = ip6t_bin
end
local result = "*" .. a
result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"')
result = result .. "COMMIT"
return result
end
local f, err = io.open(CONFIG_PATH .. ".include", "a")
if f and err == nil then
if nft_flag == "0" then
f:write(ipt_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n")
f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n")
f:write(extract_rules("4", "filter") .. "\n")
f:write("EOT" .. "\n")
f:write(ip6t_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n")
f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n")
f:write(extract_rules("6", "filter") .. "\n")
f:write("EOT" .. "\n")
f:close()
else
f:write("nft -f " .. NFT_INCLUDE_FILE .. "\n")
f:close()
end
end
end
local function start() local function start()
local enabled = tonumber(api.uci_get_s("@global[0]", "enable") or 0) local enabled = tonumber(api.uci_get_s("@global[0]", "enable") or 0)
if enabled == nil or enabled == 0 then if enabled == nil or enabled == 0 then
@@ -90,18 +41,7 @@ local function start()
end end
cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH)) cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
cmd(string.format("touch %s", LOG_APP_FILE)) cmd(string.format("touch %s", LOG_APP_FILE))
if nft_flag == "0" then local firewall_num = 0
ipt("-N PSW-SERVER")
ipt("-I INPUT -j PSW-SERVER")
ip6t("-N PSW-SERVER")
ip6t("-I INPUT -j PSW-SERVER")
else
nft_file, err = io.open(NFT_INCLUDE_FILE, "w")
nft_file:write('#!/usr/sbin/nft -f\n')
nft_file:write('add chain inet fw4 PSW-SERVER\n')
nft_file:write('flush chain inet fw4 PSW-SERVER\n')
nft_file:write('insert rule inet fw4 input position 0 jump PSW-SERVER comment "PSW-SERVER"\n')
end
api.uci_foreach_s("server", function(server) api.uci_foreach_s("server", function(server)
local id = server[".name"] local id = server[".name"]
local enable = server.enable local enable = server.enable
@@ -207,48 +147,38 @@ local function start()
cmd(bin) cmd(bin)
end end
local bind_local = server.bind_local or 0 local firewall_allow = server.firewall_allow
if bind_local and tonumber(bind_local) ~= 1 and port then if firewall_allow == "1" then
if nft_flag == "0" then firewall_num = firewall_num + 1
ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) local uid = CONFIG .. "_" .. id
ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) uci:section("firewall", "rule", uid)
if udp_forward == 1 then uci:set("firewall", uid, "name", uid)
ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) uci:set("firewall", uid, "src", server.firewall_allow_src or "wan")
ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks)) uci:set("firewall", uid, "dest_port", port)
end uci:set("firewall", uid, "target", "ACCEPT")
else
nft_file:write(string.format('add rule inet fw4 PSW-SERVER meta l4proto tcp tcp dport {%s} counter accept comment "%s"\n', port, remarks))
if udp_forward == 1 then
nft_file:write(string.format('add rule inet fw4 PSW-SERVER meta l4proto udp udp dport {%s} counter accept comment "%s"\n', port, remarks))
end
end
end end
end end
end) end)
if nft_flag == "1" then if firewall_num > 0 then
nft_file:write("add rule inet fw4 PSW-SERVER return\n") api.uci_save(uci, "firewall", true, true)
nft_file:close()
cmd("nft -f " .. NFT_INCLUDE_FILE)
end end
gen_include()
end end
local function stop() local function stop()
cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH)) cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH))
if nft_flag == "0" then if true then
ipt("-D INPUT -j PSW-SERVER 2>/dev/null") local num = 0
ipt("-F PSW-SERVER 2>/dev/null") uci:foreach("firewall", "rule", function(rule)
ipt("-X PSW-SERVER 2>/dev/null") if rule[".name"]:find(CONFIG) == 1 then
ip6t("-D INPUT -j PSW-SERVER 2>/dev/null") num = num + 1
ip6t("-F PSW-SERVER 2>/dev/null") uci:delete("firewall", rule[".name"])
ip6t("-X PSW-SERVER 2>/dev/null") end
else end)
local nft_cmd = "handles=$(nft -a list chain inet fw4 input | grep -E \"PSW-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done" if num > 0 then
cmd(nft_cmd) api.uci_save(uci, "firewall", true, true)
cmd("nft flush chain inet fw4 PSW-SERVER 2>/dev/null") end
cmd("nft delete chain inet fw4 PSW-SERVER 2>/dev/null")
end end
cmd(string.format("rm -rf %s %s %s", CONFIG_PATH, LOG_APP_FILE, CONFIG_PATH .. ".include")) cmd(string.format("rm -rf %s %s", CONFIG_PATH, LOG_APP_FILE))
end end
if action then if action then
@@ -762,7 +762,7 @@ function gen_config_server(node)
local inbound = { local inbound = {
type = node.protocol, type = node.protocol,
tag = "inbound", tag = "inbound",
listen = (node.bind_local == "1") and "127.0.0.1" or "::", listen = "::",
listen_port = tonumber(node.port), listen_port = tonumber(node.port),
} }
@@ -669,7 +669,7 @@ function gen_config_server(node)
-- 传入连接 -- 传入连接
inbounds = { inbounds = {
{ {
listen = (node.bind_local == "1") and "127.0.0.1" or nil, listen = "::",
port = tonumber(node.port), port = tonumber(node.port),
protocol = node.protocol, protocol = node.protocol,
settings = settings, settings = settings,
+9
View File
@@ -845,6 +845,9 @@ msgstr "常用的"
msgid "Only Web" msgid "Only Web"
msgstr "仅网页" msgstr "仅网页"
msgid "Forward only %s"
msgstr "仅转发 %s 端口"
msgid "default" msgid "default"
msgstr "默认" msgstr "默认"
@@ -1571,6 +1574,12 @@ msgstr "本机监听"
msgid "When selected, it can only be accessed localhost." msgid "When selected, it can only be accessed localhost."
msgstr "当勾选时,只能本机访问。" msgstr "当勾选时,只能本机访问。"
msgid "Firewall Allow"
msgstr "允许通过防火墙"
msgid "Source zone"
msgstr "源区域"
msgid "Accept LAN Access" msgid "Accept LAN Access"
msgstr "接受局域网访问" msgstr "接受局域网访问"
@@ -9,21 +9,6 @@ if [ -e "/etc/config/ucitrack" ]; then
EOF EOF
fi fi
uci -q batch <<-EOF
delete firewall.passwall_server
set firewall.passwall_server=include
set firewall.passwall_server.type='script'
set firewall.passwall_server.path='/var/etc/passwall_server.include'
EOF
if [ -x "/sbin/fw3" ]; then
uci -q set firewall.passwall_server.reload='1'
else
uci -q delete firewall.passwall_server.reload
uci -q delete firewall.passwall_server.fw4_compatible
fi
uci commit firewall
# Migrate server sections from the old `user` section type. New user entries # Migrate server sections from the old `user` section type. New user entries
# also use `user`, so only sections with a server `type` option are renamed. # also use `user`, so only sections with a server `type` option are renamed.
for sid in $(uci -q show passwall_server | sed -n 's/^passwall_server\.\([^.=]*\)=user$/\1/p'); do for sid in $(uci -q show passwall_server | sed -n 's/^passwall_server\.\([^.=]*\)=user$/\1/p'); do