[macOS翻译]解决可信执行问题

341 阅读9分钟

本文由 简悦 SimpRead 转码, 原文地址 developer.apple.com

我帮助很多开发人员解决可信执行问题。例如,他们可能有一个应用程序在......。

我帮助很多开发人员解决可信执行问题。例如,他们可能有一个应用程序被 Gatekeeper 阻止,或者有一个应用程序在启动时因代码签名错误而崩溃。

如果您遇到的问题在这里没有解释,请启动一个新的主题并提供详细信息。确保添加相关标签,如 GatekeeperCode SigningNotarization 等,以便我看到你的帖子。

重要 macOS 14 测试版有一个新工具 "syspolicy_check",专门用于帮助诊断类似问题。我计划在获得更多使用经验后更新本帖。不过,在此期间,如果你遇到了可信执行问题,并且在 macOS 14 beta 上重现,请尝试使用 syspolicy_check 并告诉我们结果如何。

Resolving Trusted Execution Problems

macOS 支持三种软件分发渠道:

  • 用户从 App Store 下载应用程序。

  • 用户直接从开发者处获取开发者 ID 签名的程序。

  • 用户使用 Apple 或第三方开发者工具在本地构建程序。

受信任的执行系统旨在保护用户免受恶意代码的侵害。它由多个不同的子系统组成。例如,Gatekeeper 可确保只有受信任的软件才能在用户的 Mac 上运行,而 XProtect 则是该平台的内置杀毒技术。

要了解有关这些技术的更多信息,请参阅 Apple Platform Security

如果你正在为 macOS 开发软件,那么你的目标就是避免可信执行纠缠。您希望用户无需采取任何特殊步骤即可安装和使用您的产品。举例来说,如果您发布的应用程序被 Gatekeeper 阻止,您很可能会失去大量客户和用户来之不易的信任。

Mac App Store 应用程序很少出现可信执行问题,因为 Mac App Store 验证过程往往能及早发现问题。本文章主要关注开发者 ID 签名的程序。

使用 Xcode 的开发人员遇到的可信执行问题较少,因为 Xcode 会处理许多代码签名和打包工作。如果您没有使用 Xcode,请考虑更换。如果您无法使用,请参考以下内容,了解如何构建、签名和打包您的代码:

Gatekeeper Basics

macOS 上的用户级应用会对新下载的内容实施隔离系统。例如,如果 Safari 下载了一个 zip 压缩包,它会对该压缩包进行隔离。这涉及在文件上设置 com.apple.quarantine 扩展属性。

注意 "com.apple.quarantine "扩展属性没有 API 文档。如果需要以编程方式添加、检查或删除文件中的检疫,请使用 quarantinePropertiesKey API。

用户级解压工具会保留隔离。继续上面的例子,如果你在 Finder 中双击被隔离的 zip 压缩包,Archive Utility 将解压压缩包并隔离由此产生的文件。

如果启动被隔离的应用程序,系统会调用 Gatekeeper。网守会检查应用程序是否存在问题。如果没有问题,它会要求用户确认是否启动,以确保万无一失。如果发现问题,它就会向用户发出警告,阻止用户启动应用程序。该警告的具体措辞因具体问题和不同版本的 macOS 而异,但通常与 Apple > Support > Safely open apps on your Mac 中显示的警告相似。

系统也可能在其他时间运行 Gatekeeper。系统运行 Gatekeeper 的具体情况没有记录,而且会随着时间的推移而变化。不过,运行被隔离的应用程序总是会调用 Gatekeeper。

Unix 网络工具,如 curlscp,不会隔离它们下载的文件。Unix 解压缩工具,如 tarunzip 不会将隔离传播到未压缩的文件。

Confirm the Problem

可信执行问题可能很难重现:

  • 您可能会遇到假阴性问题,也就是说,您遇到了可信执行问题,但在开发过程中却没有发现。

  • 你也可能遇到假阳性问题,即在某台 Mac 上出现故障,但在其他地方却能正常工作。

为避免自寻烦恼,请在一台全新的 Mac 上测试你的产品,这台 Mac 以前从未见过你的产品。最好的方法是使用虚拟机,在运行之间恢复快照。有关具体示例,请参阅 测试公证产品

最常见的问题原因是 Gatekeeper 发出警报,说它阻止了你的产品运行。不过,这并不是唯一的可能性。在进一步处理之前,请在不进行隔离的情况下运行产品,以确认问题出在 Gatekeeper 上。也就是说,重复 测试公证产品 中的步骤,但在第 2 步中,以不设置隔离的方式下载产品。然后尝试启动应用程序。如果启动失败,说明问题不在 Gatekeeper,或者问题不只在它!

注意 在不设置隔离的情况下,将应用程序下载到测试环境的最简单方法是 scp。或者,在解压缩之前使用 xattr 从下载文件中移除 com.apple.quarantine 扩展属性。有关 xattr 工具的更多信息,请参阅 xattr man page

可信执行问题形形色色。下文将讨论最常见的问题。

App Blocked by Gatekeeper

如果您的产品是一个应用程序,并且在未被隔离时运行正常,但在隔离时却被 Gatekeeper 阻止,那么您就遇到了 Gatekeeper 问题。有关如何调查此类问题的建议,请参阅 解决 Gatekeeper 问题

并非所有启动失败都是 Gatekeeper 错误。在某些情况下,应用程序只是坏了。例如

  • 应用程序的可执行文件可能缺少文件权限中设置的 x 位。

  • 应用程序的可执行文件可能与当前系统存在微妙的不兼容。最典型的例子就是试图运行包含 arm64e 代码的第三方应用程序。

    macOS 要求第三方内核扩展使用 arm64e 架构。在其他情况下,请坚持使用 arm64 作为您的出货产品。如果您想在本地测试 arm64e 代码,请参阅 准备您的应用程序以使用指针式身份验证

  • 应用程序的可执行文件可能会申请未获得供应配置文件授权的受限权限。

  • 应用程序可能存在其他代码签名问题。

注意 有关供应配置文件的更多信息,请参阅 TN3125 Inside Code Signing: Provisioning Profiles

在这种情况下,系统会显示提示信息:

The application “NoExec” can’t be opened.
[[OK]]

在 macOS 11 中,该提示为

You do not have permission to open the application “NoExec”.
Contact your computer or network administrator for assistance.
[[OK]]

这就更令人困惑了。

一个好的诊断方法是从终端运行应用程序的可执行文件。例如,缺少 x 位的应用程序将无法像下面这样运行:

% NoExec.app/Contents/MacOS/NoExec 
zsh: permission denied: NoExec.app/Contents/MacOS/NoExec

未经授权的应用程序将被可信执行系统杀死:

% OverClaim.app/Contents/MacOS/OverClaim 
zsh: killed     OverClaim.app/Contents/MacOS/OverClaim

在某些情况下,从终端运行可执行文件会显示有用的诊断信息。例如,如果应用程序引用了一个不可用的库,动态链接器就会打印出有用的诊断信息:

% MissingLibrary.app/Contents/MacOS/MissingLibrary 
dyld[88394]: Library not loaded: @rpath/CoreWaffleVarnishing.framework/Versions/A/CoreWaffleVarnishing
    …
zsh: abort      MissingLibrary.app/Contents/MacOS/MissingLibrary

Code Signing Crashes on Launch

代码签名崩溃有以下异常信息:

Exception Type:  EXC_CRASH (SIGKILL (Code Signature Invalid))

最常见的此类崩溃是启动时崩溃。要确认这一点,请查看线程回溯:

Backtrace not available

有关调试步骤,请参阅 解决启动时代码签名崩溃问题

导致此问题的一个常见原因是运行了发行版签名的代码。不要这样做!有关这不是个好主意的详细信息,请参阅 不要运行应用程序商店分发签名的代码

Code Signing Crashes After Launch

如果你的程序在启动后因代码签名问题而崩溃,你可能遇到了 更新 Mac 软件 中讨论的问题。

Non-Code Signing Failures After Launch

加固运行时 可在进程中进行多项安全检查。某些编码技术与加固运行时不兼容。如果您怀疑自己的代码与加固运行时不兼容,请参阅解决加固运行时不兼容问题

App Sandbox Inheritance

如果您在启用应用程序沙盒的情况下创建产品,而产品在 _libsecinit_appsandbox中因陷阱而崩溃,那么很可能是您遇到了应用程序沙盒继承问题。有关详情,请参阅 解决应用程序沙盒继承问题

Library Loading Problem

大多数库加载问题都有明显的原因。例如,库可能不在你期望的位置,也可能是使用错误的平台或架构构建的。不过,有些库加载问题是由可信执行系统引起的。有关详情,请参阅 解决库加载问题

Explore the System Log

如果以上方法都不能解决问题,请查看系统日志,寻找出错的线索。可以搜索的关键字包括

  • gk,表示网守

  • xprotect

  • syspolicy, 根据 syspolicyd man page

  • cmd, 用于 Mach-O 加载奇特的命令

  • amfi, 针对苹果移动文件完整性的 amfi man page

  • taskgated,参见其 "taskgated"手册页

  • yara,在Apple Platform Security中讨论。

  • ProvisioningProfiles

有关系统日志的一般信息,请参阅 Your Friend the System Log

2023-06-14 添加了对新的 syspolicy_check 工具的快速调用。

2022-06-09 添加了_启动后非代码签名失败_部分。

2022-06-03 添加了 不要运行应用程序商店分发签名代码 的链接。修复了 TN3125 的链接。

2022-05-20 首次发布。