]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
initscripts: Always wait for xtables lock when running iptables commands
authorPeter Müller <peter.mueller@ipfire.org>
Sun, 28 Sep 2025 19:51:00 +0000 (19:51 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 30 Sep 2025 08:53:01 +0000 (08:53 +0000)
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 <peter.mueller@ipfire.org>
Tested-by: Peter Müller <peter.mueller@ipfire.org>
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/initscripts/networking/red
src/initscripts/packages/tor
src/initscripts/system/dhcp
src/initscripts/system/openvpn-n2n
src/initscripts/system/openvpn-rw
src/initscripts/system/wireguard

index 6d779b3652f966442fa3e1204e06bcf2b569b75d..536fc972c925a600e76d594d2c12ceb59518b50e 100644 (file)
@@ -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
 
index 47797265cff631498f6d976ae1b177f61f7f1ecc..eef9682f33e4514e496f48cae784c072fef3bc72 100644 (file)
@@ -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
index 61b951658809f6f870145bd0d1d45da64e7ba733..826cd2dfe7ba91249d6b95ca1b31581c274bec26 100644 (file)
@@ -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..."
index 9853983795f122a555fd2c03faaf935cf8e01e52..f6d554eaf145dc0b3523957141784497780b8b8a 100644 (file)
@@ -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
index 6359d0d08cad3c427f94406ad20c928de64aa3de..d506c8ebd87a1fa76ed3e5baec4d997d0b262e6d 100644 (file)
@@ -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)
index caaa69cb96081db46ee6878ff0bef7d1bceb7387..ead1cdce885765535b011c3cd51a6767a9d36bbd 100644 (file)
@@ -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