曾经有那么一次看到了一篇文章,说是Wireguard组网,2台异地主机同时使用一个IPV6出口,使得一台没有IPV6的主机拥有访问IPV6网络的能力,今天我在Cloudcone(以下简称CC)买了台年付70的促销服务器,配置为 512MB Ram,20G Raid10 VirtIO Disk, 1v Core 2.7Ghz,1Gbps出口和每月2T流量,这台机器机房和我一直在用的RN的机器相同,互相ping延迟才1ms,况且CC可以为每台VPS都一件申请3个IPV6地址,这让我萌生了wireguard组网并使用同一个公网IPV6出口,让所有主机都可以访问IPV6网络的想法。
原料:3 VPS 均预装Ubuntu 20.04 LTS,拥有ROOT权限,ROOT账号登陆
国外VPS1 = IPV4公网 x 1 + IPV6 公网 X 3
国外VPS2 = IPV4 公网 X 1
国内VPS3 = IPV4 公网 X 1
原理:
利用wireguard转发所有主机的公网IPV6数据到VPS1上出,这样所有的主机都可以访问公网IPV6了,我的VPS情况有点特殊,VPS3在国内,只能访问VPS2 ,VPS2则可以访问VPS1和VPS3,
于是我准备将VPS2作为中转数据包的服务器,但是我准备以后添加节点都在VPS3处添加,所以VPS3承担路由内网数据的任务
想法:
VPS1和VPS2上的发向2001:16:1993::1/64的和发往 10.9.9.1/24 的数据包全部发送到VPS3处理,
VPS2和VPS3上的发往公网IPV6的数据包全部经过VPS2路由发往VPS1,使得VPS2和VPS3拥有访问IPV6公网的能力。
但是VPS1要通过VPS2与VPS1沟通,所以VPS1的内网数据全部发往VPS2让VPS2路由到VPS3处理
VPS3 <----------------------> VPS2 <================================> VPS1
IPV4分配情况:
10.9.9.3 10.9.9.2 10.9.9.1
IPV6分配情况:
2001:16:1993::3 2001:16:1993::2 2001:16:1993::1
则:
VPS1的
本地IP: 10.9.9.1/32, 2001:16:1993::1/128
发往VPS2的AllowIPS: 10.9.9.0/24, 2001:16:1993::0/64
VPS2的
本地IP: 10.9.9.2/32, 2001:16:1993::2/128
发往VPS1的AllowIPS: 10.9.9.1/32, 2001:16:1993::1/128, ::/0
发往VPS3的AllowIPS: 10.9.9.0/24, 2001:16:1993::0/64
VPS3的
本地IP: 10.9.9.3/32, 2001:16:1993::3/128
发往VPS2的AllowIPS: 10.9.9.1/32, 2001:16:1993::1/128, 10.9.9.2/32, 2001:16:1993::2/128, ::/0
以后添加节点在VPS3配置文件里添加即可,VPS1和VPS2发送的内网数据包会自动经过VPS3路由
详细步骤:
1:全都先更新软件源
apt update && apt upgrade -y
2: 在三台主机上都安装最新的wireguard组件
apt install wireguard -y
3: 准备编辑配置文件,我喜欢使用vim作为文本编辑器,用啥编辑文件随便你
(1)使用 wg genkey
生成私钥PRK1
使用 echo {你生成的PRK1} | wg genpub
生成公钥 PUB1
这对密钥给VPS1使用
(2) 使用 wg genkey
生成私钥PRK2
使用 echo {你生成的PRK2} | wg genpub
生成公钥 PUB2
这对密钥给VPS2使用
(3) 使用 wg genkey
生成私钥PRK3
使用 echo {你生成的PRK3} | wg genpub
生成公钥 PUB3
这对密钥给VPS3使用
配置文件路径均为 /etc/wireguard/wg0.conf
VPS1的配置文件:
[Interface]
Address = 10.9.9.1/32,2001:16:1993::1/128 #给这个端口分配的地址,每个地址间用逗号隔开,要转发IPV6数据包必须给接口IPV6地址
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 11451 #VPS1设计为加入组网和NAT IPV6数据包的角色,可以躲在NAT后面
PrivateKey = ${PRK1} #VPS1的私钥
[Peer] #这是VPS2节点
PublicKey =${PUB2} #VPS2的公钥
Endpoint = IPV4:PORT #这台主机要连接VPS2(有公网IP的服务器),必须要有此行,wireguard数据包会向这个地址端口发送
AllowedIPs = 10.9.9.0/24, 2001:16:1993::0/64
PersistentKeepalive = 25 #心跳包延迟,自行决定时间
VPS2的配置文件:
[Interface]
Address = 10.9.9.2/32,2001:16:1993::2/128 #分配给VPS2的地址
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 11452 #必须至少有一台VPS有公网IP且有可开放端口,这时它将作为所有数据的中转服务器,这个端口必须开放udp数据包访问
PrivateKey = ${PRK1} #VPS2的私钥
#wireguard的所有节点之间是平等的,一个端口可以添加多个节点
[Peer] #这是VPS1节点,他负责向外转发所有IPV6数据包
PublicKey =${PUB1} #VPS1的公钥
Endpoint = IPV4:PORT #VPS2作为有公网IP的节点,这里填对方节点的公网IP和端口,如果你不知道,比如对方是内网IP要走NAT,则可以不填这一行(比如内网家宽要加入组网,则删除此行,但是必须你先发送数据包到中转服务器上后虚拟局域网的其他机器才能访问你的机器,服务器会自动添加你的NAT到外部的端口,躲在NAT后的主机一定要记得选择合理的心跳包发送间隔,以及时更新NAT状态)
AllowedIPs = 10.9.9.1/32, 2001:16:1993::1/128, ::/0
PersistentKeepalive = 5 #每5秒钟发送一个心跳包,用于连接保活,自行决定时间
[Peer] #这是VPS3节点,单纯加入组网
PublicKey =${PUB3} #VPS3的公钥
Endpoint = IPV4:PORT #VPS2作为有公网IP的节点,这里填对方节点的公网IP和端口,如果你不知道,比如对方是内网IP要走NAT,则可以不填这一行(比如内网家宽要加入组网,则删除此行,但是必须你先发送数据包到中转服务器上后虚拟局域网的其他机器才能访问你的机器,服务器会自动添加你的NAT到外部的端口,躲在NAT后的主机一定要记得选择合理的心跳包发送间隔,以及时更新NAT状态)
AllowedIPs = 10.9.9.0/24, 2001:16:1993::0/64
PersistentKeepalive = 25 #每25秒钟发送一个心跳包,用于连接保活,自行决定时间
VPS3的配置文件:
[Interface]
Address = 10.9.9.3/32,2001:16:1993::3/128 #给这个端口分配的地址,每个地址间用逗号隔开,要转发IPV6数据包必须给接口IPV6地址
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE;ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 11451 #VPS3在设计中仅仅加入组网,VPS2作为中转服务器且有公网IP,则此端口可以躲在NAT后面
PrivateKey = ${PRK3} #VPS3的私钥
[Peer] #这是VPS2节点
PublicKey =${PUB2} #VPS2的公钥
Endpoint = IPV4:PORT #这台主机要连接VPS2(有公网IP的服务器),必须要有此行,wireguard数据包会向这个地址端口发送
AllowedIPs = 10.9.9.1/32, 2001:16:1993::1/128, 10.9.9.2/32, 2001:16:1993::2/128, ::/0
PersistentKeepalive = 25 #心跳包延迟,自行决定时间
然后,在三台VPS上打开网络转发
echo '''
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
''' > /etc/sysctl.conf
sudo sysctl -p
在三台VPS上执行
wg-quick up wg0
无错误后,在各台VPS上应该都可以ping通公网IPV6地址和互相PING通任意VPS的IP了,组网完成
将wireguard加入开机自启:
systemctl enable wg-quick@wg0
立即启动WG0接口:
systemctl start wg-quick@wg0