参考:
- OpenWrt UPnP协议细节 - https://blog.51cto.com/u_15346415/3694525
- Openwrt 端口转发 dmz upnp介绍 - https://www.jianshu.com/p/74410f68b146
- Openwrt unpn 配置 - https://www.52asus.com/thread-2416-1-1.html
相关
- 我给Openwrt造盔甲 - https://zhuanlan.zhihu.com/p/352839700
通用即插即用(Universal Plug and Play,UPnP)实现方便的端口转发功能。(所谓“方便”)
比如我想用wan口的IP 192.168.2.180(2222端口),远程连接lan口内网192.168.18.235的ubuntu(22端口),如何实现:
在防火墙下面添加如下规则cat /etc/config/firewall
config redirect
option enabled '1'
option proto 'tcp'
option comment 'ubuntu'
option src_dport '2222'
option dest_ip '192.168.18.235'
option dest_port '22'
option src 'wan'
option target 'DNAT'
option dest 'lan'
重启防火墙
就可以看到nat表下添加了如下规则
root@openwrt:/# iptables -t nat -nvL | grep 235
307 23589 zone_lan_prerouting all -- br-lan * 0.0.0.0/0 0.0.0.0/0
0 0 SNAT tcp -- * * 192.168.18.0/24 192.168.18.235 tcp dpt:22 /* @redirect[0] (reflection) */ to:192.168.18.1
307 23589 prerouting_lan_rule all -- * * 0.0.0.0/0 0.0.0.0/0 /* user chain for prerouting */
0 0 DNAT tcp -- * * 192.168.18.0/24 192.168.2.180 tcp dpt:2222 /* @redirect[0] (reflection) */ to:192.168.18.235:22
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:2222 /* @redirect[0] */ to:192.168.18.235:22
这样通过wan ip加src_dport (2222)就可以访问到内网机器的ssh端口(22)了。
dmz就是加强版的端口转发,比如你内网IP里面有22端口给ssh用,也有80端口给web用,也有23端口给telnet用。如果用端口转发的话,你需要建立三条端口转发的规则。用dmz的话一下子就都可以了。
在防火墙下面添加如下规则 cat /etc/config/firewall
config redirect 'dmz'
option name 'dmz'
option src 'wan'
option proto 'tcp'
option target 'DNAT'
option dest_ip '192.168.18.235'
option enabled '1'
config redirect 'dmzudp'
option name 'dmzudp'
option src_port '!67'
option src 'wan'
option proto 'udp'
option target 'DNAT'
option dest_ip '192.168.18.235'
option enabled '1'
实际实现在iptable的nat表下面添加了如下规则
root@openwrt:/# iptables -t nat -nvL | grep 235
0 0 SNAT tcp -- * * 192.168.18.0/24 192.168.18.235 /* dmz (reflection) */ to:192.168.18.1
0 0 SNAT udp -- * * 192.168.18.0/24 192.168.18.235 /* dmzudp (reflection) */ to:192.168.18.1
0 0 DNAT tcp -- * * 192.168.18.0/24 192.168.2.180 /* dmz (reflection) */ to:192.168.18.235
0 0 DNAT udp -- * * 192.168.18.0/24 192.168.2.180 /* dmzudp (reflection) */ to:192.168.18.235
5 405 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* dmz */ to:192.168.18.235
26 2270 DNAT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp spt:!67 /* dmzudp */ to:192.168.18.23
openwrt上面使用miniupnpd服务来实现upnp服务
upnp可以通过另一种方式实现端口映射,就是客户端告诉路由器说,我想要通过哪个端口应该到哪个端口,然后路由器帮忙建立端口转发规则。
root@zihome:# ps | grep mini
25503 root 1076 S /usr/sbin/miniupnpd -f /var/etc/miniupnpd.conf
28450 root 1520 S grep mini
/etc/config/upnpd里面的log_output设置成1,可以在logread下查看交互日志。
config upnpd 'config'
option enable_natpmp '1'
option enable_upnp '1'
option secure_mode '1'
option log_output '1'
root@OpenWrt:/# opkg update
root@OpenWrt:/# opkg install miniupnpd
root@OpenWrt:/# opkg install luci-app-upnp
安装完miniupnpd会生成一个upnpd配置文件,位于/etc/config/upnpd中
Default状态下会有”config”与”perm_rule”内容
config upnpd 'config’的配置参数:
选项 | 说明 |
---|---|
enable_natpmp ‘1’ | 启用NAT-PMP,1表示开启。 |
enable_natpmp ‘1’ | 开启UPnP,1表示开启。 |
secure_mode ‘1’ | 安全模式,客户端只能给自己转发一个输入口。 |
log_output ‘0’ | 日志输出级别,0表示不输出日志,如果设置了将输出到syslog中。 |
download ‘1024’ | 允许来自wan端的数据输入带宽,单位是(KB/秒)。 |
upload ‘512’ | 允许输出到wan端的数据输入带宽,单位是(KB/秒)。 |
internal_iface ‘lan’ | 内网的设备域,默认是lan。 |
external_iface ‘wan’ | 外网的设备域,默认是wan。 |
port ‘5000’ | 监听的端口 |
upnp_lease_file ‘/var/upnp.leases’ | upnp客户端租赁记录文件,如DHCP租约。 |
uuid ‘64ba8083-ed0e-4c5b-87a6-46705629624a’ | UUI自动生成第一次启动miniupnpd的 IGD。如果没有指定一个将被自动生成并添加到配置文件。 |
config perm_rule许可设置配置参数(permit):
选项 | 说明 |
---|---|
action 字符串 | 设置是否许可:allow许可,deny不许可。 |
ext_ports 字符串 | 外部端口范围。 |
int_addr 字符串 | IP地址,如果是0.0.0.0/0表示全部。 |
int_ports 字符串 | 内部端口范围。 |
comment字符串 | ‘Allow highports’,‘Default deny’。 |
下面使用ubuntu(作为客户端)请求将9000外部端口映射到2222内部端口
提示
外部端口 9000 的选定:
upnp默认只允许1024-65535端口的映射config perm_rule option action 'allow' option ext_ports '1024-65535' option int_addr '0.0.0.0/0' option int_ports '1024-65535' option comment 'Allow high ports
ubuntu安装upnp客户端 upnpc
sudo apt-get install -y miniupnpc
ubuntu设置ssh端口
sudo vim /etc/ssh/sshd_config
Port 22
Port 2222
ubuntu重启ssh sudo /etc/init.d/ssh restart
ubuntu 通过upnpc请求添加端口映射,2222内部端口,9000外部端口
upnpc -a 192.168.17.233 2222 9000 TCP
这时候在upnp.leases下面就会添加一条信息,iptable -t nat下面添加一条规则。完成端口映射
root@openwrt:/# cat /var/upnp.leases
TCP:9000:192.168.17.233:2222:1655716845:libminiupnpc
ubuntu 通过upnpc请求删除端口映射
upnpc -d 192.168.17.233 2222 9000 TCP
会有如下信息被upnpd捕获到
root@openwrt:/# cat /var/upnp.leases
TCP:54366:192.168.17.151:53533:1655706396:PTL-000C29A6B88AGXGA
UDP:54366:192.168.17.151:54366:1655706396:PTL-000C29A6B88AGXGA
TCP:53532:192.168.17.151:53532:1655706396:PTL-000C29A6B88AGXGA
root@openwrt:/# iptables -t nat -nvL
Chain MINIUPNPD (1 references)
pkts bytes target prot opt in out source destination
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:63016 to:192.168.17.151:53866
0 0 DNAT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:63016 to:192.168.17.151:63016
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53864 to:192.168.17.151:53864