端口被封杀?巧用端口转发和NAT

从外网访问内网的时候,经常会遇到端口被封杀的情况,因为运营商不希望家庭用户架设服务器;两个局域网(通过外网)互相访问的时候则更要命,比如Windows自带的SMB协议只能使用默认的445端口,这个时候端口转发也失效了。挨踢君借助OpenWrt的iptables,使用DNAT巧妙解决了端口问题。

NAT 网络地址转换

先来说说网络地址转换,Network Address Translation。在复用 - 精品教程中,我留了一个问题:路由器是如何复用ip让多个设备共用同一个公网ip上网的?

是通过端口的“时分复用”

路由器会分配端口给内网应用,应用使用完成后便收回端口,供下次分配给其他应用。这样只让端口被占用一小段时间,便实现了对ip的复用。受篇幅限制,不便展开,大家只要这样理解:

假设

  • 路由器内网ip为192.168.1.1,路由器公网ip为110.110.110.110
  • 来源地址是局域网内部机器,形如192.168.1.2
  • 目的地址是百度服务器,形如39.156.69.79。

这时,数据包发给外网

  • ip包上的来源地址(source)会被修改成路由器的公网ip,因为只有公网ip才能上网
  • (由于只有一个公网ip,所以在端口已经被使用的情况下,可能还会修改来源端口号)
  • 也就是来源地址被转换成:192.168.1.2:2333 - > 110.110.110.110:23333
  • 路由器会记住ip包的来源地址、端口号以及目的地址(destination)、端口号

点击展开👉PPPoE与公网ip

在使用远程桌面、远程SMB等服务时,可以选择使用DDNS。(什么是DDNS??)

大部分家庭宽带提供了家庭网关,也就是无需路由器了,然而部分网关无法设置端口转发,更不用提DDNS,可以联系客服改用PPPoE,然后下接一个路由。

即便用了PPPoE拨号,也可能会分配内网ip,可以进路由器查看,如果是100开头ip,则为内网。可以致电宽带商客服,修改公网ip

详见:你需要pppoe 和公网ip

在接受外网返回的数据包时

服务器成为来源,内网机器成为目的地

  • 路由器通过来源地址、端口号、目的地址以及目的端口号,确定了这个ip包的身份,也就是这个包所归属的应用
  • 路由器把目的地址(此时为公网地址)修改成内网对应地址(192.168.1.2)
  • 在数据包发给外网时,如果修改过端口号,则在此处进行相反过程
  • 也就是目的地址被转换成: 110.110.110.110:23333 - > 192.168.1.2:2333

这就是NAT,网络地址转换。

端口转发

由于网络地址转换涉及端口号的修改,而这种修改往往是随机的,所以NAT保证了内网设备的安全。也就是说,无法从外网访问内网机器

我们之前的教程windows 共享教程复用 - 精品教程,之前主要实现了内网服务。

使用端口转发,可以实现外网访问内网的服务。

SMB端口转发案例:44500 -> 445

我们可以设置路由器,把来自外网的对44500端口的访问,转发到内网的服务器的445端口。

当我们访问路由器的公网ip:对外端口时,就好像访问内网机器:服务端口。也就是110.110.110.110:44500自动被端口转发成192.168.1.2:445

市面上的路由器都支持端口转发,大家根据自己的品牌,可以搜索端口转发教程,我这里以OpenWrt的命令行配置为例。

点击展开👉命令行别怕!教程

Wow!命令行!很多朋友可能会吓跑!
此视频可破除恐惧👇

其实会点命令行才能破除恐惧,超简单教程👇:


更详细的命令行教程点我

进OpenWrt路由器,输入以下代码:

cat >>/etc/config/firewall<<EOF

config redirect
        option target 'DNAT'
        option src 'wan'
        option dest 'lan'
        option proto 'tcp udp'
        option src_dport '44500'
        option dest_ip '192.168.1.2'
        option dest_port '445'
        option name 'Forwarding44500'
EOF
/etc/init.d/firewall restart

确认即可实现端口转发。现在,当你从外网访问110.110.110.110:44500时,会自动被端口转发到192.168.1.2:445。也就是:访问路由器的公网ip:对外端口时,就好像访问内网机器:服务端口

你使用iPhone,安卓甚至是Mac 都可以开开心心的从外网访问内网的Windows服务器里面的服务了。

记得把Windows的防火墙打开(详见:复用 - 精品教程):

然而在远在宿舍的你,使用Windows却不能访问家里的SMB服务。

你还需要DNAT

当你使用iPhone连接SMB服务时,可以使用除了445端口外的其他端口。但是Windows是不支持445之外的端口的。

幸亏OpenWrt的iptables可以解君愁。

这里假定你在宿舍访问家里的文件

  • 你(在家里的)服务器使用44500端口提供服务
  • 你(在宿舍)使用OpenWrt类路由器(许多路由固件都是基于OpenWrt源码),支持iptables
  • 你访问了非常规端口44500的服务,但你的应用只支持常规端口445

此时,进路由器,输入如下命令:

iptables -t nat -I PREROUTING -p tcp -d 6.1.1.1 --dport 445 -j DNAT --to 110.110.110.110:44500

解释一下这段代码,当路由器发现局域网内的请求满足以下条件时,自动进行DNAT(目的网络地址转换):

  • 当局域网内请求目的ip 为6.1.1.1,且目的端口为445(你也可以改成任意有效的ip地址)时
  • 把目的ip改成110.110.110.110,端口改成44500
  • 反过来。当收到来自110.110.110.110:44500的包时,自动修改成6.1.1.1:445
映射网络驱动器

▲映射网络驱动器

这里假定宿舍的Windows局域网地址为192.168.1.5(你可以改成自己的);在宿舍的Windows映射网络驱动器窗口中输入地址\\6.1.1.1,即可以访问家里110.110.110.110:44500的服务。

当你的服务只能使用特定端口时,都可以利用OpenWrt的iptables来解决这个问题。iptables提供的功能是相当强大的,有时间和大家一起交流这个相对复杂的网络、防火墙工具。

总结

NAT 让我们实现了公网ip 的复用;而端口转发可以让我们从外网方便地访问内网服务,再也不怕运营商屏蔽端口;有些客户端访问服务只能使用常规端口,在这种情况下,我们使用iptables的DNAT巧妙化解问题。

2020-01-30 端口转发 nat openwrt scripts smb cifs 路由器

相关文章