update 2022-10-09 20:22:15

This commit is contained in:
github-actions[bot] 2022-10-09 20:22:15 +08:00
parent b5a3ca8d1f
commit 285e24d1f5
9 changed files with 122 additions and 55 deletions

View File

@ -303,7 +303,7 @@ end
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
o.inputstyle = "remove"
function o.write(e, e)
luci.sys.call("/usr/share/" .. appname .. "/iptables.sh flush_ipset > /dev/null 2>&1 &")
luci.sys.call("[ -n \"$(nft list sets 2>/dev/null | grep \"gfwlist\")\" ] && /usr/share/" .. appname .. "/nftables.sh flush_nftset || /usr/share/" .. appname .. "/iptables.sh flush_ipset > /dev/null 2>&1 &")
luci.http.redirect(api.url("log"))
end

View File

@ -3,6 +3,8 @@ local appname = api.appname
local fs = api.fs
local has_v2ray = api.is_finded("v2ray")
local has_xray = api.is_finded("xray")
local has_fw3 = api.is_finded("fw3")
local has_fw4 = api.is_finded("fw4")
m = Map(appname)
@ -95,6 +97,16 @@ o.default = "1:65535"
o:value("1:65535", translate("All"))
o:value("53", "DNS")
---- Use nftables
o = s:option(ListValue, "use_nft", translate("Firewall tools"))
o.default = "0"
if has_fw3 then
o:value("0", "IPtables")
end
if has_fw4 then
o:value("1", "NFtables")
end
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
o.default = "redirect"

View File

@ -15,6 +15,8 @@ local require_dir = "luci.model.cbi.passwall.server.api."
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 = sys.exec("command -v fw4") and "1" or "0"
local function log(...)
local f, err = io.open(LOG_APP_FILE, "a")
if f and err == nil then
@ -47,6 +49,11 @@ end
local function gen_include()
cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG))
if nft_flag == "1" then
cmd("echo \"\" > " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft")
local nft_cmd="for chain in $(nft -a list chains |grep -E \"chain PSW-SERVER\" |awk -F ' ' '{print$2}'); do\n nft list chain inet fw4 ${chain} >> " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n done"
cmd(nft_cmd)
end
local function extract_rules(n, a)
local _ipt = ipt_bin
if n == "6" then
@ -59,15 +66,21 @@ local function gen_include()
end
local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a")
if f and err == nil 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()
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 " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n")
f:write("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
f:close()
end
end
end
@ -78,10 +91,15 @@ local function start()
end
cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
cmd(string.format("touch %s", LOG_APP_FILE))
ipt("-N PSW-SERVER")
ipt("-I INPUT -j PSW-SERVER")
ip6t("-N PSW-SERVER")
ip6t("-I INPUT -j PSW-SERVER")
if nft_flag == "0" then
ipt("-N PSW-SERVER")
ipt("-I INPUT -j PSW-SERVER")
ip6t("-N PSW-SERVER")
ip6t("-I INPUT -j PSW-SERVER")
else
cmd("nft add chain inet fw4 PSW-SERVER\n")
cmd("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
end
uci:foreach(CONFIG, "user", function(user)
local id = user[".name"]
local enable = user.enable
@ -168,12 +186,19 @@ local function start()
local bind_local = user.bind_local or 0
if bind_local and tonumber(bind_local) ~= 1 then
ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
if udp_forward == 1 then
ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
end
if nft_flag == "0" then
ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
if udp_forward == 1 then
ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
end
else
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto tcp tcp dport {%s} accept', port))
if udp_forward == 1 then
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto udp udp dport {%s} accept', port))
end
end
end
end
end)
@ -182,12 +207,19 @@ end
local function stop()
cmd(string.format("top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH))
ipt("-D INPUT -j PSW-SERVER 2>/dev/null")
ipt("-F PSW-SERVER 2>/dev/null")
ipt("-X PSW-SERVER 2>/dev/null")
ip6t("-D INPUT -j PSW-SERVER 2>/dev/null")
ip6t("-F PSW-SERVER 2>/dev/null")
ip6t("-X PSW-SERVER 2>/dev/null")
if nft_flag == "0" then
ipt("-D INPUT -j PSW-SERVER 2>/dev/null")
ipt("-F PSW-SERVER 2>/dev/null")
ipt("-X PSW-SERVER 2>/dev/null")
ip6t("-D INPUT -j PSW-SERVER 2>/dev/null")
ip6t("-F PSW-SERVER 2>/dev/null")
ip6t("-X PSW-SERVER 2>/dev/null")
else
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"
cmd(nft_cmd)
cmd("nft flush chain inet fw4 PSW-SERVER 2>/dev/null")
cmd("nft delete chain inet fw4 PSW-SERVER 2>/dev/null")
end
cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG))
end

View File

@ -1114,6 +1114,9 @@ msgstr "节点数量"
msgid "You can only set up a maximum of %s nodes for the time being, Used for access control."
msgstr "目前最多只能设置%s个节点用于给访问控制使用。"
msgid "Firewall tools"
msgstr "防火墙工具"
msgid "IPv6 TProxy"
msgstr "IPv6透明代理(TProxy)"

View File

@ -32,6 +32,7 @@ config global_forwarding
option tcp_redir_ports '22,25,53,143,465,587,853,993,995,80,443'
option udp_redir_ports '1:65535'
option accept_icmp '0'
option use_nft '0'
option tcp_proxy_way 'redirect'
option ipv6_tproxy '0'
option sniffing '1'

View File

@ -1349,14 +1349,13 @@ start() {
start_haproxy
start_socks
nftflag=0
local use_nft=$(config_t_get global_forwarding use_nft 0)
[ "$NO_PROXY" == 1 ] || {
if [ -n "$(command -v fw4)" ] && [ -z "$(dnsmasq --version | grep 'nftset')" ]; then
echolog "检测到fw4防火墙但Dnsmasq软件包不满足nftables透明代理要求如需使用请确保dnsmasq版本在2.87以上并开启nftset支持。"
fi
if [ -n "$(command -v fw4)" ] && [ -n "$(dnsmasq --version | grep 'nftset')" ]; then
echolog "检测fw4防火墙使用nftables进行透明代理一些不支持nftables的组件如smartdns分流等将不可用。"
if [ "$use_nft" == 1 ] && [ -z "$(dnsmasq --version | grep 'Compile time options:.* nftset')" ]; then
echolog "Dnsmasq软件包不满足nftables透明代理要求如需使用请确保dnsmasq版本在2.87以上并开启nftset支持。"
elif [ "$use_nft" == 1 ] && [ -n "$(dnsmasq --version | grep 'Compile time options:.* nftset')" ]; then
echolog "使用nftables进行透明代理一些不支持nftables的组件如smartdns分流等将不可用。"
nftflag=1
start_redir TCP
start_redir UDP
@ -1379,7 +1378,8 @@ start() {
stop() {
clean_log
[ -n "$(command -v fw4)" ] && [ -n "$(dnsmasq --version | grep 'nftset')" ] && source $APP_PATH/nftables.sh stop || source $APP_PATH/iptables.sh stop
[ -n "$($(source $APP_PATH/iptables.sh get_ipt_bin) -t mangle -t nat -L -nv 2>/dev/null | grep "PSW")" ] && source $APP_PATH/iptables.sh stop
[ -n "$(nft list chains 2>/dev/null | grep "PSW")" ] && source $APP_PATH/nftables.sh stop
delete_ip2route
kill_all v2ray-plugin obfs-local
pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1

View File

@ -168,7 +168,7 @@ local dnsmasq_default_dns
local cache_text = ""
local subscribe_proxy=uci:get(appname, "@global_subscribe[0]", "subscribe_proxy") or "0"
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 .. CHINADNS_DNS .. PROXY_MODE .. NO_PROXY_IPV6 .. subscribe_proxy .. new_rules
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. CHINADNS_DNS .. PROXY_MODE .. NO_PROXY_IPV6 .. subscribe_proxy .. new_rules .. NFTFLAG
if fs.access(CACHE_TEXT_FILE) then
for line in io.lines(CACHE_TEXT_FILE) do
cache_text = line

View File

@ -461,7 +461,7 @@ load_acl() {
elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
_ipset=$(echo ${i} | sed 's#ipset:##g')
_ipt_source="ip daddr @${_ipset}"
msg="备注【$remarks】,IPset【${_ipset}】,"
msg="备注【$remarks】,NFTset【${_ipset}】,"
elif [ -n "$(echo ${i} | grep '^ip:')" ]; then
_ip=$(echo ${i} | sed 's#ip:##g')
_ipt_source=$(factor ${_ip} "ip saddr")
@ -717,13 +717,13 @@ filter_haproxy() {
local ip=$(get_host_ip ipv4 $(echo $item | awk -F ":" '{print $1}') 1)
insert_nftset $NFTSET_VPSIPLIST $ip
done
echolog "加入负载均衡的节点到ipset[$NFTSET_VPSIPLIST]直连完成"
echolog "加入负载均衡的节点到nftset[$NFTSET_VPSIPLIST]直连完成"
}
filter_vpsip() {
insert_nftset $NFTSET_VPSIPLIST $(uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d" | sed -e 's/$/,/' )
insert_nftset $NFTSET_VPSIPLIST6 $(uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e 's/$/,/' )
echolog "加入所有节点到ipset[$NFTSET_VPSIPLIST]直连完成"
echolog "加入所有节点到nftset[$NFTSET_VPSIPLIST]直连完成"
}
filter_node() {
@ -1207,10 +1207,13 @@ del_firewall_rule() {
done
done
for handle in $(nft -a list chains |grep -E "chain PSW" |awk -F '# handle ' '{print$2}'); do
for handle in $(nft -a list chains | grep -E "chain PSW" | grep -v "PSW_RULE" | awk -F '# handle ' '{print$2}'); do
nft delete chain inet fw4 handle ${handle} 2>/dev/null
done
# Need to be removed at the end, otherwise it will show "Resource busy"
nft delete chain inet fw4 handle $(nft -a list chains | grep -E "PSW_RULE" | awk -F '# handle ' '{print$2}') 2>/dev/null
ip rule del fwmark 1 lookup 100 2>/dev/null
ip route del local 0.0.0.0/0 dev lo table 100 2>/dev/null
@ -1295,14 +1298,6 @@ gen_include() {
return 0
}
get_ipt_bin() {
echo $ipt
}
get_ip6t_bin() {
echo $ip6t
}
start() {
add_firewall_rule
gen_include
@ -1325,7 +1320,7 @@ insert_rule_before)
insert_rule_after)
insert_rule_after "$@"
;;
flush_ipset)
flush_nftset)
flush_nftset
;;
get_wan_ip)

View File

@ -56,11 +56,14 @@ local function trim(text)
end
-- curl
local function curl(url, file)
local function curl(url, file, valifile)
local cmd = "curl -skL -w %{http_code} --retry 3 --connect-timeout 3 '" .. url .. "'"
if file then
cmd = cmd .. " -o " .. file
end
if valifile then
cmd = cmd .. " --dump-header " .. valifile
end
local stdout = luci.sys.exec(cmd)
if file then
@ -87,9 +90,19 @@ local function line_count(file_path)
return num;
end
local function non_file_check(file_path)
local function non_file_check(file_path, vali_file)
if nixio.fs.readfile(file_path, 1000) then
return nil;
local remote_file_size = luci.sys.exec("cat " .. vali_file .. " | grep -i Content-Length | awk '{print $2}'")
local local_file_size = luci.sys.exec("ls -l " .. file_path .. "| awk '{print $5}'")
if remote_file_size then
if tonumber(remote_file_size) == tonumber(local_file_size) then
return nil;
else
return true;
end
else
return nil;
end
else
return true;
end
@ -101,16 +114,26 @@ local function fetch_rule(rule_name,rule_type,url,exclude_domain)
local sret_tmp = 0
local domains = {}
local file_tmp = "/tmp/" ..rule_name.. "_tmp"
local vali_file = "/tmp/" ..rule_name.. "_vali"
local download_file_tmp = "/tmp/" ..rule_name.. "_dl"
local unsort_file_tmp = "/tmp/" ..rule_name.. "_unsort"
log(rule_name.. " 开始更新...")
for k,v in ipairs(url) do
sret_tmp = curl(v, download_file_tmp..k)
if sret_tmp == 200 and non_file_check(download_file_tmp..k) then
sret = 0
log(rule_name.. "" ..k.. "条规则:" ..v.. "下载文件读取出错,请检查网络或下载链接后重试!")
elseif sret_tmp == 200 then
sret_tmp = curl(v, download_file_tmp..k, vali_file..k)
if sret_tmp == 200 and non_file_check(download_file_tmp..k, vali_file..k) then
log(rule_name.. "" ..k.. "条规则:" ..v.. "下载文件读取出错,尝试重新下载。")
os.remove(download_file_tmp..k)
os.remove(vali_file..k)
sret_tmp = curl(v, download_file_tmp..k, vali_file..k)
if sret_tmp == 200 and non_file_check(download_file_tmp..k, vali_file..k) then
sret = 0
sret_tmp = 0
log(rule_name.. "" ..k.. "条规则:" ..v.. "下载文件读取出错,请检查网络或下载链接后重试!")
end
end
if sret_tmp == 200 then
if rule_name == "gfwlist" then
local domains = {}
local gfwlist = io.open(download_file_tmp..k, "r")
@ -168,6 +191,7 @@ local function fetch_rule(rule_name,rule_type,url,exclude_domain)
log(rule_name.. "" ..k.. "条规则:" ..v.. "下载失败,请检查网络或下载链接后重试!")
end
os.remove(download_file_tmp..k)
os.remove(vali_file..k)
end
if sret == 200 then