さて、今回は「OS X El Capitan」について。言わずとしれたOS Xの最新バージョンであり、初代Cheetahから数え12代目、14年半という歴史を重ねたOSだ。開発の先端はiPhoneなどモバイル分野へ移行し、かつてほど変化の幅は感じられないものの、しっかり見れば進化の跡はそこかしこに存在する。当コラムらしく、CUIの世界から眺めたその変化の様子をお届けしよう。

rootlessモードの導入

El Capitanでは、スーパーユーザ(root)の機能が制限される。正確にいえば、新たに導入された「System Integrity Protection」と呼ばれる機構により、UNIX系OSでは伝統的にあらゆる処理が許可されるroot -- OS Xの場合、sudoersで許可されたユーザを含む -- から一部の権限を奪うというもの。具体的には、/usr以下など特定領域へのファイルの書き込みおよび削除がrootですら不可能になる。rootlessモードという通称は、rootが存在しないという意味だ。

どのディレクトリがrootlessの対象か、詳細は明らかにされていないが、筆者がsudoとcpコマンドの組み合わせであれこれ試したところ表1の結果が得られた。大まかにいうと、実行形式のファイル(コマンド/ライブラリ)が置かれるディレクトリへの書き込み/削除は制限され、X Window System(X11)などオプショナルな領域についてはroot権限を使えば従来どおり制限を受けない。

この新仕様は、OS Xのセキュリティポリシー変更を受けてのもの。El Capitanでは、Sandbox構造の外にあるプロセス、具体的にはコマンドや各種デーモンにも適用されることとなり、その方策のひとつとして/binや/sbin、/usr/binなどといった伝統的にUNIXのソフトウェア/コマンドが置かれる領域への新規書き込みを禁止したというわけだ。

sudoコマンドを使い管理者権限でファイルコピーしようとしても、/usr/binなどのシステム領域では失敗してしまう

OS X Elcapitanにroot権限で書き込みできるシステム領域
ディレクトリ 書き込み可/不可
/
/bin ×
/etc
/sbin ×
/usr ×
/usr/bin ×
/usr/lib ×
/usr/libexec ×
/usr/sbin ×
/usr/share ×
/usr/standalone ×
/usr/X11
/usr/local ○※
/Applications
/Library
/System ×
/System/Library
※:El Capitanへアップデートする時点で/usr/localが存在しない場合、アップデート後には作成できない(rootlessモードの無効化が必要)

Disk Utilityからあの機能が消えた理由

このrootlessモードは、システム上"絶対的存在"であるrootですら書き込めない以上、マルウェアの入り込む余地は確実に低下する。しかし、ユーザの自由度が低下することも確かで、/usr以下の領域を使用するソフトウェア(UNIX汎用の「make install」するものの多くが該当する)は、インストール先を/usrではなく/usr/localに変更するなどの対処が必要になる。

一方、メリットもある。システム領域のファイルパーミッション(アクセス権)は、ソフトウェアアップデート適用時に自動的に実行され、rootlessモードの効果により固定化されるため、確認や修復を行う必要がなくなった。デザインが一新された「Disk Utility」からアクセス権の検証/修復機能が消えた背景には、このような事情があるのだ。

ところで、El Capitanにアップデートするときには、システム非標準の(rootlessモード下では存在が許容されない)コマンドは/Library/SystemMigration/History/Migration-(一意のID) ディレクトリ以下に移動される。この領域を調べれば、アップデート後に行方不明になったコマンドがわかることだろう。

El Capitanでデザインが一新された「Disk Utility」。アクセス権の検証/修復機能が消えている

rootlessモードを無効化する

このようなrootlessモードだが、「システム環境設定」などのツールに機能をオン/オフするスイッチは見当たらない。セキュリティに関わる機能であり、手軽にオン/オフするような性格のものではないため、この判断は妥当だろう。

方法がないわけではない。El Capitanで追加されたコマンド「csrutil」を使えば、rootlessモードをオン/オフできるのだ。しかし、Terminalを起動して「sudo csrutil disable」などと実行しても、失敗してしまう。どうすればいいのか?

それは「リカバリーモード」。Command-Rを押しながらMacの電源をオンにして、リカバリーモードでの起動が完了したところでTerminalを起動、そこで「csrutil disable」を実行すればOK。次回システムを起動したときには、rootlessモードが無効化されているはずだ。なお、デフォルトの状態に戻すには「csrutil enable」だ。

リカバリーモードでMacを起動し、Terminalでcsrutilコマンドを使えばrootlessモードを無効化できるが、セキュリティの観点からはお勧めできない