关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

2026 服务器租用跨机房组网怎么做?WireGuard 的 MTU 与 NAT 穿透实测对比 + 避雷手册

发布时间:2026-09-29

2026 服务器租用跨机房组网怎么做?WireGuard 的 MTU 与 NAT 穿透实测对比 + 避雷手册

开篇:能 ping 通不代表能用,这是 WireGuard 最常见的假象

干运维这些年,跨机房组网这件事上我见过最多的翻车现场,从来不是加密被破解,也不是带宽买小了,而是"能 ping 通就以为万事大吉"。前阵子一个客户的工单很典型:两台分布在两个机房的服务器之间拉了 WireGuard 隧道,ping 通、SSH 能登、curl 个小接口也正常,但 scp 传一个两百多兆的包必定卡在某个百分比不动,数据库主从同步断断续续,rsync 跑一半就超时。他第一反应是"机房之间的网络有问题",让机房查链路,查了两天没结果。

我登上去第一行命令就是 wg show,latest handshake 有时间戳、transfer 收发的字节数也都在涨,看着一切正常。再跑一句 ping -M do -s 1472,直接不通,逐档往下调到 1392 才通。MTU 没算对,典型的路径 MTU 黑洞。改一行配置,两分钟解决。

说白了,WireGuard 这东西本身极难配错——它没有算法协商、没有证书体系、配置文件就那么十几行。真正让人掉坑的,全是配置之外的三件小事:MTU 算错、保活没配、AllowedIPs 写重叠。这篇就把这三件事连同它们的排查手法一次讲透,顺便说清楚多机房互联到底该怎么选机器。

先给五条能直接抄走的结论:

  • 加密强度几乎从来不是 WireGuard 出问题的地方。它只有一套密码套件(Noise_IKpsk2 握手 + Curve25519 + ChaCha20-Poly1305 + BLAKE2s),不给你选,也就没什么可配错的。
  • MTU 必须自己算、自己写。WireGuard 不做路径 MTU 自动探测,不指定就用默认的 1420;物理口不是 1500 或者套了第二层封装时,这个默认值就是坑。
  • "小包通、大包死"是 PMTU 黑洞的典型长相:ping 通、SSH 能连,但 HTTPS 大文件下载卡住、scp 传一半停、数据库同步失败。根因多半是 ICMP 不可达被防火墙丢了。
  • Peer 在 NAT 后面时,PersistentKeepalive 不是可选项,是穿透的命门。不配它,结果就是单向可达——那边连得过来,你连不过去。
  • AllowedIPs 既是路由表又是 ACL,两侧要对称写;同一台机器上多个 Peer 的 AllowedIPs 一旦重叠,WireGuard 按最长前缀挑一个,另一个 Peer 永远走不到。

WireGuard 在三层跑 UDP,这套密码套件不给你选

一套密码套件,不许协商,这反而是优点

先说清楚 WireGuard 到底是个什么东西,后面所有奇怪的行为都跟它的设计选择有关。WireGuard 用的是 Noise 协议框架里的一个具体握手模式 Noise_IKpsk2,密钥交换固定 Curve25519,对称加密固定 ChaCha20-Poly1305,哈希固定 BLAKE2s。注意"固定"这两个字——它没有任何算法协商环节,不会出现两端因为配置不一致而降级到某个弱算法的情况。作者把这种设计叫 cryptographic opinionatedness,说白了就是:我不给你选,我替你选好,你只用管密钥和地址。

带来的直接好处是代码量极小,内核模块在数千行的量级(以官方代码库为准),一台机器上跑起来资源占用很轻,审计和定位问题都容易。对运维来说这意味着一件事:你几乎不可能把"加密"这部分配错,能配错的全是加密之外的地方。

三层、UDP、无连接:这三个词决定了排障方式

WireGuard 工作在三层,也就是 IP 层。它没有 MAC 地址、不学 ARP、不做二层 bridging,接口起来之后表现得像一块点对多点的三层网卡。如果你的业务真要传二层帧(比如某些老集群的心跳、某些需要广播发现的中间件),那就得在 WireGuard 之上再套一层 VXLAN 或者 GRE。提醒一句:每多套一层封装,MTU 就要再往下压,这是很多人第二次踩坑的地方。

它跑在 UDP 上,一个 ListenPort(默认常用 51820)收所有 Peer 的流量。而且它是无连接的——没有"已连接/已断开"的状态机,只有握手计时器。这跟 IPsec、OpenVPN 那种"隧道起来就是起来"的手感完全不同:WireGuard 的接口可以 up 着、路由也在表里,但对端其实根本没握手成功,你看到的现象就是"配好了但不通"。

所以排障的抓手必须是状态而不是接口:wg show 里的 latest handshake 有没有时间戳、transfer 收发字节有没有在涨、endpoint 是不是你预期的那个公网地址。这三个不看,等于闭着眼睛查。

CPU 开销:老机器上 WireGuard 未必吃亏

加密是要吃 CPU 的,这点绕不过去。ChaCha20 是纯软件实现友好的算法,在没有 AES-NI 指令集的老 CPU 上,它反而比 AES-GCM 跑得快;而现代 CPU 普遍带 AES-NI,走 IPsec 的那套硬件加速在纯吞吐上可能更占优(具体差距以实测为准,别信任何拍脑袋的百分比)。

这个结论对租服务器有实际意义:如果你手里是一批 E5 时代的老机器做跨机房互联,上 WireGuard 完全不必担心加密拖后腿;反过来,新机器上也别指望它比内核态 IPsec 更快。选型时真正该关心的不是"哪个加密更快",而是"这台机器有没有足够的单核性能扛住你那条链路的峰值小包速率"——UDP 小包转发吃的是单核软中断,核太弱就是瓶颈。

MTU 到底少了多少字节:IPv4 是 32,IPv6 是 80

封装开销的账要自己算

WireGuard 干的活是:把你原来的那个完整 IP 包(IP 头 + 载荷)整个加密,再在外面套上 WireGuard 自己的头,最后再套一层外层 IP 头 + UDP 头发出去。所以经过隧道的包一定比原包大,多出来的这部分就是开销。官方论文与白皮书给出的数字是:IPv4 承载时开销约 32 字节,IPv6 承载时约 80 字节(外层 IPv6 头本身就比 IPv4 头长不少)。

那么 WireGuard 接口的 MTU 该怎么定?工程上的算法是:接口 MTU = 物理口 MTU − 封装开销 − 安全余量。物理口 1500 的标准以太网场景下,IPv4 承载按 32 字节算理论上限能到 1468,但实际工程里统一取 1420——这也是 WireGuard 不指定 MTU 时的默认值,它留了几十字节余量,兼容 IPv6 承载、兼容你后面可能再加的封装。IPv6 承载时开销更大,一般把接口 MTU 压到 1380,保守起见直接用 1280(IPv6 规定的最小 MTU)也完全能跑,代价是分片多一点。以上数值请以你自己环境的实测为准。

配置就一行,写在 [Interface] 段里:

MTU = 1420

一张换算对照表,配之前照着查

承载场景 封装构成 封装开销 建议接口 MTU 配错的症状 验证命令
IPv4 承载,物理口 1500 外层 IPv4 头 + UDP 头 + WireGuard 头与认证标签 约 32 字节(论文口径) 1420(默认值,留余量) ping 通、大文件传输卡死 ping -M do -s 1392
IPv6 承载,物理口 1500 外层 IPv6 头 + UDP 头 + WireGuard 头与认证标签 约 80 字节(论文口径) 1380,保守取 1280 IPv6 站点间歇性超时 tracepath -6 目标地址
WireGuard 之上再套 VXLAN/GRE 再加一层隧道头,开销叠加 在 32/80 基础上再加数十字节 1280 起试,逐档上调 二层心跳丢、集群脑裂 ping -M do -s 逐档二分
物理口本身不是 1500(PPPoE、云网卡、巨帧) 先确认物理口真实 MTU 再减 以 ip link 查到的值为准 物理口 MTU − 80 起试 照抄 1420 仍不通 ip link show 物理口
未指定 MTU WireGuard 不做路径 MTU 探测 取默认 1420 标准以太网够用,其余场景要手改 换个机房就不通 wg showconf wg0

两个容易忽略的前提

第一,物理口 MTU 不一定就是 1500。拨号链路常见 1492,部分云主机的网卡是 1450 或者开了巨帧的 9000,机房内部如果走了某些封装,物理口有效 MTU 还会更小。上来就写 1420,等于假设了物理口 1500 这一个前提,前提不成立,配置就是错的。查真实值用 ip link show 看物理口那一行。

第二,WireGuard 不会帮你探测。它不像 TCP 那样有 MSS 协商兜底,也不会自动做 PMTU 发现并把结果写回接口。你写多少就是多少,写大了就等着出黑洞。这个"不智能"是设计选择,代价转嫁给了配置的人。

「小包通、大包死」:PMTU 黑洞长什么样

机制:PMTUD 依赖 ICMP,ICMP 又最容易被丢

路径 MTU 发现(PMTUD)的机制本身很朴素:发送方把 IP 包的不分片标志(DF 位)置上,中间任何一台设备发现这个包比自己出口的 MTU 大,就丢掉它,同时回一个 ICMP"需要分片"的差错报文,告诉发送方"你下次发小点"。发送方收到后降低自己的包长,重传,链路就自适应了。

问题出在那个 ICMP 上。很多机房的边界防火墙、很多主机的安全组、很多运维自己写的 iptables 规则,为了省事或者为了防攻击,把 ICMP 一刀切全丢了。ICMP 一丢,发送方永远等不到"你发小点"这句话,只能不停重传那个永远过不去的大包,直到超时。这就是 PMTU 黑洞——链路是通的,大包死在里面,而且从业务日志上看不出任何原因。

对号入座:这些症状基本都是它

  • ping 通,但大文件传不动。ping 默认只发几十字节的载荷,小包当然通;换成 ping -s 1400 立刻不通,这就是实锤。
  • SSH 能连,但 scp / sftp 传一半卡住。SSH 登录是交互式小包,传输文件才跑满窗口,大包一堵,TCP 就一直在重传。
  • 网页能打开首页,图片和资源加载一半。TLS 记录可以大到十几 KB,一个 record 封装出去超过路径 MTU,就会卡在握手之后的第一个大数据块上。
  • 数据库主从复制、rsync、对象存储同步间歇性失败。这类业务是大块顺序传输,最容易撞上,而且报错经常是"连接超时"这种误导性信息。
  • 换个机房就出问题。同机房内网可能开巨帧或者走二层,MTU 够大;一出公网、一跨机房就暴露。

两个处理方向

正解是把 MTU 配对:接口 MTU 压到真实路径能承载的值,让包在进入隧道前就被分片或者被 TCP 按更小的 MSS 发出去。改完立刻用带 DF 位的大包验证,别只看 ping 通不通。

临时兜底还有一招,就是 TCP MSS clamp——在防火墙上把经过隧道的 TCP 握手的 MSS 值强行改小,让两端协商出一个更小的数据段。这是治标,改完大文件能传了,但 UDP 业务照样死,而且会掩盖真正的问题。我一般只在客户急着恢复业务时临时用一次,回头还是要把 MTU 改对。

用 DF 位 ping 把真实 MTU 试出来

二分逼近,别一格一格试

排查 PMTU 最直接的办法,就是自己发带 DF 位、指定大小的包,看它在哪一档断掉。Linux 上的写法是:

ping -M do -s 1472 对端内网地址

这里的 1472 是 ICMP 载荷长度,加上 8 字节 ICMP 头、20 字节 IP 头,正好 1500。-M do 就是"禁止分片",等价于把 DF 位置 1。通了说明这个尺寸过得去,不通(或者报 "Frag needed and DF set")说明超了。

别从 1472 一格一格往下减,太慢。直接二分:1472 不通就试 1200,通了试 1350,再试 1420……三四次就能锁到边界。测出来的 PMTU 减去 WireGuard 的封装开销(IPv4 场景按 32 字节、IPv6 按 80 字节算,再加一点余量),就是你该填的接口 MTU。

还有一种更省事的工具:tracepath 目标地址,它会自己逐跳把路径 MTU 报出来,IPv6 用 tracepath -6。注意 tracepath 走的是 UDP,如果你的防火墙把 UDP 也拦了,它的结果会偏乐观,还是以 ping 的结果为准。

测的时候注意三件事

第一,测的目标地址要用 WireGuard 内网地址,不是对端的公网地址——你要测的是隧道内部这条路径,不是隧道外的公网路径。第二,两端都要测一遍,因为路径是非对称的,去程和回程的 MTU 不一定相同。第三,Windows 上的写法不一样,是 ping -f -l 1472 目标,-f 对应 DF,-l 对应载荷长度,别照抄 Linux 的参数。

测完之后把结果写进配置文件,重启接口,然后再跑一遍大包确认。多机房场景下,我建议每拉通一条新链路就做一次这个测试,把结果记到你们的拓扑文档里——否则半年后加机器,谁也不记得当初为什么是 1380。

PersistentKeepalive 不是可选项,是穿透的命门

WireGuard 不会帮你打洞

先把这件事说死:WireGuard 本身不做任何打洞协商,没有 STUN、没有 TURN、没有信令服务器。它的模型极简——两端各自写一段 [Peer],谁先发包谁就去握手。所谓"穿透",完全是蹭 NAT 设备自己的行为:内网机器主动往外发一个 UDP 包,NAT 就在自己的会话表里记一条映射,外面回来的包才能顺着这条映射进来。这条映射是有老化时间的,几十秒到几分钟不等,各家设备不一样(以实测为准),一段时间没流量就被清掉。

映射一清,对端再发包过来就进不来了。而 WireGuard 是无连接的,它不会主动去维持这条映射——除非你告诉它要维持。

PersistentKeepalive = 25 这一行的作用

告诉它的方式就是在 [Peer] 段里加一行:

PersistentKeepalive = 25

意思是:每 25 秒给这个 Peer 发一个保活包,不管有没有业务流量。包极小,就是一个握手包或者一个空载荷的数据包,开销可以忽略(每分钟一两个包这个量级,具体以实测为准)。但它足够让 NAT 会话表一直续着,洞一直在,对端随时能连进来。

为什么是 25 秒?因为它要小于绝大多数 NAT 设备的会话老化时间,常见的老化在 30 秒到几分钟这个量级,取 25 是保守但通用的做法。如果你确定对方的 NAT 老化时间更长,调到 60 也行,但没必要去赌——保活包的成本远低于排查一次"为什么连不上"的成本。真要省这点流量,也别省在关键链路上。

该给谁配,配错了有什么后果

规则很简单:被 NAT 挡在后面的那一侧配,有固定公网地址的那一侧可以不配。公网侧配了也不出错,只是多一点点无谓的心跳。两侧都在 NAT 后面呢?那一侧都配上,谁先起谁先握手,洞就开了。

不配的后果非常有辨识度,就是"单向可达":站在 NAT 后面的机器主动连公网那台,一握手就通;但公网那台想主动连回来,永远超时。更迷惑的是,只要内网那台刚连过一次、NAT 映射还没老化,公网侧就能连上,过一会儿又断了。这种"时好时坏"的现象,十次有九次是保活没配。判断方法也简单:wg show 里看 latest handshake 的时间戳,如果它长时间不更新,而你对端明明在线,那就是握手包根本发不出去或者收不到。

另外提醒一句移动场景和按流量计费的场景:保活包是持续产生的,量很小但从不停止。按月租的机房服务器完全不用在意,按流量计费的边缘节点心里要有个数。

Endpoint 该怎么填:一侧有公网和两侧都在 NAT 后

一侧有公网 IP:只在这一侧不配,另一侧写死

Endpoint 字段的语义是"我该往哪个公网地址:端口发包"。所以逻辑很直接:谁有固定公网地址,谁就不用填 Endpoint(它等着别人来连就行),对端在 [Peer] 里把它的公网地址和 ListenPort 写死。

写法是 Endpoint = 203.0.113.10:51820 这样,IP 或者域名都行。这一侧的 ListenPort 要在防火墙、安全组、机房的 ACL 里放行 UDP——注意是 UDP,很多人习惯性只放了 TCP,然后对着一个"永远握手不成功"的状态查半天。机房侧如果线路本身对 UDP 有限制策略,下单前就要问清楚,别等上架了才发现。

两侧都在 NAT 后面:必须有一个中转点

如果两个节点都没有公网可达的 UDP 地址,WireGuard 自己解决不了这个问题——它没有任何第三方帮你做打洞和转发。这时候只有一条路:找一台有公网地址的机器当中转(hub),两侧都跟它建隧道,流量走它转发。这也是为什么跨机房组网里,"机房有没有公网 IP、给不给单独公网地址"会直接决定你的拓扑能不能落地,租机器的时候这是要提前确认的硬指标。

中转点的位置也有讲究。它应该在网络位置上离两端都不远,最好本身就在骨干节点上,否则你只是把延迟从一个地方挪到另一个地方。对延迟敏感的业务,先把候选机房的测试 IP 要过来,自己跑几天 ping 和 mtr 再定,别看宣传词下单。

地址会变怎么办:roaming 和重解析

WireGuard 有个很实用的特性叫 cryptokey routing 的漫游(roaming):只要收到对端一个合法的数据包,它就会把该 Peer 的 endpoint 更新成这个包的来源地址。所以对端是动态 IP、或者发生了主备切换,只要对端能主动发包过来,你这边的 endpoint 会自动跟着变,不需要人工干预。wg show 里显示的 endpoint 就是当前实际生效的那个地址,跟配置文件里写的不一样是完全正常的。

但要记住一个坑:Endpoint 填域名时,解析只发生在配置加载那一刻(wg set 或 wg-quick up)。之后域名指向的 IP 变了,WireGuard 不会自己去重新解析。所以动态 IP 环境要么靠对端主动握手来触发 roaming,要么自己写个定时任务配合 DDNS 重新解析并 wg set 更新,别指望它自动跟踪域名。

AllowedIPs 同时是路由表和 ACL,这是最容易配错的地方

同一字段,两个方向,两种语义

AllowedIPs 是 WireGuard 里最反直觉的一个字段,因为它在本机和对端上表达的是完全不同的意思。

在本机的 [Peer] 段里,它是路由表:意思是"目的地址属于这些网段的包,交给这个 Peer 发"。wg-quick up 时会把这些网段写进系统路由表(除非你关掉)。

在对端的 [Peer] 段里(对端配置里指向你的那一段),它是ACL:意思是"从这个 Peer 进来的包,只有源地址落在这些网段里我才收,否则直接丢"。这一层是校验,不写就不通。

所以两边必须对称写。举个最常见的错:你这侧写了 AllowedIPs = 10.0.0.0/8,表示去 10 段都走这条隧道;对端那侧却只写了 AllowedIPs = 10.7.0.2/32,只认你一个地址。那么你从本机另一个地址(比如 10.7.0.3)发出的包到了对端会被直接丢弃,而且本机这侧看不出任何异常——包发出去了,transfer 的 tx 也在涨,但对端 rx 不动,或者干脆不计。这种"发出去没回音"的故障,一半以上出在这里。

0.0.0.0/0 的连锁反应和 Table=off

把 AllowedIPs 写成 0.0.0.0/0 表示"所有流量都走这个 Peer",也就是拿 WireGuard 当默认网关用。这在把服务器流量全收到某个出口节点的场景下很合理,但副作用不小:wg-quick 会检测到你用了 0.0.0.0/0,为了防止路由环路,它会额外加路由规则(走单独的路由表 + fwmark),结果是你的其他路由策略可能被绕过,多 Peer 时更容易互相打架。

如果你只想借 WireGuard 打通内网、不想让它接管默认路由,就在 [Interface] 里加一行 Table = off。加了之后 wg-quick 不再自动写任何路由,路由完全你自己用 ip route add 或者路由守护进程管。多机房、多 Peer、还要跑 BGP 或 OSPF 的场景,我基本都建议开 Table = off——控制权留在自己手里,出问题好查。

热更新用 syncconf,别动不动 down 掉

改 Peer 配置时,很多人习惯 wg-quick down && wg-quick up,这会短暂中断所有经过这条隧道的业务。更稳的做法是写好新配置后用 wg syncconf wg0 <(wg-quick strip wg0),它只做增量更新,已有的会话不受影响。看当前实际生效的配置用 wg showconf wg0——注意它输出的是运行态配置,和你配置文件里的写法可能有细微差异(比如域名被解析成了 IP),这是正常的。

多 Peer 的网段重叠:配了却永远走不到

最长前缀匹配,剩下的那个就是死路

一台机器上可以同时有多个 Peer,但 WireGuard 选 Peer 的方式是最长前缀匹配:一个包的目的地址同时命中多个 Peer 的 AllowedIPs 时,掩码最长的那个胜出,其他的不参与。如果两个 Peer 的 AllowedIPs 完全一样或者包含关系写反了,那么只有一个 Peer 能拿到流量,另一个 Peer 的配置看着完整、握手也正常、但永远不会有业务流量走它——这就是"配了通不了"和"通了但走错路"的根源。

举个实际例子:Peer A 的 AllowedIPs 是 10.0.0.0/8(覆盖 A 机房整个内网),Peer B 是 10.10.0.0/16(B 机房某一段)。那么去 10.10.1.5 的包会走 Peer B,去 10.20.1.5 的走 Peer A,没问题。但如果你后来把 Peer B 也写成了 10.0.0.0/8,两个 Peer 等长,结果就取决于实现的挑选顺序,你的 B 机房可能整段失联,而且现象是"时通时不通",极其难查。

唯一的解法是提前规划网段

这问题没有配置技巧可以绕,只能靠规划。多机房互联的第一件事不是装软件,而是画一张网段分配表:每个机房(或者每个节点)拿一段独立的、不重叠的地址,WireGuard 隧道本身再拿一段独立的 /24 或者更长前缀的地址专门给接口用。表画完,所有机器的 AllowedIPs 都按这张表写,之后加机器就照表续。

现实里最麻烦的是"先有服务器、后有组网"——各个机房的内网网段当初是各配各的,早就撞车了。这种情况下要么做一次地址重规划(痛苦但一劳永逸),要么在网关层做地址转换,把重叠段映射成不重叠的段再进隧道。后者能应急,但排障复杂度上一个台阶,我一般只在没法改地址的时候用。

需要同一段走多个出口时怎么办

真遇到"同一个目的段,不同来源要走不同 Peer"这种需求(比如按业务分流),AllowedIPs 这层就管不了了,得往下沉到策略路由:用 Table = off 关掉自动路由,然后自己配 ip rule + 多张路由表,按源地址或者 fwmark 分流。这一步已经超出 WireGuard 本身的范畴,是 Linux 路由的基本功,配之前先把 ip rule 的输出看明白。

wg show 三行输出教你读:握手、流量、端点

先盯这三个字段

wg show(或者 wg show wg0)的输出里,每个 Peer 有几行,真正决定成败的只有三行。

  • latest handshake:最近一次握手成功的时间。有时间戳、且在合理范围内更新(配了保活的话应该持续刷新),说明双向握手通了。如果是 "No handshake" 或者几十分钟前的时间戳,别往下查了,先解决握手——端口没放行、Endpoint 写错、密钥对错了、对端根本没起来,都停在这一步。
  • transfer:这个 Peer 收了多少字节、发了多少字节。关键不是绝对数值,是它在不在涨。过几秒再执行一次,rx 和 tx 都应该动。只有 tx 涨 rx 不动,说明你的包发出去了但对方的回包没回来(或者被对方 ACL 丢了);只有 rx 涨 tx 不动,说明对方在找你但你这边的回应没出去。
  • endpoint:当前实际使用的对端公网地址:端口。这里是判断 roaming 和 NAT 行为的唯一依据——你填的是域名,这里会显示解析后的 IP;对端 IP 变了,这里会跟着变。如果这里显示的端口和你预期的差很多,多半是中间有 NAT 做了地址转换,那 PersistentKeepalive 就必须配上。

另外两行顺手也看:allowed ips 确认生效的网段是不是你写的那些(改配置后有没有真的应用),persistent keepalive 确认保活是不是配上了(显示 "off" 就是没配)。

路由和包这两个维度也要验

握手通了、流量也涨了,业务还是不通,那问题多半在路由或者 MTU 上。路由这层用 ip route get 目标地址,它会直接告诉你这个包会走哪个接口、从哪个地址出去——比肉眼看 ip route 那张表直观得多。期望走 wg0 却走了 eth0,那就是 AllowedIPs 或者路由优先级的问题。

再往下就是抓包:tcpdump -ni eth0 udp port 51820 看物理口上有没有 UDP 包进出,tcpdump -ni wg0 看隧道内部有没有明文业务包。两边对照着看,能立刻区分"包根本没发出去"、"发出去没加密"、"加密了但没到"这几种情况。抓包时注意:wg0 上看到的是解密后的明文,如果 wg0 上能看到请求但看不到响应,问题在对端回程;两边都没有,问题在发出侧。

一条固定的排查顺序

我自己用的顺序是这样的,从下往上走,每一步都能排除一大片可能:先 ip link 确认接口起来了、物理口 MTU 是多少;再 wg show 看握手和流量;握手不通就 tcpdump 物理口看 UDP 有没有进出,同时确认防火墙和安全组;握手通了业务不通就 ip route get 验路由;路由对了还不行,就用 DF 位 ping 测 MTU。五步走完,WireGuard 的故障基本都能定位到具体那一行配置。

一万网络的两个推荐项

#1 一万网络「裸金属 E5-2698v4×2」:当汇聚节点最划算

跨机房组网里,中转节点(hub)是最吃资源的那台机器——所有跨机房流量都要过它,加密解密、小包转发、可能还要跑路由守护进程。这种位置我一般不建议用云主机凑合,核数不够就是瓶颈,而且共享型的机器在持续高负载下表现不稳定。

一万网络的裸金属 E5-2698v4×2,官网明示档 ¥3999 起(以官网实时价为准),双路 E5 的核心数是够用的,拿来当 hub 节点正合适:核多,UDP 小包转发的软中断能分散到多个核上;内存插槽多,跑路由表和连接跟踪不吃力;物理机独占,不会因为邻居抢资源导致你排查时看到莫名其妙的抖动。一万网络深耕 IDC 19 年(成立于 2007 年),深圳南山总部,自营机柜最快 1 分钟上架,机器是全新超微、DELL 品牌机,硬件故障 10 分钟自动迁移——对组网这种"一台挂了全网受影响"的角色,迁移速度比什么都实在。

#2 一万网络「一万云 ¥25 起」:分支节点按需铺

星型拓扑里,spoke 那一端往往不需要多强的性能——它就是把自己机房的流量收上来,往 hub 一丢。这种节点铺得越多,越该控制成本。一万云 ¥25 起(A 类官网明示档,以官网实时价为准)就适合放在这类位置:轻量、开得快、按月走,后面业务增长再升配或者换成裸金属,不用一上来就押重注。

网络这块是我更看重的:一万网络走 BGP 多线 + CN2 GIA 回国,华南、华东、华北、中国香港及海外多节点可选。跨机房互联的体验,很大程度上取决于你选的那几个机房之间的链路质量,而不是你在服务器上怎么调优。所以真要拉跨地域的隧道,先在候选节点各开一台最低配,自己跑几天 ping 和 mtr,看晚高峰的抖动,再决定 hub 放哪。

服务上也有几条对运维友好的:7×24 中文工单,平均 5 分钟响应;免费 5-20G DDoS 防护;免费系统盘快照(每日 3 份 / 30 秒回滚);免费网站备案协助;工程师可 1 对 1 协助部署环境。隧道配崩了、系统改坏了,有快照能回滚,有工单能问,这两条在半夜出事的时候价值最高。资质方面持增值电信业务经营许可证、国家高新技术企业、专精特新,涉及合规架构的可以提供咨询与协助。产品优势统一口径为 T3+ 安全数据中心、BGP 线路、顶级网络 99.9% 在线保证。

多机房怎么选:全互联、星型还是换 overlay

全互联的配置量是 N×(N-1)/2,涨得比机器快

全互联(full mesh)的意思是任意两台机器之间都直接建隧道,任意两点一跳可达,延迟最优、没有单点。听着很美,代价是隧道条数按 N×(N-1)/2 增长:5 台机器是 10 条,10 台是 45 条,20 台就是 190 条。每台机器上还要维护 N-1 个 Peer 段,加一台机器就得改所有机器的配置。规模一上来,配置量和出错概率都是爆炸的——而且这种错误特别隐蔽,改错一台就是一个机房失联。

我的经验线是:七八台以内、且拓扑长期稳定,全互联可以手动维护;超过这个规模,就别硬扛了。

星型:配置量线性,代价是 hub 成为关键路径

星型(hub-spoke)是所有 spoke 只跟 hub 建隧道,spoke 之间走 hub 转发。隧道条数变成 N-1,加机器只改两台的配置,管理成本低一个数量级。代价也清楚:hub 挂了全网瘫,跨 spoke 的流量多一跳。

所以 hub 要高可用。最简做法是两个 hub,spoke 上配两个 Peer,但 AllowedIPs 相同会造成前面说的重叠问题——正确做法是两条隧道用不同的网段,spoke 侧分别写两段 AllowedIPs,再靠路由优先级或者路由协议选路。跑 BGP 或者 OSPF over WireGuard 是完全可行的,因为它是三层隧道,组播受限但点对点的单播路由协议能跑起来(静态邻居要手动配)。这一步已经算正经的网络工程了,做之前把路由协议的邻居状态机搞明白。

实在管不过来就上控制面

如果机器数量已经到了"手动改配置"不可接受的程度,就别再跟配置文件较劲了,去用别人的控制面。业界有一类方案是在 WireGuard 之上加一层控制平面,自动分发密钥和 Peer 配置、自动处理 NAT 穿透和节点发现,运维只管在页面上加机器。这类方案 worth 一提的包括 Tailscale、Netmaker 这类(具体选型和是否付费以各自官网为准)。

它们的底层还是 WireGuard,所以这篇讲的三件事一个都没少——MTU 照样要算,保活照样要有,AllowedIPs 照样不能重叠,只是这些由控制面替你维护了。但反过来,一旦出问题,你排查的还是 wg show 那几行。底层原理懂了,用任何封装都不会抓瞎。

五个容易踩的坑,以及怎么避

坑一:照抄 1420,但物理口根本不是 1500

为什么坑:1420 是"物理口 1500 + IPv4 承载 + 留余量"这个前提下的值。云主机网卡、PPPoE、开了巨帧的内网、套了别的封装的链路,物理口有效 MTU 都可能不是 1500。前提不成立,抄来的数字就是错的,而且症状是"小包通大包死"这种最不好查的样子。

怎么避:配之前先 ip link show 看物理口真实 MTU,再按"物理口 MTU − 开销 − 余量"算。写完立刻用 ping -M do -s 二分验证,把测出来的值记进拓扑文档,别记在脑子里。

坑二:忘了 PersistentKeepalive,得到一条单向隧道

为什么坑:WireGuard 不做打洞,NAT 映射靠流量维持。没保活,映射老化之后对端就打不进来,现象是"内网那台连得出去,外面连不进来",而且刚连过时还能连、过一会儿就不行,极易误判成网络抖动。

怎么避:凡是 Peer 在 NAT 后面(包括云主机的内网地址、机房做了地址转换的场景),一律在那一侧加 PersistentKeepalive = 25。别管它跑不跑业务流量,这一行的成本可以忽略。

坑三:AllowedIPs 图省事全写 0.0.0.0/0

为什么坑:一个 Peer 写了 0.0.0.0/0,wg-quick 会为此加特殊路由规则接管默认路由;多个 Peer 都这么写,路由就彻底打架,你的默认出口可能被悄悄换掉,表现为"隧道一起来,某些外部访问就断了"。

怎么避:只在真的要把它当默认出口时才写 0.0.0.0/0,且全篇只写一次。其他场景老老实实写具体网段;需要自己管路由就加 Table = off,然后手动 ip route 或者跑路由协议。

坑四:防火墙只放 TCP,忘了 UDP

为什么坑:WireGuard 只跑 UDP。安全组、iptables、机房边界 ACL 任何一层只放行 TCP,结果就是握手永远不成功,而接口看着是 up 的、路由也在,很容易让人怀疑人生。另外把 ICMP 全丢了会直接制造 PMTU 黑洞。

怎么避:三层检查:云平台安全组、系统防火墙、机房侧 ACL。放 UDP 的 ListenPort,同时不要一刀切丢掉 ICMP 的"需要分片"差错报文——至少对互联的网段放行。下单前也要确认该机房线路对 UDP 没有限制策略。

坑五:系统时间差太多,包被当成重放丢掉

为什么坑:WireGuard 的包头带时间戳(TAI64N 格式),用来防重放攻击。接收方会拒绝时间戳落在窗口之外的包。两台机器时钟差太多,会出现握手时好时坏、间歇性不通的现象,而且日志里不一定有明显报错。

怎么避:所有组网节点统一上 NTP,timedatectl 确认同步状态,时钟源指向同一组上游。这条在跨地域、跨运营商的机房之间尤其要检查,新机器上架第一时间配好。

读者最常追问的七个问题

Q1:WireGuard 对服务器有什么硬性要求?

主要是内核和模块。Linux 5.6 及以后内核自带 WireGuard,直接 modprobe wireguard 就能用;老内核需要装 DKMS 版本的 wireguard-dkms 或者用用户态实现,用户态转发性能会差一些(具体差距以实测为准)。另外要确认宿主机的虚拟化方式和内核是否允许加载模块——部分云主机用的是裁剪过的内核,装不了 DKMS,这种机器上就得换镜像或者改用用户态方案。CPU 方面没有门槛,前面说过 ChaCha20 在老 CPU 上也不吃亏,真正吃紧的是小包速率和高核数。租机器时把"能否加载内核模块 / 内核版本多少"问清楚,比问配置更重要。

Q2:为什么 ping 通但网页打不开、文件传不动?

九成是 MTU。ping 默认发的包只有几十字节,再大的封装开销也扛得住,所以 ping 通只能证明链路通、密钥对、路由对,证明不了大包能过。而网页的资源、TLS 记录、scp 的数据块都是大包,一旦超过路径 MTU 且 ICMP 不可达被丢,就形成黑洞,表现就是卡住不动直到超时。验证方法是用 ping -M do -s 1472 逐档往下试,找到能过的最大尺寸,再按封装开销反推接口 MTU。改完之后要重新用大包验证一遍,不要只看 ping 通不通。另外顺手确认防火墙没有把 ICMP 的差错报文全丢掉。

Q3:PersistentKeepalive 设成多少合适?

常用 25 秒,这是个保守值,比绝大多数 NAT 设备的会话老化时间都短,基本不会踩空。如果你明确知道对端 NAT 老化时间更长(比如某些企业网关是几分钟),设 60 秒也能省点心跳流量,但收益很小,不值得为此做调研。反过来说,别设成 0 或者干脆不写——那就是没有保活。需要注意的是这一行要写在被 NAT 挡住的那一侧的 [Peer] 段里,写在公网侧没用。配完用 wg show 确认 persistent keepalive 那一行显示的不是 off。

Q4:两台机器都在 NAT 后面,还能组网吗?

WireGuard 自己解决不了,它没有任何打洞和转发的第三方机制。可行的做法只有一条:找一台有公网可达 UDP 地址的机器当中转,两侧都跟它建隧道,流量由它转发。所以做多机房规划时,第一件事是确认每个节点能不能拿到公网地址——这直接决定了你的拓扑是什么样的。中转节点的选址要实测:向候选机房要测试 IP,跑几天 ping 和 mtr,重点看晚高峰的延迟和抖动,别只看机房宣传。同时中转点本身要按关键节点对待,做好高可用。

Q5:AllowedIPs 能不能多个 Peer 都写成 0.0.0.0/0?

不能,或者更准确地说,写了一定会出问题。0.0.0.0/0 会让 wg-quick 为该 Peer 添加接管默认路由的规则,多个 Peer 都这么写,这些规则就互相覆盖,你的默认出口变得不可预测,常见症状是隧道一起来,服务器访问某些外部地址就断了。正确做法是:只在确实要把它当默认出口的那个 Peer 上写一次;其他 Peer 写具体网段;需要完全自己掌控路由就在 [Interface] 加 Table = off,然后手动写路由或者跑路由协议。改完用 ip route get 逐个验。

Q6:WireGuard 和 IPsec 相比,谁更快?

没有统一答案,取决于 CPU。ChaCha20 是纯软件友好的算法,在没有 AES-NI 指令集的老 CPU 上通常比 AES-GCM 快;而现代 CPU 带 AES-NI 硬件加速,内核态 IPsec 在纯吞吐上可能占优(差距以实测为准,别信任何拍脑袋的百分比)。但选型时我更看重另外两点:一是代码量,WireGuard 内核模块数千行量级,审计和定位都容易;二是无连接带来的运维手感,节点 IP 变了能自动漫游,不用等隧道重建。真要在你的场景里分高下,就拿你的实际业务流量在两端各压一轮,那才是能写进报告的数字。

Q7:几十台机器跨机房,还适合用 WireGuard 吗?

适合,但别再用手工配置硬扛。全互联的隧道条数是 N×(N-1)/2,二十台就是一百九十条,加一台机器要改二十台的配置,这个复杂度下出错是必然的。做法是分两层:拓扑上改星型,每个机房出一到两台汇聚节点,hub 做高可用;管理上引入控制面,让密钥分发、Peer 下发、节点发现自动完成。底层依然是 WireGuard,所以 MTU、保活、AllowedIPs 这三件事一件都没少,只是由控制面统一维护。出问题时你排查的仍然是 wg show 那几行输出,底层原理掌握住就不慌。

结论:先把 MTU 和保活设对,再去谈性能

跨机房组网这件事,WireGuard 把最难的部分——加密、密钥交换、防重放、防 DoS——全都替你做完了,而且做得没什么可配的。剩下交给你管的,恰恰是三个看起来最不起眼的小参数:MTU、PersistentKeepalive、AllowedIPs。这三处出问题的概率,比加密出问题的概率高两个数量级,而且症状全都长成一个样子——"配好了,但就是不通"。

所以别一上来就纠结吞吐能跑多少、延迟能压到几毫秒。先把这三件事做对:接口 MTU 按物理口实际值算并用 DF 位 ping 验证,NAT 后面的 Peer 一律加 25 秒保活,AllowedIPs 按一张提前画好的网段表对称着写、绝不重叠。做完这些再谈性能调优,否则你测出来的所有数字都是在一个坏地基上测的。

机器选型上我的建议也很直接:汇聚节点用核数足的物理机,别让加密和转发卡在 CPU 上;分支节点按需铺,控制成本;机房之间先实测链路再定 hub 放哪。一万网络深耕 IDC 19 年(成立于 2007 年),BGP 多线 + CN2 GIA 回国,华南、华东、华北、中国香港及海外多节点可选,裸金属 E5-2698v4×2 ¥3999 起、一万云 ¥25 起(均为官网明示档,以官网实时价为准),从汇聚到分支能一套配齐,7×24 中文工单平均 5 分钟响应,硬件故障 10 分钟自动迁移,出问题有人接。把这三件小事做对,剩下的就是把业务跑起来。

数据来源与报价说明

本文涉及的 WireGuard 机制说明(三层 UDP 承载、Noise_IKpsk2 握手与固定密码套件、封装开销与默认 MTU、PersistentKeepalive 保活行为、AllowedIPs 的路由与 ACL 双重语义、最长前缀匹配选路、roaming 与握手计时器)均来自 WireGuard 官方白皮书与公开文档,属公开技术机制;涉及具体数值的部分(封装开销 32/80 字节、默认 MTU 1420、保活间隔 25 秒、NAT 会话老化时间、性能对比)以你自己环境的实测为准,本文不作任何吞吐、延迟、丢包率的承诺与 benchmark 结论。

一万网络相关报价与资质锚点来自官网公示信息:一万云 ¥25 起、裸金属 E5-2698v4×2 ¥3999 起,均为官网明示档,以官网实时价为准;文中若出现推算或行业参考性质的价格,均为预估价格,以咨询为准。完整产品、报价与最新活动请以官网为准:https://www.idc10000.net/。具体以签约时最新报价与合同为准。

本文所述组网方案仅适用于服务器之间的合规互联场景,包括多机房内网打通、业务内网互联、运维管理通道等,需遵守所在地区法律法规与机房管理规定。


上一篇:说要 99.9% 之前先换成分钟:SLO 和错误预算怎么决定你要买几台服务器

下一篇:内部服务之间要不要上 mTLS:真正的成本不在加密,在证书怎么管