WireGuard 可以用来建立安全的点对点的连接。INRIA 的研究人员于 2019 五月发表了对于该协议的一份机器证明。
We contribute proofs for correctness, message secrecy, forward secrecy, mutual authentication, session uniqueness, and resistance against key compromise impersonation, identity mis-binding, and replay attacks.
更换了实验室(物理)以后,丧失了连接到教育网 IPv6 的能力,只能在寝室或者是使用跳板服务器,非常不方便。于是想通过 WireGuard 建立一个从实验室电脑到机房服务器的隧道,实现在本机上也能访问公网 IPv6。
安装
实验室电脑是 Arch Linux,内核用的是官方内核,因此装好 wireguard-tools
和 wireguard-arch
即可。
在 Ubuntu 上则需要自己添加相应的源再安装:
1
2
|
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt install wireguard
|
配置
配置的方法网络上已经有很多教程,比如 WireGuard 的官方教程,Linode 的教程和 Arch Linux Wiki 上的教程,都比较靠谱,并且大同小异。
另外,如果没有装 linux-headers
的话,在 ip link add dev wg0 type wireguard
时会报 Error: Unknown device type.
错误,务必装上自己内核版本对应的 headers 。
一个重要的地方
Peers
块中的 AllowedIPs
不能随意设置。
- 如果是 Server 端的配置,需要允许拥有对应公钥的设备 IP ,并且设置好掩码。
- 如果是 Client 端的配置,看情况配置:
- 只是为了异地组网,把不同机器连起来,则只需要填入该子网的 IP 段
- 想要访问内(外)网络,Server 在内(外)网,则需要将要访问的对应的内(外)网 IP 段填入。
- 经典的配置就是
0.0.0.0/0 , ::/0
,本机上所有流量都被转发给服务器了。(服务器作为一个 VPN Server)
- 如果想在外地连入校内网,则可以写
10.0.0.0/8
。
AllowIPs
这个字段通常仿佛都是人畜无害的(只是来个流量再判断一下 IP 决定是否 drop 嘛)。但是在 WireGuard 上是有副作用的:它会添加路由,以便能够使用 WireGuard 建立的那个网络。(当然了!)
所以,想象一下,如果在 Server 上设置了 AllowedIPs = 0.0.0.0, ::/0
,会发生什么?
您好!我想借用一下机房的钥匙。
其实,某个时刻两台机器应该还是通过 wg 联通着的;但是服务器已经没办法通过别的方式正常连接到了。
当时走的弯路
- 明明是要配置 NAT IPv6 路由的,可是一直没有给这俩分配 IPv6 地址。
- 跑了一次机房。
最终配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# Server
[Interface]
ListenPort = [PORT]
PrivateKey = <PrivateKey>
Address = 192.168.0.2/24, fd23:23:23::2/64
# 用 iptables 设置包转发,注意将 <dev-name> 替换为 Server 上对应的网卡设备名字
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <dev-name> -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o <dev-name> -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <dev-name> -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o <dev-name> -j MASQUERADE
[Peer]
PublicKey = <PublicKey>
# 只允许一个 IP
AllowedIPs = 192.168.0.3/32, fd23:23:23::3/128
Endpoint = <IP>:[PORT]
|
1
2
3
4
5
6
7
8
9
10
11
12
|
# Client
[Interface]
ListenPort = [PORT]
PrivateKey = <PrivateKey>
Address = 192.168.0.3/24, fd23:23:23::3/64
[Peer]
PublicKey = <PublicKey>
# IPv4 正常用就好了,目的只是 enable IPv6。
# 这里我偷了一下懒,把所有 IPv6 流量都指向服务器了,这样一来客户端本地链路上的 IPv6 就无法正常访问了(不过也通常没什么用)。
AllowedIPs = 192.168.0.2/32, ::/0
Endpoint = <IP>:[PORT]
|
最后终于:
