News Hacker|极客洞察

237 1 小时前 eclecticlight.co
😒macOS 应用解剖:App Bundle、notarization 与签名成本/兼容性痛点
现在运行个 Mac 程序也得交年费和出示护照吗?

🎯 讨论背景

这篇讨论基于一篇关于“macOS 应用结构”文章展开,原文介绍了 .app bundle 的目录和关键文件。评论主要把焦点放在 Apple 近年来对分发和运行安全的强化(如 Developer ID、notarization、Gatekeeper、stapling)对开发者和 CI 流程的影响,尤其是年费、公司验证(DUNS)与跨平台构建的阻碍。有人将 macOS 的封闭验证体系与 Windows 的 EV 证书/SmartScreen 做对比,并提到 Azure Trusted Signing / Azure KeyVault(微软的云端 code signing 与密钥管理服务)作为替代途径,但存在地域和资格限制。讨论还穿插技术史与实现细节(例如 NeXTSTEP —— NeXT 的早期操作系统,其 bundle 概念影响了 JAR;classic Mac 的 data fork/CFM)以及对界面设计的怀旧与批评。

📌 讨论焦点

notarization 与 Apple 的平台控制

评论集中批评 Apple 的 notarization 与 Developer ID 流程:尽管文章提到 stapled notarisation ticket 可选,但实际分发中未 notarize 的包会触发 macOS 的强烈警告,导致用户体验严重下降,因此对许多开发者而言 notarization 实质上是强制性的。开发者抱怨年费($99/年)、DUNS 与公司验证等强身份流程具有侵入性且透明度低,部分公司会因不明原因被拒绝;另有人指出 notarization 阻碍从 Linux 交叉编译 macOS 二进制,迫使团队在 CI 中使用 mac 硬件。支持者认为签名与 notarization 有安全收益(便于 Santa、Little Snitch 等识别并统一内核/用户态的程序身份),但也有人未能找到证据证明 notarization 实际上阻止了大量安全事件,同时偶发的 Developer ID 撤销会对合法分发造成连带伤害。

[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]

Windows 的代码签名、EV 证书与 SmartScreen 对比

多条评论把 macOS 的签名/notarization 问题与 Windows 的代码签名体系做了对比:Windows 侧也演进为“付费才能获得良好信任”的模式,EV code signing 通常需要严格的组织/身份验证并使用硬件 token,前期成本可能很高且发布权限集中。SmartScreen/Windows Defender 依赖程序“声誉”(install 数量和签名历史),即使有签名也可能因为缺乏声誉而弹出警告,形成鸡与蛋问题。最近出现的 Azure code signing / Azure Trusted Signing 与 Azure KeyVault 等云服务能以较低月费(如 $10/月)替代传统 EV 硬件方案,但存在地域和资格限制,并且对 Defender/SmartScreen 的效果在不同用户报告中不一致(有人报告 EV 可立即消除警告,也有人遇到首次运行延迟问题)。

[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7]

分发摩擦与用户体验:回避办法与现实

大量评论强调未签名或未 notarize 的应用在普通用户看来就像“坏掉”了:macOS 的弹窗设计会指名 malware,普通用户很难按路径去系统设置放行,导致潜在客户流失。开发者分享实用的应对策略:在 .dmg 内放“How to install.rtf”说明、在分发包中提供 Sentinel 之类的拖放解锁工具,或提供 Web/PWA 作为不愿安装本地应用用户的替代。也有经验称一旦完成初始验证(例如取得 DUNS 并把流程在构建服务器上自动化)后维护负担很小,但对小团队和跨国实体的首次设置仍然是显著障碍。

[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]

macOS 打包历史与技术细节(bundle、链接与运行路径)

评论补充了大量与 App bundle 与可执行文件相关的历史与实现细节:NeXTSTEP 的 bundle 概念影响了 Java JAR,Classic Mac(Power Mac、CFM-68K)在不同位置存放可执行代码(如 data fork 或 CODE 资源)的历史被提及。有人纠正文章对 launchd 的描述:命令行工具通常由 shell fork/exec 启动,而不是直接由 launchd 启动;同时讨论了 dyld、RPATH 与 .dylib 的查找行为:应用可以把库放在非标准位置(例如 AppName.app/Contents/Libraries)并通过 RPATH 配置通过 notarization,但这很少见且没有明显好处。另有评论指出 iOS 在提交时对动态库格式(.dylib vs .framework)更严格,增加额外约束。

[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7]

UI 设计与怀旧情绪

文章配图引发对经典 macOS 界面的怀旧与现代设计的争论:有人认为早期界面更实用、信息密度高,不满现代圆角和“泡泡”图标占用可用像素;也有评论指出实际像素占比在现代 Mac (尤其 5K 屏幕)并不一定更差,并对 Leopard-era Aqua 在信息密度与视觉引导间取得的平衡表示肯定。讨论还延伸到圆角对视觉注意力的影响(有人引用“Round Rects Are Everywhere”讨论圆角绘制与感知),情绪混合着怀旧、设计偏好与对效率的理性批评。

[来源1] [来源2] [来源3] [来源4] [来源5]

📚 术语解释

notarization: Apple 对 macOS 应用的自动化安全扫描与签名验证服务:开发者将二进制提交给苹果以取得 notarization ticket,未通过 notarization 的分发包会触发 Gatekeeper 的警告。

stapled notarisation ticket(stapling): 将 notarization ticket 直接“staple”到应用或安装包中,使系统在离线时也能验证该包;如果不 staple,macOS 可能在首次运行时在线查询苹果以确认状态。

Developer ID (code signing certificate): Apple 发放给在 App Store 以外分发 macOS 应用的代码签名证书,用于对应用进行 codesign 并通过 Gatekeeper/Notarization 检查,申请与维护通常涉及年费和公司/身份验证(例如 DUNS)。

EV code signing certificate (EV cert): Extended Validation 签名证书(Windows 生态中常见),需要更严格的组织/身份验证并通常使用硬件 token,能提升 Windows Defender/SmartScreen 的信任度但成本和限制更高。

SmartScreen / Windows Defender: Microsoft 的基于声誉的下载/运行筛查与防护机制,对低声誉或新出现的可执行文件弹出警告;信任通常依赖签名类型、证书和安装量(声誉)。

Azure Trusted Signing / Azure KeyVault: Microsoft Azure 提供的云端 code signing 与密钥管理服务:允许把签名密钥放在 Azure KeyVault 中并通过云服务进行签名(例如 Azure Trusted Signing),从而避免传统硬件 token,费用与资格/地域有关。

Mach-O: macOS / iOS 使用的可执行文件与目标文件格式(Mach Object),由 dyld、codesign 等工具处理。

launchd: macOS 的 init 与服务管理守护进程,用于启动系统守护进程和守护服务;交互式命令行工具通常由 shell fork/exec 启动,而不是由 launchd 直接触发。

.dylib 与 RPATH: .dylib 是 macOS 的动态库格式,RPATH(runtime library search path)用于指定运行时查找这些库的位置;通过正确配置 RPATH,可以把库放在非标准 App bundle 子目录中被正确载入。

App bundle (.app) / .dmg: macOS 应用通常以 .app 作为目录化的 bundle 展现(Contents 子目录包含 Info.plist、MacOS 可执行文件、Frameworks 等),常用 .dmg(磁盘镜像)作为分发格式以提示用户拖拽安装。