【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-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)会持续写入,建议定期清理:

    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)。
    • 避免重复加载,确保先 unload 再 load。
  2. 最小化配置 :
    • 只包含必要字段(如 Label、ProgramArguments、RunAtLoad)。
    • 避免 KeepAlive 为 true,除非任务需要持续运行。
  3. 调试优先 :
    • 始终配置 StandardOutPath 和 StandardErrorPath。
    • 测试前手动运行命令(sudo /usr/local/bin/wg-quick up wg0)确认无错误。
  4. 安全性 :
    • 确保 .plist 和配置文件权限正确,防止未授权访问。
    • 不要在 .plist 中嵌入敏感信息(如 WireGuard 密钥)。
相关推荐
沫璃染墨3 小时前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
AIex-YH5 小时前
工艺降污:把环保账前移到发酵罐——源头减量清单
制造·策略模式
AIex-YH9 小时前
资源化利用全景:饲料化/肥料化/能源化/材料化的能走与不能走
制造·策略模式
Peter(阿斯拉)11 小时前
[macOS Tahoe 26]_[使用SmartSVN访问库路径报错的问题]
macos·svn·tahoe·smartsvn·macos26
andyweike12 小时前
iOS语法原理
macos·objective-c·cocoa
传奇开心果编程1 天前
【SwiftUI提高练中学】第8课 网络层架构:拦截器、重试、缓存与离线优先
学习·macos·ui·ios·swiftui
xUxIAOrUIII1 天前
日常笔记-1005-1
linux·笔记·python·macos
传奇开心果编程1 天前
【Compose Multiplatform 跨端开发学与练】第9课 测试与调试
android·学习·macos·ios·kotlin·web·composer
supabc1231 天前
Celium:连接 Windows、Mac、Linux 与 Android,让远程访问和设备管理更简单
android·linux·windows·macos·远程访问·网络管理·celium
牛奔1 天前
Mac 精准安装指定 macOS 版本完整教程(升级 + 降级通用)
macos