本地 macOS 构建签名

背景

macOS 版 Firefox 主要通过两种不同的方式进行签名:一种用于生产版本,另一种用于在 try 上运行的构建。通常,开发人员测试本地构建时无需担心签名,除非他们正在处理受 macOS 权限影响的特定领域,例如密钥、加载第三方库或添加新的进程类型。但是,最好测试尽可能接近生产配置或 try 服务器配置的构建。本地构建不会自动签名,并且 mach 不包含对已签名构建运行测试的支持。但是,mach 命令 macos-sign 可用于对本地打包的构建进行签名以进行手动测试。macos-sign 支持对构建进行签名以匹配 try 或生产构建。

注意:在 Apple Silicon Mac 上,所有可执行文件都需要签名,Firefox 二进制文件将在编译期间由链接器自动进行“临时”自签名,但这只是对每个二进制文件进行签名,没有任何 Firefox 特定的运行时设置或权限。本文档忽略自动签名。

要对您自己的本地构建进行签名,使其具有与生产版本相同的权限集,需要从 Mozilla 的 Apple 开发者帐户获得签名证书和配置文件。权限用于授予 Firefox 某些权限,以及在 macOS 上运行时实施安全限制。某些权限被认为是受限制的,只有在使用已获得使用该权限的许可的帐户(例如密钥 macOS 权限)的证书签名时才能启用。例如,生产版本使用不允许调试器附加的权限。不允许调试器是分发所必需的,因为它是公证系统所必需的。在本地签名时,开发人员可以根据需要修改权限。

摘要

**生产构建:**需要 Mozilla 的官方 Apple 开发者 ID 证书、私钥和配置文件。只有 Mozilla 发布工程团队才能访问官方开发者 ID 证书和私钥。Mozilla 开发人员可以请求一个有限用途的 Apple 开发者证书,该证书可用于生成用于本地测试的类似生产环境的构建。请参阅下文 像生产环境一样签名构建

**开发者构建:**需要生成自签名证书(以像 try 推送签名一样签名)或使用临时签名(无需设置,仅限本地使用),将不支持密钥(或任何其他受限制的权限),在模块加载方面限制较少,可调试。

像 try 一样签名构建

要对您自己的本地构建进行签名,使其权限与用于 try 推送自动化测试的权限匹配,请使用 macOS Keychain Access 应用程序生成自签名代码签名证书。在此过程中,提供一个与其他 Keychain 条目不同的唯一名称,确保不使用任何空格。例如,my-firefox-selfsign-cert-2024。此字符串将用作签名标识,并使用 -s 选项传递给 macos-sign./mach 将其传递给 codesign 命令,该命令在 keychain 中查找该条目。运行签名命令时,系统会提示您允许 codesign 访问 keychain 条目。出现提示时,选择 始终允许

$ ./mach build package
$ open <path-to-dmg>
<drag Browser to the Desktop>
$ ./mach macos-sign -s my-firefox-selfsign-cert-2024 -a ~/Desktop/Nightly.app

此配置中使用的树中的权限标记为开发者,我们将其称为开发者构建。开发者签名的构建与生产签名的构建在以下方面有所不同

  • 它们允许调试器附加

  • 它们允许在所有进程中加载第三方库

  • 它们尊重 dyld 环境变量

  • 它们不包含受限制的权限,例如密钥权限(因此无法使用密钥)

临时签名构建 - 像 try 签名一样,但无需配置,仅供本地使用

省略 -s 选项将使用临时签名,无需任何设置。构建将比使用自签名证书签名的构建更加有限。临时签名的构建无法在任何其他系统上验证或运行。关于限制的文档很少。

$ ./mach build package
$ open <path-to-dmg>
<drag Browser to the Desktop>
$ ./mach macos-sign -a ~/Desktop/Nightly.app

像生产环境一样签名构建

要像生产版 Firefox 构建一样对本地构建进行签名,您需要一个从 Mozilla 的 Apple 开发者帐户获得的 Apple 开发者签名证书和配置文件。开发人员将获得一个开发角色登录,允许生成签名证书和配置文件。与开发证书一起使用的配置文件通过硬件 ID 将已签名的应用程序限制在 Mozilla 开发人员机器上。员工可以 在此处提交 Bug 以请求帐户。一旦开发人员的 Apple 帐户设置为 Mozilla 的 Apple 帐户的成员,Xcode 就可以用于下载用于开发用途的开发者签名证书和配置文件。使用 Keychain Access 获取开发证书的代码签名标识符,该标识符应作为 -s 代码签名标识符传递给 mach macos-sign

$ ./mach build package
$ open <path-to-dmg>
<drag Browser to the Desktop>
$ ./mach macos-sign -a ~/Desktop/Nightly.app -s <MOZILLA_DEVELOPER_CERT_ID>

示例:重新签名官方 Nightly 版本

$ ditto /Applications/Firefox\ Nightly.app ~/Desktop/FirefoxNightly.app
$ ./mach macos-sign -a ~/Desktop/FirefoxNightly.app
0:00.20 Using ad-hoc signing identity
0:00.20 Using nightly channel signing configuration
0:00.20 Using developer entitlements
0:00.20 Reading build config file /Users/me/r/mc/taskcluster/config.yml
0:00.23 Stripping existing xattrs and signatures
0:01.91 Signing with codesign
0:02.72 Verification of signed app /Users/me/Desktop/FirefoxNightly.app OK

示例:使用 rcodesign 和 pkcs12 证书密钥对重新签名官方开发者版本

有关 rcodesign 的更多信息,请参阅 Rust crate 页面github 存储库。证书可以从 Keychain Access 以 .p12 格式导出。

$ ditto /Applications/Firefox\ Developer\ Edition.app/ ~/Desktop/DevEdition.app
$ ./mach macos-sign -r -a ~/Desktop/DevEdition.app \
  --rcodesign-p12-file ./myDevId.p12 \
  --rcodesign-p12-password-file ./myDevId.p12.passwd
0:00.26 Using pkcs12 signing identity
0:00.26 Using devedition channel signing configuration
0:00.26 Using developer entitlements
0:00.26 Reading build config file /Users/me/r/mc/taskcluster/config.yml
0:00.29 Stripping existing xattrs and signatures
0:02.09 Signing with rcodesign
0:11.16 Verification of signed app /Users/me/Desktop/DevEdition.app OK