b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #!/bin/sh |
| 2 | # miniupnpd integration for firewall3 |
| 3 | |
| 4 | IPTABLES=/usr/sbin/iptables |
| 5 | IP6TABLES=/usr/sbin/ip6tables |
| 6 | |
| 7 | $IPTABLES -t filter -N MINIUPNPD 2>/dev/null |
| 8 | $IPTABLES -t nat -N MINIUPNPD 2>/dev/null |
| 9 | $IPTABLES -t nat -N MINIUPNPD-POSTROUTING 2>/dev/null |
| 10 | |
| 11 | [ -x $IP6TABLES ] && $IP6TABLES -t filter -N MINIUPNPD 2>/dev/null |
| 12 | |
| 13 | . /lib/functions/network.sh |
| 14 | |
| 15 | # helper to insert in chain as penultimate |
| 16 | iptables_prepend_rule() { |
| 17 | local iptables="$1" |
| 18 | local table="$2" |
| 19 | local chain="$3" |
| 20 | local target="$4" |
| 21 | |
| 22 | $iptables -t "$table" -I "$chain" $($iptables -t "$table" --line-numbers -nL "$chain" | \ |
| 23 | sed -ne '$s/[^0-9].*//p') -j "$target" |
| 24 | } |
| 25 | |
| 26 | ADDED=0 |
| 27 | |
| 28 | add_extzone_rules() { |
| 29 | local ext_zone="$1" |
| 30 | |
| 31 | [ -z "$ext_zone" ] && return |
| 32 | |
| 33 | # IPv4 - due to NAT, need to add both to nat and filter table |
| 34 | # need to insert as penultimate rule for input & forward & postrouting since final rule might be a fw3 REJECT |
| 35 | iptables_prepend_rule "$IPTABLES" filter "zone_${ext_zone}_input" MINIUPNPD |
| 36 | iptables_prepend_rule "$IPTABLES" filter "zone_${ext_zone}_forward" MINIUPNPD |
| 37 | $IPTABLES -t nat -A "zone_${ext_zone}_prerouting" -j MINIUPNPD |
| 38 | iptables_prepend_rule "$IPTABLES" nat "zone_${ext_zone}_postrouting" MINIUPNPD-POSTROUTING |
| 39 | |
| 40 | # IPv6 if available - filter only |
| 41 | [ -x $IP6TABLES ] && { |
| 42 | iptables_prepend_rule "$IP6TABLES" filter "zone_${ext_zone}_input" MINIUPNPD |
| 43 | iptables_prepend_rule "$IP6TABLES" filter "zone_${ext_zone}_forward" MINIUPNPD |
| 44 | } |
| 45 | ADDED=$(($ADDED + 1)) |
| 46 | } |
| 47 | |
| 48 | # By default, user configuration is king. |
| 49 | |
| 50 | for ext_iface in $(uci -q get upnpd.config.external_iface); do |
| 51 | add_extzone_rules $(fw3 -q network "$ext_iface") |
| 52 | done |
| 53 | |
| 54 | add_extzone_rules $(uci -q get upnpd.config.external_zone) |
| 55 | |
| 56 | [ "$ADDED" -ne 0 ] && exit 0 |
| 57 | |
| 58 | # If really nothing is available, resort to network_find_wan{,6} and |
| 59 | # assume external interfaces all have same firewall zone. |
| 60 | |
| 61 | # (This heuristic may fail horribly, in case of e.g. multihoming, so |
| 62 | # please set external_zone in that case!) |
| 63 | |
| 64 | network_find_wan wan_iface |
| 65 | network_find_wan6 wan6_iface |
| 66 | |
| 67 | for ext_iface in $wan_iface $wan6_iface; do |
| 68 | # fw3 -q network fails on sub-interfaces => map to device first |
| 69 | network_get_device ext_device $ext_iface |
| 70 | add_extzone_rules $(fw3 -q device "$ext_device") |
| 71 | done |