配置 HE 免费 IPv6 地址
涛叔现在 IPv6 已经算是比较普及了,无论是民用 ISP 还是各类云厂商或者 IDC,都支持配置 IPv6 网络。但有一些小型的 VPS 厂商或者一些大厂的特定产品,如阿里云的轻量服务器,仍然不支持接入 IPv6 网络。这时候我们就需要所谓的 tunnel broker1 来接入 IPv6 网络。在众多 broker 中,HE2提供的 tunnelbroker.net 最为有名,而且支持的区域也最为广泛。我之前换过几次 VPS,每次配置都要查一遍。今天把过程记录下来,做个备忘,也分享给大家。
tunnelbroker
HE 的 IPv6 隧道官网是 https://tunnelbroker.net 大家可以免费注册。注册之后就能创建 IPv6 隧道,最多可以创建五个。tunnelbroker 在北美、欧洲、亚洲、澳洲、非洲都有接入点,可谓是支持地域最多的服务商。
点击查询接入点列表
- North America
- Ashburn, VA, US 216.66.22.2
- Calgary, AB, CA 216.218.200.58
- Chicago, IL, US 184.105.253.14
- Dallas, TX, US 184.105.253.10
- Denver, CO, US 184.105.250.46
- Fremont, CA, US 72.52.104.74
- Fremont, CA, US 64.62.134.130
- Honolulu, HI, US 64.71.156.86
- Kansas City, MO, US 216.66.77.230
- Los Angeles, CA, US 66.220.18.42
- Miami, FL, US 209.51.161.58
- New York, NY, US 209.51.161.14
- Phoenix, AZ, US 66.220.7.82
- Seattle, WA, US 216.218.226.238
- Toronto, ON, CA 216.66.38.58
- Winnipeg, MB, CA 184.105.255.26
- Europe
- Amsterdam, NL 216.66.84.46
- Berlin, DE 216.66.86.114
- Budapest, HU 216.66.87.14
- Frankfurt, DE 216.66.80.30
- Lisbon, PT 216.66.87.102
- London, UK 216.66.80.26
- London, UK 216.66.88.98
- Paris, FR 216.66.84.42
- Prague, CZ 216.66.86.122
- Stockholm, SE 216.66.80.90
- Warsaw, PL 216.66.80.162
- Zurich, CH 216.66.80.98
- Asia
- Hong Kong, HK 216.218.221.6
- Singapore, SG 216.218.221.42
- Tokyo, JP 74.82.46.6
- Africa
- Djibouti City, DJ 216.66.87.98
- Johannesburg, ZA 216.66.87.134
- South America
- Bogota, CO 216.66.64.154
- Oceania
- Sydney, NSW, AU 216.218.142.50
- Middle East
- Dubai, AE 216.66.90.30
选好接入点之后,还需要输入你的公网 IPv4 地址。点创建,稍等片刻就会获得一个 SIT 隧道。 HE 会为你的隧道分配一个 /64 IPv6 地址。隧道的服务端地址为 XXX::1
,对应的客户端地址为 XXX::2
。如果你能拿到 HE IPv6 认证的 Sage 级别证书,你还可以为每一个区域的隧道申请一个 /48 网段,可玩性还是很强的。
接下来就需要在自己的服务器添加隧道配置。
iproute2
tunnelbroker 创建隧道后会提供各类系统的配置命令,大家可以到 Example Configurations 页面查看。如果是标准 Linux 系统,建议使用 iproute2 配置 SIT 隧道。
SIT 全称 Simple Internet Transition,最早用来设计在 IPv4 数据包中传输 IPv6 报文,其报文结构如下:
+---------------+-----------+---------------+-------+
|Ethernet Header|IPv4 Header|Inner IP Header|Payload|
+---------------+-----------+---------------+-------+
首先加载 SIT 隧道
modprobe sit
如果想在内核重启后自动加载,需要在 /etc/modules-load.d/modules.conf
配置中添加一行:
sit
然后创建 SIT 隧道:
ip tunnel add he-ipv6 mode sit remote 1.1.1.1 local 2.2.2.2 ttl 255
ip link set he-ipv6 up # 开启隧道
上述命令会创建一个名为 he-ipv6
的 SIT 隧道设备。名字可以任取,he-ipv6
只是 HE 推荐的名字。mode sit
指定使用 SIT 协议。remote 1.1.1.1
指定 HE 的服务端地址, 1.1.1.1
需要替换成你的隧道远端地址。同样,local 2.2.2.2
是你的本机 IPv4 地址。
根据我的经验,小型的 VPS 厂商会直接在服务器上设置公网 IPv4 地址。这种情况不会有问题。但大的云厂商都有 Virtual Private Cloud (VPC) 的概念,简单来说就是虚拟局域网。VPC 内的主机都分分配私有 IPv4 地址,但在 VPC 边缘会设置 NAT,将私有地址映射为公有地址。
假设你的公有 IPv4 地址是2.2.2.2
,但你的私有地址是10.2.2.2
。在上述命令中,你需要把 local 参数指定为私有地址10.2.2.2
,但在 tunnelbroker 后台则需要要填入公有地址。
隧道创建后可以通过ip link
命令查看设备状态:
ip link
...
6: he-ipv6@NONE: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1480 qdisc noqueue state UNKNOWN group default qlen 1000
link/sit 10.2.2.2 peer 1.1.1.1
到这一步,我们可以认为给系统加了一块新网卡,而且连好了网线。要想通信,还需要设置 IP 地址。HE 给的 SIT 隧道只能设置 IPv6 地址,而且已经指定好的。假设 HE 分配给你的网段是2001:db8:1::/64
。那么你的本地 IPv6 地址为2001:db8:1::2/64
,对端地址为 2001:db8:1::1/64
。我们使用如下 iproute2 指令设置 IPv6 地址:
ip addr add 2001:db8:1::2/64 dev he-ipv6
现在应该能 ping 通 2001:db8:1::1
了。最后,我们为 IPv6 网络设置默认路由:
ip route add ::/0 dev he-ipv6
简单来说就是把所有非本地的 IPv6 流量都使用 he-ipv6 这个隧道转发~
我们前面说过,如果你通过了 HE 的 IPv6 认证,就能为隧道申请一个 /48 网段。假设你的网段是2001:db8:2::/48
,你可以直接给 he-ipv6 添加多个 IPv6 地址:
ip addr add 2001:db8:2::/48 dev he-ipv6
注意,IPv6 不像 IPv4,没有网络地址一说,可以直接把主机标识都置为零。
一个网卡有多个地址,这就有一个问题,当程序访问外部 IPv6 网络时,默认用哪个地址呢?说实话我也不清楚,内核应该有一套默认的规则。那我们能不能指定使用某个地址呢?当然可以。假如我们希望默认使用2001:db8:2::
地址访问外网,则需要使用如下命令设置默认路由:
ip route add ::/0 from 2001:db8:2:: dev he-ipv6
这里使用from
参数来指定默认源地址~
到此我们就完成了所有配置。但使用 iproute2 只能临时更改系统配置。内核重启后所有配置都会丢失。要想让配置重启后仍能生效,需要找一个持久化方案。不同的 Linux 发行版有不同的方案。我在这里推荐大家使用 systemd-networkd 方案,几乎所有主流发行版都支持。
下面我们就将刚才的 iproute2 转化为 systemd-networkd 配置。
systemd-networkd
systemd-networkd 的配置文件位于 /etc/systemd/network
,这次我们要用到 netdev 和 network 两种配置。
netdev 顾名思义就是网络设备,用来配置 SIT 隧道。network 用来配置 IPv6 地址和路由。
我们在配置目录先创建 he-ipv6.netdev 文件,内容如下:
[NetDev]
Name=he-ipv6
Kind=sit
[Tunnel]
Independent=yes
Remote=1.1.1.1
Local=2.2.2.2
TTL=255
[NetDev]
部分用于声明隧道设备名和类型,[Tunnel]
指定隧道配置,参数跟 iproute2 能对上,不作赘述。
这里的 Independent 参数很重要,一定要设置成 yes,不然配置不会生效。我最开始从网上看到的资料没说这事,搞了半天,systemd-network 就是不创建隧道设备,真是无语。
保存配置重启 systemd-networkd
systemctl restart systemd-networkd
然后就看到新创建的隧道设备了~有了设备,我们还需要配置地址和路由,在配置目录创建 he-ipv6.network 文件:
[Match]
Name=he-ipv6
[Network]
Address=2001:db8:1::2/64
Address=2001:db8:2::2/48
[Route]
Destination=::/0
Gateway=2001:db8:1::2/64
PreferredSource=2001:db8:2::
[Match]
部分表示要设置哪个设备。[Network]
部分为隧道设置了两个地址。[Route]
部分是指定默认路由和默认源地址,基本都能跟 iproute2 对上。
保存文件后重启 systemd-networkd 就可以了~
能读到这里,说明你真是对 Linux 网络感兴趣~分享一个解锁 ChatGPT 访问的小福利。
ChatGPT
很多 VPS 没有 IPv6 或者有 IPv6 但网段被 OpenAI 屏蔽了,无法用作 ChatGPT 代理。这时候我们可以利用 HE 的 tunnelbroker 提供的隧道访问 ChatGPT。我自己用了很长时间,没有问题。
首先,我们查看 ChatGPT 的网段:
ping -c 1 api.chatgpt.com
PING api.chatgpt.com(2606:4700:4400::6812:241d (2606:4700:4400::6812:241d)) 56 data bytes
64 bytes from 2606:4700:4400::6812:241d (2606:4700:4400::6812:241d): icmp_seq=1 ttl=59 time=10.7 ms
--- api.chatgpt.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 10.666/10.666/10.666/0.000 ms
然后到 bgp.tools 上查到这个地址所在的网段为2606:4700:4400::/48
,这是 Cloudflare 的网段。我们只需要加到条路由,让该网段走 he-ipv6 隧道就可以了:
ip route add 2606:4700:4400::/48 dev he-ipv6
如果你已经设置了默认路由,那么就不需要额外的操作~但对于有原生 IPv6 的主机,我个人还是建议不要用 he-ipv6 做默认网关。
Peer 纠纷
tunnelbroker 是 HE 提供的免费服务,只能说是解决了从无到有的问题。它本身也有不少缺点。虽然 tunnelbroker 在全世界有很多接入点,但跟很多运营商(尤其是国内的ISP)都只在美国做 peer。假如你的主机在香港,虽然你跟 HE 的香港节点延迟很低,但国内 ISP 的访问流量通常都需要绕到美国再转发给香港,延迟400ms起步,只能说聊胜于无。据说 HE 曾经在香港跟大陆的运营商 peer 过,可能被薅得太厉害,直接拔线了。又听说 HE 在香港还继续与教育网 peer,有条件的在校生读者可以试一试。
tunnelbroker 另一个缺点是无法跟 Cogent 的网络实现互访,因为 HE 跟 Cogent 之间一直没达成协议,没有做 peer。HE 还给 Cogent 送过蛋糕🍰敦促双方尽快互联,但此事一直悬而未决3。
结论
以上就是本文的主要内容。本文介绍了通过 HE 家的 tunnelbroker 为纯 IPv4 主机开通 IPv6 网络的方法,并基于 systemd-networkd 实现持久化配置。最后还利用 HE 的网络解决了 ChatGPT 被禁用的问题。欢迎读者留言讨论😃
https://tunnelbroker.services 上列举了不少可用的 broker↩︎
Hurrican Electric,官网为 https://he.net,号称为世界上最大的 IPv6 ISP↩︎
https://www.datacenterknowledge.com/archives/2009/10/22/peering-disputes-migrate-to-ipv6↩︎