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

View File

@@ -1,23 +1,26 @@
config pbr 'config'
option enabled '0'
option verbosity '2'
option strict_enforcement '1'
option resolver_set 'dnsmasq.nftset'
list resolver_instance '*'
option ipv6_enabled '0'
option fw_mask '00ff0000'
list ignored_interface 'vpnserver'
option rule_create_option 'add'
option procd_boot_trigger_delay '5000'
option procd_reload_delay '1'
option webui_show_ignore_target '0'
option ipv6_enabled '0'
option lan_device 'br-lan'
option nft_rule_counter '0'
option nft_set_auto_merge '1'
option nft_set_counter '0'
option nft_set_flags_interval '1'
option nft_set_flags_timeout '0'
option nft_set_gc_interval ''
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 'tcp'
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
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/'INPUT'/'input'/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"
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

View File

@@ -10,15 +10,15 @@ else
fi
# 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
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
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
uci_commit pbr
uci_commit "$packageName"
fi
exit 0

View File

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

View File

@@ -1,87 +1,106 @@
#!/bin/sh
# 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.
# shellcheck disable=SC3043
(
timeout_nft='10'
timeout_dnsmasq='20'
pipe_ubus="/tmp/pipe.ubus.$$"
pipe_nslookup="/tmp/pipe.nslookup.$$"
log_abort='domain names in policies not resolved'
pipe_nslookup="/var/run/${packageName}.nslookup.$$"
# shellcheck disable=SC2154
output()
{
msg="$*"
msg=$(printf '%b' "$msg" | sed 's/\x1b\[[0-9;]*m//g')
output() {
local msg="$*"
msg="$(printf '%b' "$msg" | sed 's/\x1b\[[0-9;]*m//g')"
# shellcheck disable=SC2154
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
[ "$timeout_nft" -eq '0' ] && {
output "Pbr's nft sets not found, $log_abort $__FAIL__"
return 1
}
sleep '1' && timeout_nft=$((timeout_nft - 1))
sleep '1' && timeout_nft="$((timeout_nft - 1))"
done
}
run_nslookup()
{
output=$(nslookup "$1" 127.0.0.1) && { echo '0' > "$pipe_nslookup"; return; }
reason=$(printf '%s' "$output" | grep -Eo -m 1 'NXDOMAIN|SERVFAIL|timed out') && \
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 "$_WARNING_ Lookup failed for $domain ($reason)"
echo '1' > "$pipe_nslookup"
}
# shellcheck disable=SC2162
nslookup_tracker()
{
while read ec; do
entries=$((entries + 1))
[ "$ec" -eq '1' ] && errors=$((errors + 1))
nslookup_tracker() {
local entries errors
while read -r rc; do
entries="$((entries + 1))"
[ "$rc" -eq '1' ] && errors="$((errors + 1))"
done < "$pipe_nslookup"
output "Finished resolving $entries domain names in policies (${errors:-0} failed) $__OK__"
}
[ -n "$resolverSetSupported" ] || {
output "Resolver set support disabled, $log_abort $__FAIL__"
exit
}
mkfifo "$pipe_ubus"
mkfifo "$pipe_nslookup"
ubus listen -m 'ubus.object.add' > "$pipe_ubus" & ubus_listen_pid=$!
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'
# shellcheck disable=SC3045
while read -t "$timeout_dnsmasq" -r event; do
echo "$event" | grep -q "dnsmasq.dns" || continue
dnsmasq_restarted='1'
# shellcheck disable=SC2154
[ -f "$packageDnsmasqFile" ] || {
output "File $packageDnsmasqFile not found, $log_abort $__FAIL__"
break
[ -n "$resolverSetSupported" ] || {
output "Resolver set support disabled, $msg_abort $__FAIL__"
rc='1'
return "$rc"
}
nft_ready || break
nslookup_tracker & exec 3>"$pipe_nslookup"
mkfifo "$pipe_ubus"
mkfifo "$pipe_nslookup"
# The subshell may be necessary for "$!" to expand to a correct value
( exec ubus listen -m 'ubus.object.add' > "$pipe_ubus" ) &
ubus_listen_pid="$!"
(
output "Resolving domain names in policies..."
while IFS='/' read -r _ domain _; do
[ -n "$domain" ] && run_nslookup "$domain" &
entries=$((entries + 1))
done < "$packageDnsmasqFile"
wait
)
# shellcheck disable=SC3045
while read -t "$timeout_dnsmasq" -r event; do
echo "$event" | grep -q "dnsmasq.dns" || continue
dnsmasq_restarted='1'
# shellcheck disable=SC2154
[ -f "$packageDnsmasqFile" ] || {
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
}
nslookup_tracker & exec 3>"$pipe_nslookup"
(
output "Resolving domain names in policies..."
while IFS='/' read -r _ domain _; do
[ -n "$domain" ] && run_nslookup "$domain" &
entries="$((entries + 1))"
done < "$packageDnsmasqFile"
wait
)
exec 3>&-
break
done < "$pipe_ubus"
exec 3>&-
break
done < "$pipe_ubus"
[ -n "$dnsmasq_restarted" ] || output "Dnsmasq hasn't restarted, $log_abort $__FAIL__"
kill "$ubus_listen_pid"
rm "$pipe_ubus"
rm "$pipe_nslookup"
[ -n "$dnsmasq_restarted" ] || {
output "Dnsmasq hasn't restarted, $msg_abort $__FAIL__"
rc='1'
}
kill "$ubus_listen_pid"
rm -f "$pipe_ubus"
rm -f "$pipe_nslookup"
return "$rc"
}
main
return "$?"
) &