在 macOS 上使用 WireGuard VPN 时,手动执行
wg-quick up
命令来启用 VPN 连接既繁琐又容易遗忘。尤其对于依赖 VPN 才能访问公司内网或远程服务的用户来说,实现 系统开机自动启动 WireGuard 是一项高效且必要的优化。macOS 并没有像 Linux 那样的
systemd
,而是采用了自有的服务管理机制 ------launchd
。它可在系统启动或用户登录时自动运行配置好的服务,具备稳定、安全、灵活等优点,是在 macOS 中实现 VPN 自动化的首选方案。
工具安装
安装 Homebrew
bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
安装 WireGuard Tools
bash
brew install wireguard-tools
此命令会安装 wg
, wg-quick
等命令行工具。
检查是否安装成功:
bash
which wg-quick
输出应为 /opt/homebrew/bin/wg-quick
(Apple Silicon)或 /usr/local/bin/wg-quick
(Intel Mac)。
配置 WireGuard
创建配置目录
首先,创建 WireGuard 的配置目录(如果尚未存在):
bash
sudo mkdir -p /usr/local/etc/wireguard
在 macOS 上通过 Homebrew 安装
wireguard-tools
时,配置文件通常位于/usr/local/etc/wireguard/
,这是 Homebrew 的默认路径。可通过brew --prefix wireguard-tools
或brew list wireguard-tools
确认安装路径。
创建配置文件
创建并编辑配置文件 wg0.conf
:
bash
sudo vi /usr/local/etc/wireguard/wg0.conf
或使用其他编辑器如 nano
、code
(VS Code)等。
/usr/local/etc/wireguard/wg0.conf
可通过
brew list wireguard-tools
查看安装路径。
示例配置文件(wg0.conf
)
ini
[Interface]
PrivateKey = <你的私钥>
Address = 10.0.0.2/24
DNS = 8.8.8.8
[Peer]
PublicKey = <对端公钥>
AllowedIPs = 0.0.0.0/0
Endpoint = vpn.example.com:51820
PersistentKeepalive = 25
- 替换
<你的私钥>
和<服务器公钥>
为实际密钥。AllowedIPs = 0.0.0.0/0
表示将所有流量通过 WireGuard 隧道(全隧道模式)。如需仅路由特定网络,可修改为例如192.168.1.0/24
。PersistentKeepalive = 25
有助于在 NAT 环境下保持连接。
测试与启动连接
启动连接:
bash
sudo wg-quick up wg0
查看连接状态。输出应显示接口状态、公钥、数据传输量、最近握手时间等信息。:
bash
sudo wg show
停止连接:
bash
sudo wg-quick down wg0
具体配置步骤
以下是以 wg-quick up wg0
为例的 launchd
配置,优化为极简、无脚本、易管理,针对 Homebrew 安装的 WireGuard(默认路径 /opt/homebrew/bin/wg-quick
和 /usr/local/etc/wireguard/wg0.conf
)。
创建 launchd
配置文件
文件位置 :系统级任务放在 /Library/LaunchDaemons/
,以 root 权限运行,适合 wg-quick
。
bash
sudo vi /Library/LaunchDaemons/com.wgquick.plist
配置文件内容:
xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.wgquick</string>
<!-- 由 Homebrew 的 bash 执行 -c 命令,内部再用 Homebrew bash 执行 wg-quick -->
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/bash</string>
<string>-c</string>
<string>sleep 15; /opt/homebrew/bin/bash /opt/homebrew/bin/wg-quick up wg0</string>
</array>
<!-- 开机加载时运行(配合上面的 sleep 延迟) -->
<key>RunAtLoad</key>
<true/>
<!-- 日志 -->
<key>StandardOutPath</key>
<string>/var/log/wg-quick.log</string>
<key>StandardErrorPath</key>
<string>/var/log/wg-quick.err</string>
<!-- 启动后不保持常驻 -->
<key>KeepAlive</key>
<false/>
</dict>
</plist>
字段说明:
Label
:唯一标识服务,建议用com.<yourname>.<task>
格式。ProgramArguments
:执行的命令及其参数,等同于运行/opt/homebrew/bin/wg-quick up wg0
。RunAtLoad
:设置为<true/>
,表示系统启动时立即运行。StandardOutPath
/StandardErrorPath
:指定标准输出和错误日志路径,便于调试。KeepAlive
:设置为<false/>
,避免进程异常退出后无限重启(WireGuard 通常一次性配置完成)。
使用命令一键写入
用 tee 写入新的 plist(粘贴前请确认上面 plist 内容)
bash
sudo tee /Library/LaunchDaemons/com.wgquick.plist > /dev/null <<'PLIST'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.wgquick</string>
<key>ProgramArguments</key>
<array>
<string>/opt/homebrew/bin/bash</string>
<string>-c</string>
<string>sleep 15; /opt/homebrew/bin/bash /opt/homebrew/bin/wg-quick up wg0</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/wg-quick.log</string>
<key>StandardErrorPath</key>
<string>/var/log/wg-quick.err</string>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
PLIST
设置文件权限
launchd
要求 .plist
文件有正确权限:
bash
sudo chmod 644 /Library/LaunchDaemons/com.wgquick.plist
sudo chown root:wheel /Library/LaunchDaemons/com.wgquick.plist
644
:确保 root 可写,其他用户可读。root:wheel
:符合系统级服务的所有者要求。
加载服务
加载 .plist
文件以启用服务:
bash
sudo launchctl load /Library/LaunchDaemons/com.wgquick.plist
若需立即测试(无需重启):
bash
sudo launchctl start com.wgquick
验证与调试
检查服务状态:
bash
sudo launchctl list | grep com.wgquick
输出示例:
- 0 com.wgquick
- 若有
PID
(如1234
),表示服务正在运行;若无 PID,可能未启动成功。
验证 WireGuard:
bash
wg show
确认 wg0
接口是否激活并有正确的配置。
查看日志:
bash
cat /var/log/wg-quick.log
cat /var/log/wg-quick.err
若有错误(如路径错误或权限问题),日志会提供线索。
系统日志(更详细的调试):
bash
sudo log show --predicate 'eventMessage CONTAINS "wg-quick"' --last 1h
管理 WireGuard 服务
操作 | 命令 |
---|---|
加载服务 | sudo launchctl load /Library/LaunchDaemons/com.wgquick.plist |
卸载服务 | sudo launchctl unload /Library/LaunchDaemons/com.wgquick.plist |
启动服务 | sudo launchctl start com.wgquick |
停止服务 | sudo launchctl stop com.wgquick (通常不可用,仅适用于 KeepAlive) |
修改配置后重载 | 卸载后再加载:unload → 修改 → load |
删除服务 | sudo rm /Library/LaunchDaemons/com.wgquick.plist |
测试开机启动 | 重启系统 → wg show |
日志管理
-
日志文件(
/var/log/wg-quick.log
和.err
)会持续写入,建议定期清理:bashsudo rm /var/log/wg-quick.log /var/log/wg-quick.err
-
或者使用
logrotate
(需额外配置)管理日志大小。 -
更高级的日志查看:
bashsudo log stream --predicate 'eventMessage CONTAINS "wg-quick"'
最佳实践
- 命名规范 :
Label
使用com.<yourname>.<task>
格式,避免冲突(如com.user.wgquick
)。- 避免重复加载,确保先
unload
再load
。
- 最小化配置 :
- 只包含必要字段(如
Label
、ProgramArguments
、RunAtLoad
)。 - 避免
KeepAlive
为true
,除非任务需要持续运行。
- 只包含必要字段(如
- 调试优先 :
- 始终配置
StandardOutPath
和StandardErrorPath
。 - 测试前手动运行命令(
sudo /usr/local/bin/wg-quick up wg0
)确认无错误。
- 始终配置
- 安全性 :
- 确保
.plist
和配置文件权限正确,防止未授权访问。 - 不要在
.plist
中嵌入敏感信息(如 WireGuard 密钥)。
- 确保