Update the package to a commit that fixes an issue with removing PCP mappings from nftables. This also allows us to fix the nftables miniupnpd implementation on openwrt. In this new implementation, a table is created at the start of miniupnpd and it is dedicated to miniupnpd with a priority above the firewall4 table. This allows miniupnpd to go ahead of the drop rules of firewall4 and forward traffic as needed. There was the possibility of adding a chain inside the firewall4 table, but this would raise an issue where if firewall4 was reloaded the port forwardings would be lost and miniupnpd could be out of sync. When miniupnpd is stopped the table is deleted, taking the port forwardings with it. Some of this commit is based of msylgj's work, mainly the logic of the init/hotplug scripts and the makefile build parameters. Signed-off-by: ZiMing Mo <msylgj@immortalwrt.org> Signed-off-by: Tiago Gaspar <tiagogaspar8@gmail.com>
228 lines
No EOL
7.1 KiB
Bash
228 lines
No EOL
7.1 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2006-2014 OpenWrt.org
|
|
|
|
START=94
|
|
STOP=15
|
|
USE_PROCD=1
|
|
PROG=/usr/sbin/miniupnpd
|
|
[ -x "$(command -v nft)" ] && FW="fw4" || FW="fw3"
|
|
|
|
upnpd_get_port_range() {
|
|
local var="$1"; shift
|
|
local val
|
|
|
|
config_get val "$@"
|
|
|
|
case "$val" in
|
|
[0-9]*[:-][0-9]*)
|
|
export -n -- "${var}_start=${val%%[:-]*}"
|
|
export -n -- "${var}_end=${val##*[:-]}"
|
|
;;
|
|
[0-9]*)
|
|
export -n -- "${var}_start=$val"
|
|
export -n -- "${var}_end="
|
|
;;
|
|
esac
|
|
}
|
|
|
|
conf_rule_add() {
|
|
local cfg="$1"
|
|
local action int_addr
|
|
local ext_start ext_end int_start int_end comment
|
|
|
|
config_get action "$cfg" action "deny" # allow or deny
|
|
upnpd_get_port_range "ext" "$cfg" ext_ports "0-65535" # external ports: x, x-y, x:y
|
|
config_get int_addr "$cfg" int_addr "0.0.0.0/0" # ip or network and subnet mask (internal)
|
|
upnpd_get_port_range "int" "$cfg" int_ports "0-65535" # internal ports: x, x-y, x:y or range
|
|
config_get comment "$cfg" comment "ACL" # comment
|
|
|
|
# Make a single IP IP/32 so that miniupnpd.conf can use it.
|
|
[ "${int_addr%/*}" = "$int_addr" ] && int_addr="$int_addr/32"
|
|
|
|
echo "$action $ext_start${ext_end:+-}$ext_end $int_addr $int_start${int_end:+-}$int_end #$comment"
|
|
}
|
|
|
|
upnpd_write_bool() {
|
|
local opt="$1"
|
|
local def="${2:-0}"
|
|
local alt="${3:-$opt}"
|
|
local val
|
|
|
|
config_get_bool val config "$opt" "$def"
|
|
if [ "$val" -eq 0 ]; then
|
|
echo "$alt=no"
|
|
else
|
|
echo "$alt=yes"
|
|
fi
|
|
}
|
|
|
|
upnpd() {
|
|
config_load "upnpd"
|
|
local external_iface external_iface6 external_zone external_ip internal_iface
|
|
local upload download log_output port config_file serial_number model_number
|
|
local use_stun stun_host stun_port uuid notify_interval presentation_url
|
|
local upnp_lease_file clean_ruleset_threshold clean_ruleset_interval
|
|
local ipv6_disable
|
|
|
|
local enabled
|
|
config_get_bool enabled config enabled 1
|
|
[ "$enabled" -eq 0 ] && return 1
|
|
|
|
config_get external_iface config external_iface
|
|
config_get external_iface6 config external_iface6
|
|
config_get external_zone config external_zone
|
|
config_get external_ip config external_ip
|
|
config_get internal_iface config internal_iface
|
|
config_get port config port 5000
|
|
config_get upload config upload
|
|
config_get download config download
|
|
config_get_bool log_output config log_output 0
|
|
config_get config_file config config_file
|
|
config_get serial_number config serial_number
|
|
config_get model_number config model_number
|
|
config_get uuid config uuid
|
|
config_get use_stun config use_stun 0
|
|
config_get stun_host config stun_host
|
|
config_get stun_port config stun_port
|
|
config_get notify_interval config notify_interval
|
|
config_get presentation_url config presentation_url
|
|
config_get upnp_lease_file config upnp_lease_file
|
|
config_get clean_ruleset_threshold config clean_ruleset_threshold
|
|
config_get clean_ruleset_interval config clean_ruleset_interval
|
|
config_get ipv6_disable config ipv6_disable 0
|
|
|
|
local conf ifname ifname6
|
|
|
|
. /lib/functions/network.sh
|
|
|
|
if [ -n "$external_iface" ] ; then
|
|
network_get_device ifname "$external_iface"
|
|
else
|
|
if [ -n "$external_zone" ] ; then
|
|
ifname=$($FW -q zone "$external_zone" 2>/dev/null | head -1)
|
|
else
|
|
network_find_wan external_iface && \
|
|
network_get_device ifname "$external_iface"
|
|
fi
|
|
fi
|
|
if [ -n "$external_iface6" ] ; then
|
|
network_get_device ifname6 "$external_iface6"
|
|
else
|
|
if [ -n "$external_zone" ] ; then
|
|
ifname6=$($FW -q zone "$external_zone" 2>/dev/null | head -1)
|
|
else
|
|
network_find_wan6 external_iface6 && \
|
|
network_get_device ifname6 "$external_iface6"
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$config_file" ]; then
|
|
conf="$config_file"
|
|
else
|
|
local tmpconf="/var/etc/miniupnpd.conf"
|
|
conf="$tmpconf"
|
|
mkdir -p /var/etc
|
|
|
|
{
|
|
echo "ext_ifname=$ifname"
|
|
echo "ext_ifname6=$ifname6"
|
|
[ -n "$external_ip" ] && echo "ext_ip=$external_ip"
|
|
|
|
local iface
|
|
for iface in ${internal_iface:-lan}; do
|
|
local device
|
|
network_get_device device "$iface" && echo "listening_ip=$device"
|
|
done
|
|
|
|
config_load "upnpd"
|
|
upnpd_write_bool enable_natpmp 1
|
|
upnpd_write_bool enable_upnp 1
|
|
upnpd_write_bool secure_mode 1
|
|
upnpd_write_bool system_uptime 1
|
|
upnpd_write_bool igdv1 0 force_igd_desc_v1
|
|
upnpd_write_bool use_stun 0 ext_perform_stun
|
|
upnpd_write_bool ipv6_disable $ipv6_disable
|
|
|
|
[ "$use_stun" -eq 0 ] || {
|
|
[ -n "$stun_host" ] && echo "ext_stun_host=$stun_host"
|
|
[ -n "$stun_port" ] && echo "ext_stun_port=$stun_port"
|
|
}
|
|
|
|
[ -n "$upload" ] && [ -n "$download" ] && {
|
|
echo "bitrate_down=$((download * 1024 * 8))"
|
|
echo "bitrate_up=$((upload * 1024 * 8))"
|
|
}
|
|
|
|
[ -n "$upnp_lease_file" ] && touch "$upnp_lease_file" && echo "lease_file=$upnp_lease_file"
|
|
[ -n "$presentation_url" ] && echo "presentation_url=$presentation_url"
|
|
[ -n "$notify_interval" ] && echo "notify_interval=$notify_interval"
|
|
[ -n "$clean_ruleset_threshold" ] && echo "clean_ruleset_threshold=$clean_ruleset_threshold"
|
|
[ -n "$clean_ruleset_interval" ] && echo "clean_ruleset_interval=$clean_ruleset_interval"
|
|
[ -n "$serial_number" ] && echo "serial=$serial_number"
|
|
[ -n "$model_number" ] && echo "model_number=$model_number"
|
|
[ -n "$port" ] && echo "port=$port"
|
|
|
|
[ -z "$uuid" ] && {
|
|
uuid="$(cat /proc/sys/kernel/random/uuid)"
|
|
uci set upnpd.config.uuid="$uuid"
|
|
uci commit upnpd
|
|
}
|
|
|
|
[ "$uuid" = "nocli" ] || echo "uuid=$uuid"
|
|
|
|
config_foreach conf_rule_add perm_rule
|
|
|
|
if [ "Z$FW" = "Zfw4" ]; then
|
|
#When using nftables configure miniupnpd to use its own table and chains
|
|
echo "upnp_table_name=miniupnpd"
|
|
echo "upnp_nat_table_name=miniupnpd"
|
|
echo "upnp_forward_chain=forward"
|
|
echo "upnp_nat_chain=prerouting"
|
|
echo "upnp_nat_postrouting_chain=postrouting"
|
|
fi
|
|
|
|
} > "$tmpconf"
|
|
fi
|
|
|
|
if [ -n "$ifname" ]; then
|
|
# start firewall
|
|
if [ "Z$FW" = "Zfw4" ]; then
|
|
#Add a miniupnpd table so that when fw4 reloads port-forwadings aren't lost, also give it priority so that port-forwards are considered before standard firewall rules
|
|
nft add table inet miniupnpd
|
|
nft add chain inet miniupnpd forward { type filter hook forward priority -20 \; policy accept \; comment \"Miniupnpd forwarding table\" \; }
|
|
nft add chain inet miniupnpd prerouting { type nat hook prerouting priority dstnat -20 \; policy accept \; comment \"Miniupnpd prerouting table\" \; }
|
|
nft add chain inet miniupnpd postrouting { type nat hook postrouting priority srcnat -20 \; policy accept \; comment \"Miniupnpd postrouting table\" \; }
|
|
else
|
|
iptables -L MINIUPNPD >/dev/null 2>&1 || fw3 reload
|
|
fi
|
|
else
|
|
logger -t "upnp daemon" "external interface not found, not starting"
|
|
fi
|
|
|
|
procd_open_instance
|
|
procd_set_param command "$PROG"
|
|
procd_append_param command -f "$conf"
|
|
[ "$log_output" = "1" ] && procd_append_param command -d
|
|
procd_close_instance
|
|
}
|
|
|
|
stop_service() {
|
|
if [ "Z$FW" = "Zfw3" ]; then
|
|
iptables -t nat -F MINIUPNPD 2>/dev/null
|
|
iptables -t nat -F MINIUPNPD-POSTROUTING 2>/dev/null
|
|
iptables -t filter -F MINIUPNPD 2>/dev/null
|
|
[ -x /usr/sbin/ip6tables ] && ip6tables -t filter -F MINIUPNPD 2>/dev/null
|
|
else
|
|
#delete the table removing port-forwardings when exiting
|
|
nft delete table inet miniupnpd
|
|
fi
|
|
}
|
|
|
|
start_service() {
|
|
config_load "upnpd"
|
|
config_foreach upnpd "upnpd"
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "upnpd"
|
|
} |