OpenWrt 开启 IPv6 中继
最近换了个路由器,不过只能刷 OpenWrt 固件。我之前用的都是 Padavan,几乎可以一键配置 IPv6,加上有 IPv6 公网,非常方便我在外使用远程桌面。不过换成 OpenWrt 后,前后折腾了一个多星期,才搞定了 OpenWrt IPv6 中继。
这里稍微介绍一些 IPv6 基础知识,同时记录一下 OpenWrt 开启 IPv6 中继实现过程。
IPv6 基础知识
IPv6 地址规范
IPv6 地址的长度为 128 bits(2128),由八组 16 位字段组成,相邻字段用冒号分隔,如:
1 | fddd:f00d:cafe:0000:0000:0000:0000:0001 |
每组的前导零可以省略,上面的地址可以写成这样:
1 | fddd:f00d:cafe:0:0:0:0:1 |
可以用双冒号“::”表示一组 0 或多组连续的 0,但只能出现一次:
1 | fddd:f00d:cafe::1 |
IPv6 地址范围
范围 | 含义 |
---|---|
::1/128 | Loopback/本机回环地(就是localhost,类似 127.0.0.1) |
fe80::/10 | Link-Local/链路本地地址(同交换机下的地址,不能转发到其他局域网,类似 169.254.0.0/16) |
fc00::/7 | Unique-Local/唯一区域地址(大局域网地址,不能转发到公网,类似 192.168.0.0/16) |
2000::/3 | Global-Unicast/全球单播(互联网地址,就是公网 IP) |
现实中 Link-Local/链路本地地址
fe80::/10
被使用的只有fe80::/64
这一段,只要你启用了 IPv6,网口会自动根据 MAC 地址 自动生成 IPv6 地址,和 IPv4 的169.254.0.0/16
只在没有 DHCP 时才会生成的情况不一样。
IPv6 Global 子网划分
IPv6 地址子网按下图分配:
- 0—48 位:站点前缀定义从网络到路由器的公共拓扑。企业的站点前缀可以从 ISP 或区域 Internet 注册机构 (Regional Internet Registry, RIR) 获取。
- 48—64 位:子网 ID 定义网络的管理子网,它的最大长度为 16 位。可以在配置 IPv6 网络的过程中指定子网 ID。
- 64—128 位:接口 ID 用来标识特定节点的接口。接口 ID 必须在子网内唯一。IPv6 主机可以使用相邻节点搜索协议自动生成其自身的接口 ID。相邻节点搜索协议基于主机接口的 MAC 地址或 EUI-64 地址自动生成接口 ID。也可以手动指定接口 ID,建议对 IPv6 路由器和启用了 IPv6 的服务器采用这种方式。
- 子网前缀通过指定已分配了子网的特定链路来定义路由器的站点拓扑。
比如电信运营商购买了一个 2048:DEAD:BEEF::/48
网段,则最多可以划分
2^16 = 65536 个子网,分配给 65536 个用户使用。如果用户分配到了类似
2048:DEAD:BEEF:00XX::/56
地址,则可以进一步划分子网(2^8 =
256 个);如果用户分配到的是
2048:DEAD:BEEF:XXXX::/64
,尽管还有 64 位的空间(64—128
位)剩下,也不能继续往下划分子网了。因为接口 ID
是为了分配接入设备保留的。
IPv6 分发方式
IPv6 有三种分发方式:
Static:与 IPv4 一样,手动输入 IPv6 地址固定。
SLAAC:StateLess Address Auto Configuration,SLAAC 设备向路由器发送网络前缀的请求,设备使用前缀和自己的 MAC 地址创建 IP 地址,并检查是否与子网内已有的 IP 重复。
- 设备启动:当一个 IPv6 设备连接到网络时,它会生成一个链路本地地址(Link-Local)。
- 发送RS报文:设备发送 RS 报文,询问网络中的路由器是否存在。
- 接收RA报文:网络中的路由器响应 RS 报文,发送 RA 报文。RA 报文包含网络前缀、默认网关等信息。
- 生成IPv6地址:设备根据 RA 报文中的前缀和自身的 MAC 地址生成一个全局唯一的 IPv6 地址。这个过程通常使用 EUI-64 格式。
- 地址验证:设备通过发送邻居请求(NS)报文来验证生成的 IPv6 地址是否唯一。
- 配置完成:如果地址验证通过,设备就可以使用这个 IPv6 地址进行通信。
- DHCPv6:Dynamic Host Configuration Protocol,IPv6 地址可以使用 IPv6 版本的 DHCP(DHCPv6)进行分配。
- 如果主机希望通过 DHCPv6 获取 IPv6 地址,它会从 UDP 端口 546 向 DHCP
多播地址的端口 547 发送 DHCP 请求。DHCP 服务器随后会从 UDP 端口 547
向客户端 UDP 端口 546 回复 DHCP 通告。这个握手过程可以通过客户端发送
DHCP 请求和服务器(
ff02::1:2
)回复 DHCP 应答来完成。
OpenWrt 开启 IPv6 中继
先介绍一下我的网络环境:
- 光猫拨号,直接连接在光猫下的设备能够正常获取公网 IPv6;
- OpenWrt 路由器 WAN 口连接在光猫 LAN,作为二级路由,我日常设备都连接在 OpenWrt 下;
- OpenWrt 能够正常获取到公网 IPv6,连接在 OpenWrt 下的设备无法获取公网 IPv6。
如果你也是类似情况,可以参照一下步骤操作:
- 通过 SSH 登录路由器(假设路由器地址为 192.168.20.1 ):
1 | ssh root@192.168.20.1 |
- 查看 OpenWrt 是否正常获取 IPv6:
1 | ifconfig |
正常情况下,在 wan
下能找到“2”开头的 IPv6 Global
地址,类似:
1 | inet6 addr: 240e::1111:1111:1111:1111/64 Scope:Global |
- 用 VIM 编辑器打开配置文件
/etc/config/dhcp
:
1 | vim /etc/config/dhcp |
注:按“i”进入编辑模式,完成修改后,按“ESC”键,输入“:wq”,按回车保存。
- 在
config dhcp lan
和config dhcp wan6
部分修改或新增以下内容:
1 | config dhcp lan |
完成设置后,保存文件。
- 使设置生效,运行以下命令提交设置:
1 | uci commit dhcp |
- 设备重新连接 OpenWrt 后,应该就能正常获取 IPv6。Windows 系统可以在终端中输入:
1 | ipconfig |
在输出中能够找到“2”开头的 IPv6 地址。
- 浏览器打开 IP查询(ipw.cn) 测试,通常来说,这个时候 IPv6 测试通过。
如果设备在 6 中有 IPv6 地址,但在 7 中有测试不通过,可以尝试在 OpenWrt 后台管理页面:
网络 —> 接口 —> 全局网络选项 —> IPv6 ULA 前缀:清空
网络 —> DHCP/DNS —> 高级设置:
- 过滤 IPv6 AAAA 记录:不选
- 过滤 IPv4 A 记录:不选
然后保存,重启路由器。
如果还不能获取 IPv6,可以尝试
系统 —> 软件包 —> 过滤器输入:
owipcalc
—> 安装通过 SSH 登录路由器(假设路由器地址为 192.168.20.1 ):
1 | ssh root@192.168.20.1 |
- 编辑
1 | vim /etc/hotplug.d/iface/80-reset-route6 |
输入以下内容
1 | #!/bin/sh |
- 并赋予赋予执行权限:
1 | chmod +X /etc/hotplug.d/iface/80-reset-route6 |
- 同时在防火墙放行:
- 网络 —> 防火墙 —> 通信规则 —> 新建转发规则
1 | 规则已启用 |
然后保存,重启路由器。