luci: support device interface level acl

This commit is contained in:
Jarao 2024-09-23 23:10:33 +08:00 committed by GitHub
parent 2fd2b58521
commit a1fb65f3a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 104 additions and 49 deletions

View File

@ -46,7 +46,7 @@ o = s:option(DummyValue, "sources", translate("Source"))
o.rawhtml = true o.rawhtml = true
o.cfgvalue = function(t, n) o.cfgvalue = function(t, n)
local e = '' local e = ''
local v = Value.cfgvalue(t, n) or '' local v = Value.cfgvalue(t, n) or '-'
string.gsub(v, '[^' .. " " .. ']+', function(w) string.gsub(v, '[^' .. " " .. ']+', function(w)
local a = w local a = w
if mac_t[w] then if mac_t[w] then
@ -60,4 +60,10 @@ o.cfgvalue = function(t, n)
return e return e
end 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 return m

View File

@ -70,6 +70,11 @@ o = s:option(Value, "remarks", translate("Remarks"))
o.default = arg[1] o.default = arg[1]
o.rmempty = true 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 = {} local mac_t = {}
sys.net.mac_hints(function(e, t) sys.net.mac_hints(function(e, t)
mac_t[#mac_t + 1] = { mac_t[#mac_t + 1] = {
@ -90,6 +95,17 @@ table.sort(mac_t, function(a,b)
return false return false
end) 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 ---- Source
sources = s:option(DynamicList, "sources", translate("Source")) sources = s:option(DynamicList, "sources", translate("Source"))
sources.description = "<ul><li>" .. translate("Example:") sources.description = "<ul><li>" .. translate("Example:")
@ -103,6 +119,8 @@ sources.cast = "string"
for _, key in pairs(mac_t) do for _, key in pairs(mac_t) do
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip}) sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
end end
sources:depends({ use_interface = 0 })
sources.cfgvalue = function(self, section) sources.cfgvalue = function(self, section)
local value local value
if self.tag_error[section] then if self.tag_error[section] then

View File

@ -946,6 +946,12 @@ msgstr "例:"
msgid "IP range" msgid "IP range"
msgstr "IP 范围" msgstr "IP 范围"
msgid "Source Interface"
msgstr "源接口"
msgid "Use Interface With ACLs"
msgstr "使用接口控制"
msgid "Remarks" msgid "Remarks"
msgstr "备注" msgstr "备注"

View File

@ -946,13 +946,13 @@ acl_app() {
dnsmasq_port=11400 dnsmasq_port=11400
for item in $items; do for item in $items; do
index=$(expr $index + 1) 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 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 config_file 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}') 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-) eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
[ "$enabled" = "1" ] || continue [ "$enabled" = "1" ] || continue
[ -z "${sources}" ] && continue [ -z "${sources}" ] && [ -z "${interface}" ] && continue
for s in $sources; do for s in $sources; do
is_iprange=$(lua_api "iprange(\"${s}\")") is_iprange=$(lua_api "iprange(\"${s}\")")
if [ "${is_iprange}" = "true" ]; then if [ "${is_iprange}" = "true" ]; then
@ -968,9 +968,14 @@ acl_app() {
fi fi
fi fi
done 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 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" tcp_proxy_mode="global"
udp_proxy_mode="global" udp_proxy_mode="global"
@ -1041,8 +1046,8 @@ acl_app() {
echo "${redir_port}" > $TMP_ACL_PATH/$sid/var_port 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 [ -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 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 unset _ip _mac _iprange _ipset _ip_or_mac rule_list config_file interface_list
unset redirect_dns_port unset redirect_dns_port
done done
unset redir_port dns_port dnsmasq_port unset redir_port dns_port dnsmasq_port

View File

@ -222,25 +222,35 @@ load_acl() {
fi fi
} }
for i in $(cat ${TMP_ACL_PATH}/${sid}/rule_list); do _acl_list=${TMP_ACL_PATH}/${sid}/rule_list
if [ -n "$(echo ${i} | grep '^iprange:')" ]; then [ $use_interface = "1" ] && _acl_list=${TMP_ACL_PATH}/${sid}/interface_list
_iprange=$(echo ${i} | sed 's#iprange:##g')
_ipt_source=$(factor ${_iprange} "-m iprange --src-range") for i in $(cat $_acl_list); do
msg="$remarksIP range【${_iprange}】," if [ $use_interface = "0" ]; then
elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
_ipset=$(echo ${i} | sed 's#ipset:##g') _iprange=$(echo ${i} | sed 's#iprange:##g')
_ipt_source="-m set --match-set ${_ipset} src" _ipt_source=$(factor ${_iprange} "-m iprange --src-range")
msg="$remarksIPset【${_ipset}】," msg="$remarksIP range【${_iprange}】,"
elif [ -n "$(echo ${i} | grep '^ip:')" ]; then elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
_ip=$(echo ${i} | sed 's#ip:##g') _ipset=$(echo ${i} | sed 's#ipset:##g')
_ipt_source=$(factor ${_ip} "-s") _ipt_source="-m set --match-set ${_ipset} src"
msg="$remarksIP【${_ip}】," msg="$remarksIPset【${_ipset}】,"
elif [ -n "$(echo ${i} | grep '^mac:')" ]; then elif [ -n "$(echo ${i} | grep '^ip:')" ]; then
_mac=$(echo ${i} | sed 's#mac:##g') _ip=$(echo ${i} | sed 's#ip:##g')
_ipt_source=$(factor ${_mac} "-m mac --mac-source") _ipt_source=$(factor ${_ip} "-s")
msg="$remarksMAC【${_mac}】," msg="$remarksIP【${_ip}】,"
elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
_mac=$(echo ${i} | sed 's#mac:##g')
_ipt_source=$(factor ${_mac} "-m mac --mac-source")
msg="$remarksMAC【${_mac}】,"
else
continue
fi
else else
continue [ -z "${i}" ] && continue
_ifname="${i}"
_ipt_source="-i $_ifname"
msg="$remarksIF【${_ifname}】,"
fi fi
ipt_tmp=$ipt_n ipt_tmp=$ipt_n
@ -329,8 +339,8 @@ load_acl() {
$ipt_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN $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 $ip6t_m -A PSW2 $(comment "$remarks") ${_ipt_source} -p udp -j RETURN 2>/dev/null
done done
unset enabled sid remarks sources tcp_no_redir_ports udp_no_redir_ports tcp_redir_ports udp_redir_ports node 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 unset _ip _mac _iprange _ipset _ip_or_mac rule_list node_remark _acl_list
unset ipt_tmp msg msg2 unset ipt_tmp msg msg2
done done
} }

View File

@ -275,26 +275,36 @@ load_acl() {
gen_nftset $nftset_whitelist6 ipv6_addr 3d 3d gen_nftset $nftset_whitelist6 ipv6_addr 3d 3d
fi fi
} }
for i in $(cat ${TMP_ACL_PATH}/${sid}/rule_list); do _acl_list=${TMP_ACL_PATH}/${sid}/rule_list
if [ -n "$(echo ${i} | grep '^iprange:')" ]; then [ $use_interface = "1" ] && _acl_list=${TMP_ACL_PATH}/${sid}/interface_list
_iprange=$(echo ${i} | sed 's#iprange:##g')
_ipt_source=$(factor ${_iprange} "ip saddr") for i in $(cat $_acl_list); do
msg="$remarksIP range【${_iprange}】," if [ $use_interface = "0" ]; then
elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then if [ -n "$(echo ${i} | grep '^iprange:')" ]; then
_ipset=$(echo ${i} | sed 's#ipset:##g') _iprange=$(echo ${i} | sed 's#iprange:##g')
_ipt_source="ip daddr @${_ipset}" _ipt_source=$(factor ${_iprange} "ip saddr")
msg="$remarksNFTset【${_ipset}】," msg="$remarksIP range【${_iprange}】,"
elif [ -n "$(echo ${i} | grep '^ip:')" ]; then elif [ -n "$(echo ${i} | grep '^ipset:')" ]; then
_ip=$(echo ${i} | sed 's#ip:##g') _ipset=$(echo ${i} | sed 's#ipset:##g')
_ipt_source=$(factor ${_ip} "ip saddr") _ipt_source="ip daddr @${_ipset}"
msg="$remarksIP【${_ip}】," msg="$remarksNFTset【${_ipset}】,"
elif [ -n "$(echo ${i} | grep '^mac:')" ]; then elif [ -n "$(echo ${i} | grep '^ip:')" ]; then
_mac=$(echo ${i} | sed 's#mac:##g') _ip=$(echo ${i} | sed 's#ip:##g')
_ipt_source=$(factor ${_mac} "ether saddr") _ipt_source=$(factor ${_ip} "ip saddr")
msg="$remarksMAC【${_mac}】," msg="$remarksIP【${_ip}】,"
elif [ -n "$(echo ${i} | grep '^mac:')" ]; then
_mac=$(echo ${i} | sed 's#mac:##g')
_ipt_source=$(factor ${_mac} "ether saddr")
msg="$remarksMAC【${_mac}】,"
else
continue
fi
else else
continue [ -z "${i}" ] && continue
_ifname="${i}"
_ipt_source="iifname $_ifname"
msg="$remarksIF【${_ifname}】,"
fi fi
[ "$tcp_no_redir_ports" != "disable" ] && { [ "$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 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 nft "add rule $NFTABLE_NAME PSW2_MANGLE_V6 meta l4proto udp ${_ipt_source} counter return comment \"$remarks\"" 2>/dev/null
done 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 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 unset _ip _mac _iprange _ipset _ip_or_mac rule_list redir_port node_remark _acl_list _ifname
unset msg msg2 unset msg msg2
done done
} }