miniupnpd初略理解和实际使用

时间:2024-03-09 20:32:43

NAT-PMP:NAT端口映射协议(英语:NAT Port Mapping Protocol,缩写NAT-PMP)苹果开发的协议

Port Control Protocol (PCP) https://tools.ietf.org/html/rfc6887 port control protocol, the successor of NAT-PMP(PCP是NAT-PMP继承者)

FreeBSD 有三種內建於基礎系統的防火牆:PF, IPFW 與IPFILTER 即IPF

miniupnpd的论坛 http://miniupnp.tuxfamily.org/forum/ 可以找到使用方法

涉及在debian9以及centos7下开启upnp server服务
1)apt-cache search upnp找到miniupnpd
2)apt-get install miniupnpd后出现配置窗口(文字性的配置窗口),在配置的过程中丢失了ssh登陆窗口(网络不好的原因)
3)apt-get remove miniupnpd
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package \'miniupnpd\' is not installed, so not removed
E: Could not get lock /var/cache/apt/archives/lock - open (11: Resource temporarily unavailable)
E: Unable to lock directory /var/cache/apt/archives/
其中 /var/cache/apt/archives/是下载deb包的目录
手动删除rm -rf /var/cache/apt/archives/lock
接着重新安装apt-get install miniupnpd
4)apt install又出现错误
Adding group uuidd\' (GID 115) ... Done. Warning: The home dir /run/uuidd you specified can\'t be accessed: No such file or directory Adding system user uuidd\' (UID 109) ...
Adding new user uuidd\' (UID 109) with group uuidd\' ...
Not creating home directory `/run/uuidd\'.
Created symlink /etc/systemd/system/sockets.target.wants/uuidd.socket → /lib/systemd/system/uuidd.socket.
Processing triggers for systemd (232-25+deb9u11) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up net-tools (1.60+git20161116.90da8a0-1) ...
Setting up miniupnpd (1.8.20140523-4.1+deb9u2) ...
debconf: DbDriver "config": /var/cache/debconf/config.dat is locked by another process: Resource temporarily unavailable
dpkg: error processing package miniupnpd (--configure):
subprocess installed post-installation script returned error exit status 1
Processing triggers for systemd (232-25+deb9u11) ...
Errors were encountered while processing:
miniupnpd
E: Sub-process /usr/bin/dpkg returned an error code (1)
以上处理apt-get remove miniupnpd 接着apt-get install miniupnpd

5)配置使用:

man  miniupnpd如下:
NAME
       miniupnpd - UPnP Internet Gateway Device Daemon

SYNOPSIS
       miniupnpd  [-f  file]  [-i interface] [-o address] [-a address] [-p port] [-d] [-L] [-U] [-u uuid]
       [-s serial] [-m model_number] [-q queue] [-t interval] [-P file] [-B down up] [-w url]

DESCRIPTION
       miniupnpd act as a UPnP Internet Gateway Device. It is designed to run on the gateway between  the
       internet and a NAT\'ed LAN. It provides an interface, as defined in the UPnP standard, for enabling
       clients on the LAN to ask for port redirections.

OPTIONS
       -f file
              load the config from file. default is /etc/miniupnpd.conf.

       -i interface
              interface used to connect to the internet.

       -o address
              address used to connect to the internet.  default address of the interface will be used  if
              not specified.

       -a address
              address  on  the  LAN.  -a option can by used multiple time if LAN is subdivised in several
              subnetworks.

       -p port
              port used for HTTP.

       -d     debug mode : do not go to background, output messages on console and do not filter out  low
              priority messages.

       -L     set packet log in pf on

       -q queue
              set ALTQ queue in pf. filter rules must be enabled for this option to have any effect.

       -U     report system uptime instead of daemon uptime to clients.

       -u uuid
              set the uuid of the UPnP Internet Gateway Device.

       -s serial
              serial number for the UPnP Internet Gateway Device.

       -m number
              model number for the UPnP Internet Gateway Device.

       -t interval
              SSDP notify interval in seconds : SSDP announce messages will be broadcasted at this inter‐
              val.

       -P file
              pid file. default is /var/run/miniupnpd.pid

       -B down up
              download and upload bitrates reported to clients.

       -w url presentation url. default is first address on LAN, port 80.

miniupnpd配置文件在 /etc/default/miniupnpd 和 /etc/miniupnpd/miniupnpd.conf

其中/etc/miniupnpd/iptables_init.sh -----------------------------------------------------------------

#! /bin/sh
# $Id: iptables_init.sh,v 1.8 2014/04/15 13:45:08 nanard Exp $
IPTABLES="`which iptables`" || exit 1
IP="`which ip`" || exit 1

#change this parameters :
#EXTIF=eth0
EXTIF="`LC_ALL=C $IP -4 route | grep \'default\' | sed -e \'s/.*dev[[:space:]]*//\' -e \'s/[[:space:]].*//\'`" || exit 1
EXTIP="`LC_ALL=C $IP -4 addr show $EXTIF | awk \'/inet/ { print $2 }\' | cut -d "/" -f 1`"

echo "External IP = $EXTIP"

#adding the MINIUPNPD chain for nat
$IPTABLES -t nat -N MINIUPNPD
#adding the rule to MINIUPNPD
#$IPTABLES -t nat -A PREROUTING -d $EXTIP -i $EXTIF -j MINIUPNPD
$IPTABLES -t nat -A PREROUTING -i $EXTIF -j MINIUPNPD

#adding the MINIUPNPD chain for mangle
$IPTABLES -t mangle -N MINIUPNPD
$IPTABLES -t mangle -A PREROUTING -i $EXTIF -j MINIUPNPD

#adding the MINIUPNPD chain for filter
$IPTABLES -t filter -N MINIUPNPD
#adding the rule to MINIUPNPD
$IPTABLES -t filter -A FORWARD -i $EXTIF ! -o $EXTIF -j MINIUPNPD

#adding the MINIUPNPD chain for nat
$IPTABLES -t nat -N MINIUPNPD-PCP-PEER
$IPTABLES -t nat -A POSTROUTING -o $EXTIF -j MINIUPNPD-PCP-PEER

其中/etc/miniupnpd/miniupnpd.conf-------------------------------------------------------------------------

# WAN network interface
ext_ifname=eth1
#ext_ifname=xl1
# if the WAN interface has several IP addresses, you
# can specify the one to use below
#ext_ip=

# LAN network interfaces IPs / networks
# there can be multiple listening ips for SSDP traffic.
# should be under the form nnn.nnn.nnn.nnn/nn
# It can also be the network interface name (ie "eth0")
# It if mandatory to use the network interface name to enable IPv6
# HTTP is available on all interfaces.
# When MULTIPLE_EXTERNAL_IP is enabled, the external ip
# address associated with the subnet follows. for example :
#  listening_ip=192.168.0.1/24 88.22.44.13
#listening_ip=192.168.0.1/24
listening_ip=192.168.10.109/24
#listening_ip=eth0
# port for HTTP (descriptions and SOAP) traffic. set 0 for autoselect.
http_port=0
# port for HTTPS. set to 0 for autoselect (default)
#https_port=0

# path to the unix socket used to communicate with MiniSSDPd
# If running, MiniSSDPd will manage M-SEARCH answering.
# default is /var/run/minissdpd.sock
#minissdpdsocket=/var/run/minissdpd.sock

# enable NAT-PMP support (default is no)
enable_natpmp=yes

# enable UPNP support (default is yes)
enable_upnp=yes

# configure minimal and maximal lifetime of the port mapping in seconds
# 120s and 86400s (24h) are suggested values from PCP-base
min_lifetime=120
max_lifetime=86400

# chain names for netfilter (not used for pf or ipf).
# default is MINIUPNPD for both
#upnp_forward_chain=forwardUPnP
#upnp_nat_chain=UPnP

# lease file location
#lease_file=/var/log/upnp.leases

# to enable the next few runtime options, see compile time
# ENABLE_MANUFACTURER_INFO_CONFIGURATION (config.h)

# name of this service, default is "`uname -s` router"
#friendly_name=MiniUPnPd router

# manufacturer name, default is "`uname -s`"
#manufacturer_name=Manufacturer corp

# manufacturer url, default is URL of OS verndor
#manufacturer_url=http://miniupnp.free.fr/

# model name, default is "`uname -s` router"
#model_name=Router Model

# model description, default is "`uname -s` router"
#model_description=Very Secure Router - Model

# model url, default is URL of OS vendor
#model_url=http://miniupnp.free.fr/

# bitrates reported by daemon in bits per second
bitrate_up=1000000
bitrate_down=10000000

# "secure" mode : when enabled, UPnP client are allowed to add mappings only
# to their IP.
#secure_mode=yes
secure_mode=no

# default presentation url is http address on port 80
# If set to an empty string, no presentationURL element will appear
# in the XML description of the device, which prevents MS Windows
# from displaying an icon in the "Network Connections" panel.
#presentation_url=http://www.mylan/index.php

# report system uptime instead of daemon uptime
system_uptime=yes

# notify interval in seconds. default is 30 seconds.
#notify_interval=240
notify_interval=60

# unused rules cleaning.
# never remove any rule before this threshold for the number
# of redirections is exceeded. default to 20
#clean_ruleset_threshold=10
# clean process work interval in seconds. default to 0 (disabled).
# a 600 seconds (10 minutes) interval makes sense
clean_ruleset_interval=600

# log packets in pf (default is no)
#packet_log=no

# anchor name in pf (default is miniupnpd)
#anchor=miniupnpd

# ALTQ queue in pf
# filter rules must be used for this to be used.
# compile with PF_ENABLE_FILTER_RULES (see config.h file)
#queue=queue_name1

# tag name in pf
#tag=tag_name1

# make filter rules in pf quick or not. default is yes
# active when compiled with PF_ENABLE_FILTER_RULES (see config.h file)
#quickrules=no

# uuid : generate your own with "make genuuid"
uuid=33d9b85d-f8ad-4164-9111-283b7c74acb4

# serial and model number the daemon will report to clients
# in its XML description
serial=12345678
model_number=1

# UPnP permission rules
# (allow|deny) (external port range) ip/mask (internal port range)
# A port range is <min port>-<max port> or <port> if there is only
# one port in the range.
# ip/mask format must be nn.nn.nn.nn/nn
# it is advised to only allow redirection of port above 1024
# and to finish the rule set with "deny 0-65535 0.0.0.0/0 0-65535"
allow 1024-65535 192.168.0.0/24 1024-65535
allow 1024-65535 192.168.1.0/24 1024-65535
allow 1024-65535 192.168.0.0/23 22
allow 12345 192.168.7.113/32 54321
deny 0-65535 0.0.0.0/0 0-65535

root@ca:/etc/miniupnpd# cat /etc/default/miniupnpd -------------------------------------------------------------

# Set to 1 to start the daemon. Desactivated by default, because
# you don\'t want the outside to control your UPnP router, and
# as a consequence MiniUPnPd_LISTENING_IP should be set to a
# reasonable value before enabling the daemon.
START_DAEMON=0

# Define here the external interface connected to the WAN (eg: the public
# IP address NIC)
MiniUPnPd_EXTERNAL_INTERFACE=vmbr3

# IP that the daemon should listen on.
# Note that you do *not* want this to be 0.0.0.0, as you don\'t want
# your MiniUPnPd to be controled by anyone on the internet.
MiniUPnPd_LISTENING_IP=100.73.73.1

# This defines other options which you might want to use when
# starting MiniUPnPd. Note that the -S option is important:
# -S sets "secure" mode : clients can only add mappings to their own ip
# (see man page)
MiniUPnPd_OTHER_OPTIONS="-N -f /etc/miniupnpd/miniupnpd.conf"

# If this option is defined, then the init script will initialize
# the ipv6 tables.
MiniUPnPd_ip6tables_enable=no

疑问:

1)MiniUPnPd_LISTENING_IP=100.73.73.1(在/etc/default/miniupnpd中)和listening_ip (在/etc/miniupnpd/miniupnpd.conf中) 可否设置多个 ??

MiniUPnPd_LISTENING_IP实质就是shell变量,可以在/etc/default/miniupnpd中每单行设置1个,也就是说设置多个,但只有最后一行设置才会生效

listening_ip可以设置多个如下:listening_ip=bridge0 em0 wlan0 也可以单独写多行listening_ip
https://github.com/miniupnp/miniupnp/blob/master/miniupnpd/miniupnpd.conf 摘录如下:

LAN network interfaces IPs / networks
# There can be multiple listening IPs for SSDP traffic, in that case
# use multiple \'listening_ip=...\' lines, one for each network interface.
# It can be IP address or network interface name (ie. "eth0")
# It is mandatory to use the network interface name in order to enable IPv6
# HTTP is available on all interfaces.
# When MULTIPLE_EXTERNAL_IP is enabled, the external IP
# address associated with the subnet follows. For example:
#  listening_ip=192.168.0.1/24 88.22.44.13
# When MULTIPLE_EXTERNAL_IP is disabled, you can list associated network
# interfaces (for bridges)
#  listening_ip=bridge0 em0 wlan0
#listening_ip=192.168.0.1/24
#listening_ip=10.5.0.0/16
#listening_ip=eth0
# CAUTION: mixing up WAN and LAN interfaces may introduce security risks!
# Be sure to assign the correct interfaces to LAN and WAN and consider
# implementing UPnP permission rules at the bottom of this configuration file

2)/etc/default/miniupnpd和/etc/miniupnpd/miniupnpd.conf之间的关系

root@ca:~# systemctl status miniupnpd
● miniupnpd.service - LSB: daemon providing UPnP Internet Gateway Device (IGD) services
Loaded: loaded (/etc/init.d/miniupnpd; generated; vendor preset: enabled)
Active: active (exited) since Tue 2020-10-27 19:40:47 CST; 5h 22min ago
Docs: man:systemd-sysv-generator(8)
Process: 23818 ExecStart=/etc/init.d/miniupnpd start (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 6144)
Memory: 0B
CPU: 0
CGroup: /system.slice/miniupnpd.service

Oct 27 19:40:47 ca systemd[1]: Starting LSB: daemon providing UPnP Internet Gateway Device (IGD) services...
Oct 27 19:40:47 ca miniupnpd[23818]: MiniUPnPd: /etc/default/miniupnpd isn\'t set to START_DAEMON=1: exiting:
Oct 27 19:40:47 ca systemd[1]: Started LSB: daemon providing UPnP Internet Gateway Device (IGD) services.
解析上面的状态为什么是active (exited)
MiniUPnPd: /etc/default/miniupnpd isn\'t set to START_DAEMON=1 所以退出

root@ca:~# less /usr/share/doc/miniupnpd/examples/miniupnpd.default 对应/etc/default/miniupnpd 模板文件
root@ca:~# less /usr/share/doc/miniupnpd/examples/miniupnpd.conf 对应/etc/miniupnpd/miniupnpd.conf模板文件,可以看到如下:

# WAN network interface. If not supplied here, then
# we\'re going to use /etc/default/miniupnpd
#ext_ifname=eth0

上面说的很清楚,外网卡设置优先使用/etc/miniupnpd/miniupnpd.conf中配置,否者使用/etc/default/miniupnpd中配置

3)手动运行miniupnpd,如下: 手动运行后是否不会自动生成iptables规则?????不会自动生成除非自己写iptables规则
root@ca:~# miniupnpd -i vmbr3 -a 100.73.73.1/24 -d
Error: please specify LAN network interface by name instead of IPv4 address : 100.73.73.1/24
can\'t parse "100.73.73.1/24" as a valid interface name
Usage:
miniupnpd [-f config_file] [-i ext_ifname] [-o ext_ip]
[-a listening_ip] [-p port] [-d] [-U] [-S] [-N]
[-u uuid] [-s serial] [-m model_number]
[-t notify_interval] [-P pid_filename] [-B down up] [-w url] [-r clean_ruleset_interval]
[-A "permission rule"]

Notes:
There can be one or several listening_ips.
Notify interval is in seconds. Default is 30 seconds.
Default pid file is \'/var/run/miniupnpd.pid\'.
Default config file is \'/etc/miniupnpd.conf\'.
With -d miniupnpd will run as a standard program.
-S sets "secure" mode : clients can only add mappings to their own ip
-U causes miniupnpd to report system uptime instead of daemon uptime.
-N enable NAT-PMP functionality.
-B sets bitrates reported by daemon in bits per second.
-w sets the presentation url. Default is http address on port 80
-A use following syntax for permission rules :
(allow|deny) (external port range) ip/mask (internal port range)
examples :
"allow 1024-65535 192.168.1.0/24 1024-65535"
"deny 0-65535 0.0.0.0/0 0-65535"
-h prints this help and quits.
经过查询miniupnpd的版本如下:
root@ca:~# apt list --installed | grep mini
miniupnpd/oldstable,now 1.8.20140523-4.1+deb9u2 amd64 [installed]
在网上搜索发现1.8版本存在这个问题,但是已经在2.0版本上进行了修复,参考:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=885825

再次手动运行miniupnpd -i vmbr3 -a vmbr2 -a vmbr4 -S -w 8100 -A "allow 61000-62000 100.73.73.0/24 1024-65535" -A "allow 63000-64000 100.72.139.0/24 1024-65535" -A "deny 0-65535 0.0.0.0/0 0-65535" -d 提示如下:
miniupnpd[20305]: Starting UPnP-IGD with external interface vmbr3
miniupnpd[20305]: HTTP listening on port 44989
miniupnpd[20305]: no HTTP IPv6 address, disabling IPv6
miniupnpd[20305]: get_lan_for_peer(): 166.111.188.90:62262 not found !
miniupnpd[20305]: SSDP packet sender 166.111.188.90:62262 not from a LAN, ignoring
miniupnpd[20305]: get_lan_for_peer(): 166.111.188.148:53699 not found !
miniupnpd[20305]: SSDP packet sender 166.111.188.148:53699 not from a LAN, ignoring

再次miniupnpd -i vmbr3 -a vmbr2 vmbr4 -S -w 8100 -A "allow 61000-62000 100.73.73.0/24 1024-65535" -A "allow 63000-64000 100.72.139.0/24 1024-65535" -A "deny 0-65535 0.0.0.0/0 0-65535" -d 提示如下:
Unknown option: vmbr4

再次miniupnpd -i vmbr3 -a "vmbr2 vmbr4" -S -w 8100 -A "allow 61000-62000 100.73.73.0/24 1024-65535" -A "allow 63000-64000 100.72.139.0/24 1024-65535" -A "deny 0-65535 0.0.0.0/0 0-65535" -d 如下:
miniupnpd[32556]: Starting UPnP-IGD with external interface vmbr3
miniupnpd[32556]: HTTP listening on port 39751
miniupnpd[32556]: no HTTP IPv6 address, disabling IPv6
miniupnpd[32556]: get_lan_for_peer(): 166.111.188.114:51535 not found !
miniupnpd[32556]: SSDP packet sender 166.111.188.114:51535 not from a LAN, ignoring
miniupnpd[32556]: get_lan_for_peer(): 166.111.188.109:64453 not found !
miniupnpd[32556]: SSDP packet sender 166.111.188.109:64453 not from a LAN, ignoring
miniupnpd[32556]: get_lan_for_peer(): 166.111.188.142:49673 not found !
miniupnpd[32556]: SSDP packet sender 166.111.188.142:49673 not from a LAN, ignoring
miniupnpd[32556]: get_lan_for_peer(): 166.111.188.142:49674 not found
miniupnpd[32556]: get_lan_for_peer(): 166.111.188.87:57106 not found !
miniupnpd[32556]: SSDP packet sender 166.111.188.87:57106 not from a LAN, ignoring
miniupnpd[32556]: get_lan_for_peer(): 100.72.139.183:50622 found in LAN vmbr2 100.72.139.4
miniupnpd[32556]: get_lan_for_peer(): 100.72.139.183:50622 found in LAN vmbr2 100.72.139.4
miniupnpd[32556]: get_lan_for_peer(): 100.72.139.183:50622 found in LAN vmbr2 100.72.139.4
miniupnpd[32556]: get_lan_for_peer(): 100.72.139.183:57298 found in LAN vmbr2 100.72.139.4
从上面看出-a "vmbr2 vmbr4" 在vmbr2接口上生效了,但不知道在vmbr4上生效没?? 应该是存在问题的,还是应该将-a "vmbr2 vmbr4" 写成-a vmbr2 -a vmbr4

其中-a参数还存在vmbr2/24 这种使用方式 参考https://github.com/miniupnp/miniupnp/issues/274

4)探寻miniupnpd的启动脚本:
/run/systemd/generator.late/multi-user.target.wants/miniupnpd.service 在其内容中看到如下:
ExecStart=/etc/init.d/miniupnpd start
看下less /etc/init.d/miniupnpd 内容如下:

#!/bin/sh

### BEGIN INIT INFO
# Provides:             miniupnpd
# Required-Start:       $remote_fs
# Required-Stop:        $remote_fs
# Should-Start:         $local_fs $network $time
# Should-Stop:          $local_fs $network $time
# Default-Start:        2 3 4 5
# Default-Stop:         0 1 6
# Short-Description:    daemon providing UPnP Internet Gateway Device (IGD) services
# Description:          MiniUPnPd is a small daemon providing UPnP Internet Gateway
#                       Device (IGD) services to your network. UPnP and NAT-PMP are
#                       used to improve internet connectivity for devices behind a
#                       NAT router. Any peer to peer network application such as
#                       games, IM, etc. can benefit from a NAT router supporting
#                       UPnP and/or NAT-PMP.
### END INIT INFO

. /lib/lsb/init-functions

DAEMON_NAME="MiniUPnPd"
DAEMON_SERVICE_NAME="UPnP devices daemon"
IPTABLES="/sbin/iptables"
IP6TABLES="/sbin/ip6tables"
MINIUPNPD="/usr/sbin/miniupnpd"
IP="/bin/ip"

if [ -r /lib/init/vars.sh ]
then
        . /lib/init/vars.sh
fi

# Make sure the package hasn\'t been removed but not purged
if ! [ -x ${MINIUPNPD} ] && [ -x ${IPTABLES} ] && [ -x ${IP} ]
then
        exit 0
fi

if [ -f "/etc/default/miniupnpd" ]
then
        . /etc/default/miniupnpd
else
        log_daemon_msg "${DAEMON_NAME}: Default file not found: exiting"
        log_end_msg 1

        exit 0
fi

if [ "${START_DAEMON}" != "1" ]
then
        log_daemon_msg "${DAEMON_NAME}: /etc/default/miniupnpd isn\'t set to START_DAEMON=1: exiting"
        log_end_msg 1

        exit 0
fi

if [ -z "${MiniUPnPd_EXTERNAL_INTERFACE}" ]
then
        log_daemon_msg "${DAEMON_NAME}: no interface defined: exiting"
        log_end_msg 1

        exit 0
fi

if [ -z "${MiniUPnPd_LISTENING_IP}" ]
then
        log_daemon_msg "${DAEMON_NAME}: no listening IP defined: exiting"
        log_end_msg 1

        exit 0
fi

EXTIP="$(LC_ALL=C ${IP} addr show ${MiniUPnPd_EXTERNAL_INTERFACE} | grep "inet " | awk \'{ print $2 }\' | cut -d"/" -f1)"

ip6tables_init_fw_tables ()
{
        if [ -z "${EXTIP6}" ] ; then
                return
        fi
        N6DIRTY="$(LC_ALL=C ${IP6TABLES} -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"

        if [ "${N6DIRTY}" = "MINIUPNPDChain" ]
        then
                ${IP6TABLES} -F MINIUPNPD
        elif [ "${N6DIRTY}" = "Chain" ]
        then
                ${IP6TABLES} -A FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
                ${IP6TABLES} -F MINIUPNPD
        else
                ${IP6TABLES} -N MINIUPNPD
                ${IP6TABLES} -A FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
        fi
}

iptables_init_nat_tables ()
{
        # Initialize the PREROUTING chain first
        NDIRTY="$(LC_ALL=C ${IPTABLES} -t nat -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"

        if [ "${NDIRTY}" = "MINIUPNPDChain" ]
        then
                # Nat table dirty; Cleaning...
                ${IPTABLES} -t nat -F MINIUPNPD
        elif [ "${NDIRTY}" = "Chain" ]
        then
                # Dirty NAT chain but no reference..?
                ${IPTABLES} -t nat -A PREROUTING -d ${EXTIP} -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
                ${IPTABLES} -t nat -F MINIUPNPD
        else
                # NAT table clean..initalizing..
                ${IPTABLES} -t nat -N MINIUPNPD
                ${IPTABLES} -t nat -A PREROUTING -d ${EXTIP} -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
        fi

        # then do the FORWARD chain
        FDIRTY="$(LC_ALL=C ${IPTABLES} -t filter -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"

        if [ "${FDIRTY}" = "MINIUPNPDChain" ]
        then
                # Filter table dirty; Cleaning...
                ${IPTABLES} -t filter -F MINIUPNPD
        elif [ "${FDIRTY}" = "Chain" ]
        then
                # Dirty filter chain but no reference..? Fixsted.
                ${IPTABLES} -t filter -I FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} ! -o ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
                ${IPTABLES} -t filter -F MINIUPNPD
        else
                # Filter table clean..initalizing..
                ${IPTABLES} -t filter -N MINIUPNPD
                ${IPTABLES} -t filter -I FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} ! -o ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD
        fi
}

ip6tables_stop_fw_tables ()
{
        N6DIRTY="$(LC_ALL=C ${IP6TABLES} -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"
        if [ "${N6DIRTY}" = "MINIUPNPDChain" ]
        then
                ${IP6TABLES} -F MINIUPNPD || true
                ${IP6TABLES} -D FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD || true
                ${IP6TABLES} -X MINIUPNPD || true
        elif [ "${NDIRTY}" = "Chain" ]
        then
                ${IP6TABLES} -F MINIUPNPD || true
                ${IP6TABLES} -X MINIUPNPD || true
        fi
}

iptables_stop_nat_tables ()
{
        # Clean the nat tables
        NDIRTY="$(LC_ALL=C ${IPTABLES} -t nat -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"

        if [ "${NDIRTY}" = "MINIUPNPDChain" ]
        then
                ${IPTABLES} -t nat -F MINIUPNPD || true
                ${IPTABLES} -t nat -D PREROUTING -d ${EXTIP} -i ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD || true
                ${IPTABLES} -t nat -X MINIUPNPD || true
        elif [ "${NDIRTY}" = "Chain" ]
        then
                ${IPTABLES} -t nat -F MINIUPNPD || true
                ${IPTABLES} -t nat -X MINIUPNPD || true
        fi

        # Clean the filter tables
        FDIRTY="$(LC_ALL=C ${IPTABLES} -t filter -L -n | grep \'MINIUPNPD\' | awk \'{ printf $1 }\')"

        if [ "${FDIRTY}" = "MINIUPNPDChain" ]
        then
                ${IPTABLES} -t filter -F MINIUPNPD || true
                ${IPTABLES} -t filter -D FORWARD -i ${MiniUPnPd_EXTERNAL_INTERFACE} ! -o ${MiniUPnPd_EXTERNAL_INTERFACE} -j MINIUPNPD || true
                ${IPTABLES} -t filter -X MINIUPNPD || true
        elif [ "${FDIRTY}" = "Chain" ]
        then
                ${IPTABLES} -t filter -F MINIUPNPD || true
                ${IPTABLES} -t filter -X MINIUPNPD || true
        fi
}

case "${1}" in
        start)
                iptables_init_nat_tables
                if [ "${MiniUPnPd_ip6tables_enable}" = "yes" ] ; then ip6tables_init_fw_tables ; fi

                log_daemon_msg "Starting ${DAEMON_SERVICE_NAME}" ${DAEMON_NAME}

                start-stop-daemon -q --start --exec "/usr/sbin/miniupnpd" -- -i ${MiniUPnPd_EXTERNAL_INTERFACE} -o ${EXTIP} -a ${MiniUPnPd_LISTENING_IP} ${MiniUPnPd_OTHER_OPTIONS}
                RET="${?}"

                case "${RET}" in
                        0|1)
                                log_end_msg 0
                                ;;

                        *)
                                log_end_msg 1

                                exit 1
                                ;;
                esac
                ;;

        stop)
                log_daemon_msg "Stopping ${DAEMON_SERVICE_NAME}" ${DAEMON_NAME}

                start-stop-daemon -q --stop --oknodo --pidfile /var/run/miniupnpd.pid
                RET="${?}"

                iptables_stop_nat_tables
                if [ "${MiniUPnPd_ip6tables_enable}" = "yes" ] ; then ip6tables_stop_fw_tables ; fi

                case "${RET}" in
                        0|1)
                                log_end_msg 0
                                ;;

                        *)
                                log_end_msg 1

                                exit 1
                                ;;
                esac
                ;;

        restart|force-reload)
                ${0} stop
                sleep 1
                ${0} start
                ;;

        status)
                status_of_proc "/usr/sbin/minissdpd" "MiniUPnPd"
                exit ${?}
                ;;

        *)
                echo "Usage: ${0} {start|stop|restart|status}"
                exit 1
                ;;
esac

exit 0

分析以上脚本当start时,最重要的是以下这句start-stop-daemon -q --start --exec "/usr/sbin/miniupnpd" -- -i ${MiniUPnPd_EXTERNAL_INTERFACE} -o ${EXTIP} -a ${MiniUPnPd_LISTENING_IP} ${MiniUPnPd_OTHER_OPTIONS}
其中参数MiniUPnPd_OTHER_OPTIONS值为-N -f /etc/miniupnpd/miniupnpd ,-a参数可以有多个,所以 -a ${MiniUPnPd_LISTENING_IP}和/etc/miniupnpd/miniupnpd 里的listening_ip参数应该可以共存。

如何在外部地址上使用minupnpd?

参考:
Installation asks for a LAN IP, it actually wants the LAN interface and the init script fails to start up with a LAN IP. https://bugs.launchpad.net/ubuntu/+source/miniupnpd/+bug/1538192 说明了低版本miniupnpd listening_ip不能填写ip而只能填写接口的bug。

Nested routers - miniupnpd: SSDP packet sender … not from a LAN, ignoring https://forum.netgate.com/topic/74967/nested-routers-miniupnpd-ssdp-packet-sender-not-from-a-lan-ignoring

https://blog.csdn.net/u012335044/article/details/77849659

https://bryceknowhow.blogspot.com/2014/07/miniupnpd-miniupnpd-upnp-daemon.html

openwrt中miniupnpd配置说明 https://openwrt.org/docs/guide-user/firewall/upnp/miniupnpd