在中国大陆,电信运营商常为使用PPPoE拨号的用户分配/60的IPv6 prefix delegation。在本文中,笔者尝试了使用Mikrotik RouterOS获取了电信运营商分配的IPv6 PD,并为下级路由器和PPP接口上的设备继续分发了/64的IPv6 PD。

DALLE - photo of two routers connected by a cable. One router has a label ‘OpenWRT’ and the other ‘Mikrotik RouterOS’. Above them is a cloud symbol with ‘IPv6
DALLE - photo of two routers connected by a cable. One router has a label ‘OpenWRT’ and the other ‘Mikrotik RouterOS’. Above them is a cloud symbol with ‘IPv6

地址分配结构

Internet
   |
   | (WAN)
   | IPv6 Prefix: 240e:abc:1234:1950::/60
   |
MikroTik Router (pppoe-telecom)
   |
   | (LAN - bridge-eoip)
   | IPv6 Address: 240e:abc:1234:1950:20c:29ff:fefe:c01e/64
   |
   |----------------|----------------|----------------|----------------|
Device 1          Device 2         Device 3         Device 4
IPv6 Prefix:      IPv6 Prefix:     IPv6 Prefix:     IPv6 Prefix:
240e:3b6:30f0:    240e:3b6:30f0:   240e:3b6:30f0:   240e:3b6:30f0:
1950::/64         1951::/64        1952::/64        1953::/64

配置DHCPv6 Client (RouterOS)

首先确保已经在RouterOS上创建好了PPPoE / DHCP interface ,并已经拿到了ipv4地址。随后先添加一个IPv6的DHCP client:

/ipv6 dhcp-client add add-default-route=yes interface=pppoe-telecom  pool-name=delegation pool-prefix-length=64 add-default-route=no request=prefix

这里的pool-prefix-length根据运营商分配的v6 prefix的长度决定,并且**决定了下文中 DHCPv6 服务器下发前缀的长度(或者说二级路由器拿到的前缀的长度)。**一般是max(64,ISP-v6-prefix + 4),笔者从电信拿到的是/60的prefix,因此就设置了64的pool-prefix-length。在这种情况下,ROS应该能为下级设备分配16个/64的PD。

获取到地址后,ROS这边会显示“bound”,并且ipv6的pool里也会出现这个地址:

[admin@MikroTik] > /ipv6 dhcp-client  print
Flags: X - DISABLED, I - INVALID
Columns: INTERFACE, STATUS, REQUEST, PREFIX
#   INTERFACE      STATUS   REQUEST  PREFIX 
0   pppoe-telecom  bound    prefix   240e:abc:1234:1950::/60, 2d23h56m3s

[admin@MikroTik] > /ipv6 pool print             
Flags: D - DYNAMIC
Columns: NAME, PREFIX, PREFIX-LENGTH, EXPIRES-AFTER
#   NAME        PREFIX                   PREFIX-LENGTH  EXPIRES-AFTER
0 D delegation  240e:abc:1234:1950::/60             64  2d13h7m17s   

为ROS添加IPv6 Address(RouterOS)

随后,我们可以为ROS的LAN添加一个v6地址用于ROS的v6连接:

/ipv6 address add address=::/64 from-pool=delegation interface=bridge-eoip advertise=yes eui-64=yes
这里使用eui-64=yes的原因是使用接口的MAC生成地址的后64位,防止ROS拿到的IPv6地址和第一个PD Pool里网关的地址冲突。(比如在笔者的环境下,ROS就给bridge-eoip接口分配了240e:abc:1234:1950:20c:29ff:fefe:c01e/64,而不是可能和下一级PD网关(Openwrt)冲突的240e:abc:1234:1950::1/64

添加后可以用/ipv6 address print检查一下接口是不是已经获取到了ipv6地址。

在本地接口上配置 IPv6 PD 服务器 (RouterOS)

在IPv6的DHCP Server部份创建一个服务器即可(lease-time可以自行控制):

/ipv6 dhcp-server add address-pool=delegation interface=bridge-eoip lease-time=12h name=dhcpv6-lan

在PPP(包括PPTP,L2TP等)上配置 IPv6 PD 服务器 (RouterOS)

可以参考mikrotik的wiki,在PPP profile里添加dhcpv6-pd-pool即可:

/ppp profile set default dhcpv6-pd-pool=delegation

配置Openwrt上的DHCPv6 PD Client

笔者自己的Openwrt设备需要进行下述的配置才能正常使用IPv6 PD。但笔者尝试创建了一台新的Openwrt 23.05.0虚拟机,使用默认配置就立即获取到了RouterOS提供的IPv6 PD。因此下述的配置仅供参考(可能是不必要的),如果默认设置获取不到PD,请再尝试下面的配置

/etc/config/network :

config interface 'lan'
...
	option ip6assign '64'

config interface 'wan6'
	option proto 'dhcpv6'
	option device 'your-wan-interface'
	option reqaddress 'try'
	option reqprefix 'auto'
	option extendprefix '1'

Further below, I found this interesting part 7 that talks about RFC 7278 5. This seemed to be exactly what I wanted - extending the /64 prefix that is recieved on the WAN. On inspecting using my custom script, I noticed that the $EXTENDPREFIX variable was not set. Where did this come from? ——Openwrt Forum

这里的extendprefix用于在WAN接口上接收到的IPv6前缀之上扩展一个额外的前缀。但这个选项无法在GUI配置,需要手动配置network文件。

/etc/config/dhcp :

config dhcp 'lan'
...
	option dhcpv6 'server'
	option ra 'server'
	list ra_flags 'managed-config'
	list ra_flags 'other-config'
	option ndp 'relay'
	option dns_service '0'

config dhcp 'wan6'
	option interface 'wan6'
	option ignore '1'
	option master '1'
	option ndp 'relay'

同时,WAN和LAN接口也要启用NDP relay才能正确使用这个/64的prefix,以确保LAN接口上的设备可以看到并与WAN接口上的设备通信。

如果希望更换自己拿到的PD的prefix/希望固定自己拿到的prefix,可以手动配置IAID(参考Openwrt论坛上的这篇文章),在network文件的WAN6那一节里加上option reqprefix '64:2'这样的配置就行(64代表请求64位的prefix,2代表IAID设置成2),IAID可以是一个4字节的值。

DHCPv6的duid同样可以通过option clientid '0003000138822FFE7DF0'这样的配置项手动指定。

配置效果

在正确配置后,Openwrt 的web管理界面中,wan6 interface上应该有一个/64的PD prefix,一个SLAAC分配的64位地址,lan接口上应该也有一个DHCPv6分配的64位地址:

WAN6:

Protocol: DHCPv6 client
Uptime: 11h 8m 0s
RX: 487.24 MB (295262 Pkts.)
TX: 45.34 MB (295588 Pkts.)
IPv6: 240e:abc:1234:1950:d804:5eff:fe51:3fe0/64
IPv6-PD: 240e:abc:1234:1950::/64

LAN:

Protocol: Static address
Uptime: 11h 8m 42s
RX: 55.52 MB (350320 Pkts.)
TX: 616.28 MB (515726 Pkts.)
IPv4: ...
IPv6: 240e:abc:1234:1950::1/64

此时,在RouterOS上,应该也能看到相应的dhcp-server binding:

[admin@MikroTik] > /ipv6 dhcp-server binding print
Flags: D - DYNAMIC
Columns: ADDRESS, DUID, SERVER, STATUS
#   ADDRESS                  DUID                    SERVER              STATUS
0 D 240e:abc:1234:1950::/64  0x....  dhcpv6-telecom-lan  bound 

MTU问题

如果遇到了IPv6上网慢,打不开某些https网站的话,可以检查一下Openwrt上是否打开了MSS Clamping,ROS上是否有MSS Clamping的规则。

/ipv6 firewall mangle add chain=forward action=change-mss new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn
/ipv4 firewall mangle add chain=forward action=change-mss new-mss=clamp-to-pmtu passthrough=yes protocol=tcp tcp-flags=syn

参考