通过官方示例学习 Apple MDM 配置描述文件的编写


=Start=

缘由:

前段时间在测试MDM配置描述文件时遇到了一点问题,最后通过翻阅官方文档和实际测试后找到了原因(其它站点的要么介绍的不清楚,要么搜不到,还有可能说的是个错的,最靠谱的还是官方文档)。这里简单记录一下MDM配置描述文件的编写方法和注意事项,方便有需要的参考。

正文:

参考解答:
什么是配置描述文件?

配置描述文件是一个 XML 文件(以 .mobileconfig 结尾),其中包含将设置和授权信息载入到 Apple 设备的有效负载。它会自动配置设置、帐户、访问限制和凭证。这些文件可通过 MDM 解决方案或 Apple Configurator 2 创建,也可手动创建

配置描述文件的常见用途
  • 内容下发;
  • 软件下发;
  • 软件更新;
  • Web内容过滤;
  • 访问限制;
  • 远程擦除或锁定设备;
  • 证书相关设置;
  • 网络相关设置;
  • 密码相关控制;
  • 敏感行为监控(一般需配合其它软件,由配置描述文件给特定软件赋予相关权限,再由特定软件进行行为监控);
  • ……
“隐私偏好设置策略控制”自定有效负载示例
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
  <key>PayloadContent</key>
  <array>
    <dict>
     <key>PayloadDescription</key>
     <string>Corporate policy for Privacy preferences</string>
     <key>PayloadDisplayName</key>
     <string>Privacy Preferences Control</string>
     <key>PayloadIdentifier</key>
     <string>com.example.1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F.privacy.3C4D5E6F-9I0J-7G8H-5E6F-2B3C4D3C4D5E</string>
     <key>PayloadUUID</key>
     <string>3C4D5E6F-9I0J-7G8H-5E6F-2B3C4D3C4D5E</string>
     <key>PayloadType</key>
     <string>com.apple.TCC.configuration-profile-policy</string>
     <key>PayloadOrganization</key>
     <string>Example Org</string>
     <key>Services</key>
        <dict>
          <key>SystemPolicySysAdminFiles</key>
          <array>
             <dict>
                <key>Identifier</key>
                <string>com.apple.Terminal</string>
                <key>IdentifierType</key>
                <string>bundleID</string>
                <key>CodeRequirement</key>
                <string>identifier "com.apple.Terminal" and anchor apple</string>
                <key>Allowed</key>
                <true/>
                <key>Comment</key>
                <string>Allows specified apps access to some files used by system administrators. Get the CodeRequirement with 'codesign --display -r - /Applications/Utilities/Terminal.app'</string>
             </dict>
          </array>
          <key>SystemPolicyAllFiles</key>
          <array>
             <dict>
                <key>Identifier</key>
                <string>/usr/bin/mdutil</string>
                <key>IdentifierType</key>
                <string>path</string>
                <key>CodeRequirement</key>
                <string>identifier "com.apple.mdutil" and anchor apple</string>
                <key>Allowed</key>
                <true/>
                <key>Comment</key>
                <string>Allows specified apps access to data like Mail, Messages, Safari, Home, Time Machine backups, and certain administrative settings for all users on the Mac. Get the CodeRequirement with 'codesign --display -r - /usr/bin/mdutil'</string>
             </dict>
          </array>
          <key>Accessibility</key>
          <array>
             <dict>
                <key>Identifier</key>
                <string>com.example.Test</string>
                <key>IdentifierType</key>
                <string>bundleID</string>
                <key>CodeRequirement</key>
                <string>... output of 'codesign --display -r - <app>' ...</string>
                <key>Allowed</key>
                <true/>
                <key>Comment</key>
                <string>Allows specified apps to control the Mac via Accessibility APIs. The CodeRequirement can be obtained via 'codesign --display -r - /Applications/ExampleTest.app'</string>
             </dict>
          </array>
        </dict>
    </dict>
  </array>
  <key>PayloadDisplayName</key>
  <string>Privacy Preferences Configuration Profile</string>
  <key>PayloadIdentifier</key>
  <string>com.example.1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F.privacy</string>
  <key>PayloadUUID</key>
  <string>1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F</string>
  <key>PayloadType</key>
  <string>Configuration</string>
  <key>PayloadScope</key>
  <string>System</string>
  </dict>
</plist>
以上面的示例进行配置描述文件的内容/结构解读

出现在上面示例中的最外层Key列表有:

<key>PayloadContent</key> //可选,但对于有效的配置文件来说内容其实是必备的。Array of payload dictionaries. Not present if IsEncrypted is true.
<array>
...
</array>

<key>PayloadDisplayName</key> //可选,显示名称。A human-readable name for the profile.
<string>Privacy Preferences Configuration Profile</string>

<key>PayloadIdentifier</key> //唯一标识符,不能重复。A reverse-DNS style identifier (com.example.myprofile, for example) that identifies the profile.
<string>com.example.1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F.privacy</string>

<key>PayloadUUID</key> //实际内容并不重要,只要内容全局唯一就行。A globally unique identifier for the profile. In macOS, you can use uuidgen to generate reasonable UUIDs.
<string>1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F</string>

<key>PayloadType</key> //值必须为 Configuration 才行
<string>Configuration</string>

<key>PayloadScope</key> //可选,默认值为User。Determines if the profile should be installed for the system or the user.
<string>System</string>

最全的列表和说明可以参见官方文档中的 Configuration Profile Keys[1] 部分。下面对 PayloadContent 中的内容进行说明:

<key>PayloadDescription</key>
<string>Corporate policy for Privacy preferences</string>

<key>PayloadDisplayName</key>
<string>Privacy Preferences Control</string>

<key>PayloadIdentifier</key>
<string>com.example.1A2B3C4D-5E6F-7G8H-9I0J-1A2B3C4D5E6F.privacy.3C4D5E6F-9I0J-7G8H-5E6F-2B3C4D3C4D5E</string>

<key>PayloadUUID</key>
<string>3C4D5E6F-9I0J-7G8H-5E6F-2B3C4D3C4D5E</string>

<key>PayloadType</key> //表明这是一个“隐私偏好”相关的配置
<string>com.apple.TCC.configuration-profile-policy</string>

<key>PayloadOrganization</key>
<string>Example Org</string>

<key>Services</key> //表明这是一个“隐私偏好设置策略控制”的Payload
<dict>
</dict>

在“隐私偏好设置策略控制”(注意上面的 PayloadType 的key取值)的 Services 下可支持的Key列表可以参考[1](Privacy Service Dictionary Keys)部分,先对上面出现的Key进行说明:

<key>SystemPolicySysAdminFiles</key> //Optional. Allows the application access to some files used in system administration.
<array>
...</array>

<key>SystemPolicyAllFiles</key> //可选,系统全盘访问权限。 Allows the application access to all protected files, including system administration files.
<array>
...</array>

<key>Accessibility</key> //Optional. Control the application via the Accessibility subsystem.
<array>
...</array>

再以 SystemPolicyAllFiles 这个Key的取值为例进行说明(可以参考[3]中的内容):

<key>SystemPolicyAllFiles</key>
<array>
 <dict>
    <key>Identifier</key> //说明:标识符名称或文件路径
    <string>/usr/bin/mdutil</string>
    <key>IdentifierType</key> //说明:标识符类型
    <string>path</string>
    <key>CodeRequirement</key> //说明:代码签名要求
    <string>identifier "com.apple.mdutil" and anchor apple</string>
    <key>Allowed</key> //说明:允许或拒绝
    <true/>
    <key>Comment</key> //说明:注释(选填)
    <string>Allows specified apps access to data like Mail, Messages, Safari, Home, Time Machine backups, and certain administrative settings for all users on the Mac. Get the CodeRequirement with 'codesign --display -r - /usr/bin/mdutil'</string>
 </dict>
</array>
针对 Apple 设备的“自定” MDM 有效负载设置

若要允许或不允许 App 或二进制文件访问其中一个隐私类数据,您可以创建自定有效负载,并且必须包括以下要求:

要求描述示例
标识符类型指定捆绑包 ID 或文件路径。捆绑包 ID
标识符名称或文件路径捆绑包 ID 名称或实际文件路径。捆绑包 ID:com.MyOrganization.AppName文件路径:/Applications/AppName
允许或拒绝指定文件是允许访问还是拒绝访问。允许:True拒绝:False
代码签名要求实际的代码签名值。若要获取该值,请打开“终端” App 并运行以下命令:App:codesign -dr - /path/to/Application.app二进制文件:codesign -dr - /path/to/mybinaryApp:designated => (anchor apple generic and certificate leaf[field.1.2.345.678901.234.5.6.7] /* exists */ or anchor apple) and identifier "com.apple.appname.ui"二进制文件:designated => identifier "com.organization.binaryname" and anchor apple【注】不是由 Apple 提供的 App 和二进制文件可能有更长的指定要求。您的描述文件中应当包括“designated =>”之后的所有内容。
注释添加注释(选填)。允许我的组织的 App 在不提示用户的情况下与所有文件交互。
“隐私偏好设置策略控制”的限制

Apple的MDM设置中不对外开放的(隐私偏好设置相关)权限有3类:

  1. 相机(用于拒绝指定的 App 访问相机。)
  2. 麦克风(拒绝指定的 App 访问麦克风。)
  3. 屏幕录制(拒绝指定的 App 访问以阻止其拍摄(读取)系统显示的内容。)

通过MDM只能下发拒绝,不能下发允许策略。(除了上面3个之外,其实还有一个ListenEvent权限也是只能下发拒绝“Allows the application to use CoreGraphics and HID APIs to listen to (receive) CGEvents and HID events from all processes. Access to these events cannot be given in a profile; it can only be denied.”)

参考链接:

[1] Apple 设备的 MDM 概览
https://support.apple.com/zh-cn/guide/mdm/mdmbf9e668/web

[2] 针对 Apple 设备的完整 MDM 有效负载列表
https://support.apple.com/zh-cn/guide/mdm/mdm5370d089/web

[3] 针对 Apple 设备的“隐私偏好设置策略控制” MDM 有效负载设置
https://support.apple.com/zh-cn/guide/mdm/mdm38df53c2a/1/web/1.0

[4] “隐私偏好设置策略控制”自定有效负载示例
https://support.apple.com/zh-cn/guide/mdm/mdm9ddb7e0b5/1/web/1.0

[5] 针对 Apple 设备的“隐私偏好设置策略控制”有效负载设置
https://support.apple.com/zh-cn/guide/mdm/mdm38df53c2a/1/web/1

[6] Configuration Profile Reference
https://developer.apple.com/business/documentation/Configuration-Profile-Reference.pdf

[7] PrivacyPreferencesPolicyControl.Services
https://developer.apple.com/documentation/devicemanagement/privacypreferencespolicycontrol/services

=END=


《“通过官方示例学习 Apple MDM 配置描述文件的编写”》 有 5 条评论

  1. Privacy Preferences Policy Control (PPPC) Utility
    https://github.com/jamf/PPPC-Utility
    `
    PPPC Utility is a macOS (10.15 and newer) application for creating configuration profiles containing the Privacy Preferences Policy Control payload for macOS. The profiles can be saved locally, signed or unsigned. Profiles can also be uploaded directly to a Jamf Pro server.

    # 要特别注意的一点就是——屏幕录制(Screen Recording)这个隐私设置有兼容性警告(Compatibility Warning)。如果打开了之后,在10.15及之前版本会报错,在11.0及之后版本需要打开兼容性开关才行。

    Enabling Big Sur Compatibility will require the profile to be installed on macOS versions Big Sur (11.0) or greater.
    Deploying this profile to computers with macOS 10.15 or earlier will result in an error.
    `

  2. MDM的能力和限制

    Controlling “Screen Capture” using MDM
    https://developer.apple.com/forums/thread/122414
    `
    “Screen Capture” can only be denied using an Configuration Profile over MDM, never allowed.
    `

    PrivacyPreferencesPolicyControl.Services #页面搜索关键字(it can only be denied)
    https://developer.apple.com/documentation/devicemanagement/privacypreferencespolicycontrol/services
    `
    ScreenCapture
    [PrivacyPreferencesPolicyControl.Services.Identity]
    Allows the application to capture (read) the contents of the system display. Access to the contents cannot be given in a profile; it can only be denied.

    # ScreenCapture – 屏幕录制
    此隐私权限仅能通过MDM对特定app拒绝,而不能通过MDM给app主动赋予此能力。
    `

    The payload for configuring restrictions on a device.
    https://developer.apple.com/documentation/devicemanagement/restrictions

  3. 安装了不受苹果认证的描述性文件有哪些风险?
    https://www.zhihu.com/question/46343793
    `
    描述文件,为后面铺路的例子,比如他可以在用户不知的情况下开启远程管理/文件共享(系统偏好设置 > 共享),或者准许某个软件的隐私访问 (完全磁盘访问 / 屏幕录制等) 权限 (系统偏好设置 > 安全性与隐私 > 隐私) 等服务。

    隐私的安全设施的目的在于,任何一个需要访问设计用户隐私的数据/设备时,都需要明确的用户知晓的情况下的认可,也就是要弹出确认框后,用户点击许可,才可以访问。如果使用描述文件,那么就可以绕过用户许可这一步。那么,除了是企业自己的或自愿被企业管理的Mac除外,其它个人使用的Mac,除非是安装软件时自己认可的,都不该有描述文件。所以,如果是未知的,就应该删除。

    如果是买的二手Mac,而且被安装了描述文件,如果是从所属企业正常渠道购买的,需要联系该公司的技术部门,将这台机器从他们的管理数据库中删除,然后重装系统;如果从其它渠道购买,那么很可能是买到了丢失的机器,那么就要拒绝购买,或者甚至报警。

    描述文件可以安装根证书,安装后,系统就是信任该根证书,这样的潜在问题是,用该根证书签名的证书都会被系统自动信任,而不会提醒。如果被恶意安装,那么小心不安全的代码就可能被执行。所以,一定要小心。
    `

  4. 针对 Mac 电脑的 MDM 访问限制
    https://support.apple.com/zh-cn/guide/deployment/depba790e53/web
    `
    您可以在移动设备管理 (MDM) 解决方案中注册的 Mac 电脑上设定访问限制,包括修改设备及其功能。

    隔空投送: 用户不能使用“隔空投送”。
    支持的最低操作系统版本: macOS 10.13

    Organizations can restrict the use of AirDrop for devices or apps being managed by using a mobile device management (MDM) solution.

    mobile device management (MDM)
    A service that lets an administrator remotely manage enrolled devices. After a device is enrolled, the user can use the MDM service over the network to configure settings and perform other tasks on the device without user interaction.

    iCloud 文稿和数据: 文稿和数据不会添加到 iCloud。
    支持的最低操作系统版本: OS X 10.11
    `

    Device Management/Profile-Specific Payload Keys/Restrictions
    https://developer.apple.com/documentation/devicemanagement/restrictions
    `
    allowAirDrop: boolean(Default: true)
    If false, disables AirDrop. Requires a supervised device. Available in iOS 7 and later, and macOS 10.13 and later.

    allowCloudDocumentSync: boolean(Default: true)
    If false, disables document and key-value syncing to iCloud. As of iOS 13, this restriction requires a supervised device. Available in iOS 5 and later, and macOS 10.11 and later.
    `

发表评论

您的电子邮箱地址不会被公开。