问题描述
ClashMac 的 Smart Bypass(在指定 Wi-Fi 下禁用代理)无法正常工作。
启用 Smart Bypass 后,ClashMac 没有弹出 macOS 定位权限请求,也没有出现在:
系统设置 → 隐私与安全性 → 定位服务
由于应用无法取得当前 Wi-Fi 的 SSID,即使手动将 SSID 添加到 trustedSSIDs,ClashMac 仍无法判断当前连接的 Wi-Fi 是否命中绕过列表,系统代理和 TUN 会继续保持开启。
环境信息
- macOS:26.5.2
- macOS Build:25F84
- 架构:Apple Silicon / arm64
- ClashMac:27.1.2
- ClashMac Build:216
- Bundle ID:
app.clashmac
- TUN:开启
- 系统代理:开启
- DNS Enhanced Mode:Fake IP
复现步骤
- 打开 ClashMac。
- 进入 Smart Bypass / 指定 Wi-Fi 禁用代理设置。
- 开启 Smart Bypass。
- 尝试添加当前连接的 Wi-Fi。
- 观察是否出现 macOS 定位权限请求。
- 检查“系统设置 → 隐私与安全性 → 定位服务”。
- 切换或重新连接已配置的 Wi-Fi。
- 检查 ClashMac 是否自动暂停系统代理和 TUN。
预期行为
- 第一次启用 Smart Bypass 或读取当前 Wi-Fi SSID 时,ClashMac 应调用 Core Location 授权 API。
- macOS 应弹出定位权限请求。
- ClashMac 应出现在系统定位服务应用列表中。
- 用户允许后,ClashMac 应能读取当前 SSID。
- 当前 SSID 命中
trustedSSIDs 时,应自动暂停系统代理和 TUN。
- 离开该 Wi-Fi 后,应自动恢复原有代理状态。
实际行为
- 启用 Smart Bypass 后没有出现定位权限弹窗。
- ClashMac 没有出现在 macOS 定位服务列表中。
- 系统没有为
app.clashmac 创建 Location TCC 授权记录。
- 当前 Wi-Fi 已连接且默认路由走
en0,但 SSID 对普通进程仍显示为 <redacted>。
- 手动添加 SSID 后,
trustedSSIDs 能保存,但无法触发 Smart Bypass。
- 系统代理和 TUN 仍保持开启。
ClashMac 当前偏好状态
执行:
defaults read app.clashmac enableSmartBypass
defaults read app.clashmac trustedSSIDs
defaults read app.clashmac tunEnabled
输出:
说明:
- Smart Bypass 已开启。
- SSID
<SSID> 已保存。
- TUN 仍然开启。
- 当前连接的 Wi-Fi 已经是该 SSID,但绕过没有触发。
当前网络状态
默认路由确认使用 Wi-Fi 接口:
关键输出:
接口状态:
关键输出:
系统报告 Wi-Fi 已连接,但 SSID 被隐藏:
system_profiler SPAirPortDataType -json
关键输出:
{
"spairport_status_information": "spairport_status_connected",
"spairport_current_network_information": {
"_name": "<redacted>"
}
}
另一个查询同样无法取得 SSID:
networksetup -getairportnetwork en0
输出:
You are not associated with an AirPort network.
实际上设备已经连接 Wi-Fi,默认路由也使用 en0。该输出可能与新版 macOS 的 SSID 隐私限制有关。
TCC 权限检查
执行:
sqlite3 \
"$HOME/Library/Application Support/com.apple.TCC/TCC.db" \
"SELECT service,client,auth_value,auth_reason
FROM access
WHERE client='app.clashmac';"
输出中只有:
kTCCServiceAppleEvents|app.clashmac|2|3
没有发现:
尝试执行:
tccutil reset Location app.clashmac
然后重新启动 ClashMac、重新启用 Smart Bypass,仍然没有出现定位授权弹窗。
tccutil reset 只能清理已有授权,不能代替应用主动请求授权。
Info.plist 检查
应用已经声明定位权限用途:
plutil -p /Applications/ClashMac.app/Contents/Info.plist |
grep -i Location
输出:
NSLocationWhenInUseUsageDescription =
"ClashMac requires location permissions to detect the current Wi-Fi name (SSID) for the Smart Bypass feature."
因此定位权限说明字符串已经存在,但运行过程中没有观察到定位权限请求。
二进制依赖检查
执行:
otool -L /Applications/ClashMac.app/Contents/MacOS/ClashMac |
grep -Ei 'CoreLocation|CoreWLAN|SystemConfiguration'
输出中存在:
CoreWLAN.framework
SystemConfiguration.framework
但没有发现:
进一步检查可执行文件中的相关符号和字符串:
strings /Applications/ClashMac.app/Contents/MacOS/ClashMac |
grep -Ei \
'requestWhenInUseAuthorization|requestAlwaysAuthorization|CLLocationManager|SSID changed|SmartBypass'
输出只发现:
[NetworkMonitor] SSID changed from %{public}s to %{public}s
[SmartBypass] State toggled: %{bool,public}d (SSID: %{public}s)
没有发现:
CLLocationManager
requestWhenInUseAuthorization
requestAlwaysAuthorization
此项只能作为辅助证据,不排除代码使用其他动态调用方式。但结合以下现象,怀疑当前版本只通过 CoreWLAN 读取 SSID,却没有先通过 Core Location 请求定位授权:
- 没有定位权限弹窗。
- 没有 TCC Location 记录。
- SSID 始终为
<redacted>。
- Smart Bypass 无法命中已保存的 SSID。
签名信息
执行:
codesign -dv --verbose=4 /Applications/ClashMac.app
关键输出:
Identifier=app.clashmac
TeamIdentifier=not set
应用本身可以通过签名完整性检查:
codesign --verify --deep --strict /Applications/ClashMac.app
但是当前构建没有 TeamIdentifier。请确认这是否会影响 macOS 26 上 TCC 定位授权记录的创建或持久化。
可能根因
可能存在以下一种或多种情况:
- 启用 Smart Bypass 时没有创建并保留
CLLocationManager。
- 没有调用
requestWhenInUseAuthorization()。
- 只声明了
NSLocationWhenInUseUsageDescription,但没有实际请求权限。
- 在定位权限状态为
.notDetermined 时直接调用 CoreWLAN 读取 SSID,得到 nil 或 <redacted>。
- 当前发布构建没有
TeamIdentifier,可能影响新版 macOS 的 TCC 行为。
- SSID 读取失败后仍允许写入
trustedSSIDs,但运行时无法匹配当前网络。
建议修复方向
建议在 Smart Bypass 启用或首次读取 SSID 时请求定位权限,例如:
import CoreLocation
final class LocationPermissionManager: NSObject, CLLocationManagerDelegate {
private let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
}
func requestPermissionIfNeeded() {
switch manager.authorizationStatus {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .authorized, .authorizedAlways:
// 定位授权完成后再读取当前 SSID。
break
case .denied, .restricted:
// 向用户展示前往系统设置的提示。
break
@unknown default:
break
}
}
}
同时建议:
- 在定位授权成功后再读取 CoreWLAN SSID。
- SSID 为空时显示明确错误,不要静默失败。
- 定位权限被拒绝时提供“打开系统设置”按钮。
- 在界面中显示当前检测到的 SSID。
- 在界面中显示 Smart Bypass 当前是否已触发。
- 增加日志,输出定位授权状态、SSID 读取结果和匹配结果。
- 检查发布构建的 Developer ID 签名和
TeamIdentifier。
其他说明
代理节点、TUN 和基础网络连接本身正常。问题集中在当前 SSID 获取及 Smart Bypass 匹配流程。
手动写入 SSID:
defaults write app.clashmac trustedSSIDs "<SSID>"
只能让目标 SSID 出现在配置中,不能解决当前 SSID 无法读取的问题。如果 ClashMac 运行时读取不到当前 SSID,仍然无法完成匹配。
问题描述
ClashMac 的 Smart Bypass(在指定 Wi-Fi 下禁用代理)无法正常工作。
启用 Smart Bypass 后,ClashMac 没有弹出 macOS 定位权限请求,也没有出现在:
由于应用无法取得当前 Wi-Fi 的 SSID,即使手动将 SSID 添加到
trustedSSIDs,ClashMac 仍无法判断当前连接的 Wi-Fi 是否命中绕过列表,系统代理和 TUN 会继续保持开启。环境信息
app.clashmac复现步骤
预期行为
trustedSSIDs时,应自动暂停系统代理和 TUN。实际行为
app.clashmac创建 Location TCC 授权记录。en0,但 SSID 对普通进程仍显示为<redacted>。trustedSSIDs能保存,但无法触发 Smart Bypass。ClashMac 当前偏好状态
执行:
输出:
说明:
<SSID>已保存。当前网络状态
默认路由确认使用 Wi-Fi 接口:
关键输出:
接口状态:
关键输出:
系统报告 Wi-Fi 已连接,但 SSID 被隐藏:
关键输出:
{ "spairport_status_information": "spairport_status_connected", "spairport_current_network_information": { "_name": "<redacted>" } }另一个查询同样无法取得 SSID:
输出:
实际上设备已经连接 Wi-Fi,默认路由也使用
en0。该输出可能与新版 macOS 的 SSID 隐私限制有关。TCC 权限检查
执行:
输出中只有:
没有发现:
尝试执行:
然后重新启动 ClashMac、重新启用 Smart Bypass,仍然没有出现定位授权弹窗。
tccutil reset只能清理已有授权,不能代替应用主动请求授权。Info.plist 检查
应用已经声明定位权限用途:
plutil -p /Applications/ClashMac.app/Contents/Info.plist | grep -i Location输出:
因此定位权限说明字符串已经存在,但运行过程中没有观察到定位权限请求。
二进制依赖检查
执行:
输出中存在:
但没有发现:
进一步检查可执行文件中的相关符号和字符串:
输出只发现:
没有发现:
此项只能作为辅助证据,不排除代码使用其他动态调用方式。但结合以下现象,怀疑当前版本只通过 CoreWLAN 读取 SSID,却没有先通过 Core Location 请求定位授权:
<redacted>。签名信息
执行:
关键输出:
应用本身可以通过签名完整性检查:
但是当前构建没有
TeamIdentifier。请确认这是否会影响 macOS 26 上 TCC 定位授权记录的创建或持久化。可能根因
可能存在以下一种或多种情况:
CLLocationManager。requestWhenInUseAuthorization()。NSLocationWhenInUseUsageDescription,但没有实际请求权限。.notDetermined时直接调用 CoreWLAN 读取 SSID,得到nil或<redacted>。TeamIdentifier,可能影响新版 macOS 的 TCC 行为。trustedSSIDs,但运行时无法匹配当前网络。建议修复方向
建议在 Smart Bypass 启用或首次读取 SSID 时请求定位权限,例如:
同时建议:
TeamIdentifier。其他说明
代理节点、TUN 和基础网络连接本身正常。问题集中在当前 SSID 获取及 Smart Bypass 匹配流程。
手动写入 SSID:
defaults write app.clashmac trustedSSIDs "<SSID>"只能让目标 SSID 出现在配置中,不能解决当前 SSID 无法读取的问题。如果 ClashMac 运行时读取不到当前 SSID,仍然无法完成匹配。