From 6c553c24c0c10ae64f1077a3fa332b10fd0a2f41 Mon Sep 17 00:00:00 2001 From: Markus Stenberg Date: Mon, 23 Jun 2014 13:05:43 +0300 Subject: [PATCH] miniupnpd: Fixes #39. Based on discussion with jow, use external interface if specified by user first, and then network_find_wan{,6} as backup heuristic for determining firewall zone. --- miniupnpd/files/firewall.include | 51 ++++++++++++++++++++++--------- miniupnpd/files/miniupnpd.hotplug | 9 ++++-- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/miniupnpd/files/firewall.include b/miniupnpd/files/firewall.include index 5294c45..9a42e06 100644 --- a/miniupnpd/files/firewall.include +++ b/miniupnpd/files/firewall.include @@ -1,14 +1,6 @@ #!/bin/sh # miniupnpd integration for firewall3 -# Note: Correct way to do this would be probably to use -# /lib/functions/network.sh, and use network_find_wan{,6}, and then -# network_get_device, then determine their zones using fw3 -q network -# etc. However, network_find_wan* return only one device, and -# frequently incorrect one if multiple ISPs are in use. So this -# current ugly solution works, although perhaps makes holes where it -# shouldn't (if so, do override it in e.g. firewall.user) - IP6TABLES=/usr/sbin/ip6tables iptables -t filter -N MINIUPNPD 2>/dev/null @@ -16,11 +8,42 @@ iptables -t nat -N MINIUPNPD 2>/dev/null [ -x $IP6TABLES ] && $IP6TABLES -t filter -N MINIUPNPD 2>/dev/null -# IPv4 - due to NAT, need to add both to nat and filter table -iptables -t filter -I delegate_forward 2 -j MINIUPNPD -iptables -t nat -I delegate_prerouting 2 -j MINIUPNPD +. /lib/functions/network.sh -# IPv6 if available - filter only -[ -x $IP6TABLES ] && { - $IP6TABLES -t filter -I delegate_forward 2 -j MINIUPNPD +ADDED=0 + +add_extzone_rules() { + local ext_zone=$1 + + [ -z "$ext_zone" ] && return + + # IPv4 - due to NAT, need to add both to nat and filter table + iptables -t filter -I zone_${ext_zone}_forward -j MINIUPNPD + iptables -t nat -I zone_${ext_zone}_prerouting -j MINIUPNPD + + # IPv6 if available - filter only + [ -x $IP6TABLES ] && { + $IP6TABLES -t filter -I zone_${ext_zone}_forward -j MINIUPNPD + } + ADDED=$(($ADDED + 1)) } + +# By default, user configuration is king. + +for ext_iface in $(uci -q get upnpd.config.external_iface); do + add_extzone_rules $(fw3 -q network "$ext_iface") +done + +[ ! $ADDED = 0 ] && exit 0 + +# If it's not available, resort to network_find_wan{,6} and +# assume external interfaces all have same firewall zone. + +network_find_wan wan_iface +network_find_wan6 wan6_iface + +for ext_iface in $wan_iface $wan6_iface; do + # fw3 -q network fails on sub-interfaces => map to device first + network_get_device ext_device $ext_iface + add_extzone_rules $(fw3 -q device "$ext_device") +done diff --git a/miniupnpd/files/miniupnpd.hotplug b/miniupnpd/files/miniupnpd.hotplug index 7ff363a..a98a50c 100644 --- a/miniupnpd/files/miniupnpd.hotplug +++ b/miniupnpd/files/miniupnpd.hotplug @@ -9,8 +9,11 @@ fi # If miniupnpd is not running: # - check on _any_ event (even updates may contribute to network_find_wan*) + # If miniupnpd _is_ running: -# - check only on ifup +# - check only on ifup (otherwise lease updates etc would cause +# miniupnpd state loss) + [ ! "$ACTION" = "ifup" ] && service_check /usr/sbin/miniupnpd && exit 0 @@ -23,6 +26,6 @@ network_find_wan ext_iface network_find_wan6 ext_iface6 for iface in $ext_iface $ext_iface6 $(uci_get upnpd config internal_iface; uci_get upnpd config external_iface); do - [ "$INTERFACE" = "$iface" ] && /etc/init.d/miniupnpd restart - exit 0 + network_get_device device $iface + [ "$DEVICE" = "$device" ] && /etc/init.d/miniupnpd restart && exit 0 done