因为现在电信默认都会分配 IPv6 的地址,所以就在 RouterOS 上配置一下。

确认是否有 IPv6 公网地址

首先打开 ROS 的 IPv6 功能,然后创建 DHCP Client,确认能从 ISP 获得公网 IPv6.

/ipv6 dhcp-client
add add-default-route=yes interface=pppoe-out1 pool-name=ipv6-pool \
    pool-prefix-length=64 request=prefix

pool-name 为 ISP 分配的地址池。

如果开启以后,获取到了公网的 IPv6 说明运营商提供公网地址,否则不行。

SLAAC(无状态地址自动分配)

IPv6 可以不用创建 DHCP server 来使内网获得 ip 地址。可以用 SLAAC 的功能: 创建 ip-address:

/ipv6 address
add address=::1 from-pool=ipv6-pool interface=BLUE_VLAN advertise=yes

创建 ND:

/ipv6 nd
add interface=BLUE_VLAN ra-interval=20s-60s advertise-dns=yes

注意:windows 系统暂不支持 Advertise DNS 的功能,所以 windows 如果要自动获取 ipv6 DNS 还需要配置 DHCPv6.

设置 FIREWALL

创建 address-list

/ipv6 firewall address-list
add address=::/128 comment="unspecified address" list=BAD_IPV6
add address=::1/128 comment="lo" list=BAD_IPV6
add address=fec0::/10 comment="site-local" list=BAD_IPV6
add address=::ffff:0.0.0.0/96 comment="ipv4-mapped" list=BAD_IPV6
add address=::/96 comment="ipv4 compat" list=BAD_IPV6
add address=100::/64 comment="discard only " list=BAD_IPV6
add address=2001:db8::/32 comment="documentation" list=BAD_IPV6
add address=2001:10::/28 comment="ORCHID" list=BAD_IPV6
add address=3ffe::/16 comment="6bone" list=BAD_IPV6
add address=::224.0.0.0/100 comment="other" list=BAD_IPV6
add address=::127.0.0.0/104 comment="other" list=BAD_IPV6
add address=::/104 comment="other" list=BAD_IPV6
add address=::255.0.0.0/104 comment="other" list=BAD_IPV6

/ipv6 firewall filter
add action=accept chain=input comment="accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=input comment="drop invalid" connection-state=invalid
add action=accept chain=input comment="accept ICMPv6" protocol=icmpv6
add action=accept chain=input comment="accept UDP traceroute" port=33434-33534 protocol=udp
add action=accept chain=input comment="accept DHCPv6-Client prefix delegation." dst-port=546 protocol=udp src-address=fe80::/10
add action=drop chain=input comment="drop everything else not coming from LAN" in-interface-list=!VLAN
add action=accept chain=forward comment="accept established,related,untracked" connection-state=established,related,untracked
add action=drop chain=forward comment="drop invalid" connection-state=invalid
add action=drop chain=forward comment="drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment="drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=accept chain=forward comment="accept ICMPv6" protocol=icmpv6
add action=drop chain=forward comment="drop everything else not coming from LAN" in-interface-list=!VLAN

注意:IPv6 在下发地址的时候,会了,连接 udp 的 546 端口,所以要防火墙要放行。

打开 IPv6 MSS clamping

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

什么是 MSS clamping

MSS Clamping(Maximum Segment Size Clamping)是一种网络技术,用于限制TCP数据包的最大段大小(MSS)以确保数据包不会在经过网络链路时被分段。这通常在防火墙、路由器或网络设备上实现,以解决特定网络链路上的MTU(Maximum Transmission Unit)问题。

MSS Clamping的步骤通常如下:

  • 当TCP客户端发起连接时,它会发送一个带有MSS选项的SYN报文,其中包含其首选的MSS值。
  • 网络设备(如防火墙或路由器)检查SYN报文中的MSS选项以及链路上的MTU值。
  • 如果SYN报文中的MSS值大于链路上的MTU值,设备会将MSS值降低到链路MTU的大小,并将其存储在MSS Clamping表中。
  • 当TCP连接建立后,网络设备会根据MSS Clamping表中的信息对所有TCP数据包的MSS进行调整,以确保数据包不会超过链路上的MTU值。

因为默认路由器等会为 IPv4 开启 MSS clamping,但是对 IPv6 一般都不会开启,所以要主动打开。现在国内 ISP 一般都是通过 PPPoE 虚拟拨号建立 WAN 口连接的。Ethernet 的默认 MTU 是1500,但是 PPPoE 隧道有8个bytes的开销,所以 PPPoE 虚连接的 MTU 就是1500-8=1492,减掉 IPv4 包头( 20 字节)和 TCP 包头( 20 字节),可以得知 IPv4 下需要把 MSS 设为 1452 以下。 IPv6 的包头是 40 字节,所以 IPv6 下需要把 MSS 设为 1432 以下。

确认内网设备获取到了 IPv6 地址以及 dns

BTW,IPv6 对于走代理路线比较差,如果有走代理的需求,目前还是不建议使用 IPv6,然后 Linux 默认优先使用 IPv6。