- Bump to the latest Git version in order to increase the package version for simpler opkg upgrade of the broken version - (Re-)Introduce PKG_RELEASE into the package, omitting it may lead to opkg segmentation faults under certain circumstances - Utilize automatic include hooks to drop the isolated miniupnpd table in favor to chains within the main inet fw4 table, otherwise PCP is unreliable as the upnp table might accept traffic which is later rejected by fw4 - Install a fw4 script hook to restart miniupnpd on fw4 restarts and reloads in order to repopulate the upnp chains with forward rules - Register the used miniupnpd configuration file and the firewall uci configuration as change sources, otherwise `/etc/init.d/miniupnpd reload` has no effect if the firewall or upnpd config was changed Signed-off-by: Jo-Philipp Wich <jo@mein.io>
226 lines
6.6 KiB
Bash
226 lines
6.6 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 [ "$FW" = "fw4" ]; then
|
|
#When using nftables configure miniupnpd to use its own table and chains
|
|
echo "upnp_table_name=fw4"
|
|
echo "upnp_nat_table_name=fw4"
|
|
echo "upnp_forward_chain=upnp_forward"
|
|
echo "upnp_nat_chain=upnp_prerouting"
|
|
echo "upnp_nat_postrouting_chain=upnp_postrouting"
|
|
fi
|
|
|
|
} > "$tmpconf"
|
|
fi
|
|
|
|
if [ -n "$ifname" ]; then
|
|
# start firewall
|
|
if [ "$FW" = "fw4" ]; then
|
|
nft -s -t -n list chain inet fw4 upnp_forward >/dev/null 2>&1 || fw4 reload
|
|
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 file "$conf" "/etc/config/firewall"
|
|
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 [ "$FW" = "fw3" ]; 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
|
|
nft flush chain inet fw4 upnp_forward 2>/dev/null
|
|
nft flush chain inet fw4 upnp_prerouting 2>/dev/null
|
|
nft flush chain inet fw4 upnp_postrouting 2>/dev/null
|
|
fi
|
|
}
|
|
|
|
start_service() {
|
|
config_load "upnpd"
|
|
config_foreach upnpd "upnpd"
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "upnpd"
|
|
}
|