花了两天终于搞明白 OW 的upnp(算是吧),记录一下,顺便帮助到有缘的人。
我是因为需要自己局域网内部的转发功能(其实不知道作用多大,但是在路由器里能看到转发的记录就很舒爽),比如jellyfin等多媒体。
约莫2019年,upnp 在进入2.2.× 时代后,源码维护者在某次代码更新中加入了公网IP检测模块,这可对多层 NAT的国内用户(尤其是公网IP资源紧缺的移动宽带)很不友好,结果就是端口转发 fail 了 。
后续,国内的开发者 commit 了屏蔽公网IP检测的代码,不过这引发了另外一个问题,就是log里几乎分钟级的日志。git 上有人直接给上游维护者发了 issue,然而上游维护者不认可这样的更新,导致ow的维护者,回退了更新。现在 ow 19.07版本存档源里的miniupnpd_2.2.0-4还是可以实现转发的,可惜的是21.02的版本因为是这段时间刚好是测试版,所以没有保留2.2.1-2这个版本。后续更新就回退了。所以下面给出使最新版 upnp工作的方法(除了列出版本之前的版本也可以用下面的方法)。
先贴一个源码的conf
# If the WAN interface has several IP addresses, you
# can specify the one to use below.
# Setting ext_ip is also useful in double NAT setup, you can declare here
# the public IP address.
#ext_ip=
# WAN interface must have public IP address. Otherwise it is behind NAT
# and port forwarding is impossible. In some cases WAN interface can be
# behind unrestricted full-cone NAT 1:1 when all incoming traffic is NAT-ed and
# routed to WAN interfaces without any filtering. In this cases miniupnpd
# needs to know public IP address and it can be learnt by asking external
# server via STUN protocol. Following option enable retrieving external
# public IP address from STUN server and detection of NAT type. You need
# to specify also external STUN server in stun_host option below.
# This option is disabled by default.
#ext_perform_stun=yes
# Specify STUN server, either hostname or IP address
# Some public STUN servers:
# stun.stunprotocol.org
# stun.sipgate.net
# stun.xten.com
# stun.l.google.com (on non standard port 19302)
#ext_stun_host=stun.stunprotocol.org
# Specify STUN UDP port, by default it is standard port 3478.
#ext_stun_port=3478
这几乎就涵盖了非程序员两个解决方法:
1、(这个是两层NAT用户的唯一解决方法了,两层的意思是你的光猫也拿不到公网IP,说的就是移动),上文中的 ext_ip= ,具体在ow的实现是
在 /etc/config/upnpd的 config upnpd 'config' 模块中加入
option external_ip '你的公网IP'
'你的公网IP' 可以是任意公网IP,当然最好是你用IP138.com等网站检测到的。
2、(这个针对有公网IP的,且你是光猫拨号)
在 /etc/config/upnpd的 config upnpd 'config' 模块中加入
option use_stun '1'
option stun_host 'stun.stunprotocol.org'
stun.stunprotocol.org 可以是你自己找到的stun服务器,可以是上文贴出代码的一个。
然后 重启 upnp ,命令行 /etc/init.d/miniupnpd restart ,或者luci里重启。
第三种,有空再写,需要修改源码,非程序员(如我),实现有点难。