Ubuntu 22.04 安装 WireGuard 指南

Ubuntu 22.04 下用 apt 在线安装 WireGuard(wireguard-tools + 内核模块支持),生成密钥对、编写 wg0.conf、wg-quick 启动并以 systemd 托管,含真实回显、卸载与常见问题排障

WireGuardWireGuardUbuntusystemd安装部署2026/10/09

Ubuntu 22.04 安装 WireGuard 指南

目标:在 Ubuntu 22.04 上从零安装并配置 WireGuard 现代高效 VPN 服务器,实现点对点隧道并验证握手与转发,已在 Ubuntu 22.04.5 LTS(WireGuard Tools v1.0.20210914)实测通过。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(jammy)
  • 内核:6.8.0-138-generic(实测 uname -r 输出;WireGuard 要求 Linux ≥ 5.6 内核支持)
  • WireGuard 用户态工具:wireguard-tools 1.0.20210914-1ubuntu2(apt 官方仓库)
  • VPN 接口:wg0,内网网段 10.99.0.0/24
  • 服务器隧道地址:10.99.0.1/24,监听端口 UDP 51820
  • 客户端节点(peer):10.99.0.2/24
  • 数据目录:/etc/wireguard/(配置与密钥),密钥位于 wg-quick@wg0 自托管下

⚠️ 注意:WireGuard 是一个「内核模块(或内核内置)+ 用户态工具」的组合。Linux 5.6 开始 WireGuard 已合并进内核主线(默认开启)。本文在已具备内核支持的实测环境验证通过;若目标机为更早内核,需先按「四、版本选型说明」确认内核模块可用。

二、前置条件

  • 一台干净的 Ubuntu 22.04 服务器,具备 root 或 sudo 权限;
  • 服务器有可用的公网 IP(或至少 NAT 可达的 IP:端口),用于客户端连接(若仅内网测试可省略);
  • 防火墙需放行 UDP 51820(本文配置 ListenPort 为 51820);
  • 服务器与客户端各自准备两个端口可互通的网络(若做点对点实测)。本文实测环境为同一内网、双节点互通。

💡 说明:WireGuard 不需要像 OpenVPN 那样维护 CA 证书,端到端只需交换两端的公钥与允许网段即可建立隧道,密钥在节点间对称校验。

三、版本选型说明

WireGuard 的「版本」主要体现在内核模块与用户态工具上,Ubuntu 22.04 仓库中主要能看到两类包:

包名来源说明本文选择
wireguardjammy/universe元包,依赖安装 wireguard-tools 与内核模块相关依赖不单独装,装下面工具即可
wireguard-toolsjammy/main用户态命令行工具(wg / wg-quick)✅ 本文安装对象
内核支持Linux ≥ 5.6 主线内核内置 WireGuard,无需额外模块实测环境已具备

💡 说明:Ubuntu 22.04 默认内核(5.15 或 HWE 6.x)普遍已内置 WireGuard 支持;wireguard-tools 即提供 wg 与 wg-quick 两个主要命令。若确需查看仓库可用版本:

apt-cache policy wireguard wireguard-tools

实测回显(用于核对仓库版本):

$ apt-cache policy wireguard-tools
wireguard-tools:
  Installed: 1.0.20210914-1ubuntu2
  Candidate: 1.0.20210914-1ubuntu2
  Version table:
 *** 1.0.20210914-1ubuntu2 500
        500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packages
        100 /var/lib/dpkg/status

⚠️ 注意:WireGuard 要求内核支持。Linux 5.6+ 已内置;更早内核需要额外加载模块。验证方式见「四、4.4 加载与验证内核模块」。

四、部署步骤

4.1 更新软件源

apt-get update -qq

💡 说明:更新软件源以获取最新的 wireguard-tools 版本信息,实测无额外回显即为成功。

4.2 安装 wireguard-tools

apt-get install -y wireguard-tools

安装完成后核对版本与所在路径:

wg --version
which wg wg-quick

实测回显:

$ wg --version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/

$ which wg wg-quick
/usr/bin/wg
/usr/bin/wg-quick

4.3 生成服务端密钥对

WireGuard 使用基于 Curve25519 的密钥对,密钥在节点本地生成,无需 CA。用 wg genkey 生成私钥,再用私钥推导公钥:

umask 077
cd /etc/wireguard
wg genkey | tee server_private.key | wg pubkey > server_public.key

💡 说明:私钥文件权限必须为 600 左右,umask 077 可确保创建的文件不可被组用户/其他用户读取。

实测回显(某次生成的密钥,仅供格式参考;真实使用请以你生成的值替换):

$ wg genkey | tee server_private.key | wg pubkey > server_public.key
$ cat server_private.key server_public.key
<base64 私钥>
<base64 公钥>

为演示点对点握手,再生成两个客户端(peer)的密钥对,并生成一对预共享密钥(PresharedKey,可选,强烈建议用于增强防重放抗性):

cd /etc/wireguard
wg genkey > peer1_private.key; cat peer1_private.key | wg pubkey > peer1_public.key
wg genkey > peer2_private.key; cat peer2_private.key | wg pubkey > peer2_public.key
wg genpsk > psk.key

4.4 配置 wg0 接口

在 /etc/wireguard/wg0.conf 写入服务端配置。wg-quick 会按 /etc/wireguard/<接口>.conf 加载配置,文件名即接口名:

[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <server_private.key 内容>

[Peer]
PublicKey = <peer1_public.key 内容>
PresharedKey = <psk.key 内容>
AllowedIPs = 10.99.0.2/32

💡 说明:

  • Address:服务器隧道地址,即 VPN 网卡上的 IP(支持 IP/掩码);
  • ListenPort:WireGuard UDP 监听端口(默认 51820);
  • PrivateKey:服务端私钥(绝对不要外泄);
  • 每个 [Peer] 段描述一个允许连接的客户端:PublicKey 为客户端公钥,AllowedIPs 为该客户端在 VPN 内被允许使用的 IP 段。

4.5 加载与验证内核模块,启用接口

Linux 5.6+ 内核已内置 WireGuard;可通过创建 WireGuard 类型接口来验证内核是否支持,也可显式加载模块。随后用 wg-quick 拉起接口:

# 验证内核支持(能创建 wireguard 类型接口即说明内核内置/模块可用)
modprobe wireguard            # 部分内核已内置时可能提示未找到模块,属正常(见下)
# 拉起接口
wg-quick up wg0

实测回显(接口成功拉起):

$ wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.99.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0

⚠️ 注意(内核支持前提):

  • WireGuard 是内核特性,Linux ≥ 5.6 默认内置,无需单独装模块;
  • 本测试镜像的 /lib/modules 中未预置该内核版本对应的 wireguard.ko,因此 modprobe wireguard 会提示 FATAL: Module wireguard not found;但内核本身已内置 WireGuard 能力(上面的 ip link add wg0 type wireguard 与 wg-quick up wg0 均成功,说明 wireguard 以「内核内置」形态存在),这正对应真实生产环境中「已合并进内核(Linux 5.6+)」的常见现状;
  • 若你的真实内核 < 5.6 且未内置 WireGuard,请先安装对应内核模块(如 linux-modules-extra 或 dkms 方式)再继续,否则 wg-quick up 会在 ip link add wg0 type wireguard 处失败。
  • 若内核不支持,错误通常为:
    [#] ip link add wg0 type wireguard
    Error: Unknown device type.
    Unable to access interface: Protocol not supported
    

启用车后查看接口状态:

ip addr show wg0
wg show wg0

实测回显:

$ ip addr show wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.99.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever

$ wg show wg0
interface: wg0
  public key: omjFjOq26vb24495db2kUGSVx1bZHoAnkLbmsTPwmyg=
  private key: (hidden)
  listening port: 51820

peer: AYpcaJY8ZqMEYeTGQz7I+LuXpt98k5q56gr70N4sAw8=
  preshared key: (hidden)
  allowed ips: 10.99.0.2/32

4.6 验证点对点握手(客户端对端)

在另一节点(客户端 peer,隧道 IP 10.99.0.2/24)配置对端后,与服务器建立加密隧道,验证 ping 与 wg show 握手信息:

客户端 wg0.conf 要点(对应本文服务端的 peer1):

[Interface]
Address = 10.99.0.2/24
PrivateKey = <peer1_private.key 内容>

[Peer]
PublicKey = omjFjOq26vb24495db2kUGSVx1bZHoAnkLbmsTPwmyg=
PresharedKey = <psk.key 内容>
Endpoint = <服务器公网IP>:51820
AllowedIPs = 10.99.0.0/24
PersistentKeepalive = 25

💡 说明:客户端 [Peer] 的 PublicKey 应填服务器公钥,Endpoint 填服务器可达的 IP:端口,AllowedIPs 填需要经由隧道访问的网段。

建立连接后从客户端 ping 服务器隧道地址:

ping -c 3 10.99.0.1

实测回显:

$ ping -c 3 10.99.0.1
--- 10.99.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2053ms
rtt min/avg/max/mdev = 0.303/0.320/0.333/0.012 ms

服务端 wg show 显示握手与收发流量:

$ wg show wg0
interface: wg0
  public key: omjFjOq26vb24495db2kUGSVx1bZHoAnkLbmsTPwmyg=
  private key: (hidden)
  listening port: 51820

peer: AYpcaJY8ZqMEYeTGQz7I+LuXpt98k5q56gr70N4sAw8=
  preshared key: (hidden)
  endpoint: 172.24.0.3:36983
  allowed ips: 10.99.0.2/32
  latest handshake: 6 seconds ago
  transfer: 564 B received, 476 B sent

💡 说明:看到 latest handshake 与 transfer: … received, … sent 即代表加密隧道已建立并双向通信成功。endpoint 为对端当前实际来源 IP:端口。

4.7 配置 IP 转发与流量伪装(网关模式)

若要把本机当作 VPN 网关(客户端访问整网或外网),需开启内核 IP 转发,并在 wg0.conf 的 [Interface] 增加 PostUp/PostDown 规则(上联网卡以 eth0 为例,请替换为实际对外网卡名):

[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <server_private.key 内容>
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <peer1_public.key 内容>
PresharedKey = <psk.key 内容>
AllowedIPs = 10.99.0.2/32
# 开启内核转发(重启后失效,如需持久化写入 /etc/sysctl.conf)
sysctl -w net.ipv4.ip_forward=1
wg-quick down wg0 && wg-quick up wg0

4.8 以 systemd 托管(开机自启)

⚠️ 前置要求:本步依赖 systemd 的 Linux 真机(服务启用/开机自启/故障自拉起均依赖 systemd)。若你的最小化环境未以 systemd 作为 init(PID 1),请换用 4.5 的手动 wg-quick up 方式。

Ubuntu 22.04 在安装 wireguard-tools 时已一并提供 wg-quick@.service 模板单元,配置文件只需放在 /etc/wireguard/wg0.conf 即可通过 wg-quick@wg0 托管。启用并启动:

# 设置开机自启 + 立即启动(两步,二选一看习惯)
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
# 或一步到位:
systemctl enable --now wg-quick@wg0

⚠️ 说明:wg-quick@.service 单元会在接口 up/down 时调用 wg-quick up wg0 / wg-quick down wg0(同 4.5 实测回显),并自动记录为 systemd 服务,开机自启、崩溃自拉起。需要手动验证可执行第 4.9 节命令。

💡 说明:enable wg-quick@wg0 与 start wg-quick@wg0 各针对一个单元名,切勿在同一行放入多个单元名。

4.9 验证服务与接口状态

systemctl status wg-quick@wg0
systemctl is-enabled wg-quick@wg0

预期:服务处于 active(wg-quick@wg0 使用 Type=oneshot,up 完成后处于 active (exited));wg-quick@wg0 已 enable。以 wg show / ping 复核接口与吞吐同 4.6。

五、多方案对照与选择建议

方案版本来源是否需要联网内核模块依赖systemd 托管适用场景
A:apt 在线安装(本文 四 章)Ubuntu 官方仓库 1.0.20210914需要内核内置(5.6+)✅ 系统自带单元可联网的常规服务器,推荐
B:源码编译安装 wireguard-toolsgit.zx2c4.com/wireguard-tools 最新需要(git)不受影响需自建单元需要比发行版更新工具版本时

💡 选择建议:绝大多数 Ubuntu 22.04 生产环境直接选方案 A(仓库包稳定、随系统安全更新、自带 systemd 模板)。只有在需要显著更新版本、或发行版包缺失时才考虑方案 B 源码编译。

六、常见问题(FAQ)

Q1:wg-quick up wg0 报 Error: Unknown device type. / Protocol not supported?

原因:内核不支持 WireGuard(多半是内核 < 5.6 且未装模块)。解决:a) 升级到 Linux ≥ 5.6;b) 安装内核模块,如 apt-get install linux-modules-extra-$(uname -r),再 modprobe wireguard。

Q2:modprobe wireguard 提示 Module wireguard not found in directory /lib/modules/...?

这通常说明内核已经把 WireGuard 编译进内核(Linux 5.6+ 内置),而非以独立模块存在。此时不必担心——直接 wg-quick up wg0 若成功即代表内核支持(见 4.5 实测)。Modprobe 找不到模块文件、但接口能创建成功,正是「内核内置」的典型表现。

Q3:客户端连上了,但服务端 wg show 看不到 latest handshake?

常见原因:a) 服务端 [Peer] 未配置客户端的 PublicKey/AllowedIPs;b) 客户端 Endpoint 写错(应为服务器公网可达 IP:51820);c) 双方 UDP 51820 未放行(防火墙/NAT)。逐一排查,并用 4.6 的 wg show 观察握手。

Q4:能 ping 通隧道 IP,但客户端无法上网(网关模式)?

检查:a) 服务端已开启 net.ipv4.ip_forward=1;b) wg0.conf 的 PostUp MASQUERADE 规则无误且网卡名正确(eth0);c) 客户端 AllowedIPs = 0.0.0.0/0(全流量代理)或至少包含目标网段。

Q5:密钥文件权限问题?

wg-quick 对 /etc/wireguard/*.conf 权限较敏感;私钥泄露风险高。生成时用 umask 077,并确保 chmod 600 /etc/wireguard/*.key。若因权限启动失败,通常为 Not authorized to control networking 一类,调整权限后重试。

Q6:接口乱掉 / 配置改了没生效?

改完 /etc/wireguard/wg0.conf 后需重建接口:

wg-quick down wg0
wg-quick up wg0

systemd 托管时改配置后 systemctl restart wg-quick@wg0 同理。

七、卸载方式

# 1) 停止并关闭 wg0(若已 systemd 托管先禁用)
systemctl disable --now wg-quick@wg0 || wg-quick down wg0
# 2) 删除配置与密钥
rm -rf /etc/wireguard
# 3) 卸载软件包(保留日志可选加 --purge)
apt-get remove -y wireguard-tools
apt-get autoremove -y

💡 说明:wg-quick@wg0 单元在 wireguard-tools 卸载后一并移除;上文 4.7 写入的 iptables 规则会随 wg-quick down(PostDown)自动清理。

八、参考链接