滿神奇的,第1次接觸到 iOS 行動裝置管理伺服器(Mobile Device Manager, MDM)。藉由MDM服務,企業可以用來控管配發給員工的iOS Device。
首先,建立一個Enroll.mobileconfig 放在網路上給 iOS 的瀏覽器去下載。
等 iOS device 下載完 Enroll.mobileconfig 之後,iOS device 去自動去觸發 <key>CheckInURL</key> 裡的URL, EX: https://mdmserver/checkin,去註冊 device 時所帶的 plist 如下。
<?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>BuildVersion</key> <string>14G60</string> <key>IMEI</key> <string>99 000289 244779 6</string> <key>MEID</key> <string>99000289244779</string> <key>MessageType</key> <string>Authenticate</string> <key>OSVersion</key> <string>10.3.3</string> <key>ProductName</key> <string>iPad3,6</string> <key>SerialNumber</key> <string>DMPK3ML3F190</string> <key>Topic</key> <string>com.apple.mgmt.External.033dca28-442a-4bcc-9519-ad1165d859c9</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> </dict> </plist>
第1 次 mdm server 收到 MessageType=Authenticate 時就回給iOS device: http status=200 (ok) 回去就結束。 iOS device 發現被摸摸頭很高興,於是就跟 mdm server 講更多關於自己的事情 MessageType=TokenUpdate。
EX: https://mdmserver/checkin
<?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>AwaitingConfiguration</key> <false/> <key>MessageType</key> <string>TokenUpdate</string> <key>PushMagic</key> <string>2E772CFE-FA44-4C6F-B8D6-D56BE793A2AC</string> <key>Token</key> <data> UpTQP5+39KrJHjHRQCW3hAVJ5gEdjbJTpyRlLjTLiI0= </data> <key>Topic</key> <string>com.apple.mgmt.External.033dca28-442a-4bcc-9519-ad1165d859c9</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> <key>UnlockToken</key> <data> REFUQQAABORWRVJTAAAABAAAAARUWVBFAAAABAAAAAJVVUlEAAAAENxVQi0uxUK9vpMA h6TbX2pITUNLAAAAKJicev+1Kg/INk9Mi0yskAmSozj+s5s1pH4d7zE6lLFMwvj33Vj5 jnZXUkFQAAAABAAAAAFTQUxUAAAAFLAB9iKjjIO6cOWmSnJtCTQDZJytSVRFUgAAAAQA AMNQVVVJRAAAABBJYHPy2zxAd72Y8XQFxU8OQ0xBUwAAAAQAAAALV1JBUAAAAAQAAAAB S1RZUAAAAAQAAAAAV1BLWQAAACCio4CsOqbuG+ZfIL769K649iwg+JScRITAjsSSbwf8 C1VVSUQAAAAQTbNMLHZjS5CAJYSXn2SCUkNMQVMAAAAEAAAACldSQVAAAAAEAAAAA0tU WVAAAAAEAAAAAFdQS1kAAAAoCEq3sJ3fAaclGAz9PpeI3UXWhXaMkXB6nT1lTxLbpY+b wr02rXzcflVVSUQAAAAQwOczETaITtCYGKQoKeyDHkNMQVMAAAAEAAAACVdSQVAAAAAE AAAAA0tUWVAAAAAEAAAAAFdQS1kAAAAo8uZIgpAbJkDdLBBHkC0mKE1Znbx5ctVPbrxs pAysmokwWfWoCjybQ1VVSUQAAAAQh+2ChuT/SZKApwl6SN95V0NMQVMAAAAEAAAACFdS QVAAAAAEAAAAAUtUWVAAAAAEAAAAAFdQS1kAAAAg8OQJAVZOhFgU4ZNfdVyyiLK2M8Om pe1QpqKgY3zUUtZVVUlEAAAAEJuQO9TE4kKGvfitqaBZ7GZDTEFTAAAABAAAAAdXUkFQ AAAABAAAAANLVFlQAAAABAAAAABXUEtZAAAAKGSwa/xg0dfVVVsLBFwCYM+mxXCJBPaI WkfKLrBIAnLyQXQDSjgiIgpVVUlEAAAAEGd61qmxfE++u0hFhPPUjj9DTEFTAAAABAAA AAZXUkFQAAAABAAAAANLVFlQAAAABAAAAABXUEtZAAAAKDc/4WTslCM06c3+axbyhGhp ZmlGfbs/4w0D3QGP4TkBjm6mDFKpJIRVVUlEAAAAEOToSX+0SUGXvre4eTxV3dtDTEFT AAAABAAAAAVXUkFQAAAABAAAAANLVFlQAAAABAAAAABXUEtZAAAAKKVGbjWyMStmuzIt zblc9tUY/ZZXccuggmBrhQVnJmPGQYUlvXy2sIhVVUlEAAAAEOXSlmKeX0nQrTi5Bt5r /2xDTEFTAAAABAAAAANXUkFQAAAABAAAAANLVFlQAAAABAAAAABXUEtZAAAAKHBXGOT/ KqH44qwoUfw8liLoyJWmjMl1+xMx6uiIABfeeFl2RdEllClVVUlEAAAAEHNbUmvOukxn nfKr2d/7fZNDTEFTAAAABAAAAAJXUkFQAAAABAAAAANLVFlQAAAABAAAAAFXUEtZAAAA KHK9aMigbkbkEhrf9LFEp0S+lMCgkCecD4ZoW0PB2L7Kc08/UwAx9SxQQktZAAAAIO/9 UaCArpoJGpPfhqPQepJ3ZCz/Z5KNf3B41oGymXFtVVVJRAAAABDo7qHpgTZKU4LuYz6C jQ9/Q0xBUwAAAAQAAAABV1JBUAAAAAQAAAADS1RZUAAAAAQAAAAAV1BLWQAAACgWozY+ m21bLAXBz6haguaEWVmDv/n6g7MKRv0tt5MbctAeg9TeoWKVU0lHTgAAABSagQ4vwR/D NA2+pMD/8D61Ec6mSQ== </data> </dict> </plist>
當 iOS device 做完 token update 之後,會存取 EX: https://mdmserver/server , 傳的訊息內容:
<?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>Status</key> <string>Idle</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> </dict> </plist>
比照之前被摸頭的流程,所以 mdm server 回傳 200 (ok) 之後,iOS device 會再呼叫一次 /server 並告訴 mdm server 自己更多的身世。
<?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>9cf1dd6f-077d-4171-bda3-6c5dbda572e5</string> <key>QueryResponses</key> <dict> <key>AvailableDeviceCapacity</key> <real>10.320999145507812</real> <key>BatteryLevel</key> <real>0.49000000953674316</real> <key>BluetoothMAC</key> <string>94:94:94:94:94:a6</string> <key>BuildVersion</key> <string>14G60</string> <key>CellularTechnology</key> <integer>3</integer> <key>DataRoamingEnabled</key> <false/> <key>DeviceCapacity</key> <real>12.137939453125</real> <key>DeviceName</key> <string>XXX 的 iPad</string> <key>IMEI</key> <string>99 000289 244779 6</string> <key>IsRoaming</key> <true/> <key>MEID</key> <string>99000289244779</string> <key>Model</key> <string>MD525TA</string> <key>ModelName</key> <string>iPad</string> <key>ModemFirmwareVersion</key> <string>11.60.00</string> <key>OSVersion</key> <string>10.3.3</string> <key>ProductName</key> <string>iPad3,6</string> <key>SerialNumber</key> <string>DMPK3ML3F190</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> <key>WiFiMAC</key> <string>94:94:94:94:94:a5</string> </dict> <key>Status</key> <string>Acknowledged</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> </dict> </plist>
當 device 的 profile 移除的 plist:
<?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>MessageType</key> <string>CheckOut</string> <key>Topic</key> <string>com.apple.mgmt.External.033dca28-442a-4bcc-9519-ad1165d859c9</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> </dict> </plist>
滿有趣的,對 iOS device 送 command ,餵給他們吃的 command 他們不喜歡吃,吐出來時還會講:
<?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>139662d1-bb84-42d1-8785-ba8aa7409d6f</string> <key>ErrorChain</key> <array> <dict> <key>ErrorCode</key> <integer>12021</integer> <key>ErrorDomain</key> <string>MCMDMErrorDomain</string> <key>LocalizedDescription</key> <string>「ApplicationConfiguration」不是有效的要求類型。</string> <key>USEnglishDescription</key> <string>“ApplicationConfiguration” is not a valid request type.</string> </dict> </array> <key>Status</key> <string>Error</string> <key>UDID</key> <string>38c2840ff0be3ccff43299d2e06320485facb2f5</string> </dict> </plist>
相關文章:
「三次創作」:
Sample iOS MDM server
https://github.com/macadmins/mdm-server
「二次創作」:
Sample iOS MDM server
https://github.com/project-imas/mdm-server
「原創」:
Intrepidus Group’s iOS MDM tools
https://github.com/intrepidusgroup/imdmtools
Java 版本的 MDM:
https://github.com/davewang/iOS-MDM
javapns
Apple Push Notification Service Provider for Java
https://code.google.com/archive/p/javapns/
Deploying iPhone and iPad Mobile Device Management for java
https://github.com/zuoyy/IOS-MDM-Server
[iOS] get MDM settings from system dictionary in swift
https://stackoverflow.max-everyday.com/2018/01/ios-get-mdm-settings-from-system-dictionary-in-swift/
MDM推送設定值到 iOS device
https://stackoverflow.max-everyday.com/2017/09/mdm-settings-ios-device/
MDM推送App到 iOS device
https://stackoverflow.max-everyday.com/2017/09/mdm-install-app/
請問作者
有遇過當 MDM 的憑證過期時,有辦法透過 MDM server 送command 去更新Device憑證嗎?
請問作者
有處理過 MDM 憑證到期 renew 相關憑證(MDM server 與 Device 上的 .mobileconfig) 的經驗嗎?
renew 的步驟大概是要到 https://identity.apple.com/pushcert/ 做的
不是很清楚,如有先感謝你的分享