Hello Peter,

Nice to read you on this list again :)

I cannot say that I have ever noticed that we had any races here. I have merged 
the patch into next and it will be released with Core Update 199.

Best,
-Michael

> On 28 Sep 2025, at 20:51, Peter Müller <[email protected]> wrote:
> 
> If not explicitly instructed to do so, iptables by default aborts with
> an error message such as
> 
>> Can't lock /run/xtables.lock: Resource temporarily unavailable
>> Another app is currently holding the xtables lock. Perhaps you want to use 
>> the -w option?
> 
> if the Xtables lock is still set, i.e., another iptables operation is
> currently in progress. This causes iptables commands not to be executed
> at all if there are delays during the boot procedure, e.g. due to slow
> PPPoE dial-up procedure or similar.
> 
> To ensure deterministic behavior, this match modifies initscripts to
> always execute iptables to wait for the Xtables lock to be removed, to
> make sure iptables rules are installed properly (the "firewall"
> initscript is doing so already).
> 
> Fixes: #13896 - OpenVPN RW port not opened in firewall after reboot
> Signed-off-by: Peter Müller <[email protected]>
> Tested-by: Peter Müller <[email protected]>
> ---
> src/initscripts/networking/red     |  4 ++--
> src/initscripts/packages/tor       | 10 +++++-----
> src/initscripts/system/dhcp        | 16 ++++++++--------
> src/initscripts/system/openvpn-n2n | 10 +++++-----
> src/initscripts/system/openvpn-rw  |  6 +++---
> src/initscripts/system/wireguard   | 20 ++++++++++----------
> 6 files changed, 33 insertions(+), 33 deletions(-)
> 
> diff --git a/src/initscripts/networking/red b/src/initscripts/networking/red
> index 6d779b365..536fc972c 100644
> --- a/src/initscripts/networking/red
> +++ b/src/initscripts/networking/red
> @@ -162,8 +162,8 @@ case "${1}" in
> 
> elif [ "${TYPE}" == "DHCP" ]; then
> # Add firewall rules to allow comunication with the dhcp server on red.
> - iptables -A REDINPUT -p tcp --source-port 67 --destination-port 68 -i 
> ${DEVICE} -j ACCEPT
> - iptables -A REDINPUT -p udp --source-port 67 --destination-port 68 -i 
> ${DEVICE} -j ACCEPT
> + iptables --wait -A REDINPUT -p tcp --source-port 67 --destination-port 68 
> -i ${DEVICE} -j ACCEPT
> + iptables --wait -A REDINPUT -p udp --source-port 67 --destination-port 68 
> -i ${DEVICE} -j ACCEPT
> 
> echo -n "${DEVICE}" > /var/ipfire/red/iface
> 
> diff --git a/src/initscripts/packages/tor b/src/initscripts/packages/tor
> index 47797265c..eef9682f3 100644
> --- a/src/initscripts/packages/tor
> +++ b/src/initscripts/packages/tor
> @@ -37,19 +37,19 @@ function setup_firewall() {
> # Allow incoming traffic to Tor relay (and directory) port and
> # all outgoing TCP connections from Tor user.
> if [ "${TOR_RELAY_ENABLED}" = "on" -a -n "${TOR_RELAY_PORT}" ]; then
> - iptables -A TOR_INPUT -p tcp --dport "${TOR_RELAY_PORT}" -j ACCEPT
> - iptables -A TOR_OUTPUT -p tcp -m owner --uid-owner tor -j ACCEPT
> + iptables --wait -A TOR_INPUT -p tcp --dport "${TOR_RELAY_PORT}" -j ACCEPT
> + iptables --wait -A TOR_OUTPUT -p tcp -m owner --uid-owner tor -j ACCEPT
> fi
> 
> if [ "${TOR_RELAY_ENABLED}" = "on" -a -n "${TOR_RELAY_DIRPORT}" ] && [ 
> "${TOR_RELAY_DIRPORT}" -ne 0 ]; then
> - iptables -A TOR_INPUT -p tcp --dport "${TOR_RELAY_DIRPORT}" -j ACCEPT
> + iptables --wait -A TOR_INPUT -p tcp --dport "${TOR_RELAY_DIRPORT}" -j ACCEPT
> fi
> }
> 
> function flush_firewall() {
> # Flush all rules.
> - iptables -F TOR_INPUT
> - iptables -F TOR_OUTPUT
> + iptables --wait -F TOR_INPUT
> + iptables --wait -F TOR_OUTPUT
> }
> 
> case "${1}" in
> diff --git a/src/initscripts/system/dhcp b/src/initscripts/system/dhcp
> index 61b951658..826cd2dfe 100644
> --- a/src/initscripts/system/dhcp
> +++ b/src/initscripts/system/dhcp
> @@ -28,10 +28,10 @@ eval $(/usr/local/bin/readhash 
> /var/ipfire/ethernet/settings)
> eval $(/usr/local/bin/readhash /var/ipfire/dhcp/settings)
> 
> function flush_chains() {
> - iptables -F DHCPGREENINPUT
> - iptables -F DHCPGREENOUTPUT
> - iptables -F DHCPBLUEINPUT
> - iptables -F DHCPBLUEOUTPUT
> + iptables --wait -F DHCPGREENINPUT
> + iptables --wait -F DHCPGREENOUTPUT
> + iptables --wait -F DHCPBLUEINPUT
> + iptables --wait -F DHCPBLUEOUTPUT
> }
> 
> case "$1" in
> @@ -41,14 +41,14 @@ case "$1" in
> if [ -n "${GREEN_DEV}" -a -e "/var/ipfire/dhcp/enable_green" ]; then
> LISTEN_INTERFACES+=" ${GREEN_DEV}"
> 
> - iptables -A DHCPGREENINPUT  -i "${GREEN_DEV}" -j DHCPINPUT
> - iptables -A DHCPGREENOUTPUT -o "${GREEN_DEV}" -j DHCPOUTPUT
> + iptables --wait -A DHCPGREENINPUT  -i "${GREEN_DEV}" -j DHCPINPUT
> + iptables --wait -A DHCPGREENOUTPUT -o "${GREEN_DEV}" -j DHCPOUTPUT
> fi
> if [ -n "${BLUE_DEV}" -a -e "/var/ipfire/dhcp/enable_blue" ]; then
> LISTEN_INTERFACES+=" ${BLUE_DEV}"
> 
> - iptables -A DHCPBLUEINPUT  -i "${BLUE_DEV}" -j DHCPINPUT
> - iptables -A DHCPBLUEOUTPUT -o "${BLUE_DEV}" -j DHCPOUTPUT
> + iptables --wait -A DHCPBLUEINPUT  -i "${BLUE_DEV}" -j DHCPINPUT
> + iptables --wait -A DHCPBLUEOUTPUT -o "${BLUE_DEV}" -j DHCPOUTPUT
> fi
> 
> boot_mesg "Starting DHCP Server..."
> diff --git a/src/initscripts/system/openvpn-n2n 
> b/src/initscripts/system/openvpn-n2n
> index 985398379..f6d554eaf 100644
> --- a/src/initscripts/system/openvpn-n2n
> +++ b/src/initscripts/system/openvpn-n2n
> @@ -63,10 +63,10 @@ update_firewall_rules() {
> local local_address
> 
> # Flush the block chain
> - iptables -F OVPNBLOCK
> + iptables --wait -F OVPNBLOCK
> 
> # Flush the NAT chain
> - iptables -t nat -F OVPNNAT
> + iptables --wait -t nat -F OVPNNAT
> 
> local IFS=','
> 
> @@ -85,10 +85,10 @@ update_firewall_rules() {
> fi
> 
> # Open port
> - iptables -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j ACCEPT
> + iptables --wait -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j ACCEPT
> 
> # Block all communication from transfer networks
> - iptables -A OVPNBLOCK -s "${transfer_subnet}" -j DROP
> + iptables --wait -A OVPNBLOCK -s "${transfer_subnet}" -j DROP
> 
> # Calculate NAT addresses
> transfer_address="$(calculate_transfer_address "${transfer_subnet}" 
> "${role}")"
> @@ -96,7 +96,7 @@ update_firewall_rules() {
> 
> # NAT all outgoing connections away from the transfer net
> if [ -n "${transfer_address}" -a -n "${local_address}" ]; then
> - iptables -t nat -A OVPNNAT -s "${transfer_address}" \
> + iptables --wait -t nat -A OVPNNAT -s "${transfer_address}" \
> -j SNAT --to-source "${local_address}"
> fi
> done < /var/ipfire/ovpn/ovpnconfig
> diff --git a/src/initscripts/system/openvpn-rw 
> b/src/initscripts/system/openvpn-rw
> index 6359d0d08..d506c8ebd 100644
> --- a/src/initscripts/system/openvpn-rw
> +++ b/src/initscripts/system/openvpn-rw
> @@ -38,10 +38,10 @@ case "${1}" in
> modprobe tun &>/dev/null
> 
> # Flush all firewall rules
> - iptables -F OVPNINPUTRW
> + iptables --wait -F OVPNINPUTRW
> 
> # Open the port
> - iptables -A OVPNINPUTRW \
> + iptables --wait -A OVPNINPUTRW \
> -p "${DPROTOCOL}" --dport "${DDEST_PORT}" -j ACCEPT
> 
> boot_mesg "Starting OpenVPN Roadwarrior Server..."
> @@ -60,7 +60,7 @@ case "${1}" in
> killproc /usr/sbin/openvpn
> 
> # Flush all firewall rules
> - iptables -F OVPNINPUTRW
> + iptables --wait -F OVPNINPUTRW
> ;;
> 
> restart)
> diff --git a/src/initscripts/system/wireguard 
> b/src/initscripts/system/wireguard
> index caaa69cb9..ead1cdce8 100644
> --- a/src/initscripts/system/wireguard
> +++ b/src/initscripts/system/wireguard
> @@ -216,7 +216,7 @@ generate_config() {
> ip addr add "${local_address}" dev "${intf}"
> 
> # Apply MASQUERADE
> - iptables -t nat -A WGNAT -o "${intf}" -j MASQUERADE
> + iptables --wait -t nat -A WGNAT -o "${intf}" -j MASQUERADE
> fi
> 
> echo "[Interface]"
> @@ -230,7 +230,7 @@ generate_config() {
> echo "ListenPort = ${port}"
> 
> # Open the port
> - iptables -A WGINPUT -p udp --dport "${port}" -j ACCEPT
> + iptables --wait -A WGINPUT -p udp --dport "${port}" -j ACCEPT
> fi
> 
> echo "[Peer]"
> @@ -285,7 +285,7 @@ generate_config() {
> # Set blocking rules
> for local_subnet in ${local_subnets//|/ }; do
> for remote_subnet in ${remote_subnets//|/ }; do
> - iptables -I WGBLOCK \
> + iptables --wait -I WGBLOCK \
> -s "${remote_subnet}" -d "${local_subnet}" -j RETURN
> done
> done
> @@ -297,23 +297,23 @@ generate_config() {
> 
> reload_firewall() {
> # Flush all previous rules
> - iptables -F WGINPUT
> - iptables -t nat -F WGNAT
> + iptables --wait -F WGINPUT
> + iptables --wait -t nat -F WGNAT
> 
> if [ "${ENABLED}" = "on" ]; then
> - iptables -A WGINPUT -p udp --dport "${PORT}" -j ACCEPT
> + iptables --wait -A WGINPUT -p udp --dport "${PORT}" -j ACCEPT
> fi
> 
> - iptables -F WGBLOCK
> + iptables --wait -F WGBLOCK
> 
> # Don't block any traffic from Roadwarrior peers
> if [ -n "${CLIENT_POOL}" ]; then
> - iptables -A WGBLOCK -s "${CLIENT_POOL}" -i wg0 -j RETURN
> - iptables -A WGBLOCK -d "${CLIENT_POOL}" -o wg0 -j RETURN
> + iptables --wait -A WGBLOCK -s "${CLIENT_POOL}" -i wg0 -j RETURN
> + iptables --wait -A WGBLOCK -d "${CLIENT_POOL}" -o wg0 -j RETURN
> fi
> 
> # Block all other traffic
> - iptables -A WGBLOCK -j REJECT --reject-with icmp-admin-prohibited
> + iptables --wait -A WGBLOCK -j REJECT --reject-with icmp-admin-prohibited
> 
> # Flush any custom routes
> ip route flush table wg 2>/dev/null
> -- 
> 2.51.0
> 


Reply via email to