第10章 SELinux systemd のアクセス制御
Red Hat Enterprise Linux 7 では、システムサービスは
systemd デーモンにより制御されます。Red Hat Enterprise Linux の以前のリリースでは、デーモンを起動する方法が 2 つありました。
- システムの起動時に、System V
initデーモンはinit.rcスクリプトを起動し、このスクリプトにより必要なデーモンを起動します。たとえば、システムの起動時に起動した Apache サーバーには、以下の SELinux ラベルが貼られています。system_u:system_r:httpd_t:s0
system_u:system_r:httpd_t:s0Copy to Clipboard Copied! Toggle word wrap Toggle overflow - 管理者が手動で
init.rcスクリプトを起動すると、デーモンが実行します。たとえば、service httpd restart コマンドを Apache サーバーで実行すると、表示される SELinux ラベルは次のようになります。unconfined_u:system_r:httpd_t:s0
unconfined_u:system_r:httpd_t:s0Copy to Clipboard Copied! Toggle word wrap Toggle overflow
手動で開始すると、このプロセスでは、開始した SELinux ラベルのユーザー部分が採用され、上記の 2 つのシナリオでのラベリングに矛盾が発生します。
systemd デーモンでは、遷移が大きく異なります。systemd は、init_t タイプを使用して、システムでデーモンを開始および停止するすべての呼び出しを処理するため、デーモンを手動で再起動すると、ラベルのユーザー部分を上書きできます。その結果、上記の両方のシナリオのラベルは、期待どおりに system_u:system_r:httpd_t:s0 で、SELinux ポリシーを改善して、どのドメインがどのユニットを制御できるかを管理できます。
10.1. サービスへの SELinux のアクセス権限 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
以前のバージョンの Red Hat Enterprise Linux では、管理者は System V Init スクリプトのラベルに基づいて、どのユーザーまたはアプリケーションがサービスを開始または停止できるかを制御できました。現在、
systemd はすべてのサービスを開始および停止し、ユーザーとプロセスは、systemctl ユーティリティーを使用して systemd と通信します。systemd デーモンは、SELinux ポリシーを調べ、呼び出しているプロセスのラベルと、呼び出し元が管理しようとしているユニットファイルのラベルを確認してから、呼び出し元のアクセスを許可するかどうかを SELinux に確認します。このアプローチにより、システムサービスの開始や停止などの、重要なシステム機能へのアクセス制御が強化されます。
たとえば、管理者は、NetworkManager が
systemctl を実行して D-Bus メッセージを systemd に送信できるようにする必要がありました。これにより、NetworkManager が要求するサービスが開始または停止します。実際、NetworkManager は、systemctl ができることをすべて実行できるようになっていました。また、特定のサービスのみを開始または停止できるように、限定管理者を設定することもできませんでした。
この問題を修正するために、
systemd は SELinux Access Manager としても機能します。systemctl を実行しているプロセス、またはsystemd に D-Bus メッセージを送信したプロセスのラベルを取得できます。次に、デーモンは、プロセスが設定するユニットファイルのラベルを探します。最後に、SELinux ポリシーでプロセスラベルとユニットファイルラベルとの間で特定のアクセスが許可されている場合、systemd はカーネルから情報を取得できます。これは、特定のサービスに対して、systemd と相互作用する必要がある侵害されたアプリケーションを SELinux が制限できることを意味します。ポリシー作成者は、このような粒度の細かい制御を使用して、管理者を制限することもできます。ポリシーの変更には、以下のパーミッションを持つ service という名前の新しいクラスが関与します。
たとえば、ポリシーの作成者は、ドメインがサービスのステータスを取得したり、サービスを開始および停止したりできるようになりましたが、サービスを有効または無効にすることはできません。SELinux および
systemd でのアクセス制御操作は、すべての場合で一致するわけではありません。SELinux アクセスログと、systemd メソッド呼び出しをラインアップするためにマッピングが定義されました。表10.2「SELinux アクセスチェックでの systemd 一般システムコールのマッピング」 は、システム全般のアクセスチェックをカバーするのに対し、表10.1「SELinux アクセスチェックでの systemd ユニットファイルメソッド呼び出しのマッピング」 は、ユニットファイルのアクセスチェックをマップします。いずれかのテーブルに一致するものが見つからない場合は、undefined システムチェックが呼び出されます。
systemd ユニットファイルメソッド | SELinux アクセスチェック |
|---|---|
| DisableUnitFiles | disable |
| EnableUnitFiles | enable |
| GetUnit | status |
| GetUnitByPID | status |
| GetUnitFileState | status |
| Kill | stop |
| KillUnit | stop |
| LinkUnitFiles | enable |
| ListUnits | status |
| LoadUnit | status |
| MaskUnitFiles | disable |
| PresetUnitFiles | enable |
| ReenableUnitFiles | enable |
| Reexecute | start |
| Reload | reload |
| ReloadOrRestart | start |
| ReloadOrRestartUnit | start |
| ReloadOrTryRestart | start |
| ReloadOrTryRestartUnit | start |
| ReloadUnit | reload |
| ResetFailed | stop |
| ResetFailedUnit | stop |
| 再起動 | start |
| RestartUnit | start |
| 起動 | start |
| StartUnit | start |
| StartUnitReplace | start |
| 停止 | stop |
| StopUnit | stop |
| TryRestart | start |
| TryRestartUnit | start |
| UnmaskUnitFiles | enable |
systemd 汎用システムコール | SELinux アクセスチェック |
|---|---|
| ClearJobs | reboot |
| FlushDevices | halt |
| Get | status |
| GetAll | status |
| GetJob | status |
| GetSeat | status |
| GetSession | status |
| GetSessionByPID | status |
| GetUser | status |
| Halt | halt |
| Introspect | status |
| KExec | reboot |
| KillSession | halt |
| KillUser | halt |
| ListJobs | status |
| ListSeats | status |
| ListSessions | status |
| ListUsers | status |
| LockSession | halt |
| PowerOff | halt |
| 再起動 | reboot |
| SetUserLinger | halt |
| TerminateSeat | halt |
| TerminateSession | halt |
| TerminateUser | halt |
例10.1 システムサービスに関する SELinux ポリシー
sesearch ユーティリティーを使用すると、システムサービスのポリシールールをリスト表示できます。たとえば、sesearch -A -s NetworkManager_t -c service コマンドを呼び出すと以下が返されます。