今天记录一下OpenWrt路由器在IPv6环境下,如何设置防火墙实现按需开放公网访问内部设备。
IPv6 已经相当普及,无论是家宽、校园网,抑或是蜂窝移动网络,获得/64
的 IPv6 子网已经不是难事。特别是当前运营商对于家宽正逐步停止提供公网IPv4,未来从公网访问家庭局域网的需求只能通过IPv6实现。
环境
- 路由器:
OpenWrt 22.03.2
服务器托管网
- 绝大部分厂商的原厂固件的 IPv6 防火墙都是残缺的,请不要使用原厂固件
- 光猫应当配置为桥接模式并使用路由器拨号,请不要让光猫承担它不该承受之重
- 需要暴露的主机:
Any GNU/Linux
- 当然也包含各种NAS
准备工作
确认已经取得/64的 IPv6 子网
一般可在路由器管理页面确认,也可通过其他方式确认。
如果获得的子网大小不是/64
,本文仍可供参考,但需要有一些小改动。实际经常遇到的是直接给了 /60
的子网(电信or移动)。
如果只能取得/128
的子网(整个子网只有一个地址),还是别折腾了,换运营商。
下文中,我们假定取得的子网是2409:1111:2222:3333::/64
。
确认 ISP 没有阻止入站连接
如果路由器使用的是 OpenWrt,默认的防火墙规则不会阻止 ICMP 入站连接;如果是其他路由器固件,请先完全关闭防火墙。
本文假设系统防火墙已经被恰当配置,不会阻止需要暴露的端口的入站连接。
- 访问ip.sb,取得当前设备的 IPv6 临时公网地址,我们假设它是
2409:1111:2222:3333::1234
。 - 尝试在外部网络ping 上述 IPv6 公网地址。
- 最简单的方式是,在 Android 手机上通过Termux使用蜂窝移动网络 ping。(应当先确定 Termux 能连接到 IPv6)
- 如果能 ping 通,则进行下一步。如果不能,通常没有必要再进行下一步。
- 向 OpenWrt 添加一条通信规则(访问
cgi-bin/luci/admin/network/firewall/rules
)以临时允许入站连接:
- 允许
TCP 和 UDP
,源区域为wan
(包含 wan, wan6),目标区域为lan
,操作为接受
,其余留空,保存并应用。
- 在本机挂载一个 web 服务,如
python3 -m http.server 8888
。 - 尝试在外部网络访问这个端口,如
curl http://[2409:1111:2222:3333::1234]:8888
。 - 更换端口重试几遍,重点留意
80
,443
,8080
等常见端口有无被封锁;如被封锁,尝试不常见的端口。 - 关闭 web 服务,删除先前创建的通信规则,保存并应用。如果是其他路由器固件,请重新打开防火墙,并想办法刷入 OpenWrt。
如果 ISP 阻止了入站连接,请考虑换一家 ISP。
有些路由器的原厂固件可能无法关闭 IPv6 防火墙并造成假阳性结果,请考虑使用OpenWrt。
取得设备的不变后缀
选项一:EUI-64(推荐)
EUI-64 地址有着我们需要的优点:后缀固定不变、前缀实时更新。一般情况下,我们应该使用它。如果获得的子网大小不是
/64
,可能不按预期工作。
Linux:
sudo ifconfig
Windows(需要提权):
set-netipv6protocol -RandomizeIdentifiers Disabled # Windows 默认不使用 EUI-64,启用它
ipconfig /all
- 找到目前用于连接互联网的网络适配器。
- 找到一个 IP 地址,它应该类似于
2409:1111:2222:3333:****:**ff:fe**:****
,它就是该设备的 EUI-64 地址。 - 记下
****:**ff:fe**:****
的部分,下文假设它是1:20ff:fe77:2077
。 - 验证 EUI-64 地址(可选):参见通过EUI-64自动生成IPv6地址和IPv6链路本地地址(Link-Local Address) | CCIE 工程师社区。
选项二:使用临时 IPv6 地址
并不推荐使用临时地址,这将导致防火墙规则难以编写。
请直接跳到下一节。
选项三:DHCPv6
并不推荐使用 DHCPv6,因为它总是落后于网络变化。如果家宽重拨导致分配到的 v6 子网变化,它根本不会自动更新,只有等到租约到期(一般是
12h
)续租时才会更新。
首先选定一个 IPv6 后缀如a1cd
(也可不选定。默认分配的后缀一般是设备特定且不变的,不选定则自行记录默认分配的后缀)。
注意:有时候,在系统的默认配置下并没有完整的 stateful DHCPv6 支持,此时请使用其他方法。本文亦不含有打开 stateful DHCPv6 的教学。(DHCPv6 坏坏)
- 在 OpenWrt 为需要的设备创建一个静态地址分配(访问
cgi-bin/luci/admin/network/dhcp
),指定租期如5m
(因租约到期才会自动刷新,必须设定为较短的值以确保 DHCPv6 分配维持最新),填写选定的 IPv6 后缀(也可留空),保存并应用。 - 物理上重新连接目标设备。
- 刷新页面,在页面底部的
已分配的 DHCPv6 租约
里确认确实为该设备正确分配了需要的后缀和租期。 - 如果租期没有被正确分配,仍为默认的
12h
,则该设备不适合该方法。(除非能获得不变的 IPv6 子网)
配置防火墙
向 OpenWrt 添加一条通信规则(访问cgi-bin/luci/admin/network/f服务器托管网irewall/rules
):
- 协议:
TCP 和 UDP
- 源区域:
wan
(包含 wan, wan6) - 目标区域:
lan
- 目标地址:
- 使用 EUI-64 或 DHCPv6:
::/::ffff:ffff:ffff:ffff
,如::1:20ff:fe77:2077/::ffff:ffff:ffff:ffff
或::a1cd/::ffff:ffff:ffff:ffff
(如果子网大小不是/64
,请自行改变掩码) - 使用临时地址:留空(注意:这会导致其他主机一并暴露,请避免同时留空目标端口)
- 目标端口:
- 暴露特定端口:
- 整台主机暴露:留空
- 操作:
接受
- 高级设置
- 限制地址类型:
仅 IPv6
- 其余维持默认
- 特别提醒:源端口留空,只填目标端口
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net