WireGuard (简体中文) - ArchWiki

Jump to content

# WireGuard (简体中文)

From ArchWiki

本文或本节需要翻译。要贡献翻译，请访问简体中文翻译团队。

附注： 翻译中，但未同步最新的英文版本（在 Talk:WireGuard (简体中文)# 中讨论）

引用自 WireGuard 项目主页:

WireGuard 是一种极其简单但快速且现代的 VPN，它利用了最先进的加密技术。它的目标是比 IPsec 更快、更简单、更精简和更有用，同时避免令人头疼的问题。旨在提供比 OpenVPN 更高的性能。WireGuard 被设计为在嵌入式接口和超级计算机等上运行的通用 VPN，适用于许多不同的环境。最初仅支持 Linux 平台，现在可以进行跨平台（Windows、macOS、BSD、iOS、Android）的广泛部署。目前仍然在大力开发中，但已经被认为是业内最安全、最容易使用和最简单的 VPN 解决方案。

警告： WireGuard 尚未经过适当程度的安全审计，协议仍有可能更改。[1]

## 安装

1. 安装 wireguard-tools 包
2. 对于版本小于 5.6 的 Linux 内核，需要额外安装合适的内核模块（当使用默认的 linux 包时不需要）：
   - wireguard-dkmsAUR 用于其他版本小于 5.6 的 DKMS 变体内核。

提示： systemd-networkd 和 NetworkManager 都为 WireGuard 接口设置提供原生支持，它们只需要内核模块。

## 使用

在 peer 上生成公钥和私钥：

    $ wg genkey | tee privatekey | wg pubkey > publickey

下面的指令会演示如何以表中的配置建立一条两个 peer 之间的隧道

| Peer A | Peer B
--- | --- | ---
公网地址 | 10.10.10.1/24 | 10.10.10.2/24
内网地址 | 10.0.0.1/24 | 10.0.0.2/24
wireguard 监听端口 | UDP/4857 | UDP/3981

Peer 应当已经拥有公网地址。例如，peer A 应当能够通过 `ping 10.10.10.2` ping 通 peer B，反之亦然。内部地址是由下文 `ip` 命令创建的新地址，并且将在 WireGuard 网络中共享。IP地址中 `/24` 的含义详见 CIDR

### Peer A 配置

这个 peer 将监听 UDP 端口 48574，通过将 peer B 的公钥与其内部和外部 IP 地址关联，接受来自 peer B 的连接。

    # ip link add dev wg0 type wireguard
    # ip link set dev wg0 mtu 1420
    # ip addr add 10.0.0.1/24 dev wg0
    # wg set wg0 listen-port 4857 private-key ./privatekey
    # wg set wg0 peer [Peer B public key] persistent-keepalive 25 allowed-ips 10.0.0.2/32 endpoint 10.10.10.2:3981
    # ip link set wg0 up

`[Peer B public key]` 的格式应当如同 `EsnHH9m6RthHSs+sd9uM6eCHe/mMVFaRh93GYadDDnM=`。`allowed-ips` 是 peer A 能够向之发送流量的地址列表。`allowed-ips 0.0.0.0/0` 将允许向任意地址发送流量。

### Peer B 配置

如同 Peer A，只不过 wireguard 守护监听 UDP 端口 39814 并且只接受 peer A 的连接

    # ip link add dev wg0 type wireguard
    # ip link set dev wg0 mtu 1420
    # ip addr add 10.0.0.2/24 dev wg0
    # wg set wg0 listen-port 3981 private-key ./privatekey
    # wg set wg0 peer [Peer A public key] persistent-keepalive 25 allowed-ips 10.0.0.1/32 endpoint 10.10.10.1:4857
    # ip link set wg0 up

### 基本检查

不带任何参数使用 wg 命令可以快速查看当前的配置。

例如，当 peer A 配置好之后，我们可以看见它的身份和与之关联的 peers。

     peer-a$ wg
     interface: wg0
       public key: UguPyBThx/+xMXeTbRYkKlP0Wh/QZT3vTLPOVaaXTD8=
       private key: (hidden)
       listening port: 4857

     peer: 9jalV3EEBnVXahro0pRMQ+cHlmjE33Slo9tddzCVtCw=
       endpoint: 10.10.10.2:3981
       allowed ips: 10.0.0.2/32

此时我们可以 ping 通隧道的另一端：

     peer-a$ ping 10.0.0.2

### 配置持久化

配置可以通过 `showconf` 来保存

    # wg showconf wg0 > /etc/wireguard/wg0.conf
    # wg setconf wg0 /etc/wireguard/wg0.conf

### 示例 peer 配置

    /etc/wireguard/wg0.conf

    [Interface]
    PrivateKey = [CLIENT PRIVATE KEY]
    MTU = 1420

    [Peer]
    PublicKey = [SERVER PUBLICKEY]
    AllowedIPs = 10.0.0.0/24, 10.123.45.0/24, 1234:4567:89ab::/48
    Endpoint = [SERVER ENDPOINT]:5182
    PersistentKeepalive = 25

## 配置一个 VPN 服务器

WireGuard 自带一个快速创建和销毁 VPN 服务器的工具，`wg-quick`。注意这里使用的配置文件不是一个能被 `wg setconf` 有效的配置文件，并且你可能至少要把 `eth0` 改成你实际使用的。

### 服务器

    /etc/wireguard/wg0server.conf

    [Interface]
    Address = 10.0.0.1/24  # This is the virtual IP address, with the subnet mask we will use for the VPN
    PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -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
    ListenPort = 5182
    PrivateKey = [SERVER PRIVATE KEY]
    MTU = 1420

    [Peer]
    PublicKey = [CLIENT PUBLIC KEY]
    AllowedIPs = 10.0.0.2/32  # 这表示客户端只有一个 IP。

要使 iptables 规则生效，启用 IPv4 转发：

    # sysctl net.ipv4.ip_forward=1

永久保留这项改变，向 `/etc/sysctl.d/99-sysctl.conf` 添加 `net.ipv4.ip_forward = 1`。

使用 `wg-quick up wg0server` 启用 Interface，`wg-quick down wg0server` 用以关闭

### 客户端 (转发所有流量)

    /etc/wireguard/wg0.conf

    [Interface]
    Address = 10.0.0.2/24  # The client IP from wg0server.conf with the same subnet mask
    PrivateKey = [CLIENT PRIVATE KEY]
    DNS = 10.0.0.1
    MTU = 1420

    [Peer]
    PublicKey = [SERVER PUBLICKEY]
    AllowedIPs = 0.0.0.0/0, ::0/0
    Endpoint = [SERVER ENDPOINT]:5182
    PersistentKeepalive = 25

使用 `wg-quick up wg0` 来启用 Interface, 使用 `wg-quick down wg0` 来关闭。

使用 `systemctl enable wg-quick@wg0` 来自动启动。

如果你使用 NetworkManager, 可能有必要启用 NetworkManager-wait-online.service `systemctl enable NetworkManager-wait-online.service`

或者你使用的是 systemd-networkd, 启用 systemd-networkd-wait-online.service `systemctl enable systemd-networkd-wait-online.service`

等待所有设备就绪再尝试 WireGuard 连接

## 疑难解答

### DKMS module not available

如果你在安装了 wireguard-dkmsAUR 后执行下面的命令没有列出任何模块

    $ modprobe wireguard && lsmod | grep wireguard

或者在使用下面的命令创建一个新的连接时提示 `RTNETLINK answers: Operation not supported`

    # ip link add dev wg0 type wireguard

可能是因为缺失了 linux 头文件。

linux 头文件可以通过安装 linux-headers 获取。

## 使用技巧

### 以加密的形式存储私钥

以加密的形式存储私钥可能是可以实现的，例如通过使用 pass。只需将配置文件中[Interface]下的 PrivateKey 一行替换为。

     PostUp = wg set %i private-key <(su user -c "export PASSWORD_STORE_DIR=/path/to/your/store/; pass WireGuard/private-keys/%i")

where user is your username. See the `wg-quick(8)` man page for more details.

将其中的user替换成你的用户名。更多细节请参见 `wg-quick(8)` man 页面。

Category:

- Virtual Private Network (简体中文)

Hidden category:

- Pages or sections flagged with Template:Translateme (简体中文)