diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua
index 26a07ac3b..1eb1ac542 100644
--- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua
+++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl.lua
@@ -46,7 +46,7 @@ o = s:option(DummyValue, "sources", translate("Source"))
o.rawhtml = true
o.cfgvalue = function(t, n)
local e = ''
- local v = Value.cfgvalue(t, n) or ''
+ local v = Value.cfgvalue(t, n) or '-'
string.gsub(v, '[^' .. " " .. ']+', function(w)
local a = w
if mac_t[w] then
@@ -60,4 +60,10 @@ o.cfgvalue = function(t, n)
return e
end
+i = s:option(DummyValue, "interface", translate("Source Interface"))
+i.cfgvalue = function(t, n)
+ local v = Value.cfgvalue(t, n) or '-'
+ return v
+end
+
return m
diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua
index e6c9730c8..2bb7a96d5 100644
--- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua
+++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/acl_config.lua
@@ -70,6 +70,11 @@ o = s:option(Value, "remarks", translate("Remarks"))
o.default = arg[1]
o.rmempty = true
+use_if = s:option(Flag, "use_interface", translate("Use Interface With ACLs"))
+use_if.default = 0
+use_if.rmempty = false
+
+
local mac_t = {}
sys.net.mac_hints(function(e, t)
mac_t[#mac_t + 1] = {
@@ -90,6 +95,17 @@ table.sort(mac_t, function(a,b)
return false
end)
+local device_list = {}
+device_list = sys.net.devices()
+table.sort(device_list)
+interface = s:option(ListValue, "interface", translate("Source Interface"))
+
+for k, name in ipairs(device_list) do
+ interface:value(name)
+end
+
+interface:depends({ use_interface = 1 })
+
---- Source
sources = s:option(DynamicList, "sources", translate("Source"))
sources.description = "
- " .. translate("Example:")
@@ -103,6 +119,8 @@ sources.cast = "string"
for _, key in pairs(mac_t) do
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
end
+sources:depends({ use_interface = 0 })
+
sources.cfgvalue = function(self, section)
local value
if self.tag_error[section] then
diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
index 8cb2989b9..42bdf2c3c 100644
--- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua
+++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
@@ -1238,7 +1238,10 @@ function gen_config(var)
address = direct_dns_udp_server,
port = tonumber(direct_dns_udp_port) or 53,
network = "udp",
- nonIPQuery = "skip"
+ nonIPQuery = "skip",
+ blockTypes = {
+ 65
+ }
},
proxySettings = {
tag = "direct"
diff --git a/luci-app-passwall2/po/zh-cn/passwall2.po b/luci-app-passwall2/po/zh-cn/passwall2.po
index 81859642a..856af5b39 100644
--- a/luci-app-passwall2/po/zh-cn/passwall2.po
+++ b/luci-app-passwall2/po/zh-cn/passwall2.po
@@ -946,6 +946,12 @@ msgstr "例:"
msgid "IP range"
msgstr "IP 范围"
+msgid "Source Interface"
+msgstr "源接口"
+
+msgid "Use Interface With ACLs"
+msgstr "使用接口控制"
+
msgid "Remarks"
msgstr "备注"
diff --git a/luci-app-passwall2/root/usr/share/passwall2/app.sh b/luci-app-passwall2/root/usr/share/passwall2/app.sh
index fa2e73bf3..1af69469f 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/app.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/app.sh
@@ -946,13 +946,13 @@ acl_app() {
dnsmasq_port=11400
for item in $items; do
index=$(expr $index + 1)
- local enabled sid remarks sources node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
- local _ip _mac _iprange _ipset _ip_or_mac rule_list config_file
+ local enabled sid remarks sources node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy interface use_interface
+ local _ip _mac _iprange _ipset _ip_or_mac rule_list interface_list config_file
sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
[ "$enabled" = "1" ] || continue
- [ -z "${sources}" ] && continue
+ [ -z "${sources}" ] && [ -z "${interface}" ] && continue
for s in $sources; do
is_iprange=$(lua_api "iprange(\"${s}\")")
if [ "${is_iprange}" = "true" ]; then
@@ -968,9 +968,14 @@ acl_app() {
fi
fi
done
- [ -z "${rule_list}" ] && continue
+ for i in $interface; do
+ interface_list="${interface_list}\n$i"
+ done
+ [ -z "${rule_list}" ] && [ -z "${interface_list}" ] && continue
mkdir -p $TMP_ACL_PATH/$sid
- echo -e "${rule_list}" | sed '/^$/d' > $TMP_ACL_PATH/$sid/rule_list
+
+ [ ! -z "${rule_list}" ] && echo -e "${rule_list}" | sed '/^$/d' > $TMP_ACL_PATH/$sid/rule_list
+ [ ! -z "${interface_list}" ] && echo -e "${interface_list}" | sed '/^$/d' > $TMP_ACL_PATH/$sid/interface_list
tcp_proxy_mode="global"
udp_proxy_mode="global"
@@ -1041,8 +1046,8 @@ acl_app() {
echo "${redir_port}" > $TMP_ACL_PATH/$sid/var_port
}
[ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port
- unset enabled sid remarks sources node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
- unset _ip _mac _iprange _ipset _ip_or_mac rule_list config_file
+ unset enabled sid remarks sources interface node direct_dns_query_strategy remote_dns_protocol remote_dns remote_dns_doh remote_dns_client_ip remote_dns_detour remote_fakedns remote_dns_query_strategy
+ unset _ip _mac _iprange _ipset _ip_or_mac rule_list config_file interface_list
unset redirect_dns_port
done
unset redir_port dns_port dnsmasq_port
diff --git a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
index 3e0c6e3bf..73af69df0 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/iptables.sh
@@ -222,25 +222,35 @@ load_acl() {
fi
}
- for i in $(cat ${TMP_ACL_PATH}/${sid}/rule_list); do
- if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
- _iprange=$(echo ${i} | sed 's#iprange:##g')
- _ipt_source=$(factor ${_iprange} "-m iprange --src-range")
- msg="【$remarks】,IP range【${_iprange}】,"
- elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
- _ipset=$(echo ${i} | sed 's#ipset:##g')
- _ipt_source="-m set --match-set ${_ipset} src"
- msg="【$remarks】,IPset【${_ipset}】,"
- elif [ -n "$(echo ${i} | grep '^ip:')" ]; then
- _ip=$(echo ${i} | sed 's#ip:##g')
- _ipt_source=$(factor ${_ip} "-s")
- msg="【$remarks】,IP【${_ip}】,"
- elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
- _mac=$(echo ${i} | sed 's#mac:##g')
- _ipt_source=$(factor ${_mac} "-m mac --mac-source")
- msg="【$remarks】,MAC【${_mac}】,"
+ _acl_list=${TMP_ACL_PATH}/${sid}/rule_list
+ [ $use_interface = "1" ] && _acl_list=${TMP_ACL_PATH}/${sid}/interface_list
+
+ for i in $(cat $_acl_list); do
+ if [ $use_interface = "0" ]; then
+ if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
+ _iprange=$(echo ${i} | sed 's#iprange:##g')
+ _ipt_source=$(factor ${_iprange} "-m iprange --src-range")
+ msg="【$remarks】,IP range【${_iprange}】,"
+ elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
+ _ipset=$(echo ${i} | sed 's#ipset:##g')
+ _ipt_source="-m set --match-set ${_ipset} src"
+ msg="【$remarks】,IPset【${_ipset}】,"
+ elif [ -n "$(echo ${i} | grep '^ip:')" ]; then
+ _ip=$(echo ${i} | sed 's#ip:##g')
+ _ipt_source=$(factor ${_ip} "-s")
+ msg="【$remarks】,IP【${_ip}】,"
+ elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
+ _mac=$(echo ${i} | sed 's#mac:##g')
+ _ipt_source=$(factor ${_mac} "-m mac --mac-source")
+ msg="【$remarks】,MAC【${_mac}】,"
+ else
+ continue
+ fi
else
- continue
+ [ -z "${i}" ] && continue
+ _ifname="${i}"
+ _ipt_source="-i $_ifname"
+ msg="【$remarks】,IF【${_ifname}】,"
fi
ipt_tmp=$ipt_n
@@ -329,8 +339,8 @@ 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
done
- unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node
- unset _ip _mac _iprange _ipset _ip_or_mac rule_list node_remark
+ unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node use_interface interface
+ unset _ip _mac _iprange _ipset _ip_or_mac rule_list node_remark _acl_list
unset ipt_tmp msg msg2
done
}
diff --git a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
index 854d1b235..86a27f1bb 100755
--- a/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
+++ b/luci-app-passwall2/root/usr/share/passwall2/nftables.sh
@@ -275,26 +275,36 @@ load_acl() {
gen_nftset $nftset_whitelist6 ipv6_addr 3d 3d
fi
}
-
- for i in $(cat ${TMP_ACL_PATH}/${sid}/rule_list); do
- if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
- _iprange=$(echo ${i} | sed 's#iprange:##g')
- _ipt_source=$(factor ${_iprange} "ip saddr")
- msg="【$remarks】,IP range【${_iprange}】,"
- elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
- _ipset=$(echo ${i} | sed 's#ipset:##g')
- _ipt_source="ip daddr @${_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")
- msg="【$remarks】,IP【${_ip}】,"
- elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
- _mac=$(echo ${i} | sed 's#mac:##g')
- _ipt_source=$(factor ${_mac} "ether saddr")
- msg="【$remarks】,MAC【${_mac}】,"
+
+ _acl_list=${TMP_ACL_PATH}/${sid}/rule_list
+ [ $use_interface = "1" ] && _acl_list=${TMP_ACL_PATH}/${sid}/interface_list
+
+ for i in $(cat $_acl_list); do
+ if [ $use_interface = "0" ]; then
+ if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
+ _iprange=$(echo ${i} | sed 's#iprange:##g')
+ _ipt_source=$(factor ${_iprange} "ip saddr")
+ msg="【$remarks】,IP range【${_iprange}】,"
+ elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
+ _ipset=$(echo ${i} | sed 's#ipset:##g')
+ _ipt_source="ip daddr @${_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")
+ msg="【$remarks】,IP【${_ip}】,"
+ elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
+ _mac=$(echo ${i} | sed 's#mac:##g')
+ _ipt_source=$(factor ${_mac} "ether saddr")
+ msg="【$remarks】,MAC【${_mac}】,"
+ else
+ continue
+ fi
else
- continue
+ [ -z "${i}" ] && continue
+ _ifname="${i}"
+ _ipt_source="iifname $_ifname"
+ msg="【$remarks】,IF【${_ifname}】,"
fi
[ "$tcp_no_redir_ports" != "disable" ] && {
@@ -384,8 +394,8 @@ 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
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
- unset _ip _mac _iprange _ipset _ip_or_mac rule_list redir_port node_remark
+ 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 use_interface interface
+ unset _ip _mac _iprange _ipset _ip_or_mac rule_list redir_port node_remark _acl_list _ifname
unset msg msg2
done
}