从 swift 调用 nettop:"Unable to allocate a kernel control socket"

Calling nettop from swift: "Unable to allocate a kernel control socket"

我正在为命令行 nettop 实用程序编写一个 macOS GUI 包装器。

当我通过 zsh 从终端应用程序调用 nettop -P -L 1 时,它会显示正确的输出,但是当我从我的 Swift 应用程序中启动进程时,它会在我的应用程序中显示以下内容:

nettop[19213:2351456] [NetworkStatistics] Unable to allocate a kernel control socket nettop: NStatManagerCreate failed

这是某种权限或沙盒问题吗?如果是,我如何让我的应用请求适当的权限?

代码片段:

func shell(launchPath: String, arguments: [String] = []) -> (String? , Int32) {
    let task = Process()
    task.launchPath = launchPath
    task.arguments = arguments

    let pipe = Pipe()
    task.standardOutput = pipe
    task.standardError = pipe
    task.launch()
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8)
    task.waitUntilExit()
    return (output, task.terminationStatus)
}

...


struct ContentView: View {
    var body: some View {
            Text(shell(launchPath: "/usr/bin/nettop", arguments: ["-P", "-L", "1"]).0 ?? "No Output")
    }
}

这确实是一个沙箱问题:nettop 通过创建一个 com.apple.network.statistics PF_SYSTEM/SYSPROTO_CONTROL 套接字进行操作(来源示例可以在 http://newosxbook.com/code/listings/17-1-lsock.c 中看到),它可以是沙盒化。

对该套接字的访问受到两层限制:

  • 当 net.statistics_privcheck sysctl 设置为 1 时,将强制执行 com.apple.private.network.statistics 权利。这不是你的情况,因为你正在执行 nettop,它无论如何都有权利

  • 除非

    明确允许,否则沙盒配置文件会阻止创建系统套接字
     (allow network-outbound
             (control-name "com.apple.network.statistics")
             (control-name "com.apple.netsrc"))
    

规则。

您的情况似乎是后一种情况,但从您的详细信息来看,尚不清楚故障是在您自己的应用程序的沙箱配置文件中还是在 exec'ed nettop 中。要确定这一点,请尝试自己创建套接字 - 如果您可以这样做,那就是 exec 的问题。如果你不能,那就是你自己的个人资料。可以创建您自己的沙盒配置文件,但 Apple 永远不会公开允许这样做,并且可能会让您被踢出 App Store。

另一项测试 - 运行 直接从命令行运行您的应用。 (也就是说,在终端中,然后是 /Applications/path/to/your.app/Contents/MacOS/yourApp)。这样,它就不会被 xpcproxy 启动,并且会受到较少的沙箱限制。