From 21839726775f0feba2cdc2545c42545e7edff633 Mon Sep 17 00:00:00 2001 From: gitea-action Date: Thu, 5 Dec 2024 23:00:22 +0800 Subject: [PATCH] luci-app-passwall2: sync upstream last commit: https://github.com/xiaorouji/openwrt-passwall2/commit/848e992a05c15748e49c5d6d3abfe6d319a0309e --- luci-app-passwall2/Makefile | 10 +- .../client/node_subscribe_config.lua | 8 +- .../model/cbi/passwall2/client/other.lua | 6 +- .../model/cbi/passwall2/client/rule.lua | 11 ++ luci-app-passwall2/luasrc/passwall2/api.lua | 45 ++++++ luci-app-passwall2/po/zh-cn/passwall2.po | 16 +- .../root/usr/share/passwall2/app.sh | 17 ++ .../root/usr/share/passwall2/iptables.sh | 115 ++++++++++---- .../root/usr/share/passwall2/nftables.sh | 150 ++++++++++++------ .../root/usr/share/passwall2/subscribe.lua | 17 +- 10 files changed, 307 insertions(+), 88 deletions(-) diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 6511ef231..1994f808b 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=24.11.19 -PKG_RELEASE:=2 +PKG_VERSION:=24.12.05 +PKG_RELEASE:=1 PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \ @@ -24,6 +24,7 @@ PKG_CONFIG_DEPENDS:= \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SingBox \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client \ + CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geoview \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin LUCI_TITLE:=LuCI support for PassWall 2 @@ -135,6 +136,11 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client select PACKAGE_tuic-client default n +config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geoview + bool "Include V2ray_Geoview" + select PACKAGE_geoview + default y if aarch64||arm||i386||x86_64 + config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin bool "Include V2ray-Plugin (Shadowsocks Plugin)" select PACKAGE_v2ray-plugin diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua index cd13e9aaa..64d37e289 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/node_subscribe_config.lua @@ -171,12 +171,18 @@ o.default = 2 o:depends("week_update", "8") o.rmempty = true +o = s:option(ListValue, "access_mode", translate("Subscribe URL Access Method")) +o.default = "" +o:value("", translate("Auto")) +o:value("direct", translate("Direct Connection")) +o:value("proxy", translate("Proxy")) + o = s:option(Value, "user_agent", translate("User-Agent")) o.default = "v2rayN/9.99" o:value("curl", "Curl") o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux") o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows") o:value("Passwall2/OpenWrt", "PassWall2") -o:value("v2rayN/9.99", "V2rayN") +o:value("v2rayN/9.99", "v2rayN") return m diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua index e41f576f3..0930eb713 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/other.lua @@ -164,8 +164,9 @@ if has_xray then o = s_xray:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) o.default = 0 - o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address"), translate("Override the connection destination address with the sniffed domain.")) + o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address")) o.default = 0 + o.description = translate("Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly.") o = s_xray:option(Flag, "route_only", translate("Sniffing Route Only")) o.default = 0 @@ -224,9 +225,10 @@ if has_singbox then s.anonymous = true s.addremove = false - o = s:option(Flag, "sniff_override_destination", translate("Override the connection destination address"), translate("Override the connection destination address with the sniffed domain.")) + o = s:option(Flag, "sniff_override_destination", translate("Override the connection destination address")) o.default = 0 o.rmempty = false + o.description = translate("Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly.") o = s:option(Value, "geoip_path", translate("Custom geoip Path")) o.default = "/usr/share/singbox/geoip.db" diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua index e8aeba77b..c651f019a 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/rule.lua @@ -22,6 +22,17 @@ o.default = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/ o.rmempty = false ---- +if api.is_finded("geoview") then + o = s:option(Flag, "enable_geoview", translate("Enable Geo Data Parsing")) + o.default = 0 + o.rmempty = false + o.description = "" +end + s:append(Template(appname .. "/rule/rule_version")) ---- Auto Update diff --git a/luci-app-passwall2/luasrc/passwall2/api.lua b/luci-app-passwall2/luasrc/passwall2/api.lua index 6db3a0272..9491c885f 100644 --- a/luci-app-passwall2/luasrc/passwall2/api.lua +++ b/luci-app-passwall2/luasrc/passwall2/api.lua @@ -62,6 +62,29 @@ function base64Decode(text) end end +--提取URL中的域名和端口(no ip) +function get_domain_port_from_url(url) + local scheme, domain, port = string.match(url, "^(https?)://([%w%.%-]+):?(%d*)") + if not domain then + scheme, domain, port = string.match(url, "^(https?)://(%b[])([^:/]*)/?") + end + if not domain then return nil, nil end + if domain:sub(1, 1) == "[" then domain = domain:sub(2, -2) end + port = port ~= "" and tonumber(port) or (scheme == "https" and 443 or 80) + if datatypes.ipaddr(domain) or datatypes.ip6addr(domain) then return nil, nil end + return domain, port +end + +--解析域名 +function domainToIPv4(domain, dns) + local Dns = dns or "223.5.5.5" + local IPs = luci.sys.exec('nslookup %s %s | awk \'/^Name:/{getline; if ($1 == "Address:") print $2}\'' % { domain, Dns }) + for IP in string.gmatch(IPs, "%S+") do + if datatypes.ipaddr(IP) and not datatypes.ip6addr(IP) then return IP end + end + return nil +end + function curl_base(url, file, args) if not args then args = {} end if file then @@ -91,6 +114,28 @@ function curl_logic(url, file, args) return return_code, result end +function curl_direct(url, file, args) + --直连访问 + if not args then args = {} end + local tmp_args = clone(args) + local domain, port = get_domain_port_from_url(url) + if domain then + local ip = domainToIPv4(domain) + if ip then + tmp_args[#tmp_args + 1] = "--resolve " .. domain .. ":" .. port .. ":" .. ip + end + end + return curl_base(url, file, tmp_args) +end + +function curl_auto(url, file, args) + local return_code, result = curl_proxy(url, file, args) + if not return_code or return_code ~= 0 then + return_code, result = curl_direct(url, file, args) + end + return return_code, result +end + function url(...) local url = string.format("admin/services/%s", appname) local args = { ... } diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po index 9f8004f1e..678280ee9 100644 --- a/luci-app-passwall2/po/zh-cn/passwall2.po +++ b/luci-app-passwall2/po/zh-cn/passwall2.po @@ -820,6 +820,15 @@ msgstr "V2ray/Xray 资源文件目录" msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." msgstr "此变量指定geoip.dat和geosite.dat文件所在的目录。" +msgid "Enable Geo Data Parsing" +msgstr "开启 Geo 数据解析" + +msgid "Analyzes and preloads GeoIP/Geosite data to enhance the shunt performance of Sing-box/Xray." +msgstr "分析和预加载 GeoIP/Geosite 数据,以增强 Sing-box/Xray 的分流效果。" + +msgid "Note: Increases resource usage; Geosite analysis is only supported in ChinaDNS-NG and SmartDNS modes." +msgstr "注:会增加一些系统资源的开销,仅在 ChinaDNS-NG 和 SmartDNS 模式下支持分析 Geosite 。" + msgid "Shunt Rule" msgstr "分流规则" @@ -889,6 +898,9 @@ msgstr "订阅备注(机场)" msgid "Subscribe URL" msgstr "订阅网址" +msgid "Subscribe URL Access Method" +msgstr "订阅网址访问方式" + msgid "Please input the subscription url first, save and submit before manual subscription." msgstr "请输入订阅网址保存应用后再手动订阅。" @@ -1474,8 +1486,8 @@ msgstr "Sing-Box 会在启动时自动下载资源文件,您可以使用此功 msgid "Override the connection destination address" msgstr "覆盖连接目标地址" -msgid "Override the connection destination address with the sniffed domain." -msgstr "用探测出的域名覆盖连接目标地址。" +msgid "Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly." +msgstr "用探测出的域名覆盖连接目标地址。
启用后仅使用域名进行流量匹配,将忽略IP规则。
如使用分流节点,请正确设置域名分流规则。" msgid "Handshake Server" msgstr "握手服务器" diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh index 8ddacdfab..9e0bf5c23 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/app.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh @@ -299,6 +299,23 @@ get_dnsmasq_conf_dir() { } } +get_geoip() { + local geoip_code="$1" + local geoip_type_flag="" + local geoip_path="$(config_t_get global_rules v2ray_location_asset)" + geoip_path="${geoip_path%*/}/geoip.dat" + [ -e "$geoip_path" ] || { echo ""; return; } + case "$2" in + "ipv4") geoip_type_flag="-ipv6=false" ;; + "ipv6") geoip_type_flag="-ipv4=false" ;; + esac + if type geoview &> /dev/null; then + geoview -input "$geoip_path" -list "$geoip_code" $geoip_type_flag -lowmem=true + else + echo "" + fi +} + run_xray() { local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password local dns_listen_port direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy dns_cache write_ipset_direct diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh index 7fc8e023c..0a4e2d9dd 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh @@ -219,6 +219,34 @@ load_acl() { local ipset_whitelist6="passwall2_${sid}_whitelist6" ipset -! create $ipset_whitelist nethash maxelem 1048576 ipset -! create $ipset_whitelist6 nethash family inet6 maxelem 1048576 + + #分流规则的IP列表(使用分流节点时导入) + local _USE_SHUNT_NODE=0 + _NODE_PROTOCOL=$(config_n_get $node protocol) + [ "$_NODE_PROTOCOL" = "_shunt" ] && _USE_SHUNT_NODE=1 + [ "$_USE_SHUNT_NODE" = "1" ] && { + local _SHUNT_DEFAULT_NODE=$(config_n_get $NODE default_node _direct) + local _GEOIP_CODE="" + 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_RULE_NODE=$(config_n_get $NODE ${_shunt_id} nil) + [ "${_SHUNT_RULE_NODE}" == "_default" ] && _SHUNT_RULE_NODE=${_SHUNT_DEFAULT_NODE} + [ "${_SHUNT_RULE_NODE}" == "_direct" ] && { + config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_whitelist &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_whitelist6 &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + [ "$(config_t_get global_rules enable_geoview)" = "1" ] && { + local _geoip_code=$(config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$_geoip_code" ] && _GEOIP_CODE="${_GEOIP_CODE:+$_GEOIP_CODE,}$_geoip_code" + } + } + done + } + + if [ -n "$_GEOIP_CODE" ] && type geoview &> /dev/null; then + get_geoip $_GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_whitelist &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + get_geoip $_GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_whitelist6 &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]解析并加入分流节点 GeoIP 到 IPSET 完成" + fi fi } @@ -300,8 +328,10 @@ load_acl() { msg2="${msg}使用 TCP 节点[$node_remark]" if [ -n "${is_tproxy}" ]; then msg2="${msg2}(TPROXY:${redir_port})" + ipt_j="-j PSW2_RULE" else msg2="${msg2}(REDIRECT:${redir_port})" + ipt_j="$(REDIRECT $redir_port)" fi [ "${write_ipset_direct}" = "1" ] && $ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(dst $ipset_whitelist) ! -d $FAKE_IP -j RETURN @@ -315,15 +345,11 @@ load_acl() { $ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} -d $FAKE_IP_6 $(REDIRECT) 2>/dev/null $ip6t_n -A PSW2 $(comment "$remarks") -p ipv6-icmp ${_ipt_source} $(REDIRECT) 2>/dev/null } - - if [ "${ipt_tmp}" = "${ipt_n}" ]; then - $ipt_n -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP $(REDIRECT $redir_port) - $ipt_n -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(factor $tcp_redir_ports "-m multiport --dport") $(REDIRECT $redir_port) - else - $ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP -j PSW2_RULE - $ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(factor $tcp_redir_ports "-m multiport --dport") -j PSW2_RULE - $ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) - fi + + $ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP ${ipt_j} + $ipt_tmp -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(factor $tcp_redir_ports "-m multiport --dport") ${ipt_j} + [ -n "${is_tproxy}" ] && $ipt_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) + [ "$PROXY_IPV6" == "1" ] && { [ "${write_ipset_direct}" = "1" ] && $ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} $(dst $ipset_whitelist6) ! -d $FAKE_IP_6 -j RETURN $ip6t_m -A PSW2 $(comment "$remarks") -p tcp ${_ipt_source} -d $FAKE_IP_6 -j PSW2_RULE 2>/dev/null @@ -353,7 +379,7 @@ load_acl() { } $ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN 2>/dev/null - unset ipt_tmp _ipt_source msg msg2 + unset ipt_tmp ipt_j _ipt_source msg msg2 done unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface unset node_remark _acl_list @@ -392,8 +418,10 @@ load_acl() { msg2="${msg}使用 TCP 节点[$(config_n_get $NODE remarks)]" if [ -n "${is_tproxy}" ]; then msg2="${msg2}(TPROXY:${REDIR_PORT})" + ipt_j="-j PSW2_RULE" else msg2="${msg2}(REDIRECT:${REDIR_PORT})" + ipt_j="$(REDIRECT $REDIR_PORT)" fi [ "${WRITE_IPSET_DIRECT}" = "1" ] && $ipt_tmp -A PSW2 $(comment "默认") -p tcp $(dst $ipset_global_whitelist) ! -d $FAKE_IP -j RETURN @@ -407,15 +435,10 @@ load_acl() { $ip6t_n -A PSW2 $(comment "默认") -p ipv6-icmp -d $FAKE_IP_6 $(REDIRECT) $ip6t_n -A PSW2 $(comment "默认") -p ipv6-icmp $(REDIRECT) } - - if [ -z "${is_tproxy}" ]; then - $ipt_n -A PSW2 $(comment "默认") -p tcp -d $FAKE_IP $(REDIRECT $REDIR_PORT) - $ipt_n -A PSW2 $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(REDIRECT $REDIR_PORT) - else - $ipt_m -A PSW2 $(comment "默认") -p tcp -d $FAKE_IP -j PSW2_RULE - $ipt_m -A PSW2 $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") -j PSW2_RULE - $ipt_m -A PSW2 $(comment "默认") -p tcp $(REDIRECT $REDIR_PORT TPROXY) - fi + + $ipt_tmp -A PSW2 $(comment "默认") -p tcp -d $FAKE_IP ${ipt_j} + $ipt_tmp -A PSW2 $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") ${ipt_j} + [ -n "${is_tproxy}" ] && $ipt_m -A PSW2 $(comment "默认") -p tcp $(REDIRECT $REDIR_PORT TPROXY) [ "$PROXY_IPV6" == "1" ] && { [ "${WRITE_IPSET_DIRECT}" = "1" ] && $ip6t_m -A PSW2 $(comment "默认") -p tcp $(dst $ipset_global_whitelist6) ! -d $FAKE_IP_6 -j RETURN @@ -456,11 +479,10 @@ filter_haproxy() { } filter_vpsip() { - 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/^/add $IPSET_VPSLIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - 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/^/add $IPSET_VPSLIST6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - uci show $CONFIG | grep ".download_address=" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPSLIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - uci show $CONFIG | grep ".download_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/^/add $IPSET_VPSLIST6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - echolog "加入所有节点到ipset[$IPSET_VPSLIST]直连完成" + uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_VPSLIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]加入所有IPv4节点到ipset[$IPSET_VPSLIST]直连完成" + uci show $CONFIG | grep -E "(.address=|.download_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/^/add $IPSET_VPSLIST6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]加入所有IPv6节点到ipset[$IPSET_VPSLIST6]直连完成" } filter_node() { @@ -627,6 +649,34 @@ add_firewall_rule() { ipset -! create $ipset_global_whitelist nethash maxelem 1048576 timeout 259200 ipset -! create $ipset_global_whitelist6 nethash family inet6 maxelem 1048576 timeout 259200 + #分流规则的IP列表(使用分流节点时导入) + local USE_SHUNT_NODE=0 + NODE_PROTOCOL=$(config_n_get $NODE protocol) + [ "$NODE_PROTOCOL" = "_shunt" ] && USE_SHUNT_NODE=1 + [ "$USE_SHUNT_NODE" = "1" ] && { + local SHUNT_DEFAULT_NODE=$(config_n_get $NODE default_node _direct) + local GEOIP_CODE="" + 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_RULE_NODE=$(config_n_get $NODE ${shunt_id} nil) + [ "${SHUNT_RULE_NODE}" == "_default" ] && SHUNT_RULE_NODE=${SHUNT_DEFAULT_NODE} + [ "${SHUNT_RULE_NODE}" == "_direct" ] && { + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_global_whitelist &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_global_whitelist6 &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + [ "$(config_t_get global_rules enable_geoview)" = "1" ] && { + local geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$geoip_code" ] && GEOIP_CODE="${GEOIP_CODE:+$GEOIP_CODE,}$geoip_code" + } + } + done + } + + if [ -n "$GEOIP_CODE" ] && type geoview &> /dev/null; then + get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}" | sed -e "s/^/add $ipset_global_whitelist &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $ipset_global_whitelist6 &/g" -e "s/$/ timeout 0/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + echolog " - [$?]解析并加入分流节点 GeoIP 到 IPSET 完成" + fi + # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & filter_haproxy > /dev/null 2>&1 & @@ -811,17 +861,20 @@ add_firewall_rule() { $ip6t_n -A PSW2_OUTPUT -p ipv6-icmp $(REDIRECT) } - if [ -z "${is_tproxy}" ]; then - $ipt_n -A PSW2_OUTPUT -p tcp -d $FAKE_IP $(REDIRECT $REDIR_PORT) - $ipt_n -A PSW2_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(REDIRECT $REDIR_PORT) - $ipt_n -A OUTPUT -p tcp -j PSW2_OUTPUT + if [ -n "${is_tproxy}" ]; then + ipt_j="-j PSW2_RULE" else - $ipt_m -A PSW2_OUTPUT -p tcp -d $FAKE_IP -j PSW2_RULE - $ipt_m -A PSW2_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") -j PSW2_RULE + ipt_j="$(REDIRECT $REDIR_PORT)" + fi + + $ipt_tmp -A PSW2_OUTPUT -p tcp -d $FAKE_IP ${ipt_j} + $ipt_tmp -A PSW2_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") ${ipt_j} + [ -z "${is_tproxy}" ] && $ipt_n -A OUTPUT -p tcp -j PSW2_OUTPUT + [ -n "${is_tproxy}" ] && { $ipt_m -A PSW2 $(comment "本机") -p tcp -i lo $(REDIRECT $REDIR_PORT TPROXY) $ipt_m -A PSW2 $(comment "本机") -p tcp -i lo -j RETURN insert_rule_before "$ipt_m" "OUTPUT" "mwan3" "$(comment mangle-OUTPUT-PSW2) -p tcp -j PSW2_OUTPUT" - fi + } if [ "$PROXY_IPV6" == "1" ]; then $ip6t_m -A PSW2_OUTPUT -p tcp -d $FAKE_IP_6 -j PSW2_RULE diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh index d2ccda9a9..fd985e576 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh @@ -273,6 +273,34 @@ load_acl() { local nftset_whitelist6="passwall2_${sid}_whitelist6" gen_nftset $nftset_whitelist ipv4_addr 3d 3d gen_nftset $nftset_whitelist6 ipv6_addr 3d 3d + + #分流规则的IP列表(使用分流节点时导入) + local _USE_SHUNT_NODE=0 + _NODE_PROTOCOL=$(config_n_get $node protocol) + [ "$_NODE_PROTOCOL" = "_shunt" ] && _USE_SHUNT_NODE=1 + [ "$_USE_SHUNT_NODE" = "1" ] && { + local _SHUNT_DEFAULT_NODE=$(config_n_get $NODE default_node _direct) + local _GEOIP_CODE="" + 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_RULE_NODE=$(config_n_get $NODE ${_shunt_id} nil) + [ "${_SHUNT_RULE_NODE}" == "_default" ] && _SHUNT_RULE_NODE=${_SHUNT_DEFAULT_NODE} + [ "${_SHUNT_RULE_NODE}" == "_direct" ] && { + insert_nftset $ipset_whitelist "0" $(config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}") + insert_nftset $ipset_whitelist6 "0" $(config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + [ "$(config_t_get global_rules enable_geoview)" = "1" ] && { + local _geoip_code=$(config_n_get $_shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$_geoip_code" ] && _GEOIP_CODE="${_GEOIP_CODE:+$_GEOIP_CODE,}$_geoip_code" + } + } + done + } + + if [ -n "$_GEOIP_CODE" ] && type geoview &> /dev/null; then + insert_nftset $ipset_whitelist "0" $(get_geoip $_GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}") + insert_nftset $ipset_whitelist6 "0" $(get_geoip $_GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + echolog " - [$?]解析并加入分流节点 GeoIP 到 IPSET 完成" + fi fi } @@ -344,8 +372,12 @@ load_acl() { msg2="${msg}使用 TCP 节点[$node_remark]" if [ -n "${is_tproxy}" ]; then msg2="${msg2}(TPROXY:${redir_port})" + nft_chain="PSW2_MANGLE" + nft_j="counter jump PSW2_RULE" else msg2="${msg2}(REDIRECT:${redir_port})" + nft_chain="PSW2_NAT" + nft_j="$(REDIRECT $redir_port)" fi [ "${write_ipset_direct}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" @@ -363,19 +395,14 @@ load_acl() { nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 ${_ipt_source} return comment \"$remarks\"" 2>/dev/null } - if [ -z "${is_tproxy}" ]; then - nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP $(REDIRECT $redir_port) comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") $(REDIRECT $redir_port) comment \"$remarks\"" - else - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" - fi + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} ip daddr $FAKE_IP ${nft_j} comment \"$remarks\"" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") ${nft_j} comment \"$remarks\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" [ "$PROXY_IPV6" == "1" ] && { [ "${write_ipset_direct}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr @$nftset_whitelist6 counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} ip6 daddr $FAKE_IP_6 counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") jump PSW2_RULE comment \"$remarks\"" 2>/dev/null + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(factor $tcp_redir_ports "tcp dport") counter jump PSW2_RULE comment \"$remarks\"" 2>/dev/null nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ${_ipt_source} $(REDIRECT $redir_port TPROXY) comment \"$remarks\"" 2>/dev/null } echolog " - ${msg2}" @@ -388,7 +415,7 @@ load_acl() { [ "${write_ipset_direct}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr @$nftset_whitelist counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} ip daddr $FAKE_IP counter jump PSW2_RULE comment \"$remarks\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") jump PSW2_RULE comment \"$remarks\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(factor $udp_redir_ports "udp dport") counter jump PSW2_RULE comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} $(REDIRECT $redir_port TPROXY4) comment \"$remarks\"" [ "$PROXY_IPV6" == "1" ] && [ "$PROXY_IPV6_UDP" == "1" ] && { @@ -401,7 +428,7 @@ load_acl() { } nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ${_ipt_source} counter return comment \"$remarks\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null - unset _ipt_source msg msg2 + unset nft_chain nft_j _ipt_source msg msg2 done unset enabled sid remarks sources tcp_proxy_mode udp_proxy_mode tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node interface unset redir_port node_remark _acl_list @@ -413,8 +440,8 @@ load_acl() { msg="【默认】," [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { - nft add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" - nft add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\" + nft "add rule $NFTABLE_NAME $nft_prerouting_chain ip protocol tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_NO_REDIR_PORTS "tcp dport") counter return comment \"默认\"" if [ "$TCP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 TCP 端口[${TCP_NO_REDIR_PORTS}]" else @@ -438,12 +465,16 @@ load_acl() { msg2="${msg}使用 TCP 节点[$(config_n_get $NODE remarks)]" if [ -n "${is_tproxy}" ]; then msg2="${msg2}(TPROXY:${REDIR_PORT})" + nft_chain="PSW2_MANGLE" + nft_j="counter jump PSW2_RULE" else msg2="${msg2}(REDIRECT:${REDIR_PORT})" + nft_chain="PSW2_NAT" + nft_j="$(REDIRECT $REDIR_PORT)" fi - [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"默认\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ip daddr @$nftset_global_whitelist counter return comment \"默认\"" [ "$accept_icmp" = "1" ] && { nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT ip protocol icmp ip daddr $FAKE_IP $(REDIRECT) comment \"默认\"" @@ -457,19 +488,14 @@ load_acl() { nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT meta l4proto icmpv6 return comment \"默认\"" } - if [ -z "${is_tproxy}" ]; then - nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT) comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT) comment \"默认\"" - else - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" - fi + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j} comment \"默认\"" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j} comment \"默认\"" + [ -n "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" [ "$PROXY_IPV6" == "1" ] && { - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr @$nftset_global_whitelist6 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" } @@ -479,15 +505,15 @@ load_acl() { if [ "$UDP_PROXY_MODE" != "disable" ] && [ "$NODE" != "nil" ]; then msg2="${msg}使用 UDP 节点[$(config_n_get $NODE remarks)](TPROXY:${REDIR_PORT})" - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr @$nftset_global_whitelist counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr @$nftset_global_whitelist counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp $(REDIRECT $REDIR_PORT TPROXY4) comment \"默认\"" [ "$PROXY_IPV6" == "1" ] && [ "$PROXY_IPV6_UDP" == "1" ] && { - [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr @$nftset_global_whitelist6 counter return comment \"$remarks\"" + [ "${WRITE_IPSET_DIRECT}" = "1" ] && nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr @$nftset_global_whitelist6 counter return comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE comment \"默认\"" - nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE comment \"默认\"" + nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE comment \"默认\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp $(REDIRECT $REDIR_PORT TPROXY) comment \"默认\"" } @@ -515,11 +541,10 @@ filter_vps_addr() { } filter_vpsip() { - insert_nftset $NFTSET_VPSLIST "-1" $(uci show $CONFIG | grep ".address=" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d") - insert_nftset $NFTSET_VPSLIST6 "-1" $(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") - insert_nftset $NFTSET_VPSLIST "-1" $(uci show $CONFIG | grep ".download_address=" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sed -e "/^$/d") - insert_nftset $NFTSET_VPSLIST6 "-1" $(uci show $CONFIG | grep ".download_address=" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d") - echolog "加入所有节点到nftset[$NFTSET_VPSLIST]直连完成" + insert_nftset $NFTSET_VPSLIST "-1" $(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | grep -v "^127\.0\.0\.1$" | sed -e "/^$/d") + echolog " - [$?]加入所有IPv4节点到nftset[$NFTSET_VPSLIST]直连完成" + insert_nftset $NFTSET_VPSLIST6 "-1" $(uci show $CONFIG | grep -E "(.address=|.download_address=)" | cut -d "'" -f 2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d") + echolog " - [$?]加入所有IPv6节点到nftset[$NFTSET_VPSLIST6]直连完成" } filter_node() { @@ -683,6 +708,34 @@ add_firewall_rule() { gen_nftset $nftset_global_whitelist ipv4_addr 0 0 gen_nftset $nftset_global_whitelist6 ipv6_addr 0 0 + #分流规则的IP列表(使用分流节点时导入) + local USE_SHUNT_NODE=0 + NODE_PROTOCOL=$(config_n_get $NODE protocol) + [ "$NODE_PROTOCOL" = "_shunt" ] && USE_SHUNT_NODE=1 + [ "$USE_SHUNT_NODE" = "1" ] && { + local SHUNT_DEFAULT_NODE=$(config_n_get $NODE default_node _direct) + local GEOIP_CODE="" + 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_RULE_NODE=$(config_n_get $NODE ${shunt_id} nil) + [ "${SHUNT_RULE_NODE}" == "_default" ] && SHUNT_RULE_NODE=${SHUNT_DEFAULT_NODE} + [ "${SHUNT_RULE_NODE}" == "_direct" ] && { + insert_nftset $ipset_global_whitelist "0" $(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}") + insert_nftset $ipset_global_whitelist6 "0" $(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + [ "$(config_t_get global_rules enable_geoview)" = "1" ] && { + local geoip_code=$(config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "^geoip:" | grep -v "^geoip:private" | sed -E 's/^geoip:(.*)/\1/' | sed ':a;N;$!ba;s/\n/,/g') + [ -n "$geoip_code" ] && GEOIP_CODE="${GEOIP_CODE:+$GEOIP_CODE,}$geoip_code" + } + } + done + } + + if [ -n "$GEOIP_CODE" ] && type geoview &> /dev/null; then + insert_nftset $ipset_global_whitelist "0" $(get_geoip $GEOIP_CODE ipv4 | grep -E "(\.((2(5[0-5]|[0-4][0-9]))|[0-1]?[0-9]{1,2})){3}") + insert_nftset $ipset_global_whitelist6 "0" $(get_geoip $GEOIP_CODE ipv6 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}") + echolog " - [$?]解析并加入分流节点 GeoIP 到 IPSET 完成" + fi + # 过滤所有节点IP filter_vpsip > /dev/null 2>&1 & filter_haproxy > /dev/null 2>&1 & @@ -860,8 +913,8 @@ add_firewall_rule() { } [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { - nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return - nft add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_NO_REDIR_PORTS "udp dport") counter return" if [ "$UDP_NO_REDIR_PORTS" != "1:65535" ]; then echolog " - ${msg}不代理 UDP 端口[${UDP_NO_REDIR_PORTS}]" else @@ -884,21 +937,26 @@ add_firewall_rule() { nft "add rule $NFTABLE_NAME PSW2_ICMP_REDIRECT oif lo meta l4proto icmpv6 counter return" } - if [ -z "${is_tproxy}" ]; then - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip protocol tcp ip daddr $FAKE_IP $(REDIRECT $REDIR_PORT)" - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_NAT ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") $(REDIRECT $REDIR_PORT)" - nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" + if [ -n "${is_tproxy}" ]; then + nft_chain="PSW2_OUTPUT_MANGLE" + nft_j="counter jump PSW2_RULE" else - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol tcp ip daddr $FAKE_IP counter jump PSW2_RULE" - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" + nft_chain="PSW2_OUTPUT_NAT" + nft_j="$(REDIRECT $REDIR_PORT)" + fi + + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp ip daddr $FAKE_IP ${nft_j}" + nft "add rule $NFTABLE_NAME $nft_chain ip protocol tcp $(factor $TCP_REDIR_PORTS "tcp dport") ${nft_j}" + [ -z "${is_tproxy}" ] && nft "add rule $NFTABLE_NAME nat_output ip protocol tcp counter jump PSW2_OUTPUT_NAT" + [ -n "${is_tproxy}" ] && { nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol tcp iif lo counter return comment \"本机\"" nft "add rule $NFTABLE_NAME mangle_output ip protocol tcp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" - fi + } [ "$PROXY_IPV6" == "1" ] && { nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto tcp $(factor $TCP_REDIR_PORTS "tcp dport") counter jump PSW2_RULE" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto tcp iif lo counter return comment \"本机\"" } @@ -912,14 +970,14 @@ add_firewall_rule() { # 加载路由器自身代理 UDP if [ "$NODE" != "nil" ] && [ "$UDP_LOCALHOST_PROXY" = "1" ]; then nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp ip daddr $FAKE_IP counter jump PSW2_RULE" - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE ip protocol udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo $(REDIRECT $REDIR_PORT TPROXY4) comment \"本机\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE ip protocol udp iif lo counter return comment \"本机\"" nft "add rule $NFTABLE_NAME mangle_output ip protocol udp counter jump PSW2_OUTPUT_MANGLE comment \"PSW2_OUTPUT_MANGLE\"" if [ "$PROXY_IPV6_UDP" == "1" ]; then nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp ip6 daddr $FAKE_IP_6 jump PSW2_RULE" - nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") jump PSW2_RULE" + nft "add rule $NFTABLE_NAME PSW2_OUTPUT_MANGLE_V6 meta l4proto udp $(factor $UDP_REDIR_PORTS "udp dport") counter jump PSW2_RULE" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo $(REDIRECT $REDIR_PORT TPROXY) comment \"本机\"" nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp iif lo counter return comment \"本机\"" fi diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index cfc8779d8..29e46ecc6 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -1187,12 +1187,19 @@ local function processData(szType, content, add_mode, add_from) return result end -local function curl(url, file, ua) +local function curl(url, file, ua, mode) local curl_args = api.clone(api.curl_args) if ua and ua ~= "" and ua ~= "curl" then table.insert(curl_args, '--user-agent "' .. ua .. '"') end - local return_code, result = api.curl_logic(url, file, curl_args) + local return_code + if mode == "direct" then + return_code = api.curl_direct(url, file, curl_args) + elseif mode == "proxy" then + return_code = api.curl_proxy(url, file, curl_args) + else + return_code = api.curl_auto(url, file, curl_args) + end return return_code end @@ -1581,8 +1588,10 @@ local execute = function() domain_strategy_node = domain_strategy_default end local ua = value.user_agent - log('正在订阅:【' .. remark .. '】' .. url) - local raw = curl(url, "/tmp/" .. cfgid, ua) + local access_mode = value.access_mode + local result = (not access_mode) and "自动" or (access_mode == "direct" and "直连访问" or (access_mode == "proxy" and "通过代理" or "自动")) + log('正在订阅:【' .. remark .. '】' .. url .. ' [' .. result .. ']') + local raw = curl(url, "/tmp/" .. cfgid, ua, access_mode) if raw == 0 then local f = io.open("/tmp/" .. cfgid, "r") local stdout = f:read("*all")