diff --git a/bbfdm/Makefile b/bbfdm/Makefile index e788e60b7..1c6987b76 100644 --- a/bbfdm/Makefile +++ b/bbfdm/Makefile @@ -225,7 +225,9 @@ define Package/userinterface/install $(INSTALL_BIN) ./files/etc/init.d/userinterface $(1)/etc/init.d/userinterface $(INSTALL_BIN) ./files/etc/uci-defaults/93-userinterface-firewall $(1)/etc/uci-defaults/93-userinterface-firewall $(INSTALL_BIN) ./files/etc/uci-defaults/94-userinterface-json $(1)/etc/uci-defaults/94-userinterface-json + $(INSTALL_BIN) ./files/etc/uci-defaults/95-portmap-firewall $(1)/etc/uci-defaults/95-portmap-firewall $(INSTALL_BIN) ./files/etc/firewall.userinterface $(1)/etc/firewall.userinterface + $(INSTALL_BIN) ./files/etc/firewall.portmap $(1)/etc/firewall.portmap endef Package/libbbfdm/prerm = $(Package/libbbfdm/default/prerm) diff --git a/bbfdm/files/etc/firewall.portmap b/bbfdm/files/etc/firewall.portmap new file mode 100755 index 000000000..f134ae1a7 --- /dev/null +++ b/bbfdm/files/etc/firewall.portmap @@ -0,0 +1,74 @@ +#!/bin/sh + +. /lib/functions.sh + +log() { + echo "${@}"|logger -t firewall.dnat -p info +} + +exec_cmd() { + if ! eval "$*"; then + log "Failed to run [$*]" + fi +} + +reorder_dnat_rules() { + nat_chains=$(iptables -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 -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep -v "\-s ") + if [ -n "${EMPTY_HOST_PORT}" ]; then + echo "${EMPTY_HOST_PORT}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')" + exec_cmd $cmd1 + done + fi + + # Collect empty remote host but non empty dport rules + EMPTY_HOST=$(iptables -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep "\-\-dport" | grep -v "\-s ") + if [ -n "${EMPTY_HOST}" ]; then + echo "${EMPTY_HOST}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')" + exec_cmd $cmd1 + done + fi + + # Collect non empty remote host but empty dport rules + EMPTY_PORT=$(iptables -t nat -S ${chain} | grep -E "REDIRECT|DNAT" | grep -v "\-\-dport" | grep "\-s ") + if [ -n "${EMPTY_PORT}" ]; then + echo "${EMPTY_PORT}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd | sed 's/-A /-D /g')" + exec_cmd $cmd1 + done + fi + + # 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 + if [ -n "${EMPTY_PORT}" ]; then + echo "${EMPTY_PORT}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd)" + exec_cmd $cmd1 + done + fi + + if [ -n "${EMPTY_HOST}" ]; then + echo "${EMPTY_HOST}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd)" + exec_cmd $cmd1 + done + fi + + if [ -n "${EMPTY_HOST_PORT}" ]; then + echo "${EMPTY_HOST_PORT}" | while read cmd; do + cmd1="iptables -t nat $(echo $cmd)" + exec_cmd $cmd1 + done + fi + done +} + +# Re-order portmapping rules according to precedence hierarchy +reorder_dnat_rules diff --git a/bbfdm/files/etc/uci-defaults/95-portmap-firewall b/bbfdm/files/etc/uci-defaults/95-portmap-firewall new file mode 100644 index 000000000..83c54d90a --- /dev/null +++ b/bbfdm/files/etc/uci-defaults/95-portmap-firewall @@ -0,0 +1,12 @@ +#!/bin/sh + +uci -q batch <<-EOT + delete firewall.port_hook + set firewall.port_hook=include + set firewall.port_hook.path=/etc/firewall.portmap + set firewall.port_hook.reload=1 + commit firewall +EOT + +exit 0 +