开场:一个让我抓狂的周五下午

上周五下午五点半,我准备下班,突然想起家里的 NAS 上有一份重要的项目文档,周末要用。

打开手机一看——家里的公网 IP 又变了。上个月刚配好的端口转发,白搞了。

我试过这些方案:

  • frp 内网穿透:配置文件写了 50 行,还要维护服务端,每次改配置都要重启
  • ZeroTier:有时候连接稳定,有时候突然断线,像开盲盒
  • Tailscale:好用,但免费版只能 3 个用户,团队协作不够用

直到同事推荐了 WireGuard

第一次用的时候我惊了——配置文件只有 8 行,连接速度快到我怀疑它是不是真的加密了。更离谱的是,它的代码量只有 OpenVPN 的 1/100,安全性反而更高。

这篇文章就解决一件事:怎么在 Ubuntu 上从零开始配置 WireGuard,搭建一个稳定、安全的虚拟局域网。

先搞清楚:WireGuard 到底是什么?

在动手之前,先花 2 分钟搞清楚 WireGuard 的核心思想,不然你会一直踩坑。

密钥对就是你的身份

WireGuard 的身份验证简单到让人怀疑人生:每个设备一对密钥(公钥+私钥)

打个比方:你去银行办业务,柜员要验证你的身份。WireGuard 的验证方式就像这样:

  • 公钥 = 你的身份证号(可以告诉任何人)
  • 私钥 = 你的密码(打死不能泄露)
  • 预共享密钥(可选)= 银行给你发的动态验证码(额外安全层)

关键区别:WireGuard 没有"服务器"和"客户端"的概念——所有节点都是平等的 peer。

这就像微信群:每个人都可以给其他人发消息,没有"群主"的概念(虽然技术上你可以指定一个节点作为中继)。

为什么这很重要?

  1. 点对点连接:设备之间直接通信,不经过中心节点,延迟更低
  2. 拓扑灵活:星型、网状、混合都可以,按需选择
  3. 单点故障风险低:一个节点挂了,其他节点不受影响

性能对比:WireGuard vs 传统 VPN

协议代码量握手延迟吞吐量配置复杂度安全性
WireGuard~4,000 行<100ms接近线速⭐ 极简✅ 现代加密
OpenVPN~100,000 行1-3s中等⭐⭐⭐ 复杂✅ 成熟稳定
IPSec~500,000 行2-5s中等⭐⭐⭐⭐ 很复杂✅ 企业级

结论:WireGuard 在性能和易用性上碾压传统方案,唯一缺点是生态还在发展中(但已经够用了)。

配置前的准备工作

你需要什么

  1. 两台 Ubuntu 机器(物理机、虚拟机、VPS 都行)
    • 一台有公网 IP(作为中继节点)
    • 一台在家里/公司(内网环境)
  2. root 或 sudo 权限
  3. 基础网络知识(IP 地址、子网、端口)

网络规划

先画好你的虚拟局域网蓝图:

节点角色真实 IP虚拟 IP监听端口
Node A中继服务器公网 IP10.0.0.151820
Node B家庭设备内网 IP10.0.0.251820

虚拟 IP 段选择

  • 推荐 10.0.0.0/24192.168.x.0/24
  • 避开现有网络:如果你家路由器用 192.168.1.0/24,就别用这个段,否则路由会打架

实战:6 步配置 WireGuard

第一步:安装 WireGuard

两台机器都执行:

sudo apt update && sudo apt install wireguard -y

验证内核模块加载:

lsmod | grep wireguard
# 输出类似:wireguard             294912  0

第二步:生成密钥对

在每台机器上分别生成(不要在一台机器上生成然后复制!):

# 生成密钥对
wg genkey | tee privatekey | wg pubkey > publickey

# 查看
cat privatekey  # 私钥,保密!
cat publickey   # 公钥,可以发给其他节点

踩坑提醒:我第一次配置的时候,在一台机器上生成了所有密钥,结果死活连不上。WireGuard 的密钥是绑定设备的,必须每台机器自己生成。

第三步:配置 Node A(中继服务器)

sudo nano /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <Node A 的私钥>
Address = 10.0.0.1/24
ListenPort = 51820
# 启用 IP 转发和 NAT
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <Node B 的公钥>
AllowedIPs = 10.0.0.2/32

配置解释

  • PostUp/PostDown:启用 IP 转发和 NAT,让 Node B 可以通过 Node A 访问外网
  • AllowedIPs = 10.0.0.2/32:只接受 Node B 的流量(/32 表示单个 IP)

第四步:配置 Node B(家庭设备)

sudo nano /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <Node B 的私钥>
Address = 10.0.0.2/24
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = <Node A 的公钥>
Endpoint = <Node A 的公网 IP>:51820
AllowedIPs = 10.0.0.0/24, 0.0.0.0/0
PersistentKeepalive = 25

关键配置

  • AllowedIPs = 0.0.0.0/0所有流量都走 VPN(如果只想访问虚拟局域网,改成 10.0.0.0/24
  • PersistentKeepalive = 25:每 25 秒发心跳包,保持 NAT 映射不过期(内网穿透必备!)

第五步:启动 WireGuard

两台机器都执行:

# 启动
sudo wg-quick up wg0

# 开机自启
sudo systemctl enable wg-quick@wg0

# 检查状态
sudo wg show

正常输出:

interface: wg0
  public key: <公钥>
  private key: (hidden)
  listening port: 51820

peer: <对端公钥>
  endpoint: <对端 IP>:<端口>
  allowed ips: 10.0.0.0/24
  latest handshake: 1 minute, 42 seconds ago
  transfer: 1.24 MiB received, 5.32 MiB sent

第六步:测试连接

# 在 Node B 上 ping Node A
ping 10.0.0.1

# 如果能 ping 通,恭喜!你已经成功了

常见问题:3 个最常踩的坑

坑 1:ping 不通

症状ping 10.0.0.1 没有响应

排查步骤

# 1. 检查接口是否启动
sudo wg show

# 2. 检查防火墙
sudo ufw status
sudo iptables -L -n

# 3. 检查 IP 转发(最常被忽略!)
cat /proc/sys/net/ipv4/ip_forward
# 如果是 0,启用它:
sudo sysctl -w net.ipv4.ip_forward=1

# 4. 持久化 IP 转发
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

踩坑经历:我有次配置完死活 ping 不通,排查了 2 小时才发现 ip_forward 没开。这个参数重启后会重置,一定要持久化!

坑 2:连接不稳定

症状:有时候能 ping 通,有时候突然断

解决方案

  • 确认 PersistentKeepalive 已设置(建议 25-30 秒)
  • 检查路由器是否清理不活跃的 UDP 连接(有些路由器 5 分钟就清理)
  • 尝试更换监听端口(有些 ISP 会限制 51820 等常见端口)

坑 3:速度慢

症状:VPN 连接后网速断崖式下跌

排查步骤

# 1. 测试 VPN 内部速度
iperf3 -s  # 一台机器运行服务端
iperf3 -c 10.0.0.1  # 另一台测试

# 2. 调整 MTU(重要!)
sudo ip link set wg0 mtu 1420

为什么 MTU 重要? WireGuard 会给你原始数据包加上加密头,如果原始数据包已经接近 MTU 上限,加上加密头后就会超过,导致分片,速度暴跌。1420 是经验值,大多数场景都能用。

进阶配置:让你的 WireGuard 更强大

配置多个节点

只需 3 步:

  1. 在新设备上生成密钥对
  2. 在中继服务器添加 [Peer]
  3. 在新设备配置中继服务器信息
# 在 Node A 的配置中添加 Node C
[Peer]
PublicKey = <Node C 的公钥>
AllowedIPs = 10.0.0.3/32

配置防火墙

# UFW
sudo ufw allow 51820/udp
sudo ufw reload

# iptables
sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT

配置节点间直接通信

如果你希望 Node B 和 Node C 直接通信(不经过中继),在 Node B 的配置中添加:

[Peer]
PublicKey = <Node C 的公钥>
Endpoint = <Node C 的公网 IP>:51820
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25

安全加固:3 个必须做的安全措施

1. 使用预共享密钥

# 生成预共享密钥
wg genpsk > presharedkey

在每个 [Peer] 配置中添加:

PresharedKey = <预共享密钥>

为什么需要? 即使量子计算机破解了 WireGuard 的非对称加密,预共享密钥还能提供额外保护。

2. 限制配置文件权限

sudo chown root:root /etc/wireguard/wg0.conf
sudo chmod 600 /etc/wireguard/wg0.conf

3. 定期轮换密钥

建议每 3-6 个月更换一次密钥对。虽然 WireGuard 的密钥管理已经很安全,但定期轮换是好习惯。

实际应用场景

场景 1:远程访问家庭 NAS

配置 WireGuard 后,你可以:

  • 访问 10.0.0.2 直接连到家里的 NAS
  • 使用 SMB/NFS 协议挂载远程文件系统
  • 就像在家一样访问所有资源

场景 2:安全访问公司内网

在公司服务器上配置 WireGuard:

  • 在家安全访问公司内部系统
  • 避免直接暴露公司服务到公网
  • 通过公司网络访问其他资源

场景 3:游戏联机

和朋友一起玩 Minecraft、Valheim:

  • 不需要公网 IP
  • 不需要端口转发
  • 低延迟、高安全性

关键要点

  1. 密钥对是核心:公钥是身份,私钥是密码,每台设备自己生成
  2. 配置极简:一个配置文件,8 行搞定
  3. 性能碾压:比 OpenVPN 快 3-5 倍,代码量只有 1/100
  4. 安全可靠:现代加密算法 + 代码量少 = 容易审计
  5. 灵活部署:星型、网状、混合拓扑随你选

下一步

  1. 配置多节点:添加手机、笔记本等设备
  2. 学习策略路由:实现分流(部分流量走 VPN,部分走直连)
  3. 探索容器化:用 Docker 运行 WireGuard
  4. 对比其他方案:Tailscale、ZeroTier、OpenVPN 各有优劣

参考资源


作者注:这篇文章基于我在 Ubuntu 22.04/24.04 上的实际配置经验。如果你在配置过程中遇到问题,欢迎在评论区留言,我会尽力帮你解决。