macOSにSystem Extensionが登場してから、管理されているmacOSにおけるSystem Extensionの知見があまり見受けられなかったため、備忘を兼ねて記載していこうと思います。

System Extensionとは

macOS Catalina (10.15)より、Kernel Extensionは非推奨となり、新たにSystem Extensionが導入されました。 Big Sur (11.0)より徐々に機能使えなくなり、将来的にはすべてのKernel Extensionが使えなくなる予定です。

System Extensionを使用することで、アプリケーションはカーネルレベルのアクセスを必要とすることなく、macOSの機能を拡張できるようになりました。

エンドユーザーはKernel Extensionの時と同じく、[システム環境設定] > [セキュリティとプライバシー] > [一般]から対象のExtensionを許可することで、System Extensionを利用するアプリケーションが使用できます。

OS上のSystem Extensionの情報収集

systemextensionsctlコマンド

$ systemextensionsctl
systemextensionsctl: usage:
  systemextensionsctl developer [on|off]
  systemextensionsctl list [category]
  systemextensionsctl reset  - reset all System Extensions state
  systemextensionsctl uninstall <teamId> <bundleId>; can also accept '-' for teamID

systemextensionsctlコマンドにはlistサブコマンドがあります。 これにより、どのSystem Extensionをどのアプリケーションが使用しているかや、System Extensionを使用しているアプリケーションの情報が確認できます。

$ systemextensionsctl list
2 extension(s)
--- com.apple.system_extension.network_extension
enabled  active  teamID  bundleID (version)  name  [state]
*  *  UBF8T346G9  com.microsoft.wdav.netext (101.49.25/101.49.25)  Microsoft Defender ATP Network Extension  [activated enabled]
--- com.apple.system_extension.endpoint_security
enabled  active  teamID  bundleID (version)  name  [state]
*  *  UBF8T346G9  com.microsoft.wdav.epsext (101.49.25/101.49.25)  Microsoft Defender ATP Endpoint Security Extension  [activated enabled]

/Library/SystemExtensions/db.plistファイル

systemextensionsctllistサブコマンドでSystem Extensionの状態を確認できました。 より詳細の情報を確認したい場合は、/Library/SystemExtensions/db.plist を参照することで確認できます。

このファイルには、

  • ポリシーによって、どのSystem Extensionが有効化されているか
    • developerModeキーが該当
  • デベロッパーモードかどうか
    • extensionPoliciesキーが該当
  • OSが認識しているSystem Extensionの詳細情報
    • extensionsキーが該当

の情報が保存されています。

$ plutil -convert xml1 -o - /Library/SystemExtensions/db.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>bootUUID</key>
  <string>6109BDDC-E257-4CDC-97F5-52B06A9061F5</string>
  <key>developerMode</key>
  <false/>
  <key>extensionPolicies</key>
  <array>
    <dict>
      <key>allowUserOverrides</key>
      <true/>
      <key>allowedExtensionTypes</key>
      <dict/>
      <key>allowedExtensions</key>
      <dict>
        <key>UBF8T346G9</key>
        <array>
          <string>com.microsoft.wdav.netext</string>
          <string>com.microsoft.wdav.epsext</string>
        </array>
      </dict>
      <key>allowedTeamIDs</key>
      <array/>
      <key>uniqueID</key>
      <string>57E74064-648C-42CE-BD97-14B06326A3FA</string>
    </dict>
  </array>
  <key>extensions</key>
  <array>
    <dict>
      <key>additionalLaunchdPlistEntries</key>
      <data>
      xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
      </data>
      <key>bundleVersion</key>
      <dict>
        <key>CFBundleShortVersionString</key>
        <string>101.49.25</string>
        <key>CFBundleVersion</key>
        <string>101.49.25</string>
      </dict>
      <key>categories</key>
      <array>
        <string>com.apple.system_extension.endpoint_security</string>
      </array>
      <key>container</key>
      <dict>
        <key>bundlePath</key>
        <string>/Applications/Microsoft Defender ATP.app</string>
      </dict>
      <key>identifier</key>
      <string>com.microsoft.wdav.epsext</string>
      <key>originPath</key>
      <string>/Applications/Microsoft Defender ATP.app/Contents/Library/SystemExtensions/com.microsoft.wdav.epsext.systemextension</string>
      <key>references</key>
      <array>
        <dict>
          <key>appIdentifier</key>
          <string>com.microsoft.wdav</string>
          <key>appRef</key>
          <string>file:///.file/id=6571367.12966214250/</string>
          <key>teamID</key>
          <string>UBF8T346G9</string>
        </dict>
      </array>
      <key>stagedBundleURL</key>
      <dict>
        <key>relative</key>
        <string>file:///Library/SystemExtensions/FE13FAA3-3E65-48E1-B422-DCA47F56DF6E/com.microsoft.wdav.epsext.systemextension/</string>
      </dict>
      <key>stagedCdhashes</key>
      <dict>
        <key>42dcc7c4b5269f6a539c7766640e04263abc201d</key>
        <dict>
          <key>cpusubtype</key>
          <integer>0</integer>
          <key>cputype</key>
          <integer>16777228</integer>
        </dict>
        <key>af3e8c0fd64cec8340081360171504b1994b656b</key>
        <dict>
          <key>cpusubtype</key>
          <integer>3</integer>
          <key>cputype</key>
          <integer>16777223</integer>
        </dict>
      </dict>
      <key>state</key>
      <string>activated_enabled</string>
      <key>teamID</key>
      <string>UBF8T346G9</string>
      <key>uniqueID</key>
      <string>FE13FAA3-3E65-48E1-B422-DCA47F56DF6E</string>
    </dict>
    <dict>
    (略)
    </dict>
  </array>
  <key>version</key>
  <integer>1</integer>
</dict>
</plist>

アプリケーションの直接参照

systemextensionsctlコマンドや/Library/SystemExtensions/db.plistファイルからは、あくまでアプリケーションが一度起動しないと情報が取得できません。 しかし、一度もアプリケーションを起動せずにSystem Extensionの情報を取得したい場合もあります。

その際は、アプリケーションの中身を直接確認することで、System Extensionの情報を取得できます。

System Extensionを有するアプリケーション(ここではSample.appとします)にはSample.app/Contents/Library/SystemExtensionsディレクトリが存在し、その中にbundleIDごとのディレクトリが存在します。

たとえば、System Extensionを有するMicrosoft Defender for Endpointのアプリケーションであれば、以下のようにSystem Extensionが用意されていることがわかります。

$ ls -l "/Applications/Microsoft Defender ATP.app/Contents/Library/SystemExtensions/"
total 0
drwxr-xr-x  3 root  wheel  96 11  4 02:24 com.microsoft.wdav.epsext.systemextension
drwxr-xr-x  3 root  wheel  96 11  4 02:24 com.microsoft.wdav.netext.systemextension

アプリケーションの直接参照におけるteamIDとbundleIDの特定方法

System Extensionを一意に特定するには、teamIDbundleIDが必要です。 systemextensionsctlコマンドや/Library/SystemExtensions/db.plistファイルでは、これらの情報を参照できました。

アプリケーションを直接参照する場合は、codesignコマンドでこれらの情報が取得できます。

$ codesign -dvvv "/Applications/Microsoft Defender ATP.app/Contents/Library/SystemExtensions/com.microsoft.wdav.epsext.systemextension" 2>&1 | awk -F= '/^TeamIdentifier/ {print $NF}'
UBF8T346G9
$ codesign -dvvv "/Applications/Microsoft Defender ATP.app/Contents/Library/SystemExtensions/com.microsoft.wdav.epsext.systemextension" 2>&1 | awk -F= '/^Identifier/ {print $NF}'
com.microsoft.wdav.epsext

System Extensionのアンインストールについて

前述したsystemextensionsctlコマンドの使用例を見てみると、list以外にもresetuninstallが存在します。 しかし、これらのコマンドはSIP(System Integrity Protection)を無効化しなければ機能しません。

$ systemextensionsctl uninstall
At this time, this tool cannot be used if System Integrity Protection is enabled.
This limitation will be removed in the near future.
Please remember to re-enable System Integrity Protection!

macOS MontereyからはSystem Extensionを管理するペイロードにRemovableSystemExtensionsが追加1され、System Extensionの削除が可能となりました。

macOS Big Sur以下の場合、SIPを無効化する方法はセキュリティのリスク高める可能性があるため、あまりお勧めできません。

しかし、System Extensionをアンインストールしたい場合もあるため、代替案を紹介します。

macOS Big Surまでの代替案

ゴミ箱を介したSystem Extensionのアンインストール

GUIを用いて、System Extensionを含んだアプリケーションをゴミ箱アイコンにドラックアンドドロップすることでSystem Extensionの削除に関するダイアログが表示されます。 ダイアログに従い削除すると、管理者権限を求められます。 その後、OSを再起動することでSystem Extensionが削除されます。

deactivationRequestのAPIを介したアンインストール

ゴミ箱を介した方法は管理権限が必要でした。 しかし、管理されているmacOSでは管理者権限を用いずにSystem Extensionを削除したい場合があります。

対象のアプリケーションがdeactivationRequestの呼び出しをサポートしている場合は、OSの設定を変更することで管理者権限をバイパスすることできます。

たとえば、Micorosft Defender for Endpointの場合は以下のコマンドでdeactivationRequestを発行できます。

"/Applications/Microsoft Defender ATP.app/Contents/MacOS/wdavdaemon" uninstall-system-extension ここにbundleID

通常ではdeactivationRequestのAPIを呼び出した場合は、管理者権限が要求されます。 しかし、認証データベースのcom.apple.system-extensions.adminを書き換えることで、管理者権限を求められないようになります。

$ security authorizationdb read com.apple.system-extensions.admin
<?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>class</key>
  <string>rule</string>
  <key>comment</key>
  <string>Authorize a 3rd party application which wants to manipulate system extensions.</string>
  <key>created</key>
  <real>611474119.72543597</real>
  <key>modified</key>
  <real>611474119.72543597</real>
  <key>rule</key>
  <array>
    <string>authenticate-admin-nonshared</string>
  </array>
  <key>version</key>
  <integer>0</integer>
</dict>
</plist>
YES (0)

デフォルトではauthenticate-admin-nonshared、つまり管理者権限を要求するように設定されています。 このルールをallowに変更することで管理者権限を要求しないように変更できます。

認証データベースのルールは以下のように変更します。

$ security authorizationdb write com.apple.system-extensions.admin allow
YES (0)
$ security authorizationdb read com.apple.system-extensions.admin
<?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>class</key>
  <string>rule</string>
  <key>created</key>
  <real>611474119.72543597</real>
  <key>modified</key>
  <real>667494210.52982104</real>
  <key>rule</key>
  <array>
    <string>allow</string>
  </array>
  <key>version</key>
  <integer>0</integer>
</dict>
</plist>
YES (0)

MDMにおけるSystem Extensionの制御

System Extnsionは通常、管理者権限を用いて [システム環境設定] > [セキュリティとプライバシー] > [一般] から個別に許可する必要があります。

しかし、管理されているmacOSの場合はMDMのAPI(プロファイル)を使用してSystem Extensionを許可できます。

Jamf ProにおけるSystem Extensionの許可方法

Jamf Proでは構成プロファイルを用いて、System Extensionの統制ができます。

[コンピュータ] > [構成プロファイル] > [新規] > [システム拡張機能] から設定をします。

Jamf Proにおける構成プロファイルのSystem Extension設定

System Extensionの許可に関しては以下の3つの方法が用意されています。

  1. teamIDとbundleIDを指定
    • Allowed System Exntesionが該当
  2. teamIDを指定
    • Allowed Team Identifersが該当
  3. Extensionの種類を指定
    • Allowed System Exntesion Typesが該当

執筆現在、期待通りに動作するのは「teamIDとbundleIDを指定」の方法のみであったため、注意が必要です。 ちなみに「teamIDを指定」する方法はSystem Extension [activated waiting for user] - Jamf Nation Community - 229168にてバグのため機能しないことが言及されています。Jamf社側もこの問題を認識しており、PI-007713というチケット番号でIssueが管理されています。

例のごとく、Microsoft Defender for Endpointの場合は以下のように設定します。

Jamf Proにおける構成プロファイルのSystem Extensionの設定 - Microsoft Defender for Endpointのケース

終わりに

管理されているmacOSでは、EDRやAVといったソフトウェアが導入されることが多いと思います。 そのほとんどがSystem Extensionを使用しているため、それをきっかけにSystem Extensionを管理したいと考える方もいると思います。

私も最初はバグにも悩まされ、どのようにしたら期待通りに機能するかがわかりませんでした。 System Extensionに関してはJamfのサポートに問い合わせても、なかなか良い回答が得られなかった経験があるため、困っている方の一助になれば幸いです。

ちなみに、EDRやAVといったソフトウェアはSystem Extension以外にも、ファイルスキャンのためすべてのファイルのアクセスを行うため、合わせてPPPCの設定をする場合があります。 System ExtensionとPPPCを混同しがちなのでご注意ください。