奇怪的断连
最近我发现了一个令人费解的地方:我的远程桌面通过WireGuard进行连接,但是最近却突然连不上了。
经过一番排查,被WireGuard在Windows下的表现气得半死——这个时候我还不知道是谁的问题。明明状态栏显示连接正常,图标也是绿的,但就是上不了网。ping网关不通,远程连接转圈转到天荒地老。这还不是偶尔发生,是隔三差五就来一次。
更加奇怪的是,同一个子网内的两台设备,设备A是可以连上的设备B确是不能连上的。更加古怪的是,设备A和B是在同一物理子网下的,拥有几乎一致的配置。而且在这种情况下,我通过设备A做跳板能是够连接到设备B的。
奇怪的日志如下,这里隐去了IP地址等敏感信息:
2026-07-15 19:33:43.053928: [TUN] [client] Handshake for peer 1 (x.x.x.x:12345) did not complete after 5 seconds, retrying (try 9)
2026-07-15 19:33:43.053928: [TUN] [client] Sending handshake initiation to peer 1 (x.x.x.x:12345)
2026-07-15 19:33:48.522142: [TUN] [client] Handshake for peer 1 (x.x.x.x:12345) did not complete after 5 seconds, retrying (try 10)
2026-07-15 19:33:48.522142: [TUN] [client] Sending handshake initiation to peer 1 (x.x.x.x:12345)
2026-07-15 19:33:53.652097: [TUN] [client] Sending handshake initiation to peer 1 (x.x.x.x:12345)
2026-07-15 19:33:58.977940: [TUN] [client] Handshake for peer 1 (x.x.x.x:12345) did not complete after 5 seconds, retrying (try 2)
为了解决这个问题,我也是排查了很多方向。
MTU问题?
其中一些是说MTU存在问题,这样就导致握手的包被丢了。但是这非常奇怪,因为我的两台设备一个可以连上,另一个却不行,这说明并不是MTU存在问题。特别是握手的包很小,不太可能是这类问题。
时间同步问题
另一个想法是时间同步存在问题。也就是说,握手的包是存在时间戳的,而这些时间戳和服务器的时间戳不匹配。被服务器识别为了重放攻击,所以连接失败了。这里列一些参考文章:
- 解决WireGuard在OpenWrt路由器上重启后无法连接问题的过程 - WuSiYu Blog
- wireguard: unable to route all traffic through interface · Issue #51258 · NixOS/nixpkgs
- Wireguard客户端在nixos上没有完成握手。-腾讯云开发者社区-腾讯云
我修改了时间同步服务器,还以为解决的这个问题,结果还是不对劲,问题还是会重复发生。
- 这是之前的时间服务器问题解决文章:时间同步服务器 – 软软橘子
运营商QoS
最后发现应该最可能的应该是运营商QoS!!!也就是运营商给限流了!!
原因很简单,我只需要重启这个隧道——重启时他会自动更换随机端口,然后立马秒连接!这说明和时间、MTU什么的都没关系,就是网络被封了!!!实在是可恶的运营商!!!
重连脚本
既然知道了问题所在,而且解决方案(重启隧道)也有了,那么剩下的就是实现了。
写了一个脚本,可以自动Ping检查连通性。如果不连通,则自动重启WireGuard服务。
@echo off
setlocal
:: ==============================================================================
:: CONFIGURATION
:: TARGET_IP: WireGuard server IP. The IP address to ping.
:: TUNNEL_NAME: The name of your WireGuard config file (without .conf).
:: This must match the interface name in Windows Network Connections.
:: LOG_FILE: The path and name of the log file where results will be saved.
:: SERVICE_NAME: The internal Windows Service name for WireGuard.
:: It is automatically generated.
:: ==============================================================================
set "TARGET_IP=1.2.3.4"
set "TUNNEL_NAME=interface_name"
set "LOG_FILE=log.txt"
set "SERVICE_NAME=WireGuardTunnel$%TUNNEL_NAME%"
:: ==============================================================================
:: INITIALIZATION: Generate Timestamp
:: ==============================================================================
for /f "tokens=1-3 delims=/-. " %%a in ("%date%") do set "DATE_STR=%%a-%%b-%%c"
for /f "tokens=1-3 delims=:." %%a in ("%time%") do set "TIME_STR=%%a:%%b:%%c"
set "TIMESTAMP=[%DATE_STR% %TIME_STR%]"
:: ==============================================================================
:: [1] CONNECTIVITY CHECK
:: ==============================================================================
ping -n 1 -w 3000 %TARGET_IP% >nul 2>&1
if %errorlevel% equ 0 (
call :Log "Network OK. Exit."
exit /b 0
)
call :Log "[WARN] Failed to check tunnel: %TUNNEL_NAME%"
call :Log "[WARN] Ping FAIL. Restarting service..."
:: ==============================================================================
:: [2] SERVICE RESTART
:: ==============================================================================
sc stop "%SERVICE_NAME%" >nul 2>&1
timeout /t 2 /nobreak >nul
sc start "%SERVICE_NAME%" >nul 2>&1
if %errorlevel% equ 0 (
call :Log "SUCCESS: Service restarted."
) else (
call :Log "[ERROR] FAIL: Service restart error. Please check service name: %SERVICE_NAME%"
)
exit /b 0
:: ==============================================================================
:: [3] SUBROUTINE: Log Writer
:: ==============================================================================
:Log
echo %TIMESTAMP% %~1 >> "%LOG_FILE%"
goto :eof
这里有几个变量需要自己替换:
- TARGET_IP设置为自己的服务器IP;
- TUNNEL_NAME设置为自己的配置名称——也就是自己网络适配器的名称,WireGuard会自动用配置名称来建立虚拟网卡,就是那个名字。
- 这里还记录了日志,可以自己调整路径。
不知道网络适配器的名称就用这个命令查询:
netsh interface show interface
定时启动
自己新建一个计划任务来实现定时启动脚本即可!
要点:
- 不管是否登录都运行;必须最高权限运行。
- 触发器选择“启动时”;
- 重复间隔自己选,我觉得2分钟合适;
- 可以设置延迟执行。因为计算机刚启动时WireGuard可能尚未启动,此时会触发找不到适配器的路径;延迟2分钟一般就不会出现这种问题了。
- 启动程序时记得配置“起始于”,因为这里有记录日志,日志用的是相对路径。
- 在条件中可以设置用电源时不执行此任务。
不要设置chcp
有时候我们会在脚本一开始加上 chcp 65001 用来切换代码页到 UTF-8。不推荐这么做!两个原因:
- 一般你这么做是因为是用了中文吧……如果你要输出日志,则很可能会遇到问题!所以不推荐使用中文,用英文是最稳妥的。
- 切换代码页在某些 Windows 版本或任务计划程序的上下文中,会导致控制台进程无法正确释放句柄!这就会让任务计划程序误判进程仍在运行,导致程序的状态一直是“正在运行”而不是“准备就绪”。

Comments NOTHING