pbr: update to 1.2.1-r35

pbr 1.2.1-r35

Makefile:
* split uci-defaults into different purpose files
* add handling of netifd integration

Config:
* update with default values for all options (thanks @betonmischer86)

Init-script:
* add netifd integration handling
* add ip() function to emulate ip rule replace
* add netbird intrfaces support (thanks @egc112)
* reorganize loading/handling of options in load_package_config()
* improve display of interface triggers in service_triggers()
* remove chains cleanup from stop_service() due to exclusive use of fw4 nft files
* improve status_service() output
* drop input and postrouting as valid options for policy chain

Uci-defaults files:
* 91-pbr-nft: cosmetic improvements

Default nft files:
* drop use of input and postrouting chanins

Custom User files:
* dns-prefetch: functional improvements (thanks @betonmischer86)

Signed-off-by: Stan Grishin <stangri@melmac.ca>
This commit is contained in:
Stan Grishin
2025-12-08 19:51:30 +00:00
parent 803a754525
commit 8bf5f683fe
8 changed files with 592 additions and 341 deletions

View File

@@ -4,8 +4,8 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=pbr PKG_NAME:=pbr
PKG_VERSION:=1.2.0 PKG_VERSION:=1.2.1
PKG_RELEASE:=2 PKG_RELEASE:=35
PKG_LICENSE:=AGPL-3.0-or-later PKG_LICENSE:=AGPL-3.0-or-later
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca> PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
@@ -82,27 +82,28 @@ define Package/pbr/default/install
$(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d/ $(CP) ./files/usr/share/nftables.d/* $(1)/usr/share/nftables.d/
$(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/90-pbr $(1)/etc/uci-defaults/90-pbr $(INSTALL_BIN) ./files/etc/uci-defaults/90-pbr $(1)/etc/uci-defaults/90-pbr
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-nft $(1)/etc/uci-defaults/91-pbr-nft
$(INSTALL_BIN) ./files/etc/uci-defaults/99-pbr-version $(1)/etc/uci-defaults/99-pbr-version
endef endef
define Package/pbr/install define Package/pbr/install
$(call Package/pbr/default/install,$(1)) $(call Package/pbr/default/install,$(1))
$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-nft $(1)/etc/uci-defaults/91-pbr-nft
endef endef
define Package/pbr-netifd/install define Package/pbr-netifd/install
$(call Package/pbr/default/install,$(1)) $(call Package/pbr/default/install,$(1))
$(INSTALL_DIR) $(1)/etc/uci-defaults $(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-netifd $(1)/etc/uci-defaults/91-pbr-netifd
endef endef
# $(INSTALL_BIN) ./files/etc/uci-defaults/91-pbr-netifd $(1)/etc/uci-defaults/91-pbr-netifd
define Package/pbr/postinst define Package/pbr/postinst
#!/bin/sh #!/bin/sh
# check if we are on real system # check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then if [ -z "$${IPKG_INSTROOT}" ]; then
chmod -x /etc/init.d/pbr || true /etc/init.d/pbr netifd check && {
fw4 -q reload || true echo -n "Reinstalling pbr netifd integration... "
chmod +x /etc/init.d/pbr || true /etc/init.d/pbr netifd install >/dev/null 2>&1 && echo "OK" || echo "FAIL"
}
echo -n "Installing rc.d symlink for pbr... " echo -n "Installing rc.d symlink for pbr... "
/etc/init.d/pbr enable && echo "OK" || echo "FAIL" /etc/init.d/pbr enable && echo "OK" || echo "FAIL"
fi fi
@@ -114,9 +115,13 @@ define Package/pbr/prerm
# check if we are on real system # check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then if [ -z "$${IPKG_INSTROOT}" ]; then
echo -n "Stopping pbr service... " echo -n "Stopping pbr service... "
/etc/init.d/pbr stop quiet >/dev/null 2>&1 && echo "OK" || echo "FAIL" /etc/init.d/pbr stop >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo -n "Removing rc.d symlink for pbr... " echo -n "Removing rc.d symlink for pbr... "
/etc/init.d/pbr disable && echo "OK" || echo "FAIL" /etc/init.d/pbr disable && echo "OK" || echo "FAIL"
/etc/init.d/pbr netifd check && {
echo -n "Uninstalling pbr netifd integration... "
/etc/init.d/pbr netifd uninstall >/dev/null 2>&1 && echo "OK" || echo "FAIL"
}
fi fi
exit 0 exit 0
endef endef
@@ -134,10 +139,9 @@ define Package/pbr-netifd/postinst
#!/bin/sh #!/bin/sh
# check if we are on real system # check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then if [ -z "$${IPKG_INSTROOT}" ]; then
chmod -x /etc/init.d/pbr || true echo -n "Installing pbr integration with netifd... "
fw4 -q reload || true /etc/init.d/pbr netifd check && /etc/init.d/pbr netifd install >/dev/null 2>&1 && echo "OK" || echo "FAIL"
chmod +x /etc/init.d/pbr || true echo -n "Installing rc.d symlink for pbr... "
echo -n "Installing rc.d symlink for pbr-netifd... "
/etc/init.d/pbr enable && echo "OK" || echo "FAIL" /etc/init.d/pbr enable && echo "OK" || echo "FAIL"
fi fi
exit 0 exit 0
@@ -147,31 +151,12 @@ define Package/pbr-netifd/prerm
#!/bin/sh #!/bin/sh
# check if we are on real system # check if we are on real system
if [ -z "$${IPKG_INSTROOT}" ]; then if [ -z "$${IPKG_INSTROOT}" ]; then
echo -n "Stopping pbr-netifd service... " echo -n "Stopping pbr service... "
/etc/init.d/pbr stop quiet >/dev/null 2>&1 && echo "OK" || echo "FAIL" /etc/init.d/pbr stop >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo -n "Removing rc.d symlink for pbr... " echo -n "Removing rc.d symlink for pbr... "
/etc/init.d/pbr disable && echo "OK" || echo "FAIL" /etc/init.d/pbr disable && echo "OK" || echo "FAIL"
echo -n "Cleaning up /etc/iproute2/rt_tables... " echo -n "Uninstalling pbr integration with netifd... "
if sed -i '/pbr_/d' /etc/iproute2/rt_tables; then /etc/init.d/pbr netifd check && /etc/init.d/pbr netifd uninstall >/dev/null 2>&1 && echo "OK" || echo "FAIL"
echo "OK"
else
echo "FAIL"
fi
echo -n "Cleaning up /etc/config/network... "
uci -q delete 'network.pbr_default' || true
uci -q delete 'network.pbr_default6' || true
uci commit network || true
if sed -i '/ip.table.*pbr_/d' /etc/config/network; then
echo "OK"
else
echo "FAIL"
fi
echo -n "Restarting Network... "
if /etc/init.d/network restart >/dev/null 2>&1; then
echo "OK"
else
echo "FAIL"
fi
fi fi
exit 0 exit 0
endef endef

View File

@@ -1,23 +1,26 @@
config pbr 'config' config pbr 'config'
option enabled '0' option enabled '0'
option verbosity '2' option fw_mask '00ff0000'
option strict_enforcement '1'
option resolver_set 'dnsmasq.nftset'
list resolver_instance '*'
option ipv6_enabled '0'
list ignored_interface 'vpnserver' list ignored_interface 'vpnserver'
option rule_create_option 'add' option ipv6_enabled '0'
option procd_boot_trigger_delay '5000' option lan_device 'br-lan'
option procd_reload_delay '1'
option webui_show_ignore_target '0'
option nft_rule_counter '0' option nft_rule_counter '0'
option nft_set_auto_merge '1' option nft_set_auto_merge '1'
option nft_set_counter '0' option nft_set_counter '0'
option nft_set_flags_interval '1' option nft_set_flags_interval '1'
option nft_set_flags_timeout '0' option nft_set_flags_timeout '0'
option nft_set_gc_interval ''
option nft_set_policy 'performance' option nft_set_policy 'performance'
option nft_set_timeout '' option nft_user_set_counter '0'
option procd_boot_trigger_delay '5000'
option procd_reload_delay '0'
list resolver_instance '*'
option resolver_set 'dnsmasq.nftset'
option strict_enforcement '1'
option uplink_interface 'wan'
option uplink_interface6 'wan6'
option uplink_ip_rules_priority '30000'
option uplink_mark '00010000'
option verbosity '2'
list webui_supported_protocol 'all' list webui_supported_protocol 'all'
list webui_supported_protocol 'tcp' list webui_supported_protocol 'tcp'
list webui_supported_protocol 'udp' list webui_supported_protocol 'udp'

File diff suppressed because it is too large Load Diff

View File

@@ -11,7 +11,6 @@ fi
# Transition from older versions of pbr # Transition from older versions of pbr
sed -i "s/resolver_ipset/resolver_set/g" /etc/config/pbr sed -i "s/resolver_ipset/resolver_set/g" /etc/config/pbr
sed -i "s/iptables_rule_option/rule_create_option/g" /etc/config/pbr
sed -i "s/'FORWARD'/'forward'/g" /etc/config/pbr sed -i "s/'FORWARD'/'forward'/g" /etc/config/pbr
sed -i "s/'INPUT'/'input'/g" /etc/config/pbr sed -i "s/'INPUT'/'input'/g" /etc/config/pbr
sed -i "s/'OUTPUT'/'output'/g" /etc/config/pbr sed -i "s/'OUTPUT'/'output'/g" /etc/config/pbr

View File

@@ -9,6 +9,10 @@ else
printf "%b: pbr init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$pbrFunctionsFile" printf "%b: pbr init.d file (%s) not found! \n" '\033[0;31mERROR\033[0m' "$pbrFunctionsFile"
fi fi
setup_netifd 'on_install' if netifd 'check'; then
rc_procd stop_service 'on_netifd_install'
netifd 'install'
rc_procd start_service 'on_netifd_install'
fi
exit 0 exit 0

View File

@@ -10,15 +10,15 @@ else
fi fi
# Transition resolver_set depending on dnsmasq support # Transition resolver_set depending on dnsmasq support
if [ "$(uci_get pbr config resolver_set)" != 'dnsmasq.nftset' ]; then if [ "$(uci_get "$packageName" 'config' 'resolver_set')" != 'dnsmasq.nftset' ]; then
if check_dnsmasq_nftset; then if check_dnsmasq_nftset; then
output "Setting resolver_set to 'dnsmasq.nftset'... " output "Setting resolver_set to 'dnsmasq.nftset'... "
uci_set pbr config resolver_set 'dnsmasq.nftset' && output_okn || output_failn uci_set "$packageName" 'config' 'resolver_set' 'dnsmasq.nftset' && output_okn || output_failn
else else
output "Setting resolver_set to 'none'... " output "Setting resolver_set to 'none'... "
uci_set pbr config resolver_set 'none' && output_okn || output_failn uci_set "$packageName" 'config' 'resolver_set' 'none' && output_okn || output_failn
fi fi
uci_commit pbr uci_commit "$packageName"
fi fi
exit 0 exit 0

View File

@@ -1,6 +1,4 @@
chain pbr_dstnat {} chain pbr_dstnat {}
chain pbr_forward {} chain pbr_forward {}
chain pbr_input {}
chain pbr_output {} chain pbr_output {}
chain pbr_prerouting {} chain pbr_prerouting {}
chain pbr_postrouting {}

View File

@@ -1,59 +1,67 @@
#!/bin/sh #!/bin/sh
# When using pbr with dnsmasq's nft set support, a domain-based policy will not take effect until # When using pbr with dnsmasq's nft set support, a domain-based policy will not take effect until
# the remote domain name has been resolved by dnsmasq. Resolve all domain names in pbr policies in advance. # the remote domain name has been resolved by dnsmasq. Resolve all domain names in pbr policies in advance.
# shellcheck disable=SC3043
( (
timeout_nft='10' pipe_nslookup="/var/run/${packageName}.nslookup.$$"
timeout_dnsmasq='20'
pipe_ubus="/tmp/pipe.ubus.$$"
pipe_nslookup="/tmp/pipe.nslookup.$$"
log_abort='domain names in policies not resolved'
output() {
local msg="$*"
msg="$(printf '%b' "$msg" | sed 's/\x1b\[[0-9;]*m//g')"
# shellcheck disable=SC2154 # shellcheck disable=SC2154
output()
{
msg="$*"
msg=$(printf '%b' "$msg" | sed 's/\x1b\[[0-9;]*m//g')
logger -t "$packageName [$$]" "$(printf '%b' "$msg")" logger -t "$packageName [$$]" "$(printf '%b' "$msg")"
} }
nft_ready() nft_ready() {
{ local timeout_nft='10'
while ! /usr/sbin/nft list sets 'inet' | grep -q "pbr"; do while ! /usr/sbin/nft list sets 'inet' | grep -q "pbr"; do
[ "$timeout_nft" -eq '0' ] && { [ "$timeout_nft" -eq '0' ] && {
output "Pbr's nft sets not found, $log_abort $__FAIL__"
return 1 return 1
} }
sleep '1' && timeout_nft=$((timeout_nft - 1)) sleep '1' && timeout_nft="$((timeout_nft - 1))"
done done
} }
run_nslookup() run_nslookup() {
{ local output reason
output=$(nslookup "$1" 127.0.0.1) && { echo '0' > "$pipe_nslookup"; return; }
reason=$(printf '%s' "$output" | grep -Eo -m 1 'NXDOMAIN|SERVFAIL|timed out') && \ output="$(nslookup "$1" 127.0.0.1)" && { echo '0' > "$pipe_nslookup"; return; }
reason="$(printf '%s' "$output" | grep -Eo -m 1 'NXDOMAIN|SERVFAIL|timed out')" && \
output "$_WARNING_ Lookup failed for $domain ($reason)" output "$_WARNING_ Lookup failed for $domain ($reason)"
echo '1' > "$pipe_nslookup" echo '1' > "$pipe_nslookup"
} }
# shellcheck disable=SC2162 nslookup_tracker() {
nslookup_tracker() local entries errors
{
while read ec; do while read -r rc; do
entries=$((entries + 1)) entries="$((entries + 1))"
[ "$ec" -eq '1' ] && errors=$((errors + 1)) [ "$rc" -eq '1' ] && errors="$((errors + 1))"
done < "$pipe_nslookup" done < "$pipe_nslookup"
output "Finished resolving $entries domain names in policies (${errors:-0} failed) $__OK__" output "Finished resolving $entries domain names in policies (${errors:-0} failed) $__OK__"
} }
main() {
local pipe_ubus="/var/run/${packageName}.ubus.$$"
local timeout_dnsmasq='20'
local msg_abort='domain names in policies not resolved'
local dnsmasq_restarted ubus_listen_pid event domain entries
local rc='0'
[ -n "$resolverSetSupported" ] || { [ -n "$resolverSetSupported" ] || {
output "Resolver set support disabled, $log_abort $__FAIL__" output "Resolver set support disabled, $msg_abort $__FAIL__"
exit rc='1'
return "$rc"
} }
mkfifo "$pipe_ubus" mkfifo "$pipe_ubus"
mkfifo "$pipe_nslookup" mkfifo "$pipe_nslookup"
ubus listen -m 'ubus.object.add' > "$pipe_ubus" & ubus_listen_pid=$! # The subshell may be necessary for "$!" to expand to a correct value
( exec ubus listen -m 'ubus.object.add' > "$pipe_ubus" ) &
ubus_listen_pid="$!"
# shellcheck disable=SC3045 # shellcheck disable=SC3045
while read -t "$timeout_dnsmasq" -r event; do while read -t "$timeout_dnsmasq" -r event; do
@@ -61,27 +69,38 @@
dnsmasq_restarted='1' dnsmasq_restarted='1'
# shellcheck disable=SC2154 # shellcheck disable=SC2154
[ -f "$packageDnsmasqFile" ] || { [ -f "$packageDnsmasqFile" ] || {
output "File $packageDnsmasqFile not found, $log_abort $__FAIL__" output "File $packageDnsmasqFile not found, $msg_abort $__FAIL__"
rc='1'
break
}
nft_ready || {
output "Pbr's nft sets not found, $msg_abort $__FAIL__"
rc='1'
break break
} }
nft_ready || break
nslookup_tracker & exec 3>"$pipe_nslookup" nslookup_tracker & exec 3>"$pipe_nslookup"
( (
output "Resolving domain names in policies..." output "Resolving domain names in policies..."
while IFS='/' read -r _ domain _; do while IFS='/' read -r _ domain _; do
[ -n "$domain" ] && run_nslookup "$domain" & [ -n "$domain" ] && run_nslookup "$domain" &
entries=$((entries + 1)) entries="$((entries + 1))"
done < "$packageDnsmasqFile" done < "$packageDnsmasqFile"
wait wait
) )
exec 3>&- exec 3>&-
break break
done < "$pipe_ubus" done < "$pipe_ubus"
[ -n "$dnsmasq_restarted" ] || output "Dnsmasq hasn't restarted, $log_abort $__FAIL__" [ -n "$dnsmasq_restarted" ] || {
output "Dnsmasq hasn't restarted, $msg_abort $__FAIL__"
rc='1'
}
kill "$ubus_listen_pid" kill "$ubus_listen_pid"
rm "$pipe_ubus" rm -f "$pipe_ubus"
rm "$pipe_nslookup" rm -f "$pipe_nslookup"
return "$rc"
}
main
return "$?"
) & ) &