补充于 2018-04-23
本文在ZJW同学于2018-03-11整理发布前,更早地由XYenon于2017-10-09发布于他的博客上,原文为《路由器转发 IPv6 配置方法》,采用 署名-非商业性使用-相同方式共享 3.0 中国大陆 协议许可,在此感谢原作者XYenon同学的无私奉献。


本文参考自ZJW同学发布的《通过校园网IPv6网络实现不限网络流量/网络加速的方法》,在此感谢ZJW同学对XYenon同学所著文章进行的补充和整理。本人在该文章的基础之上再次进行了适当整理,以小节的形式给出操作步骤,同时调整了一些步骤的顺序,使读者得以更清晰直观地理解各步骤的思路和意义。同时,本人对文章进行了完善和补充,增加了测试和优化部分,便于读者评估自己的 IPv6 路由性能。


前置声明

本方案并不能绕过校园网付费系统,仍然需要缴纳每月40元的上网费用。请欲绕过校园网付费系统的读者注意,本文也许无法为您提供任何帮助。
由于翻译原因,本文中提到的选项名称可能与你持有的路由器上的实际名称略有偏差,请自行对应。

硬件要求

  1. 带有 OpenWrt / LEDE / PandoraBox 系统的路由器,且通过有线校园网连接到 Internet(请自行解决刷机和联网过程),本文以 斐讯K2 的 PandoraBox 17.01 版本为例
  2. 支持 IPv6 的上网设备(请自行开启设备 IPv6 功能)

启用路由器的SSH连接功能

  1. 登录路由器管理页面(一般为 192.168.1.1),打开“系统-管理”页面。
  2. 在“SSH访问”部分中,将接口设为 LAN,端口设为 22,勾选“密码验证”及“Root权限登录”复选框,点击“保存&应用”按钮。

安装 IPv6 所需的必备组件

由于 PandoraBox 官方软件源已经关闭,因此我们首先需要将系统内置的软件源修改为尚存活的镜像源。对于 OpenWrt 和 LEDE 用户,建议参考此步骤的操作,将软件源修改为国内镜像源,以避免网络问题导致的无法下载或包损坏问题(镜像源请自行查找,推荐USTC反向代理)。

  1. 登录路由器管理页面,打开“系统-软件包”页面。
  2. 点击“设置”选项卡,将“发行版软件源”中所有内容替换为如下内容,并点击“提交”按钮。(该软件源至本文写作时即 2018-04-20 尚可用)
    src/gz 17.05_core http://mirrors.moekr.com/pandorabox/targets/ralink/mt7620/packages
    src/gz 17.05_base http://mirrors.moekr.com/pandorabox/packages/mipsel_24kec_dsp/base
    src/gz 17.05_lafite http://mirrors.moekr.com/pandorabox/packages/mipsel_24kec_dsp/lafite
    src/gz 17.05_luci http://mirrors.moekr.com/pandorabox/packages/mipsel_24kec_dsp/luci
    src/gz 17.05_mtkdrv http://mirrors.moekr.com/pandorabox/packages/mipsel_24kec_dsp/mtkdrv
    src/gz 17.05_packages http://mirrors.moekr.com/pandorabox/packages/mipsel_24kec_dsp/packages
  3. 通过SSH连接路由器,依次输入以下指令:
    opkg update && opkg install kmod-ipt-nat6
    uci set network.globals.ula_prefix="$(uci get network.globals.ula_prefix | sed 's/^./d/')"
    uci commit network
    uci set dhcp.lan.ra_default='1'
    uci commit dhcp

    (本步骤中更新了软件列表,安装了 kmod-ipt-nat6 组件,并校正了相关配置文件。本步骤中第一行代码也可在路由器管理页面中实现。)

配置并启用 IPv6 功能,开启 IPv6 流量转发,并允许 IPv6 流量通过防火墙

本着“傻瓜化”的原则,建议 Windows 用户使用 WinSCP 软件连接路由器后进行操作。有 Linux 使用基础的读者也可以使用SSH连接路由器,使用路由器系统自带的 vi 工具修改文件内容。

之所以把这么多看似复杂的步骤安排在本段内而没有拆分,就是因为这些“看似复杂”的步骤实际上是固定的。只要读者按部就班地操作,大部分情况下都不会出现问题。

配置并启用 IPv6 功能

  1. 创建 IPv6 配置文件
    在SSH中依次键入以下指令,创建IPv6配置文件并赋予可执行权限:
    touch /etc/init.d/nat6
    chmod +x /etc/init.d/nat6
  2. 配置 IPv6 功能
    打开 /etc/init.d/nat6 文件,将以下内容复制到该文件中并保存:
    #!/bin/sh /etc/rc.common
    # NAT6 init script for OpenWrt // Depends on package: kmod-ipt-nat6
    START=55
    # Options
    # -------
    # Use temporary addresses (IPv6 privacy extensions) for outgoing connections? Yes: 1 / No: 0
    PRIVACY=1
    # Maximum number of attempts before this script will stop in case no IPv6 route is available
    # This limits the execution time of the IPv6 route lookup to (MAX_TRIES+1)*(MAX_TRIES/2) seconds. The default (15) equals 120 seconds.
    MAX_TRIES=15
    # An initial delay (in seconds) helps to avoid looking for the IPv6 network too early. Ideally, the first probe is successful.
    # This would be the case if the time passed between the system log messages "Probing IPv6 route" and "Setting up NAT6" is 1 second.
    DELAY=5
    # Logical interface name of outbound IPv6 connection
    # There should be no need to modify this, unless you changed the default network interface names
    # Edit by Vincent: I never changed my default network interface names, but still I have to change the WAN6_NAME to "wan" instead of "wan6"
    WAN6_NAME="wan6"
    # ---------------------------------------------------
    # Options end here - no need to change anything below
    boot() {
         [ $DELAY -gt 0 ] && sleep $DELAY
         logger -t NAT6 "Probing IPv6 route"
         PROBE=0
         COUNT=1
         while [ $PROBE -eq 0 ]
         do
                 if [ $COUNT -gt $MAX_TRIES ]
                 then
                         logger -t NAT6 "Fatal error: No IPv6 route found (reached retry limit)" && exit 1
                 fi
                 sleep $COUNT
                 COUNT=$((COUNT+1))
                 PROBE=$(route -A inet6 | grep -c '::/0')
         done
         logger -t NAT6 "Setting up NAT6"
         WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname")
         if [ -z "$WAN6_INTERFACE" ] || [ ! -e "/sys/class/net/$WAN6_INTERFACE/" ] ; then
                 logger -t NAT6 "Fatal error: Lookup of $WAN6_NAME interface failed. Were the default interface names changed?" && exit 1
         fi
         WAN6_GATEWAY=$(route -A inet6 -e | grep "$WAN6_INTERFACE" | awk '/::\/0/{print $2; exit}')
         if [ -z "$WAN6_GATEWAY" ] ; then
                 logger -t NAT6 "Fatal error: No IPv6 gateway for $WAN6_INTERFACE found" && exit 1
         fi
         LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
         if [ $(echo "$LAN_ULA_PREFIX" | grep -c -E "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then
                 logger -t NAT6 "Fatal error: IPv6 ULA prefix $LAN_ULA_PREFIX seems invalid. Please verify that a prefix is set and valid." && exit 1
         fi
         ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
         if [ $? -eq 0 ] ; then
                 logger -t NAT6 "Added IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)"
         else
                 logger -t NAT6 "Fatal error: Failed to add IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)" && exit 1
         fi
         route -A inet6 add 2000::/3 gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
         if [ $? -eq 0 ] ; then
                 logger -t NAT6 "Added $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
         else
                 logger -t NAT6 "Error: Failed to add $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
         fi
         if [ $PRIVACY -eq 1 ] ; then
                 echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/accept_ra"
                 if [ $? -eq 0 ] ; then
                         logger -t NAT6 "Accepting router advertisements on $WAN6_INTERFACE even if forwarding is enabled (required for temporary addresses)"
                 else
                         logger -t NAT6 "Error: Failed to change router advertisements accept policy on $WAN6_INTERFACE (required for temporary addresses)"
                 fi
                 echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/use_tempaddr"
                 if [ $? -eq 0 ] ; then
                         logger -t NAT6 "Using temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
                 else
                         logger -t NAT6 "Error: Failed to enable temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
                 fi
         fi
         exit 0
    }
  3. 启用 IPv6 功能:
    在SSH中键入以下指令并执行:/etc/init.d/nat6 enable

开启 IPv6 流量转发

  1. 打开 /etc/sysctl.conf 文件,将 net.ipv6.conf.* 这一部分修改为如下内容并保存:
    net.ipv6.conf.default.forwarding=2
    net.ipv6.conf.all.forwarding=2
    net.ipv6.conf.default.accept_ra=2
    net.ipv6.conf.all.accept_ra=2

允许 IPv6 流量通过防火墙

  1. 打开 /etc/firewall.user 文件,在文件末尾增加如下内容:
    uci set firewall.@rule["$(uci show firewall | grep 'Allow-ICMPv6-Forward' | cut -d'[' -f2 | cut -d']' -f1)"].enabled='0'
    uci commit firewall
    ip6tables -t nat -I POSTROUTING -s $(uci get network.globals.ula_prefix) -j MASQUERADE



至此,IPv6 功能已经启用并安装完毕,现在,你的路由器已经可以直接访问纯 IPv6 网络。但是,依然有一些事情要做。

配置 IPv6 DNS

  1. 登录路由器管理页面,打开“网络-接口”页面,点击“wan”接口的“修改”按钮。
  2. 点击“高级设置”选项卡,取消“使用端局通告的DNS服务器”复选框,在出现的“使用自定义的DNS服务器”文本框中,依次键入以下DNS服务器:
    240C::6666
    240C::6644
    202.97.224.68
    202.97.224.69

    其中,前两个DNS来源于 China IPv6 DNS 提供的全国首个公共 IPv6 DNS,也可以使用北邮或者上海交大的 IPv6 DNS。后两个DNS来源于 DNSPod“本地DNS优化”功能优选的适用于哈工程校园网的最快DNS节点。
    若不设定 IPv6 DNS,可能导致无法解析纯 IPv6 域名;若只设定 IPv6 DNS,则可能导致无法解析某些纯 IPv4 域名(如无法解析百度搜索结果页面上的静态图片地址)。

  3. [可选] 根据你的个人喜好或具体需求,确定优先使用 IPv4 DNS 还是 IPv6 DNS,或者不设定优先级。
    差别在于,若优先使用 IPv6 DNS,则解析域名时,路由器会优先请求 IPv6 DNS,将域名解析为 IPv6 地址,若无 IPv6 地址,再请求 IPv4 DNS,将域名解析为 IPv4 地址;IPv4 反之。若不设定优先级,则同时向各个DNS服务器发出解析请求,哪个DNS的响应速度快(延时低),就优先采用哪个DNS的解析结果。
    根据本人测试,若 IPv4 DNS 为优选 DNS,则其响应延时应在 15 ms 以下,而 IPv6 DNS 由于数量较少,其延时会在 65 ms 左右。因此,除本校自有 IPv6 DNS 的用户以外,大部分地区的用户的大部分网络连接均会通过 IPv4 进行,这保证了对现时国内网络的兼容性。
    因此,考虑到解析的响应速度(直观表现为网页加载时间)和对现时国内网络的兼容性,个人推荐不设优先级。
    若希望不设优先级,则可以在路由器管理页面,打开“网络-DHCP/DNS”页面,点击“高级设置”选项卡,找到“同时使用所有服务器”复选框,勾选即可。
    若希望优先解析 IPv4,则在第二步中将 IPv4 DNS 置于较前的位置,然后取消上述复选框即可。IPv6 优先同理。取消该复选框后,路由器将会按顺序逐个请求DNS服务器,直到获得解析结果为止。

[可选]启动硬件加速(硬件NAT)

如果你对QoS类应用没有使用需求,则建议开启硬件NAT功能,以提升转发效率,降低CPU负载。
在路由器管理页面,打开“网络-硬件加速”页面,按需启用硬件加速功能即可。

重启路由器

以防万一嘛……
Waiting......

测试 IPv6 连通性

路由器重启后,可以通过 test-ipv6.comipv6-test.com 提供的测试功能检测你的网络配置是否正确。若正确,则大部分测试项目会显示为“通过”状态。否则,请根据测试反馈进行排查。

事已至此,路由器上的操作就算是彻底结束了。你的路由器已经成功接入中国教育和科研计算机网(CERNET)的 IPv6 网络。你的路由器已经具备了完整的访问 IPv6 网络的能力。此后的内容将专注于强制使 IPv4 流量走 IPv6,以达到绕过校园网对 IPv4 的带宽限制,从而实现网速(带宽)的提升。

租一台支持 IPv6 的 VPS,开启bbr加速,并架设梯子

据本人所知,学生买得起的且支持 IPv6 的 VPS 供应商只有 Digital Ocean 和 Vultr 两家。
可以在 Github Education 申请并获得 Student Developer Pack。其中包含 Digital Ocean 的 50美元优惠券(需要充值5美元才可使用)。两家网站均可通过邀请他人注册并消费的方式获得更多优惠。
创建 VPS 实例、开启bbr加速及架设梯子的步骤在此略去,请自行处理。个人推荐使用SSR做梯子,后文步骤以此为例,其他VPN方案也大同小异。

安装 Proxifier 及 SSR

安装步骤及激活步骤略。建议不要使用便携版的 Proxifier,因其不支持强制系统底层服务和其他用户进程走代理。

配置SSR

SSR的具体使用方法略,在此强调几个必需或推荐操作。

  1. 连接到VPS上的SSR。
  2. “系统代理模式”设为“全局”。
  3. 代理规则设为“绕过局域网”。
  4. “选项设置”中,勾选“允许来自局域网的连接”。并设置端口号(必需)、用户名和密码(非必需)。
  5. 如果你有多个使用 IPv4 的SSR服务器,建议将服务器固定为上一节中搭建的 IPv6 服务器。否则,负载均衡机制可能不会将所有流量都转发到 IPv6 上,也就无法绕过带宽限制。

配置 Proxifier

  1. 添加代理服务器
    打开 Proxifier,点击菜单中的“Profile-Proxy Servers”,添加你的本地SSR服务器。代理协议为“SOCKS Version 5”,IP为127.0.0.1,端口号为你在上一步中设置的端口号,默认为1080。保存服务器配置,将其应用于所有规则,并进行测试。
  2. 为防止SSR客户端产生回环(即自己走自己的代理,一直在本地转圈圈),需要在代理规则中排除SSR客户端。
    点击菜单中的“Profile-Proxification Rules”,添加一条规则,名称自拟,如“Disable SSR LOOP”,在“Applications”选择你的SSR客户端程序,“Target Hosts”及“Target Ports”均留空,即均设为“Any”,“Action”设为“Direct”,点击“OK”保存即可。如果你有除“Localhost”、“Default”之外的其他自定义规则,则需要将该规则置于“Localhost”规则上方并相邻(涉及到规则的优先级问题)。
  3. 强制所有应用走代理
    强制直接连接(即不进行域名解析,直接连接至确切IP的网络连接)走代理:点击菜单中的“Profile-Advanced-Handle Direct Connection”,使其前面的复选框为启用状态。
    强制系统服务及其他用户应用走代理:点击菜单中的“Profile-Advanced-Services and Other Users”,勾选窗口中的两个复选框“Applications run by other users on this computer”、“Windows services and other system process”。

事已至此,所有的配置步骤全部结束。现在,你可以同时打开SSR和 Proxifier 来强制使所有流量走 IPv6 以提升带宽。

按需开启 强制 IPv6 / 非强制 IPv6

如果你需要浏览网页或玩网络游戏,只需要关闭SSR和Proxifier,那么你的 IPv4 流量会自行走IPv4,带宽仍为 4 Mbps,与普通上网无异,你对Google、Youtube、北邮人及六度空间等仅可以通过 IPv6 访问的网站(包括支持 IPv6 的被墙网站及仅支持 IPv6 的网站)将会自行走IPv6。

如果你需要进行高带宽的下载活动,只需要开启SSR及Proxifier,即可绕过校园网对 IPv4 的带宽限制。根据个人测试,强制 IPv6 的情况下,尽管网络延时很高(访问国内网站,延时约为 1700 ms,浮动范围约为 700 ms),但是在下载资源良好的情况下,下载速度几乎可以达到路由器满载。本人使用斐讯K2进行百度网盘下载(使用软件为Pandownload,同时进行的任务数为3个,每个任务并发连接数为32个),跑出了峰值 50 Mbps,稳定 40 Mbps 的带宽,观察发现速度瓶颈在于路由器CPU负载而非网络带宽限制;使用室友的电脑进行 Steam 下载,跑出了峰值 40 Mbps,稳定 13 Mbps 的带宽。

本教程至此结束,自认为写的比较全(luo)面(suo)。最后,祝诸位下载愉快。

最后,再次感谢原作者XYenon同学对该方法做出的巨大贡献,感谢ZJW同学对原文章做出的补充、整理和传播。