使IPv4-Only支持IPv6双栈

处女帖。不想太水,发个自认为有点小用的吧。

为何要这样做?

一般是IPv6-Only的主机配置IPv4比较常见,我这里正好反过来,因为笔者对IPv6有种莫名的执念,且手里正好有双栈主机和v4only主机,所以前段时间研究了一下,发在了自己的博客上但未在L站上发,过了一段时间后才克服了自己的懒癌,故现于此略作修改(指删了一些中二语录和废话,又叠了点甲)与诸位分享探讨。

我尝试的淘汰方案:

  • Cloudflare WARP: 免费易操作,但是只支持主机以v6对外访问而不支持v6的入站,不满足我的要求。
  • Hurricane Electric的Free IPv6 Tunnel Broker: 网上教程很多,诸位可以参考。配置同样简单,但IP不干净,线路差,速度堪忧。

因此,我决定自己搭建6in4隧道达成目的。

6in4隧道的部署

相关IP变量的说明及示例

<assigned_sub6net>:你分配给该隧道的子网

<client_ipv4>:IPv4-Only主机的IPv4地址

<server_ipv4>:IPv4/IPv6双栈主机的IPv4地址

<assigned_server_ipv6>:分配给IPv4/IPv6双栈主机的隶属于上文子网的IPv6地址

<assigned_client_ipv6>:分配给IPv4-Only主机的隶属于上文子网的IPv6地址

<assigned_client_ipv6_without_cidr>:分配给IPv4-Only主机的隶属于上文子网的IPv6地址,但去除了/xx部分

如,IPv4/IPv6双栈主机拥有2001:db8:1000:2000::/64网段,你可以把2001:db8:1000:2000:1::/80子网分配给隧道。当然你也可以分配其他子网甚至是不同大小的子网。

但还请注意:IPv6的最小子网通常是/64,但由于大部分双栈主机给分配的v6都小于或等于/64,因此无视了此约定,还请读者知悉。据笔者测试,并不会产生任何影响。

以下是一种可能示例:

<assigned_sub6net> = 2001:db8:1000:2000:ffff::/80
<assigned_server_ipv6> = 2001:db8:1000:2000:ffff::1/80
<assigned_client_ipv6> = 2001:db8:1000:2000:ffff::2/80
<assigned_client_ipv6_without_cidr> = 2001:db8:1000:2000:ffff::2

服务端

服务端即IPv4/IPv6双栈的主机。

SIT隧道是专门为了连接IPv4与IPv6网络的技术,因此我们这里用SIT隧道。

有关SIT、GRE、IPIP隧道技术的区别,可参见ChatGPT的回答:

要求

  • 拥有IPv4公网地址(静态、动态与否均可,动态需要额外配置,可自行寻找方案,恕不赘述)
  • 拥有可继续路由的IPv6地址块(有关此,可参见参考文章1,2),在继续前,务必确定该点
  • 您的系统内核支持SIT隧道

操作步骤

笔者的服务端使用的是Misaka家的香港服务器,拥有可NDP通告的/64地址块。如果您不确定您的服务商为您提供的是什么样的地址块,可参见参考文献2查询,如没有,可自行测试或联系服务商。

因为我服务器搭载的是Ubuntu 22.04 LTS,因此以此为例,个人经验判断只要是Debian系的,以下操作步骤基本可以通用。

我全程使用root用户操作,因此没有使用sudo,望注意。

首先安装我们需要的工具

apt update
apt install iproute2
# 如果你有PD地址块则不需要
apt install ndppd

修改一下系统配置,使其可以转发流量

vim /etc/sysctl.conf

在文件底下加入下面两行

net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.all.proxy_ndp = 1

还需修改防火墙,放行转发流量

# 设置IPv6转发链的默认策略为接受
ip6tables -P FORWARD ACCEPT

修改ndppd设置

vim /etc/ndppd.conf
route-ttl 30000
proxy enp3s0 {
    router yes
    timeout 500
    ttl 30000
    rule <assigned_sub6net> {
        static
    }
}

请注意:该文件中的enp3s0是我主机上的物理网卡名称,您需要改成您主机上的网卡名称才能正常工作,如您不知道,可以通过ifconfigip a查询。

随后,启动ndppd

systemctl start ndppd

再配置SIT隧道

ip tunnel add sit1 mode sit remote <client_ipv4>
ip link set sit1 up
ip addr add <assigned_server_ipv6> dev sit1
# 可能不需要,不通时再执行
ip link set sit0 up

配置邻居

ip -6 neigh add proxy <assigned_client_ipv6_without_cidr> dev enp3s0
# 此处enp3s0的注意事项同上

客户端

客户端即IPv4-Only的主机。

要求

  • 拥有IPv4公网地址(静态、动态与否均可,动态需要额外配置,可自行寻找方案,恕不赘述)
  • 您的系统内核支持SIT隧道

笔者的客户端是阿里云的香港轻量应用服务器,只支持IPv4,搭载Ubuntu 22.04 LTS。

首先安装需要的工具

apt update
apt install iproute2

执行以下命令

ip tunnel add sit1 mode sit remote <server_ipv4>
ip link set sit1 up
ip addr add <assigned_client_ipv6> dev sit1
ip -6 route add default dev sit1

后续步骤

服务端:ping <assigned_client_ipv6>,此时Ping不通是正常的,不要停止Ping。

客户端:ping <assigned_server_ipv6>,此时应该可以Ping通了。

保活:

由于我的IPv6地址块是通过NDP宣告的,NDP会过期,长时间没有连接的时候,首次PING会失败,这是因为IP报文触发后,通告母鸡需要一点时间。所以如果我们一直保持连接,NDP就不会过期。

因此,我们有两个方案:Crontab脚本与Screen持续Ping。

笔者对Crontab不熟,因此直接采用后者。

在客户端上执行:

screen -S ping
 
ping -i 60 <assigned_server_ipv6> # 每隔60s Ping一次服务器保活

持久化保存

以上设置,除了/etc/sysctl.conf,余下的设置会在主机重启后失效。这有好处,万一你搞坏了,重启一下便可以恢复到之前的正常设置。但是如果你想持久化保存,也是可以的。

可以通过networkd或netplan管理设置,这里由于笔者经常瞎折腾再加上开关机不是特别频繁,故省去设置。您可以在搜索引擎搜索使用方法,抑或询问AI,将服务端和客户端要用到的ip配置指令发送,让他教您对应步骤。

使IPv4-Only网站可通过IPv6访问

现在,我们已经使我们网站的宿主机获取到了一个接近native的IPv6。你当然可以用它访问网站或者被访问。

你可以在IPv4-Only主机上输入该指令:

curl ipv6.ip.sb

你应该可以看到刚才配置的<assigned_client_ipv6>

同时,理论上不需要别的配置就可以无痛进入IPv6了,但是由于笔者网站宿主机使用了老版本的BT面板,其网站设置的Nginx检测到主机没有IPv6后不会给其配置IPv6的监听。因此需要手动修改Nginx的配置文件。示例如下:

server
{
    listen 80;
    listen [::]:80;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ...
}

注意,listen 443 ssl http2;listen [::]:443 ssl http2; 是只有配备了SSL的网站才需要配置的,如果你是HTTP,而非HTTPS,则无需配置这两行。(这年头应该没人还在不配HTTPS了吧)

参考文章

  1. 关于IPv6的常识科普,以及VPS通过ndppd向母鸡广播小鸡内网IPv6邻居的方法教程》By Just纱世里

  2. 征集整理,各大VPS供应商对IPv6/子网路由的支持程度》By Just纱世里

  3. Linux下建立GRE隧道并获取IPv6地址

一些废话

为什么我对IPv6有种不可割舍的情感(?

我认为主要还是因为中国高校走在了IPv6的最前列,CERNET对IPv6的支持相当不错,从我个人角度看,我所在的学校IPv4线路基本限速在50Mbps,我估计这与CERNET的v4跨网结算费用高有着密不可分的关系,但是IPv6线路的下载速度能到400Mbps到1000Mbps不等。

为什么不用反向代理?

你就当我是闲的没事干吧,我总觉得反向代理不够好(当然我的方案可能也没好到哪去),更何况这个既能入站又能出站(嘿嘿

结尾碎碎念

笔者测试了很多次,均能调通。但限于自身水平,如有错误还请各位不吝赐教,万分感谢!

9 Likes

其实感觉用wireguard更简单而且性能更好,需要打通二层可以在wireguard里面跑vxlan也更灵活,需要注意的是,6in4有些提供商的防火墙不支持转发protocol 41流量,比如gcp,点对点隧道其实可以直接分配/128。

确实没考虑到Wireguard…
学到了学到了,感谢佬友

1 Like

太强了,大佬!

1 Like

学习了额,感谢