From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.haj.ipfire.org (localhost [IPv6:::1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4cbX2b0pPzz2ymx for ; Tue, 30 Sep 2025 08:55:35 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mail01.haj.ipfire.org", Issuer "R13" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4cbX2W4qwmz2xP7 for ; Tue, 30 Sep 2025 08:55:31 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4cbX2T57Z8z3rm; Tue, 30 Sep 2025 08:55:29 +0000 (UTC) DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1759222530; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uN7UpvuP/IvZE2pI4+jMd+5NFzG/pY2vG+iIoQHeYRA=; b=zv8k2PAjTQi1lN9CufCBMBC3rx6BfzgpZWgnsC5SSoWM7zgAKOKcUtl0W8HhQQ6iyOBUUs AA82KpC5f1Y2r1Bw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1759222530; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uN7UpvuP/IvZE2pI4+jMd+5NFzG/pY2vG+iIoQHeYRA=; b=Vu8ixMNzIC8Vk3fT7oNLJkD/Nchq2locA8w0QP/2Eof8JpdipbEGAnunw08SaC/7KvcksX ey/gSFS/Nhpztf6FjN+rIEVzBwFms8gZPyFTBxo1a0C4B5mdi9nNf46yl+cPqSL/i3UUDZ jz89vif4lGDcQ96J07D7ruldPWe/RTIWCvS6VjNsOxJOnGLXZbuRN4ZYf6r4m5YtPS6JqV rpVQQbRNZ7LszTMhEQEXolUij8ZCsIb2mcmNpv4zn+V750yspQKEnx/3iIO6KO2e3poOT/ 5zS7ZVIkeLMt7mWuCEhyDthQ5AZ10kDKsm49wRjJ6HEIBZV9X3UHog4MdXtO/Q== Content-Type: text/plain; charset=utf-8 Precedence: list List-Id: List-Subscribe: , List-Unsubscribe: , List-Post: List-Help: Sender: Mail-Followup-To: Mime-Version: 1.0 Subject: Re: [PATCH] initscripts: Always wait for xtables lock when running iptables commands From: Michael Tremer In-Reply-To: <2dbd27d0-92f5-4611-b7c8-a98185601f0e@ipfire.org> Date: Tue, 30 Sep 2025 09:55:27 +0100 Cc: "IPFire: Development" Content-Transfer-Encoding: quoted-printable Message-Id: References: <2dbd27d0-92f5-4611-b7c8-a98185601f0e@ipfire.org> To: =?utf-8?Q?Peter_M=C3=BCller?= 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=C3=BCller = wrote: >=20 > If not explicitly instructed to do so, iptables by default aborts with > an error message such as >=20 >> 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? >=20 > 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. >=20 > 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). >=20 > Fixes: #13896 - OpenVPN RW port not opened in firewall after reboot > Signed-off-by: Peter M=C3=BCller > Tested-by: Peter M=C3=BCller > --- > 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(-) >=20 > 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 >=20 > elif [ "${TYPE}" =3D=3D "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 >=20 > echo -n "${DEVICE}" > /var/ipfire/red/iface >=20 > 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}" =3D "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 >=20 > if [ "${TOR_RELAY_ENABLED}" =3D "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 > } >=20 > function flush_firewall() { > # Flush all rules. > - iptables -F TOR_INPUT > - iptables -F TOR_OUTPUT > + iptables --wait -F TOR_INPUT > + iptables --wait -F TOR_OUTPUT > } >=20 > 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) >=20 > 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 > } >=20 > case "$1" in > @@ -41,14 +41,14 @@ case "$1" in > if [ -n "${GREEN_DEV}" -a -e "/var/ipfire/dhcp/enable_green" ]; then > LISTEN_INTERFACES+=3D" ${GREEN_DEV}" >=20 > - 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+=3D" ${BLUE_DEV}" >=20 > - 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 >=20 > 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 >=20 > # Flush the block chain > - iptables -F OVPNBLOCK > + iptables --wait -F OVPNBLOCK >=20 > # Flush the NAT chain > - iptables -t nat -F OVPNNAT > + iptables --wait -t nat -F OVPNNAT >=20 > local IFS=3D',' >=20 > @@ -85,10 +85,10 @@ update_firewall_rules() { > fi >=20 > # Open port > - iptables -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j ACCEPT > + iptables --wait -A OVPNINPUTN2N -p "${proto}" --dport "${port}" -j = ACCEPT >=20 > # Block all communication from transfer networks > - iptables -A OVPNBLOCK -s "${transfer_subnet}" -j DROP > + iptables --wait -A OVPNBLOCK -s "${transfer_subnet}" -j DROP >=20 > # Calculate NAT addresses > transfer_address=3D"$(calculate_transfer_address "${transfer_subnet}" = "${role}")" > @@ -96,7 +96,7 @@ update_firewall_rules() { >=20 > # 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 >=20 > # Flush all firewall rules > - iptables -F OVPNINPUTRW > + iptables --wait -F OVPNINPUTRW >=20 > # Open the port > - iptables -A OVPNINPUTRW \ > + iptables --wait -A OVPNINPUTRW \ > -p "${DPROTOCOL}" --dport "${DDEST_PORT}" -j ACCEPT >=20 > boot_mesg "Starting OpenVPN Roadwarrior Server..." > @@ -60,7 +60,7 @@ case "${1}" in > killproc /usr/sbin/openvpn >=20 > # Flush all firewall rules > - iptables -F OVPNINPUTRW > + iptables --wait -F OVPNINPUTRW > ;; >=20 > 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}" >=20 > # Apply MASQUERADE > - iptables -t nat -A WGNAT -o "${intf}" -j MASQUERADE > + iptables --wait -t nat -A WGNAT -o "${intf}" -j MASQUERADE > fi >=20 > echo "[Interface]" > @@ -230,7 +230,7 @@ generate_config() { > echo "ListenPort =3D ${port}" >=20 > # Open the port > - iptables -A WGINPUT -p udp --dport "${port}" -j ACCEPT > + iptables --wait -A WGINPUT -p udp --dport "${port}" -j ACCEPT > fi >=20 > 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() { >=20 > reload_firewall() { > # Flush all previous rules > - iptables -F WGINPUT > - iptables -t nat -F WGNAT > + iptables --wait -F WGINPUT > + iptables --wait -t nat -F WGNAT >=20 > if [ "${ENABLED}" =3D "on" ]; then > - iptables -A WGINPUT -p udp --dport "${PORT}" -j ACCEPT > + iptables --wait -A WGINPUT -p udp --dport "${PORT}" -j ACCEPT > fi >=20 > - iptables -F WGBLOCK > + iptables --wait -F WGBLOCK >=20 > # 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 >=20 > # 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 >=20 > # Flush any custom routes > ip route flush table wg 2>/dev/null > --=20 > 2.51.0 >=20