在Linux VPS上配置WireGuard和Tailscale VPN
在Ubuntu 24.04和Debian 12上从零搭建WireGuard或部署Tailscale托管VPN,涵盖DNS泄漏防护、PreSharedKey加固以及包含Headscale的中立对比。
本指南介绍两种Linux VPS的VPN接入方案:WireGuard(手动配置,完全掌控)和Tailscale(托管服务,开箱即用)。两者底层都使用WireGuard协议,区别在于谁来管理密钥、路由和协调。
选择适合你情况的章节,或者通读三个部分以做出明智的选择。
前提条件:
- 一台运行Ubuntu 24.04或Debian 12的VPS(适用于Virtua Cloud VPS)
- 拥有sudo权限的非root用户的SSH访问
- 已配置并启用的防火墙
- 一台本地机器(Linux、macOS或Windows)作为VPN客户端
为什么要通过VPN连接你的Linux VPS?
每个暴露在公网IP上的服务都是攻击目标。SSH暴力破解机器人在几分钟内就能发现新服务器。数据库端口、管理面板和API端点持续遭到扫描。VPN可以让管理接口完全远离公网。
原理很简单:将敏感服务绑定到VPN接口地址而非0.0.0.0。只有持有有效VPN密钥的设备才能访问。公网永远看不到这些端口的存在。
常见使用场景:
- 无需公开SSH的管理访问。 将
sshd绑定到WireGuard IP。不再向外界暴露22端口。没有可供暴力破解的目标时,Fail2ban变得可选。 - 通往私有AI推理API的隧道。 在VPS上运行Ollama或私有LLM端点?放在VPN后面。内部访问无需API网关,无需管理token认证。
- 多云Mesh网络。 将不同提供商(Virtua、Hetzner、OVH)的VPS节点连接成私有网络。服务通过加密隧道通信,无需公共端点。
- 在不可信网络上加密流量。 在咖啡馆或酒店WiFi工作时,将所有流量路由通过VPS。你的ISP和本地网络运营商只能看到加密的WireGuard数据包。
威胁模型很重要。如果你只从固定的办公IP访问VPS,防火墙规则可能就够了。但如果你从多个地点工作、使用多台设备,或管理一个有不同访问级别的团队,VPN是更干净的方案。
如何在Ubuntu 24.04或Debian 12上安装WireGuard?
WireGuard是自Linux内核5.6版本起内置的VPN协议。它使用Curve25519进行密钥交换,ChaCha20进行加密,代码量约4000行(相比OpenVPN的10万行以上)。用apt安装,生成密钥对,写配置文件,启动隧道。整个过程不到10分钟。
在服务器上安装WireGuard:
sudo apt update && sudo apt install wireguard wireguard-tools -y
wireguard包提供内核模块。wireguard-tools包提供wg和wg-quick用户空间工具。
如何生成WireGuard密钥并配置服务器?
WireGuard使用非对称密钥对(每个对等节点一个)加上一个可选的预共享密钥(PreSharedKey)用于后量子防御。生成一个服务器密钥对、一个客户端密钥对和一个双方共享的预共享密钥。预共享密钥在WireGuard的Curve25519交换之上添加一层对称加密。如果未来量子计算机破解了非对称密钥交换,对称预共享密钥仍然保护隧道。
在服务器上使用限制性umask生成密钥,确保文件以600权限创建:
umask 077
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
wg genpsk | sudo tee /etc/wireguard/psk.key
ls -la /etc/wireguard/
-rw------- 1 root root 45 Mar 19 10:01 psk.key
-rw------- 1 root root 45 Mar 19 10:01 server_private.key
-rw------- 1 root root 45 Mar 19 10:01 server_public.key
三个文件都是600权限(仅所有者可读写)。私钥和预共享密钥绝不能离开服务器。
在你的本地机器(客户端)上生成自己的密钥对:
umask 077
wg genkey | tee client_private.key | wg pubkey > client_public.key
你需要把客户端的公钥放在服务器上,服务器的公钥放在客户端上。预共享密钥两边都需要。绝不传输私钥。
启用IP转发
服务器需要为VPN客户端路由流量。启用IPv4和IPv6转发:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-wireguard.conf
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
使用/etc/sysctl.d/中的文件优于直接编辑/etc/sysctl.conf。它能在软件包更新中保留,并清楚标明哪些设置属于哪个服务。
服务器配置文件
确认服务器的公网网络接口:
ip route show default
default via 203.0.113.1 dev eth0 proto static metric 100
此例中接口是eth0。你的可能是ens3、ens18或其他名称。使用dev后面显示的名称。
创建服务器配置:
sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.1/24, fd42:42:42::1/64
ListenPort = 51820
PrivateKey = <contents of /etc/wireguard/server_private.key>
PostUp = nft add table ip wireguard; nft add chain ip wireguard forward { type filter hook forward priority 0 \; policy accept \; }; nft add rule ip wireguard forward iifname "wg0" accept; nft add table ip nat; nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }; nft add rule ip nat postrouting oifname "eth0" masquerade
PostDown = nft delete table ip wireguard; nft delete table ip nat
[Peer]
PublicKey = <contents of client_public.key>
PresharedKey = <contents of /etc/wireguard/psk.key>
AllowedIPs = 10.66.66.2/32, fd42:42:42::2/128
将PostUp/PostDown行中的eth0替换为你的实际接口名称。
各节的作用:
Address:分配给此服务器的VPN IP。/24和/64定义VPN子网大小。ListenPort:WireGuard监听的UDP端口。51820是惯例。PostUp/PostDown:启用NAT伪装的nftables规则。当VPN客户端向互联网发送流量时,服务器将源IP重写为自己的公网IP。这是全隧道VPN的工作原理。[Peer]节中的AllowedIPs:此客户端可以使用的VPN IP。/32表示恰好一个IP。这防止客户端伪造其他VPN地址。
如果你使用ufw而非直接使用nftables,将PostUp/PostDown替换为:
PostUp = ufw route allow in on wg0 out on eth0; iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostDown = ufw route delete allow in on wg0 out on eth0; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
锁定配置文件权限。它包含你的私钥:
sudo chmod 600 /etc/wireguard/wg0.conf
开放防火墙并启动隧道
在防火墙中允许WireGuard的UDP端口:
sudo ufw allow 51820/udp
或直接使用nftables:
sudo nft add rule inet filter input udp dport 51820 accept
启动隧道。enable指令使其在重启后持续运行。--now标志立即启动:
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled; preset: enabled)
Active: active (exited) since ...
状态显示active (exited),因为wg-quick设置完接口后就退出了。内核模块从此接管隧道。检查运行中的隧道:
sudo wg show
interface: wg0
public key: aB3dEfGhIjKlMnOpQrStUvWxYz1234567890abc=
private key: (hidden)
listening port: 51820
peer: xY9zAbCdEfGhIjKlMnOpQrStUvWxYz1234567890=
preshared key: (hidden)
allowed ips: 10.66.66.2/32, fd42:42:42::2/128
输出中的(hidden)表示WireGuard在保护敏感密钥材料。如果你看到某个对等节点的latest handshake,说明该对等节点已成功连接。
客户端配置
在你的本地机器上创建WireGuard配置:
sudo nano /etc/wireguard/wg0.conf
[Interface]
Address = 10.66.66.2/24, fd42:42:42::2/64
PrivateKey = <contents of client_private.key>
DNS = 10.66.66.1
[Peer]
PublicKey = <contents of server_public.key>
PresharedKey = <contents of psk.key>
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = YOUR_SERVER_PUBLIC_IP:51820
PersistentKeepalive = 25
关键设置说明:
AllowedIPs = 0.0.0.0/0, ::/0将所有流量路由通过VPN(全隧道)。如果只想让VPN子网流量通过隧道(分割隧道),改为AllowedIPs = 10.66.66.0/24, fd42:42:42::/64。Endpoint是服务器的公网IP和端口。客户端需要它来发起连接。服务器不需要客户端的端点,因为它从传入数据包中获取。PersistentKeepalive = 25每25秒发送一个保活包。这维持NAT映射,使服务器能够到达客户端。没有它,连接会在NAT超时后断开(通常30-120秒无活动)。DNS = 10.66.66.1将DNS查询指向服务器的VPN地址。这防止DNS泄漏(下节详述)。
在macOS和Windows上,使用WireGuard应用。导入配置文件或粘贴内容。
从客户端连接:
sudo wg-quick up wg0
ping 10.66.66.1
PING 10.66.66.1 (10.66.66.1) 56(84) bytes of data.
64 bytes from 10.66.66.1: icmp_seq=1 ttl=64 time=4.23 ms
64 bytes from 10.66.66.1: icmp_seq=2 ttl=64 time=3.98 ms
从本地机器确认公网IP已变更(使用全隧道时):
curl -s https://ifconfig.me
应该返回VPS的公网IP,而非你的家庭IP。
添加更多客户端
每个额外客户端需要生成新的密钥对和新的预共享密钥(每对对等节点一个PSK)。在服务器的wg0.conf中添加[Peer]块:
[Peer]
PublicKey = <new client public key>
PresharedKey = <new preshared key>
AllowedIPs = 10.66.66.3/32, fd42:42:42::3/128
每个客户端递增IP地址。编辑后,在不断开现有连接的情况下重载:
sudo wg syncconf wg0 <(sudo wg-quick strip wg0)
这会应用新的对等配置而不重启接口。现有连接保持不变。
MTU调优
WireGuard每个数据包增加60字节开销(外层IPv4和UDP头28字节,WireGuard头32字节)。如果你的VPS标准MTU为1500字节,在[Interface]节中将WireGuard MTU设为1420:
MTU = 1420
服务器和客户端都要设置。MTU不匹配会导致数据包分片和吞吐量下降,且难以诊断。如果在已降低MTU的链路上运行WireGuard(PPPoE、VXLAN),相应减去即可。
如何防止WireGuard的DNS泄漏?
DNS泄漏发生在系统将DNS查询发送到VPN隧道外部时,向ISP或本地网络暴露你访问的域名。这使通过VPN路由流量的隐私优势失效。解决方案:在VPN服务器上运行本地DNS解析器,并将客户端的DNS通过隧道指向它。
在服务器上安装Unbound:
sudo apt install unbound -y
创建配置文件让Unbound监听WireGuard接口:
sudo nano /etc/unbound/unbound.conf.d/wireguard.conf
server:
interface: 10.66.66.1
interface: fd42:42:42::1
interface: 127.0.0.1
access-control: 10.66.66.0/24 allow
access-control: fd42:42:42::/64 allow
access-control: 127.0.0.0/8 allow
do-ip6: yes
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
use-caps-for-id: yes
prefetch: yes
hide-identity和hide-version指令阻止Unbound在DNS响应中披露软件版本。版本披露帮助攻击者针对已知漏洞。harden-*选项强制执行DNSSEC验证并防止缓存投毒。use-caps-for-id选项为DNS查询添加0x20编码,这是针对伪造响应的轻量级防御。
在Ubuntu 24.04上,systemd-resolved默认监听53端口,与Unbound冲突。禁用它:
sudo systemctl disable --now systemd-resolved
sudo rm /etc/resolv.conf
echo "nameserver 127.0.0.1" | sudo tee /etc/resolv.conf
启动Unbound:
sudo systemctl enable --now unbound
sudo systemctl status unbound
● unbound.service - Unbound DNS server
Loaded: loaded (/usr/lib/systemd/system/unbound.service; enabled; preset: enabled)
Active: active (running) since ...
测试Unbound是否从WireGuard接口解析:
dig @10.66.66.1 example.com +short
你应该能得到一个或多个IP地址。具体IP取决于域名当前的DNS记录。
客户端配置已设置DNS = 10.66.66.1。当WireGuard隧道活跃时,所有DNS查询通过加密隧道到达Unbound。没有查询泄漏给ISP。
在客户端确认,连接VPN后检查:
resolvectl status wg0
DNS服务器应只显示10.66.66.1。你也可以使用dnsleaktest.com。
| 测试项 | VPN前 | VPN后(使用Unbound) |
|---|---|---|
| 显示的DNS服务器 | ISP解析器(如192.168.1.1) | 10.66.66.1(VPS Unbound) |
| 测试站点看到的IP | 家庭/办公IP | VPS公网IP |
| ISP可见DNS查询 | 是 | 否 |
更深入的DNS安全内容包括DNSSEC和DNS-over-HTTPS,参见。
Kill switch:隧道断开时会怎样?
如果WireGuard隧道断开,流量通过默认路由以明文传输。你的真实IP和DNS查询暴露无遗。Kill switch通过在防火墙层面阻断所有非VPN流量来防止这种情况。
在客户端添加nftables规则,仅允许通过WireGuard接口的流量和到服务器端点的加密连接:
sudo nft add table inet killswitch
sudo nft add chain inet killswitch output { type filter hook output priority 0 \; policy drop \; }
sudo nft add rule inet killswitch output oifname "wg0" accept
sudo nft add rule inet killswitch output ip daddr YOUR_SERVER_PUBLIC_IP udp dport 51820 accept
sudo nft add rule inet killswitch output oifname "lo" accept
启用后,如果wg0断开,所有出站流量被丢弃。没有DNS泄漏,没有明文数据包。唯一允许的流量是到服务器的加密WireGuard握手。
移除kill switch以恢复正常路由:
sudo nft delete table inet killswitch
如需持久化的kill switch自动激活,将这些规则保存到文件中,并用一个在wg-quick@wg0之前启动的systemd服务来加载。
如何在Linux VPS上安装Tailscale?
Tailscale是基于WireGuard构建的Mesh VPN服务。它通过协调服务器处理密钥分发、NAT穿透和对等节点发现。你安装客户端,用身份提供商认证,设备之间就能互相访问。不需要手动密钥交换,不需要端口转发,不需要开放防火墙规则。
权衡点在于:Tailscale的协调服务器是第三方服务。它能看到你的设备元数据(IP、主机名、哪些设备在线),但看不到你的流量——流量通过WireGuard点对点传输。
如何在Ubuntu 24.04或Debian 12上安装Tailscale?
添加官方Tailscale仓库并安装软件包。这避免了curl | sh的方式,让你可以通过apt验证更新。
Ubuntu 24.04(Noble):
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/noble.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update && sudo apt-get install tailscale -y
Debian 12(Bookworm):
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.noarmor.gpg | sudo tee /usr/share/keyrings/tailscale-archive-keyring.gpg >/dev/null
curl -fsSL https://pkgs.tailscale.com/stable/debian/bookworm.tailscale-keyring.list | sudo tee /etc/apt/sources.list.d/tailscale.list
sudo apt-get update && sudo apt-get install tailscale -y
启动Tailscale并认证:
sudo tailscale up
这会输出一个认证URL。在浏览器中打开它,用你的身份提供商(Google、Microsoft、GitHub等)登录。认证完成后,VPS加入你的tailnet。
sudo systemctl status tailscaled
● tailscaled.service - Tailscale node agent
Loaded: loaded (/usr/lib/systemd/system/tailscaled.service; enabled; preset: enabled)
Active: active (running) since ...
查看分配的Tailscale IP:
tailscale ip -4
100.64.0.1
tailnet中的每台设备都会获得一个稳定的100.x.x.x(CGNAT范围)地址。此IP在重启和重连后持续有效。用它从同一tailnet的任何其他设备访问你的VPS。
检查与其他设备的连通性:
tailscale status
100.64.0.1 vps-frankfurt youruser@ linux -
100.64.0.2 laptop youruser@ macOS active; direct 203.0.113.50:41641
direct标识表示流量通过WireGuard点对点传输。如果显示relay,流量经过DERP中继服务器,会增加延迟。当两个对等节点都在限制性NAT后面无法直连时,会发生DERP中继。
禁用服务器的密钥过期
Tailscale密钥默认180天过期。密钥过期后,设备离线直到有人重新认证。对于必须保持连接的VPS,你有两个选择。
选项1:在管理控制台禁用过期。 前往Machines页面,找到你的VPS,点击菜单,选择"Disable key expiry"。
选项2(推荐):使用带标签的认证密钥。 带标签的设备自动禁用密钥过期。在管理控制台的Settings > Keys中生成可复用的带标签认证密钥,然后加入:
sudo tailscale up --auth-key=tskey-auth-XXXXX --advertise-tags=tag:server
标签也适用于ACL(下文介绍),使其成为服务器基础设施的更好选择。
如何在VPS上配置Tailscale出口节点?
出口节点(exit node)将你所有设备的互联网流量路由通过VPS。你的出站流量看起来源自VPS的IP地址。这就像传统VPN:加密一切,从VPS所在位置出去。
在VPS上启用IP转发:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
将VPS声明为出口节点:
sudo tailscale set --advertise-exit-node
在管理控制台批准出口节点。找到VPS,点击菜单,进入"Edit route settings",启用"Use as exit node"。
从客户端设备开始使用出口节点:
sudo tailscale set --exit-node=<vps-tailscale-ip>
保持本地局域网访问(打印机、NAS、其他本地设备),同时通过出口节点路由互联网流量:
sudo tailscale set --exit-node=<vps-tailscale-ip> --exit-node-allow-lan-access=true
停止通过出口节点路由:
sudo tailscale set --exit-node=
从客户端检查公网IP以确认出口节点工作正常:
curl -s https://ifconfig.me
应返回VPS的公网IP。
子网路由
子网路由将VPS后面的私有网络暴露给tailnet。当VPS能访问私有数据库子网或未运行Tailscale的内部服务时很有用。
sudo tailscale set --advertise-routes=192.168.1.0/24
在管理控制台中按照批准出口节点的方式批准路由。批准后,所有tailnet设备可以通过VPS作为网关访问192.168.1.0/24,无需在该子网的每台主机上安装Tailscale。
可以用逗号分隔声明多个路由:
sudo tailscale set --advertise-routes=192.168.1.0/24,10.0.0.0/16
对于并发流量大的子网路由器,Tailscale建议使用内核模式(仅限Linux)而非用户空间模式。Linux上默认就是内核模式。检查:
tailscale debug prefs | grep RouteAll
如何设置Tailscale ACL来控制VPS访问?
默认情况下,tailnet中的所有设备可以在所有端口互相访问。生产环境中,应通过tailnet策略文件中的ACL加以限制。
限制VPS访问仅限管理员组的最小策略:
{
"groups": {
"group:admins": ["alice@example.com", "bob@example.com"]
},
"tagOwners": {
"tag:server": ["group:admins"]
},
"acls": [
{
"action": "accept",
"src": ["group:admins"],
"dst": ["tag:server:*"]
}
]
}
含义是:只有group:admins的成员可以访问标记为tag:server的设备。所有其他连接默认拒绝。在管理控制台的Access Controls中编辑。
加入tailnet时为VPS打标签:
sudo tailscale up --advertise-tags=tag:server
更细粒度的策略可以按端口限制:
{
"groups": {
"group:admins": ["alice@example.com"],
"group:developers": ["bob@example.com", "charlie@example.com"]
},
"tagOwners": {
"tag:server": ["group:admins"]
},
"acls": [
{
"action": "accept",
"src": ["group:admins"],
"dst": ["tag:server:*"]
},
{
"action": "accept",
"src": ["group:developers"],
"dst": ["tag:server:22,80,443"]
}
]
}
开发者获得SSH(22)和Web(80、443)访问。管理员获得完全访问。其他人无法访问服务器。Tailscale在客户端级别执行这些规则,流量在到达服务器之前就被阻断。
MagicDNS
Tailscale包含MagicDNS,为每台设备提供可在tailnet内解析的主机名。不用记100.64.0.1,直接SSH到vps-frankfurt。在管理控制台的DNS设置中启用。不需要Unbound或手动DNS配置。
什么是Headscale?何时该使用它?
Headscale是Tailscale协调服务器的开源自托管实现。它使用标准Tailscale客户端,但在你自己的基础设施上运行控制平面。没有设备限制,没有遥测,不依赖Tailscale的SaaS。兼容所有官方Tailscale客户端(Linux、macOS、Windows、iOS、Android)。
架构:
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ 客户端 A │──────▶│ Headscale │◀──────│ 客户端 B │
│ (tailscale) │ │ (你的服务器) │ │ (tailscale) │
└──────┬───────┘ └──────────────────┘ └──────┬───────┘
│ │
└────────────── WireGuard隧道 ─────────────────────┘
(直连,点对点)
Headscale处理密钥交换、设备注册和ACL执行。实际VPN流量通过WireGuard在对等节点间直接传输。Headscale永远看不到你的数据流量,只有协调元数据。
Headscale目前支持: 设备注册(CLI和OIDC)、ACL、子网路由器、出口节点、MagicDNS、预授权密钥和标签。涵盖了Tailscale的核心功能集。
不支持的: Tailscale Funnel、Serve、网络流日志和一些beta功能。管理界面仅限命令行。社区构建的Web UI存在(headscale-ui),但未覆盖所有功能。
Headscale适用的场景:
- 法规禁止第三方协调服务器。Tailscale的SaaS可能需要GDPR数据处理协议。Headscale消除了这一依赖。
- 你需要超过Tailscale免费套餐允许的设备数量。
- 你需要对设备注册和密钥管理拥有完全的审计控制。
- 你构建的基础设施中,依赖外部SaaS是单点故障。
不适用的场景:
- 你需要Tailscale的全球DERP中继网络来实现可靠的NAT穿透。Headscale可以使用DERP,但你需要运行自己的中继或接受使用Tailscale的公共中继。
- 你想要精美的管理界面。Headscale以命令行为主。
- 你的团队很小,不想再维护一个服务。
Headscale的完整搭建教程计划在后续文章中发布。目前请参阅Headscale文档。
WireGuard vs Tailscale vs Headscale:哪个适合你?
需要完全控制、最小延迟、气隙网络或禁止第三方协调服务器的合规要求时,使用WireGuard。管理多台设备、需要无端口转发的NAT穿透或想要无需手动配置的ACL时,使用Tailscale。想要Tailscale功能但自托管控制的团队,考虑Headscale。
| 维度 | WireGuard | Tailscale | Headscale |
|---|---|---|---|
| 安装时间 | 每个对等节点10-15分钟 | 每台设备2分钟 | 30-60分钟(服务器+客户端) |
| 密钥管理 | 手动(自行生成、分发、轮换) | 自动(协调服务器处理) | 自动(你的协调服务器) |
| NAT穿透 | 无。至少一端需要端口转发或公网IP | 内置(DERP中继+STUN) | 部分(自建DERP或使用公共中继) |
| 对等节点发现 | 手动配置每个对等节点 | 自动Mesh | 自动Mesh |
| ACL | 防火墙规则(nftables/iptables) | 管理控制台中的策略文件 | 你服务器上的策略文件 |
| 最大设备数 | 无限 | 免费套餐有限制(见定价页面) | 无限 |
| 多云Mesh | 每个节点都要配置,N*(N-1)/2个对等条目 | 加入tailnet,Mesh自动形成 | 同Tailscale,自托管控制 |
| 第三方依赖 | 无 | Tailscale Inc.(仅协调) | 无 |
| GDPR/合规 | 完全控制,无第三方数据处理者 | Tailscale处理设备元数据 | 完全控制 |
| DNS | 手动(Unbound等) | MagicDNS(自动,每设备主机名) | MagicDNS(需配置) |
| 延迟 | 最小(内核级WireGuard) | 直连时最小;DERP中继时+20-50ms | 同Tailscale |
| 团队接入 | 手动分享配置文件和密钥 | 发送邀请链接,SSO登录 | 通过CLI或OIDC注册 |
| 后量子防御 | PreSharedKey(手动设置) | 用户不可配置 | 用户不可配置 |
快速决策
独立开发者,一台VPS: WireGuard。最简单的路径。零依赖。尽可能低的延迟。生成两个密钥,写两个配置文件。
3-15人团队,多台设备: Tailscale。协调服务器省去数小时的密钥管理。ACL比维护每个对等节点的nftables规则更清晰。NAT穿透无需网络变更即可工作。
受监管环境或自托管要求: 如果想要Tailscale的用户体验而不依赖第三方,选Headscale。如果想要零活动部件且团队能管理配置,选原始WireGuard。
多云Mesh(5+节点,跨提供商): Tailscale或Headscale。使用WireGuard时,10个节点总共需要45个对等条目。20个节点则是190个。配置管理开销呈二次方增长。
AI推理端点访问: 从笔记本通过隧道连接GPU VPS,两者都可以。Tailscale配置更快。WireGuard对延迟敏感的推理调用不增加可测量的开销。跨提供商的多GPU设置,Tailscale的Mesh值得权衡。
故障排除
WireGuard隧道已启动但没有流量:
检查IP转发:
sysctl net.ipv4.ip_forward
应返回net.ipv4.ip_forward = 1。检查masquerade规则是否已加载:
sudo nft list ruleset | grep masquerade
如果为空,PostUp规则未执行。用sudo systemctl restart wg-quick@wg0重启,并查看journalctl -u wg-quick@wg0中的错误。
WireGuard握手始终无法完成:
sudo wg show
如果某个对等节点始终不出现latest handshake,UDP端口51820在某处被阻断。确认服务器在监听:
sudo ss -ulnp | grep 51820
UNCONN 0 0 0.0.0.0:51820 0.0.0.0:*
WireGuard直接使用内核模块,所以ss可能不会为该socket显示进程名。
然后从客户端测试。如果客户端在企业防火墙后面,UDP 51820可能被阻断。某些网络只允许TCP 443。
Tailscale在管理控制台显示"offline":
sudo systemctl status tailscaled
如果服务在运行但显示离线,重新认证:
sudo tailscale up --force-reauth
如果tailscaled未运行,检查是否与其他VPN软件存在端口冲突。
安装Unbound后DNS仍然泄漏:
检查Unbound是否在WireGuard IP上监听:
ss -ulnp | grep :53
在输出中查找10.66.66.1:53。如果Unbound只绑定到127.0.0.1,重新检查/etc/unbound/unbound.conf.d/wireguard.conf中的interface:行。
在Ubuntu上,还要确认systemd-resolved确实已停止:
sudo systemctl is-active systemd-resolved
如果返回active,它在与Unbound争抢53端口。
服务日志:
journalctl -u wg-quick@wg0 -f
journalctl -u tailscaled -f
journalctl -u unbound -f
版权所有 2026 Virtua.Cloud。保留所有权利。 本内容为 Virtua.Cloud 团队原创作品。 未经书面许可,禁止复制、转载或再分发。