#!/bin/sh . /lib/functions.sh reorder_dnat_rules() { nat_chains=$(iptables -w -t nat -S | grep -E "^-N zone[a-zA-Z0-9_]+prerouting$" | cut -d' ' -f 2) for chain in ${nat_chains}; do # Collect empty remote host & empty dport rules EMPTY_HOST_PORT=$(iptables -w -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep -v "\-s ") # Collect empty remote host but non empty dport rules EMPTY_HOST=$(iptables -w -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep "\-\-dport" | grep -v "\-s ") # Collect non empty remote host but empty dport rules EMPTY_PORT=$(iptables -w -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep "\-s ") # Skip this chain if no matching rules were found [ -n "${EMPTY_HOST_PORT}" -o -n "${EMPTY_HOST}" -o -n "${EMPTY_PORT}" ] || continue ( echo '*nat' # Delete collected rules [ -n "${EMPTY_HOST_PORT}" ] && echo "${EMPTY_HOST_PORT}" | sed 's/^-A /-D /' [ -n "${EMPTY_HOST}" ] && echo "${EMPTY_HOST}" | sed 's/^-A /-D /' [ -n "${EMPTY_PORT}" ] && echo "${EMPTY_PORT}" | sed 's/^-A /-D /' # Now add rules as per datamodel precedence shown below ## Non empty remote host, empty dport ## empty remote host, non empty dport ## empty remote host, empty dport [ -n "${EMPTY_PORT}" ] && echo "${EMPTY_PORT}" [ -n "${EMPTY_HOST}" ] && echo "${EMPTY_HOST}" [ -n "${EMPTY_HOST_PORT}" ] && echo "${EMPTY_HOST_PORT}" echo 'COMMIT' ) | iptables-restore -w -n done } # Re-order portmapping rules according to precedence hierarchy reorder_dnat_rules