移动设备管理(MDM)协议提供了一种方法,告诉设备远程执行某些管理命令。它的工作方式很简单。
安装期间:
•用户或管理所有设备在安装中。显示负载的结构是在MDM有效载荷结构中描述。
•设备连接到检查-服务器中。设备当前的身份验证证书,以及它的UDID和推送通知主题。
note
虽然udid由MDM使用,但对于iOS应用程序,udid的使用是不推荐的。
而且,在未来,UDID不一定总是41个字符,它可以长或短。它还可以包含其他字符,如破折号。不要在产品中硬编码假设。如果你这样做了,将来注册可能会失败。
如果服务器接受该设备,则该设备向服务器提供其推送通知设备令牌。服务器应使用此令牌向设备发送推送消息。此签入消息还包含PushMagic字符串。服务器必须记住此字符串,并将其包含在发送到设备的任何推送消息中。
正常运行期间:
•服务器(在未来某个时间点)向设备发送soutapush通知。
•设备按照服务器的命令响应PushNotification。
•设备执行命令。
•设备连接服务器,以导入last命令的结果并请求下一个命令。
设备令牌可能会不时更改。当检测到更改时,设备自动检入MDM服务器以报告其新的推送通知令牌。
note
设备仅在响应推送通知时轮询;它不会在安装后立即轮询服务器。服务器必须向设备发送推送通知才能开始事务。
设备通过建立到MDMServerURL的TLS连接来启动与MDMServer的通信,以响应推送通知。设备验证服务器的证书,然后使用其MDM负载中指定的标识作为连接的客户端身份验证证书。
note
MDM遵循HTTP 3xx重定向,无需用户交互。但是,它不记得HTTP 301(永久移动)重定向给出的URL。每个事务都从MDM负载中指定的URL开始。
移动设备管理,顾名思义,最初是为嵌入式系统开发的。为了支持计算机绑定到开放目录服务器并且各种网络用户可以登录的环境,开发了MDM协议的扩展,以识别和验证网络用户登录,以便任何网络用户也由MDM服务器(通过其用户配置文件)管理。MDM协议扩展描述了对MDM协议的扩展。
note
当联系MDM服务器以获取其最新设置时,可能会暂时阻止登录。设备注册也可以在计算机连接到Internet后执行。
MDM有效载荷结构
移动设备管理(MDM)负载是一个简单的属性列表,由com.apple.mdm公司PayloadType字段中的值。此有效负载定义了特定于MDM有效负载的以下键:
Key | Type | Value |
---|---|---|
IdentityCertificateUUID | String | 强制性的。设备标识的证书有效负载的UUID。它还可以指向SCEP负载。 |
Topic | String | 强制性的。MDM侦听推送通知的主题。服务器用于发送推送通知的证书的主题必须相同。主题必须以com.apple.mgmt. 前缀。 |
ServerURL | String | 强制性的。设备联系以检索设备管理指令的URL。必须以https://URL scheme开头,并且可能包含端口号(例如:1234)。 |
ServerCapabilities | Array | 可选。表示服务器功能的字符串数组。如果服务器管理macOS设备或共享iPad,则此字段是必需的,并且必须包含值com.apple.mdm.per-user-connections。这表示服务器同时支持设备和用户连接。请参阅MDM协议扩展。 |
SignMessage | Boolean | 可选。如果为true,则来自设备的每个消息都带有额外的Mdm签名HTTP头。默认为false。有关详细信息,请参见通过代理传递客户端标识。 |
CheckInURL | String | 可选。设备在安装期间应用于签入的URL。必须以https://URL scheme开头,并且可能包含端口号(例如:1234)。如果未提供此URL,则服务器URL用于这两个目的。 |
CheckOutWhenRemoved | Boolean | 可选。如果为true,则在删除配置文件时,设备将尝试向签入服务器发送签出消息。默认为false。注意:macOS v10.8的作用好像这个设置总是正确的。可用性:在iOS 5.0及更高版本中可用 |
AccessRights | Integer, flags | 必修的。以下位标志的逻辑或:•1:允许检查已安装的配置文件。•2:允许安装和移动配置个人资料。•4:允许删除设备锁和密码。•8:允许删除设备。•16:允许查询设备信息(设备容量,序列号)。•32:允许查询网络信息(电话/SIM卡数字,MAC地址)。•64:AllowInspectionOnFinStalledProvisioningProfiles。•128:允许安装和拆卸个人资料。•256:Allowinspectionofinstalledapplications。•512:与分配定价相关的查询。•1024:允许安全相关查询。2048:允许设置的操作。可用性:在iOS 5.0及更高版本中可用。提供于macOS 10.9用于某些命令。•4096:分配管理。可用性:在iOS 5.0及更高版本中可用。提供于macOS 10.9用于某些命令。可能不是零。如果指定了2,则还必须指定1。如果指定128,则还必须指定64。 |
UseDevelopmentAPNS | Boolean | 可选。如果为true,则设备使用开发APNS服务器。否则,设备将使用生产服务器。默认为false。注意,如果您的Apple推送通知服务证书是由Apple推送证书门户颁发的,则必须将此属性设置为false(https://identity.apple.com/pushcert). 该门户仅为生产推送环境颁发证书。 |
ServerURLPinningCertificateUUIDs | Array | 可选。包含证书的payloaduuid的字符串数组,在评估对MDM服务器的…/connect/url的信任时将使用这些证书。可用性:在macOS 10.13及更高版本中可用。 |
CheckInURLPinningCertificateUUIDs | Array | 可选。包含证书的payloaduuid的字符串数组,在评估对MDM服务器的…/checkin/url的信任时将使用这些证书。可用性:在macOS 10.13及更高版本中可用。 |
PinningRevocationCheckRequired | Boolean | 可选。如果为true,则连接将失败,除非在证书吊销检查期间获得经过验证的肯定响应。如果为false,则在最佳尝试的基础上进行吊销检查,并且不认为到达服务器失败是致命的。默认值为false。可用性:在macOS 10.13及更高版本中可用。 |
此外,必须定义四个标准有效载荷键:
Key | Value |
---|---|
PayloadType | 强制性的。com.apple.mdm. |
PayloadVersion | 1 |
PayloadIdentifier | 必须提供值 |
PayloadUUID | 必须提供全局唯一值 |
这些键记录在配置概要文件中的“所有有效负载通用的有效负载字典键”中参考资料。
有关有效负载的一般结构和示例,请参阅配置中的“配置配置文件密钥参考”配置文件引用。
注意
前缀为“payload”的配置文件有效负载字典键是保留的键名,决不能被视为托管首选项。有效负载字典中的任何其他键都可以被视为该首选域的托管首选项。
MDM消息的结构
安装MDM负载后,设备将侦听推送通知。MDM侦听的主题对应于推送通知客户端证书的Subject字段中的User ID参数的内容。
为了使设备轮询MDM服务器以获取命令,MDM服务器通过APNS网关向设备发送通知。与推送通知一起发送的消息是JSON格式的,并且必须包含PushMagic字符串作为mdm键的值。例如:
{”mdm”:”PushMagicValue”}
代替上面的PushMagicValue,替换设备在TokenUpdate消息中发送给MDM服务器的实际PushMagic字符串。这应该是全部信息。不应该有aps密钥。(aps密钥仅用于第三方应用推送通知。)
设备通过使用httpputovertls(SSL)联系MDM服务器来响应此推送通知。此消息可能包含空闲状态,也可能包含以前操作的结果。如果在设备执行任务时断开连接,则在恢复网络后,设备将尝试再次报告其结果。
MDM请求有效负载示例显示MDM请求有效负载的示例。
清单3.1:MDM请求负载示例:
PUT /your/url HTTP/1.1
Host: www.yourhostname.com
Content-Length: 1234
Content-Type: application/x-apple-aspen-mdm; charset=UTF-8
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE plist PUBLIC ”-//Apple//DTD PLIST 1.0//EN” ”http://www.apple.com/DTDs/
PropertyList-1.0.dtd”> <plist version=”1.0”>
<dict>
<key>UDID</key>
<string>...</string>
<key>CommandUUID</key> <string>9F09D114-BCFD-42AD-A974-371AA7D6256E</string> <key>Status</key>
<string>Acknowledged</string>
</dict>
</plist>
服务器通过发送设备应该执行的下一个命令来响应,方法是将它封装在HTTP应答中。MDM response payload示例显示服务器的响应负载示例。
清单3.2:MDM响应负载示例:
HTTP/1.1 200 OK
Content-Length: 1234
Content-Type: application/xml; charset=UTF-8
<?xml version=”1.0” encoding=”UTF-8”?>
<!DOCTYPE plist PUBLIC ”-//Apple//DTD PLIST 1.0//EN” ”http://www.apple.com/DTDs/
PropertyList-1.0.dtd”> <plist version=”1.0”>
<dict>
<key>CommandUUID</key> <string>9F09D114-BCFD-42AD-A974-371AA7D6256E</string> <key>Command</key>
<dict>
...
</dict>
</dict>
</plist>
设备执行该命令,并在另一个HTTP PUT请求中将其回复发送到MDM服务器。然后,MDM服务器可以用下一个命令进行回复,或者通过发送一个带有空响应体的200状态(OK)来结束连接。
注意
空响应正文的长度必须为零字节,而不是空属性列表。
如果在设备执行命令时连接断开,则设备将缓存该命令的结果,并重新尝试连接到服务器,直到状态被传递为止。
向设备发送多个推送通知是安全的。APNS合并多个通知,并只向设备发送最后一个通知。
您可以使用Xcode或Apple Configurator 2在设备控制台中监视MDM活动。健康的(但空的)推送活动应该如下所示:
Wed Sep 29 02:09:05 unknown mdmd[1810] <Warning>: MDM|mdmd starting...
Wed Sep 29 02:09:06 unknown mdmd[1810] <Warning>: MDM|Network reachability has
changed.
Wed Sep 29 02:09:06 unknown mdmd[1810] <Warning>: MDM|Polling MDM server https
://10.0.1.4:2001/mdm for commands
Wed Sep 29 02:09:06 unknown mdmd[1810] <Warning>: MDM|Transaction completed. Status:
200
Wed Sep 29 02:09:06 unknown mdmd[1810] <Warning>: MDM|Server has no commands for
this device.
Wed Sep 29 02:09:08 unknown mdmd[1810] <Warning>: MDM|mdmd stopping...
note
如果想看更详细的MDM活动,请查看我的文章:iOS MDM设备底层工作原理
MDM命令有效载荷
主机可以通过发送包含以下所需密钥的plist编码字典向设备发送命令:
Key | Type | Value |
---|---|---|
CommandUUID | String | 命令的UUID |
Command | Dictionary | 命令的数据, Dictionary类型 |
Command字段命令字典的内容必须包括以下必需的键,以及由每个命令。
Key | Type | Value |
---|---|---|
RequestType | String | 请求类型。查看每个命令的描述。 |
RequestRequiresNetworkTether | Boolean | 可选。如果为true,则仅当设备具有连接的网络连接时才执行该命令;否则,将返回12081的MCMDM错误值(请参阅mcmderrordomain)。默认值为false。 |
MDM结果有效载荷
设备通过发送plist编码的字典(包含以下密钥)以及每个命令返回的其他密钥来回复主机。
Key | Type | Value |
---|---|---|
Status | String | 状态。合法值在下面的MDM状态代码中描述。 |
UDID | String | 设备的UUID |
CommandUUID | String | 命令UUID的响应。 |
ErrorChain | Array | 可选。表示发生的错误链的字典数组。这些字典的内容在下面的ErrorChain数组字典键中描述。 |
Status的值包含以下字符串之一:
表3.6:MDM状态代码:
Key | Description |
---|---|
Acknowledged | 一切顺利。 |
Error | 发生错误。有关详细信息,请参见ErrorChain数组。 |
CommandFormatError | 发生协议错误。命令的格式可能不正确。 |
Idle | 设备空闲(没有状态) |
NotNow | 设备接收到命令,但此时无法执行。它将在将来再次轮询服务器。有关详细信息,请参见错误处理。 |
ErrorChain键包含一个数组。第一项是顶级错误。数组中的后续项是导致顶级错误的基础错误。
ErrorChain数组中的每个条目都包含以下字典:
表3.7:ErrorChain数组字典键
Key | Type | Value |
---|---|---|
LocalizedDescription | String | 设备本地化语言中的错误描述 |
USEnglishDescription | String | 可选。美式英语错误描述。 |
ErrorDomain | String | 错误域 |
ErrorCode | Number | 错误code |
ErrorDomain和ErrorCode键包含Apple使用的内部代码,这些代码可能对诊断有用。您的主机不应该依赖这些值,因为它们可能在软件版本之间发生变化。但是,作为参考,当前代码列在错误代码中。