光阴冢

We make choices and life has a way of making us pay for them.

使用 WireGuard 配置一个 IPv6 Tunnel

Nov 30, 2019   # WireGuard  # Networking 

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-toolswireguard-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]

最后终于:

WG IPv6