【Mac】WireGuard:使用 launchd 管理服务

在 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-toolsbrew list wireguard-tools 确认安装路径。

创建配置文件

创建并编辑配置文件 wg0.conf

bash 复制代码
sudo vi /usr/local/etc/wireguard/wg0.conf

或使用其他编辑器如 nanocode(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)会持续写入,建议定期清理:

    bash 复制代码
    sudo rm /var/log/wg-quick.log /var/log/wg-quick.err
  • 或者使用 logrotate(需额外配置)管理日志大小。

  • 更高级的日志查看:

    bash 复制代码
    sudo log stream --predicate 'eventMessage CONTAINS "wg-quick"'

最佳实践

  1. 命名规范
    • Label 使用 com.<yourname>.<task> 格式,避免冲突(如 com.user.wgquick)。
    • 避免重复加载,确保先 unloadload
  2. 最小化配置
    • 只包含必要字段(如 LabelProgramArgumentsRunAtLoad)。
    • 避免 KeepAlivetrue,除非任务需要持续运行。
  3. 调试优先
    • 始终配置 StandardOutPathStandardErrorPath
    • 测试前手动运行命令(sudo /usr/local/bin/wg-quick up wg0)确认无错误。
  4. 安全性
    • 确保 .plist 和配置文件权限正确,防止未授权访问。
    • 不要在 .plist 中嵌入敏感信息(如 WireGuard 密钥)。
相关推荐
后端常规开发人员3 小时前
MacOS系统:从Docker Desktop迁移到Colima + 外置硬盘存储
macos·docker·colima·外接硬盘
DogDaoDao11 小时前
深入理解VideoToolbox:iOS/macOS视频硬编解码实战指南
macos·ios·音视频·实时音视频·视频编解码·videotoolbox·硬编码
归辞...1 天前
「iOS」————自动释放池底层原理
macos·ios·cocoa
高克莱1 天前
【macOS操作系统部署开源DeepSeek大模型,搭建Agent平台,构建私有化RAG知识库完整流程】
macos·llm·agent·知识库·anythingllm·ollama·deepseek
程序员果子1 天前
macOS Python 安装
python·macos
橘色的喵1 天前
嵌入式C语言编程:策略模式、状态模式和状态机的应用
c语言·状态模式·策略模式·状态机
Someone_sky2 天前
Daemon Tools for Mac —— 专业虚拟光驱与磁盘映像工具
macos
小指纹2 天前
cf--思维训练
c++·算法·macos·ios·objective-c·cocoa
小指纹2 天前
河南萌新联赛2025第(四)场【补题】
数据结构·c++·算法·macos·objective-c·cocoa·图论