SELinux の使用


Red Hat Enterprise Linux 10

Security-Enhanced Linux (SELinux) を使用して、ユーザーやプロセスによるファイルやデバイスに対する不正な操作を防止する

概要

SELinux を設定することで、システムのセキュリティーを強化できます。SELinux は強制アクセス制御 (MAC) の実装であり、追加のセキュリティー層を提供します。SELinux ポリシーは、ユーザーとプロセスがシステム上のファイルと対話する方法を定義します。特定の SELinux で制限されたユーザーにマッピングすることで、どのユーザーがどのアクションを実行できるかを制御できます。

Red Hat ドキュメントへのフィードバック (英語のみ)

Red Hat は質の高いドキュメントを提供することに尽力しており、皆様からのフィードバックを大切にしています。改善にご協力いただくため、Red Hat Jira トラッキングシステムを通じてご提案やエラー報告をお寄せください。

手順

  1. Jira の Web サイトにログインします。

    アカウントがない場合、アカウント作成オプションを選択します。

  2. 上部のナビゲーションバーで Create をクリックします。
  3. Summary フィールドにわかりやすいタイトルを入力します。
  4. Description フィールドに、ドキュメントの改善に関するご意見を記入してください。ドキュメントの該当部分へのリンクも追加してください。
  5. ダイアログの下部にある Create をクリックします。

第1章 SELinux の使用

Security Enhanced Linux (SELinux) の基本概念を理解することで、システムのセキュリティーを強化します。SELinux のアーキテクチャー、パッケージ、および動作モードに関する知識は、システムポリシーを効果的に管理するのに役立ちます。

1.1. SELinux の概要

Security Enhanced Linux (SELinux) は、システムセキュリティーを強化する強制アクセス制御 (MAC) の実装です。SELinux は、プロセスがファイルやネットワークリソースとどのようにやり取りするかを制限するきめ細かなポリシーを適用することで、侵害されたアプリケーションの影響を軽減し、不正アクセスを防止します。

標準任意アクセス制御 (DAC) は、ユーザー、グループ、およびその他の権限に基づいてアクセスポリシーを設定します。このモデルでは、システム管理者が、特定のアプリケーションにはログファイルの閲覧のみを許可し、他のアプリケーションにはログファイルへのデータ追加を許可するなど、きめ細かなセキュリティーポリシーを作成できなくなります。

SELinux は、強制アクセス制御 (MAC) ポリシーを適用することで、保護のレイヤーを追加します。MAC ポリシーは、Web サーバーはユーザーのホームディレクトリー内のファイルにアクセスしてもよいか? などの <対象> は <オブジェクト> に対して <アクション> を実行してもよいか? という質問に答えます。すべてのプロセスおよびシステムリソースには、SELinux コンテキスト と呼ばれる特別なセキュリティーラベルがあります。SELinux コンテキスト (SELinux ラベル とも呼ばれる) は、システムレベルの詳細を抽象化し、エンティティーのセキュリティー特性に焦点を当てるための識別子です。この識別子は、SELinux ポリシー内のオブジェクトを参照するための一貫した方法を提供し、他の識別方法に見られる曖昧さを解消します。たとえば、バインドマウントを使用するシステムでは、1 つのファイルに複数の有効なパス名が存在する可能性があります。

SELinux ポリシーは、プロセスがシステムリソースにアクセスする方法を定義するルールの中で、コンテキストを使用します。デフォルトでは、ルールによって明示的にアクセスが許可されない限り、ポリシーはすべての操作を拒否します。

詳細は、selinux(8) の man ページ、および selinux-policy-doc パッケージがシステムにインストールされている場合に man -k selinux コマンドで表示される man ページを参照してください。

注記

SELinux ポリシールールは、DAC ルールの後にチェックされます。DAC ルールがアクセスを拒否した場合、SELinux ポリシールールは評価されず、SELinux によるアクセス拒否はログに記録されません。

SELinux のコンテキストには、ユーザー、ロール、タイプ、セキュリティーレベルの 4 つのフィールドがあります。SELinux ポリシーにおいて最も重要なのはタイプフィールドです。理由は、プロセスとリソース間の許可される操作を定義する際、一般的なポリシールールではコンテキスト全体ではなく、このタイプが判断基準として用いられるからです。SELinux のタイプの名前は、最後に _t が付きます。たとえば、Web サーバーのタイプコンテキストは httpd_t です。/var/www/html/ 内のファイルとディレクトリーは httpd_sys_content_t タイプを、/tmp および /var/tmp/ 内のファイルとディレクトリーは tmp_t を使用します。Web サーバーポートのタイプは http_port_t です。

Apache (httpd_t として実行する Web サーバープロセス) を許可するポリシールールがあります。このルールでは、通常 /var/www/html/ にあるコンテキストを持つファイルおよびディレクトリーと、その他の Web サーバーディレクトリー (httpd_sys_content_t) へのアクセスを許可します。通常、/tmp および /var/tmp/ にあるファイルに対する許可ルールはポリシーにないため、アクセスは許可されません。SELinux を使用すれば、Apache が危険にさらされ、悪意のあるスクリプトがアクセスを得た場合でも、/tmp ディレクトリーにアクセスすることはできなくなります。

図1.1 Apache と MariaDB を安全に実行するのに SELinux がどのように役立つかの例

SELinux_Apache_MariaDB_example

前述の図が示すように、SELinux は httpd_t として実行されている Apache プロセスが /var/www/html/ ディレクトリーにアクセスすることを許可しますが、httpd_t および mysqld_db_t タイプのコンテキストに対して許可ルールが存在しないため、/data/mysql/ へのアクセスを拒否します。逆に、mysqld_t として実行されている MariaDB プロセスは /data/mysql/ にアクセスできますが、httpd_sys_content_t とラベル付けされている /var/www/html/ へのアクセスは拒否されます。

1.2. SELinux を実行する利点

Security Enhanced Linux (SELinux) を使用することで、特権昇格攻撃を軽減し、データの機密性を確保できます。プロセスがファイルやシステムリソースとどのようにやり取りするかを制限し、きめ細かなアクセス制御を実装し、侵害されたアプリケーションの影響を最小限に抑えることができます。

SELinux を実行することで、以下のセキュリティー上の利点が得られます。

  • プロセスとファイルにはすべてラベルが付いています。SELinux ポリシーにより、プロセスがファイルと相互作用する方法と、プロセスが互いに相互作用する方法が定義されます。SELinux ポリシー規則で明示的に許可されている場合にのみ、アクセスが許可されます。
  • SELinux はきめ細かなアクセス制御を提供します。ユーザーの裁量と、Linux のユーザー ID およびグループ ID に基づいて制御される従来の UNIX アクセス権とは異なり、SELinux のアクセス決定は、SELinux のユーザー、ロール、タイプ、および (オプションで) セキュリティーレベルなど、入手可能なすべての情報に基づいています。
  • SELinux ポリシーは管理者が定義し、システム全体に適用されます。
  • SELinux は権限昇格攻撃を軽減できます。プロセスはドメインで実行するため、互いに分離しています。SELinux ポリシールールは、プロセスがどのようにファイルやその他のプロセスにアクセスするかを定義します。プロセスへのアクセスが不正に行われても、攻撃者は、そのプロセスの通常の機能と、そのプロセスがアクセスするように設定されているファイルにしかアクセスできません。たとえば、Apache HTTP Server が侵害されても、そのようなアクセスを許可する特定の SELinux ポリシールールが追加または設定されていない限り、攻撃者はそのプロセスを使用してユーザーのホームディレクトリー内のファイルを読み取ることはできません。
  • SELinux はデータの機密性と整合性を強化し、信頼できない入力からプロセスを保護できます。

SELinux は、ウイルス対策ソフトウェア、セキュアなパスワード、ファイアウォール、その他のセキュリティーシステムに代わるものではなく、既存のセキュリティーソリューションを強化することを目的としたものです。SELinux を実行している場合でも、ソフトウェアを最新の状態にする、推測が困難なパスワードを使用する、ファイアウォールを使用するなど、優れたセキュリティー対策を続けることが重要です。

1.3. SELinux の例

Security-Enhanced Linux (SELinux) のセキュリティー上の利点は、多くの実用的なシナリオで有効です。プロセス分離とユーザー制限の実際の事例を検証することで、SELinux が特権昇格、設定エラー、および一般的な脆弱性をどのように軽減するのかが理解できます。

SELinux は、以下のようないくつかの方法でシステムセキュリティーを強化します。

  • デフォルトのアクションは拒否です。アクセスを許可する SELinux のポリシールール (ファイルを開くプロセスなど) が存在しない場合は、SELinux によりアクセスが拒否されます。
  • 制限付きユーザーは特権が限定されます。Linux ユーザーを制限付き SELinux ユーザーにマッピングして、セキュリティールールを適用できます。たとえば、Linux ユーザーを user_u にマッピングすると、そのユーザーは sudosu などの setuid アプリケーションを実行できなくなります。
  • SELinux ドメイン は、プロセスとデータの分離を強化します。ドメインを使用して、どのプロセスが特定のファイルやディレクトリーにアクセスできるかを定義します。たとえば、攻撃者は Samba サーバーを侵害しても、そのサーバーを使用して、MariaDB データベースなど、他のプロセスで使用されるファイルにアクセスできません。
  • SELinux は設定エラーを軽減します。攻撃者は、Domain Name System (DNS) のゾーン転送を悪用して、偽の情報を注入できます。RHEL 上で Berkeley Internet Name Domain (BIND) を DNS サーバーとして実行し、ゾーン転送を制限しない場合、デフォルトの SELinux ポリシーにより、named デーモンやその他のプロセスがゾーン転送を使用してゾーンファイルを更新できなくなります。 [1].
  • SELinux はパストラバーサル攻撃を軽減します。攻撃者は、Apache Web サーバーの脆弱性を悪用して、../ などの特殊な要素を使用してファイルシステムにアクセスできます。SELinux を enforcing モードで実行する場合、ポリシーにより httpd プロセスが不正なファイルにアクセスできないようにします。
  • SELinux は、SMAP 非対応プラットフォームでのカーネル NULL ポインター参照解除の悪用を防止します。攻撃者は、mmap 関数の脆弱性を悪用して、null ページに任意のコードを配置できます (CVE-2019-9213)。SELinux を enforcing モードで実行している場合、このポリシーによってこの種の攻撃が防止されます。
  • SELinux は *PTRACE_TRACEME の悪用を防止します。* deny_ptrace ブール値を使用すると、PTRACE_TRACEME の脆弱性 (CVE-2019-13272) からシステムを保護できます。これにより、攻撃者が root 特権を取得できないようにします。
  • SELinux は NFS の設定ミスを防ぎます。nfs_export_all_rw および nfs_export_all_ro ブール値を使用すると、/home ディレクトリーを誤って共有するなど、ネットワークファイルシステム (NFS) の設定ミスを防ぐことができます。


[1] ホスト名から IP アドレスへのマッピングなど、DNS 情報を含むテキストファイル。

1.4. SELinux のアーキテクチャーおよびパッケージ

SELinux カーネルサブシステムはセキュリティーポリシーを適用し、systemd デーモンはアクセス制御を強化してシステムサービスを保護します。SELinux のインストールとメンテナンスに必要なパッケージを特定し、管理に必要なユーティリティーが揃うようにします。

SELinux は、Linux カーネルに組み込まれた Linux Security Module (LSM) です。アクセスを制御するために、ユーザーが管理するセキュリティーポリシーを適用します。SELinux はアクセス要求を傍受し、ロードされたポリシーと照合してチェックします。ポリシーが要求を許可している場合、SELinux はそのアクションを許可します。そうでない場合、SELinux はその操作をブロックし、エラーを報告します。

SELinux は、アクセスを許可するか拒否するかといった決定事項を、Access Vector Cache (AVC) にキャッシュします。このキャッシュは、ポリシー規則のチェック回数を減らすことでパフォーマンスを向上させます。SELinux のポリシー規則は、任意アクセス制御 (DAC) 規則によって先にアクセスが許可された場合にのみ適用されます。SELinux は type=AVC 識別子を使用して監査メッセージを /var/log/audit/audit.log にロギングします。

RHEL 10 では、systemd デーモンがシステムサービスを管理します。systemd はすべてのサービスを開始および停止し、ユーザーとプロセスは systemctl ユーティリティーを使用して systemd と通信します。systemd デーモンは SELinux ポリシーをチェックし、呼び出し元のプロセスとユニットファイルのラベルを検証してアクセスを許可します。このアプローチにより、システムサービスの開始や停止といった重要なシステム機能へのアクセス制御が強化されます。

systemd デーモンは、SELinux Access Manager としても機能します。systemctl を実行するプロセス、または D-Bus メッセージを送信するプロセスのラベルを取得します。次に、デーモンは、プロセスが設定するユニットファイルのラベルを探します。最後に、systemd はカーネルに問い合わせて、ポリシーがプロセスラベルとユニットファイルラベル間の特定のアクセスを許可しているかどうかを判断します。この隔離により、侵害されたアプリケーションが制限されます。ポリシー作成者は、これらの統制手段を用いて管理者の権限を制限することもできます。

SELinux ポリシーによって 2 つのプロセス間の D-Bus 通信が拒否された場合、システムは USER_AVC 拒否メッセージをログに記録し、通信はタイムアウトします。D-Bus 通信は双方向です。

重要

SELinux のラベル付けミスやそれに伴う問題を回避するため、systemctl start コマンドを使用してサービスを開始するようにしてください。

RHEL 10 では、SELinux を使用するために以下のパッケージが提供されています。

  • ポリシー: selinux-policy-targetedselinux-policy-mls
  • ツール - policycoreutilspolicycoreutils-guilibselinux-utilspolicycoreutils-python-utilssetools-consolecheckpolicy

1.5. SELinux のステータスおよびモード

SELinux の enforcing モード、permissive モード、disabled モードは、システムセキュリティーを効果的に管理するのに役立ちます。これらの状態を利用することで、システム運用を中断することなく、ポリシーを適用したり、アクセス拒否のトラブルシューティングを行ったりすることができます。

SELinux は、3 つのモード (Enforcing、Permissive、または Disabled) のいずれかで実行できます。

  • Enforcing モードは、デフォルトのモードで、推奨される動作モードです。SELinux は、Enforcing モードでは正常に動作し、読み込んだセキュリティーポリシーをシステム全体に強制します。
  • Permissive モードでは、システムは、読み込んだセキュリティーポリシーを SELinux が強制しているように振る舞い、オブジェクトのラベリングや、アクセスを拒否したエントリーをログに出力しますが、実際に操作を拒否しているわけではありません。Permissive モードは、実稼働システムで使用することは推奨されませんが、SELinux ポリシーの開発やデバッグには役に立ちます。
  • Disabled モードを使用することは推奨されません。システムは、SELinux ポリシーの強制を回避するだけでなく、ファイルなどのあらゆる永続オブジェクトにラベルを付けなくなり、将来的に SELinux を有効にすることが難しくなります。

Enforcing モードと Permissive モードとの間を切り替えるには setenforce ユーティリティーを使用してください。setenforce で行った変更は、システムを再起動すると元に戻ります。Enforcing モードに変更するには、Linux の root ユーザーで、setenforce 1 コマンドを実行します。Permissive モードに変更するには、setenforce 0 コマンドを実行します。getenforce ユーティリティーを使用して、現在の SELinux モードを表示します。

# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
# setenforce 1
# getenforce
Enforcing

Red Hat Enterprise Linux では、システムを Enforcing モードで実行している場合に、個々のドメインを Permissive モードに設定できます。たとえば、httpd_t ドメインを Permissive に設定するには、以下のコマンドを実行します。

# semanage permissive -a httpd_t

Permissive ドメインは、システムのセキュリティーを侵害できる強力なツールです。Red Hat は、特定のシナリオのデバッグ時など、Permissive ドメインを使用する場合は慎重に使用することを推奨します。

第2章 SELinux のステータスおよびモードの変更

SELinux を enforcing モード、permissive モード、または disabled モードに設定することで、システムがセキュリティーポリシーをどのように適用するかを制御できます。これらの状態は、永続的に適用することも、起動時に適用することもできます。これにより、アクセス拒否のトラブルシューティングや、SELinux を有効にする際にファイルシステムが正しくラベル付けされるようにします。

SELinux が有効になっている場合は、Enforcing モードまたは Permissive モードのいずれかで実行できます。デフォルトでは、SELinux は有効になっており、enforcing モードで実行されます。SELinux を無効にしたり、permissive モードに設定したりすると、SELinux によるシステムの保護ができなくなります。setenforce コマンドを使用して SELinux ステータスを変更した場合は、変更は一時的で、再起動後に元に戻ります。SELinux ステータスを永続的に変更するには、SELinux 設定ファイルまたはカーネルパラメーターを変更する必要があります。

2.1. SELinux のステータスおよびモードの永続的変更

SELinux モードは、システムがセキュリティーポリシーをどのように適用し、アクセス違反をどのようにログに記録するかを決定します。正しいモードを設定することで、システムのセキュリティーが確保され、SELinux を無効状態から有効にした際にファイルシステムのラベル変更によって発生する起動障害を防ぐことができます。

SELinux は、有効状態または無効状態のどちらかで動作します。有効にすると、SELinux は enforcing モードまたは permissive モードで実行されます。これらのモードの詳細は、SELinux の状態とモード を参照してください。

getenforce コマンドは、現在のモードとして EnforcingPermissive、または Disabled のいずれか報告します。

sestatus コマンドは、SELinux の状態とロードされている SELinux ポリシーに関する情報を報告します。

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Memory protection checking:     actual (secure)
Max kernel policy version:      31
警告

Permissive モードで SELinux を実行すると、ユーザーやプロセスにより、さまざまなファイルシステムオブジェクトのラベルが間違って設定される可能性があります。SELinux が無効になっている間に作成されたファイルシステムのオブジェクトには、ラベルが追加されません。ただし、SELinux では、ファイルシステムオブジェクトのラベルが正しいことが必要になるため、これにより Enforcing モードに変更したときに問題が発生します。

SELinux では、誤ったラベル付けやラベル付けされていないファイルが問題を引き起こすことを防ぐため、Disabled 状態から Permissive モードまたは Enforcing モードに変更すると、ファイルシステムのラベルが自動的に再設定されます。root として fixfiles -F onboot コマンドを使用して /.autorelabel ファイルを作成します。-F オプションを指定することで、次回の再起動時にファイルが強制的に再ラベル付けされるようにします。

再ラベル付けのためにシステムを再起動する前に、enforcing=0 カーネルオプションを使用するなどして、システムが Permissive モードで起動することを確認します。これにより、selinux-autorelabel サービスを起動する前に、systemd が必要とするラベルのないファイルがシステムにある場合に、システムが起動に失敗することを防ぎます。詳細は、RHBZ#2021835 を参照してください。

2.2. SELinux の Permissive モードへの変更

拒否メッセージのトラブルシューティングやセキュリティーポリシーのデバッグを行うには、SELinux を permissive モードで実行するように設定します。このモードでは、システムは Access Vector Cache (AVC) イベントをログに記録しますが、アクティブなポリシーは適用しないため、システム操作をブロックすることなく影響を分析できます。SELinux は、拒否については一度だけログに記録します。

前提条件

  • selinux-policy-targetedlibselinux-utils、および policycoreutils パッケージがシステムにインストールされている。
  • selinux=0 または enforcing=0 カーネルパラメーターは使用されません。

手順

  1. テキストエディターで /etc/selinux/config ファイルを開き、SELINUX=permissive オプションを設定します。

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #       enforcing - SELinux security policy is enforced.
    #       permissive - SELinux prints warnings instead of enforcing.
    #       disabled - No SELinux policy is loaded.
    SELINUX=permissive
    # SELINUXTYPE= can take one of these two values:
    #       targeted - Targeted processes are protected,
    #       mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  2. システムを再起動します。

    # reboot

検証

  1. システムの再起動後に、getenforce コマンドが Permissive を返すことを確認します。

    $ getenforce
    Permissive

2.3. SELinux の Enforcing モードへの変更

不正アクセスを拒否してシステムを保護するために、SELinux を enforcing モードで実行するように設定します。このモードでは、システムは読み込まれたセキュリティーポリシーを適用し、ポリシー違反をブロックします。SELinux を無効状態から有効にした場合、システムは次回の起動時に自動的にファイルのラベルを変更します。

SELinux を有効にしてシステムをインストールすると、RHEL はデフォルトで enforcing モードを有効にします。

前提条件

  • selinux-policy-targetedlibselinux-utils、および policycoreutils パッケージがシステムにインストールされている。
  • selinux=0 または enforcing=0 カーネルパラメーターは使用されません。

手順

  1. テキストエディターで /etc/selinux/config ファイルを開き、SELINUX=enforcing オプションを設定します。

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #       enforcing - SELinux security policy is enforced.
    #       permissive - SELinux prints warnings instead of enforcing.
    #       disabled - No SELinux policy is loaded.
    SELINUX=enforcing
    # SELINUXTYPE= can take one of these two values:
    #       targeted - Targeted processes are protected,
    #       mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  2. 変更を保存して、システムを再起動します。

    # reboot

    次にシステムを起動する際に、SELinux はシステム内のファイルおよびディレクトリーのラベルを再設定し、SELinux が無効になっている間に作成したファイルおよびディレクトリーに SELinux コンテキストを追加します。

検証

  1. システムの再起動後に、getenforce コマンドが Enforcing を返すことを確認します。

    $ getenforce
    Enforcing

トラブルシューティング

Enforcing モードに変更したあと、SELinux ポリシールールが間違っていたか、設定されていなかったため、SELinux が一部のアクションを拒否する場合があります。

  • SELinux に拒否されるアクションを表示するには、root で以下のコマンドを実行します。

    # ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts today
  • または、setroubleshoot-server パッケージがインストールされている場合は、次のように入力します。

    # grep "SELinux is preventing" /var/log/messages
  • SELinux が有効で、Audit デーモン (auditd) がシステムで実行していない場合は、dmesg コマンドの出力で SELinux メッセージを検索します。

    # dmesg | grep -i -e type=1300 -e type=1400

詳細は、SELinux に関連する問題のトラブルシューティング を参照してください。

2.4. 以前は無効にしていたシステムで SELinux を有効にする

セキュリティー保護を復元し、強制的なアクセス制御を適用するために、以前 SELinux が無効になっていたシステムで SELinux を有効にします。まず、システムを permissive モードで起動し、ファイルシステムにラベルを再設定する必要があります。そうすることで、セキュリティーラベルの欠落や誤りによって発生する起動エラーを防ぐことができます。

SELinux が disabled の状態で作成されたファイルシステムオブジェクトには、セキュリティーラベルは付与されません。システムはアクセス決定を行うために正しいコンテキストに依存しているため、ラベルがない状態で直接 enforcing モードに変更するとエラーが発生します。

警告

再ラベル付けのためにシステムを再起動する前に、enforcing=0 カーネルオプションを使用するなどして、システムが Permissive モードで起動することを確認します。これにより、selinux-autorelabel サービスを起動する前に、systemd が必要とするラベルのないファイルがシステムにある場合に、システムが起動に失敗することを防ぎます。詳細は、RHBZ#2021835 を参照してください。

手順

  1. SELinux を Permissive モードで有効にします。詳細は、SELinux を permissive モードに変更する を参照してください。
  2. システムを再起動します。

    # reboot
  3. SELinux 拒否メッセージを確認します。詳細は、SELinux 拒否の特定 を参照してください。
  4. 次の再起動時に、ファイルが再ラベル付けされていることを確認します。

    # fixfiles -F onboot

    これにより、-F オプションの効果により、/.autorelabel ファイルが作成されます。

    警告

    fixfiles -F onboot コマンドを入力する前に、必ず Permissive モードに切り替えてください。

    デフォルトでは、autorelabel はシステムで使用可能な CPU コアと同じ数のスレッドを並列に使用します。ラベルの自動再設定中に単一のスレッドのみを使用するには、fixfiles -T 1 onboot コマンドを使用します。

  5. 拒否がない場合は、Enforcing モードに切り替えます。詳細は システム起動時の SELinux モードの変更 を参照してください。

検証

  1. システムの再起動後に、getenforce コマンドが Enforcing を返すことを確認します。

    $ getenforce
    Enforcing

次のステップ

Enforcing モードで SELinux を使用してカスタムアプリケーションを実行するには、次のいずれかのシナリオを選択してください。

  • unconfined_service_t ドメインでアプリケーションを実行します。
  • アプリケーションに新しいポリシーを記述します。詳細は、カスタム SELinux ポリシーの作成 のセクションを参照してください。

2.5. SELinux の無効化

SELinux を無効にするには、カーネルコマンドラインを設定してセキュリティーインフラストラクチャーを完全に無効化します。このモードではシステムがファイルにラベルを付けなくなり、SELinux を再度有効にするのが難しくなるため、このモードは必要な場合にのみ使用してください。

SELinux を無効にすると、システムはセキュリティーポリシーをロードせず、Access Vector Cache (AVC) メッセージをログに記録しません。したがって、SELinux を実行する利点 はすべて失われます。

警告

セキュリティー強度が低くても問題ない、パフォーマンス重視のシステムなど、特定のシナリオを除き、SELinux を無効にしないでください。

実稼働環境でシステムをデバッグする必要がある場合は、SELinux を永続的に無効にする代わりに、一時的に permissive モードを使用します。Permissive モードの詳細は Permissive モードへの変更 を参照してください。

前提条件

  • grubby パッケージがインストールされている。

    $ rpm -q grubby
    grubby-<version>

手順

  1. ブートローダーを設定して、カーネルコマンドラインに selinux=0 を追加します。

    $ sudo grubby --update-kernel ALL --args selinux=0
  2. システムを再起動します。

    $ reboot

検証

  • 再起動したら、getenforce コマンドが Disabled を返すことを確認します。

    $ getenforce
    Disabled

2.6. SELinux カーネルの起動パラメーター

カーネル起動パラメーターは、起動時の SELinux モードとシステム初期化を制御します。これらのパラメーターを使用すると、システム起動時のデフォルトのセキュリティー設定をオーバーライドできます。

enforcing=0

このパラメーターを設定すると、システムを起動する際に、Permissive モードで起動します。これは、問題のトラブルシューティングを行うときに便利です。ファイルシステムが破損している場合は、Permissive モードを使用することが、問題を検出するための唯一の選択肢となるかもしれません。さらに、permissive モードでは、システムはラベルを正しく作成します。このモードで生成される AVC メッセージは、enforcing モードで生成されるメッセージとは異なる場合があります。

permissive モードでは、システムは一連の同じ拒否が続く場合、最初の拒否のみを報告します。一方、Enforcing モードでは、ディレクトリーの読み込みに関する拒否が発生し、アプリケーションが停止する場合があります。permissive モードでは、同じ AVC メッセージが表示されますが、アプリケーションはディレクトリー内のファイルの読み取りを継続し、拒否されるたびに AVC メッセージが表示されます。

selinux=0

このパラメーターにより、カーネルは、SELinux インフラストラクチャーのどの部分も読み込まないようになります。init スクリプトは、システムが selinux=0 パラメーターで起動したことを検出し、/.autorelabel ファイルを作成します。これにより、次回 SELinux を有効にしてシステムを起動する際にシステムのラベルが自動的に再設定されます。

重要

実稼働環境では selinux=0 パラメーターを使用しないでください。システムをデバッグするには、SELinux を無効にする代わりに、一時的に permissive モードを使用してください。

autorelabel=1

このパラメーターにより、システムは以下のコマンドと同様に再ラベル付けを強制されます。

# touch /.autorelabel
# reboot

ファイルシステムに間違ったラベルが付いたオブジェクトが大量に含まれる場合は、システムを Permissive モードで起動して自動再ラベルプロセスを正常に実行します。

checkreqprot などの追加の SELinux のカーネル起動パラメーターは、kernel-doc パッケージと一緒にインストールされる /usr/share/doc/kernel-doc-<KERNEL_VER>/Documentation/admin-guide/kernel-parameters.txt ファイルを参照してください。<KERNEL_VER> 文字列をインストール済みカーネルのバージョン番号に置き換えます。以下に例を示します。

+

# dnf install kernel-doc
$ less /usr/share/doc/kernel-doc-6.12.0-55.9.1/Documentation/admin-guide/kernel-parameters.txt

第3章 制限のあるユーザーおよび制限のないユーザーの管理

ポリシーで定義された特定の SELinux ユーザーに Linux ユーザーとそのプロセスが実行できるアクションをマッピングすることで制御します。この方法は、割り当てられた SELinux プロファイルに基づいて、きめ細かなセキュリティー制限を適用するのに役立ちます。

各 Linux ユーザーは、SELinux ポリシーのルールに基づいて SELinux ユーザーにマッピングされます。管理者は、semanage login ユーティリティーを使用するか、Linux ユーザーを特定の SELinux ユーザーに直接割り当てることで、このルールを変更できます。したがって、Linux ユーザーには、割り当てられている SELinux ユーザーの制限が適用されます。SELinux ユーザーに割り当てられた Linux ユーザーがプロセスを起動すると、他のルールで別のロールまたはタイプが指定されていない限り、このプロセスは SELinux ユーザーの制限を継承します。詳細は、システムに selinux-policy-doc パッケージとともにインストールされている unconfined_selinux(8)user_selinux(8)staff_selinux(8)、および sysadm_selinux(8) の man ページを参照してください。

3.1. SELinux における制限のあるユーザーおよび制限のないユーザー

デフォルトでは、管理者権限を持つユーザーを含め、Red Hat Enterprise Linux のすべての Linux ユーザーは、制限のない SELinux ユーザー unconfined_u にマッピングされます。SELinux の制限のあるユーザーにユーザーを割り当てることで、システムのセキュリティーを強化できます。

Linux ユーザーのセキュリティーコンテキストは、SELinux ユーザー、SELinux ロール、および SELinux タイプで構成されます。以下に例を示します。

user_u:user_r:user_t

詳細は、以下のようになります。

user_u
SELinux ユーザーです。
user_r
SELinux ロールです。
user_t
SELinux タイプです。

Linux ユーザーのログイン後に、その SELinux ユーザーを変更することはできません。ただし、そのタイプとロールは、移行中などに変更できます。

システムで SELinux ユーザーマッピングを表示するには、root で semanage login -l コマンドを使用します。

# semanage login -l
Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *

Red Hat Enterprise Linux では、Linux ユーザーはデフォルトで SELinux の __default__ ログインにマッピングされ、これは、SELinux unconfined_u ユーザーにマッピングされます。以下の行は、デフォルトのマッピングを定義します。

__default__          unconfined_u         s0-s0:c0.c1023       *

制限のあるユーザーは、現在の SELinux ポリシーで明示的に定義されている SELinux ルールにより制限されます。制限のないユーザーには、SELinux による制限が最小限にとどまります。

制限のある Linux ユーザーおよび制限のない Linux ユーザーは、実行可能および書き込み可能なメモリーチェックの対象となり、また MCS または MLS によっても制限されます。

利用可能な SELinux ユーザーをリスト表示するには、以下のコマンドを実行します。

$ seinfo -u
Users: 8
   guest_u
   root
   staff_u
   sysadm_u
   system_u
   unconfined_u
   user_u
   xguest_u

seinfo コマンドは、setools-console パッケージにより提供されることに注意してください。これは、デフォルトではインストールされません。

制限のない Linux ユーザーが、unconfined_t ドメインから自身の制限のあるドメインに移行できるものとして SELinux ポリシーが定義するアプリケーションを実行すると、制限のない Linux ユーザーは制限のあるドメインの制限を引き続き受けます。このセキュリティー上の利点は、Linux ユーザーが制限なしで実行している場合でも、アプリケーションは制限されたままになることです。したがって、アプリケーションにおける不具合の悪用はポリシーによって制限できます。

同様に、これらのチェックを制限のあるユーザーに適用できます。制限のある各ユーザーは、制限のあるユーザードメインによって制限されます。SELinux ポリシーは、制限のあるユーザードメインから自身のターゲット制限のあるドメインへの移行を定義することもできます。このような場合、制限のあるユーザーはそのターゲットの制限のあるドメインの制限を受けます。重要な点は、制限されたユーザーには、そのロールに応じて特別な特権が付与されるということです。

3.2. SELinux ユーザーのロールとアクセス権

ポリシーブール値を調整し、Linux ユーザーを適切なロールにマッピングすることで、SELinux ユーザーの権限とアクセス権限を管理します。このプロセスにより、RHEL のユーザーにそれぞれのタスクに応じた適切な認可が確実に割り当てられるようになります。

SELinux ポリシーは、各 Linux ユーザーを SELinux ユーザーにマッピングします。これにより、Linux ユーザーは SELinux ユーザーの制限を継承できます。ポリシーのブール値を調整することで、SELinux ポリシーの制限ユーザーの権限を、特定のニーズに合わせてカスタマイズできます。semanage boolean -l コマンドを使用すると、このブール値の現在の状態を確認できます。すべての SELinux ユーザー、その SELinux ロール、MLS および MCS のレベルと範囲をリスト表示するには、root として semanage user -l コマンドを使用します。

Expand
表3.1 SELinux ユーザーのロール
Userデフォルトロール追加のロール

unconfined_u

unconfined_r

system_r

guest_u

guest_r

 

xguest_u

xguest_r

 

user_u

user_r

 

staff_u

staff_r

sysadm_r

unconfined_r

system_r

sysadm_u

sysadm_r

 

root

staff_r

sysadm_r

unconfined_r

system_r

system_u

system_r

 

system_u は、システムプロセスおよびオブジェクトの特別なユーザー ID であり、system_r は関連付けられたロールであることに注意してください。管理者は、この system_u ユーザーと system_r ロールを Linux ユーザーに関連付けることはできません。また、unconfined_u および root は制限のないユーザーです。このため、これらの SELinux ユーザーに関連付けられたロールは、以下の表 SELinux ロールの種類とアクセス権 には含まれていません。

各 SELinux ロールは SELinux のタイプに対応しており、特定のアクセス権限を提供します。

Expand
表3.2 SELinux ロールの種類とアクセス権
ロールX Window System を使用したログインsu および sudoホームディレクトリーおよび /tmp (デフォルト) での実行ネットワーク

unconfined_r

unconfined_t

はい

はい

はい

はい

guest_r

guest_t

いいえ

いいえ

はい

いいえ

xguest_r

xguest_t

はい

いいえ

はい

Web ブラウザーのみ (Mozilla Firefox、GNOME Web)

user_r

user_t

はい

いいえ

はい

はい

staff_r

staff_t

はい

sudo のみ

はい

はい

auditadm_r

auditadm_t

 

はい

はい

はい

dbadm_r

dbadm_r

 

はい

はい

はい

logadm_r

logadm_t

 

はい

はい

はい

webadm_r

webadm_r

 

はい

はい

はい

secadm_r

secadm_t

 

はい

はい

はい

sysadm_r

sysadm_t

xdm_sysadm_login のブール値が on の場合のみ

はい

はい

はい

非管理者ロールの詳細は、SELinux における制限のある非管理者ロール を参照してください。

管理者ロールの詳細は、SELinux における制限のある管理者ロール を参照してください。

利用可能なロールの一覧を表示するには、seinfo -r コマンドを実行します。

$ seinfo -r
Roles: 14
   auditadm_r
   dbadm_r
   guest_r
   logadm_r
   nx_server_r
   object_r
   secadm_r
   staff_r
   sysadm_r
   system_r
   unconfined_r
   user_r
   webadm_r
   xguest_r

seinfo コマンドは、setools-console パッケージにより提供されることに注意してください。これは、デフォルトではインストールされません。詳細は、システムに selinux-policy-doc パッケージとともにインストールされている seinfo(1)semanage-login(8)、および xguest_selinux(8) の man ページを参照してください。

3.3. SELinux における制限のある非管理者ロール

制限のある非管理者ロールは、割り当てられた Linux ユーザーに対して、特定のタスクを実行するための特定の特権と許可を付与します。個別の制限のある非管理者ロールを割り当てることで、個々のユーザーに特定の権限を割り当てることができます。これは、複数のユーザーが異なるレベルの認可を持っている場合に便利です。

システム上の関連する SELinux ブール値を変更することで、SELinux ロールの権限をカスタマイズすることもできます。SELinux のブール値とその現在の状態を確認するには、root として semanage boolean -l コマンドを使用します。selinux-policy-devel パッケージをインストールすると、より詳細な説明を取得できます。

# semanage boolean -l
SELinux boolean                State  Default Description
…
xguest_connect_network         (on   ,   on)  Allow xguest users to configure Network Manager and connect to apache ports
xguest_exec_content            (on   ,   on)  Allow xguest to exec content
…

user_tguest_t、および xguest_t ドメインの Linux ユーザーは、SELinux ポリシーで許可されている場合のみ (passwd など)、setuid (set user ID) アプリケーションを実行できます。これらのユーザーは setuid アプリケーション su および sudo を実行できないため、これらのアプリケーションを使用して root になることはできません。

デフォルトでは、staff_t ドメイン、user_t ドメイン、guest_t ドメイン、および xguest_t ドメインの Linux ユーザーは、ホームディレクトリーと /tmp でアプリケーションを実行できます。アプリケーションは、それを実行したユーザーの権限を継承します。

guest_t および xguest_t ユーザーが書き込みアクセス権を持つディレクトリーでアプリケーションを実行できないようにするには、guest_exec_content および xguest_exec_content のブール値を off に設定します。

SELinux には、次の制限のある非管理者ロールがあり、それぞれに特定の権限と制限があります。

guest_r

非常に限られた権限しかありません。このロールに割り当てられたユーザーは、ネットワークにアクセスできませんが、/tmp および /home ディレクトリー内のファイルを実行できます。

関連するブール値:

SELinux boolean                State  Default Description
guest_exec_content             (on   ,   on)  Allow guest to exec content
xguest_r

権限が制限されています。このロールに割り当てられたユーザーは、X Window にログインし、ネットワークブラウザーを使用して Web ページにアクセスし、メディアにアクセスできます。/tmp および /home ディレクトリー内のファイルを実行することもできます。

関連するブール値:

SELinux boolean                State  Default Description
xguest_connect_network         (on   ,   on)  Allow xguest users to configure Network Manager and connect to apache ports
xguest_exec_content            (on   ,   on)  Allow xguest to exec content
xguest_mount_media             (on   ,   on)  Allow xguest users to mount removable media
xguest_use_bluetooth           (on   ,   on)  Allow xguest to use blue tooth devices
user_r

非特権アクセス権と完全なユーザー権限を持ちます。このロールに割り当てられたユーザーは、管理者権限を必要としないほとんどのアクションを実行できます。

関連するブール値:

SELinux boolean                State  Default Description
unprivuser_use_svirt           (off  ,  off)  Allow unprivileged user to create and transition to svirt domains.
staff_r

user_r と同様の権限と追加の特権を持ちます。特に、このロールに割り当てられたユーザーは、sudo を実行して、通常は root ユーザー用に予約されている管理コマンドを実行できます。これにより、ロールと実効ユーザー ID (EUID) が変更されますが、SELinux ユーザーは変更されません。

関連するブール値:

SELinux boolean                State  Default Description
staff_exec_content             (on   ,   on)  Allow staff to exec content
staff_use_svirt                (on   ,   on)  allow staff user to create and transition to svirt domains.

各ロールと関連するタイプに関する詳細は、システムに selinux-policy-doc パッケージとともにインストールされている guest_selinux(8)xguest_selinux(8)user_selinux(8)、および staff_selinux(8) の man ページを参照してください。

Linux ユーザーを staff_u にマッピングして sudo を設定する場合は、sudo および sysadm_r ロールを使用した管理者の制限 セクションを参照してください。

3.4. SELinux における制限のある管理者ロール

制限のある管理者ロールは、特定のタスクを実行するための特定の権限とアクセス権のセットを、そのロールに割り当てられた Linux ユーザーに付与します。個別の制限のある管理者ロールを割り当てることにより、システム管理のさまざまなドメインに対する権限を個々のユーザーに分割できます。これは、複数の管理者がそれぞれ別のドメインを持つシナリオで役立ちます。

このロールは、semanage user コマンドを使用して SELinux ユーザーに割り当てることができます。

SELinux には、次の制限のある管理者ロールがあります。

auditadm_r

監査管理者のロールでは、監査サブシステムに関連するプロセスを管理できます。

関連するブール値:

SELinux boolean                State  Default Description
auditadm_exec_content          (on   ,   on)  Allow auditadm to exec content
dbadm_r

データベース管理者ロールでは、MariaDB および PostgreSQL データベースを管理できます。

関連するブール値:

SELinux boolean                State  Default Description
dbadm_exec_content             (on   ,   on)  Allow dbadm to exec content
dbadm_manage_user_files        (off  ,  off)  Determine whether dbadm can manage generic user files.
dbadm_read_user_files          (off  ,  off)  Determine whether dbadm can read generic user files.
logadm_r

ログ管理者ロールでは、ログ、特に Rsyslog ログサービスと監査サブシステムに関連する SELinux タイプを管理できます。

関連するブール値:

SELinux boolean                State  Default Description
logadm_exec_content            (on   ,   on)  Allow logadm to exec content
webadm_r

Web 管理者は、Apache HTTP サーバーの管理を許可します。

関連するブール値:

SELinux boolean                State  Default Description
webadm_manage_user_files       (off  ,  off)  Determine whether webadm can manage generic user files.
webadm_read_user_files         (off  ,  off)  Determine whether webadm can read generic user files.
secadm_r

セキュリティー管理者ロールでは、SELinux データベースを管理できます。

関連するブール値:

SELinux boolean                State  Default Description
secadm_exec_content            (on   ,   on)  Allow secadm to exec content
sysadm_r

システム管理者のロールでは、前述のロールのすべてを行うことができ、追加の特権があります。デフォルト以外の設定では、SELinux ポリシーで sysadm_secadm モジュールを無効にして、セキュリティー管理をシステム管理から切り離すことができます。詳細な手順は、MLS でのシステム管理とセキュリティー管理の分離 を参照してください。

sysadm_u ユーザーは、SSH を使用して直接ログインできません。sysadm_u の SSH ログインを有効にするには、ssh_sysadm_login ブール値を on に設定します。

# setsebool -P ssh_sysadm_login on

関連するブール値:

SELinux boolean                State  Default Description
ssh_sysadm_login               (on   ,   on)  Allow ssh logins as sysadm_r:sysadm_t
sysadm_exec_content            (on   ,   on)  Allow sysadm to exec content
xdm_sysadm_login               (on   ,   on)  Allow the graphical login program to login directly as sysadm_r:sysadm_t

各ロールと関連するタイプの詳細は、システムにインストールされている selinux-policy-doc パッケージに含まれる関連する man ページ (auditadm_selinux(8)dbadm_selinux(8)logadm_selinux(8)webadm_selinux(8)secadm_selinux(8)sysadm_selinux(8)) を参照してください。

3.5. SELinux の unconfined_u ユーザーに自動的にマッピングされる新規ユーザーの追加

RHEL 10 で、デフォルトの SELinux unconfined_u ユーザーに自動的にマッピングされる新しい Linux ユーザーを作成します。このプロセスにより、タスクに厳密な SELinux による制限を必要としないユーザーをすぐに追加できます。

前提条件

  • root ユーザーは、Red Hat Enterprise Linux のデフォルト設定と同様に、制限なしで実行されています。

手順

  1. 次のコマンドを入力して、<example_user> という名前の新しい Linux ユーザーを作成します。

    # useradd <example_user>
  2. Linux の <example_user> ユーザーにパスワードを割り当てるには、次のコマンドを実行します。

    # passwd <example_user>
    Changing password for user <example_user>.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
  3. 現在のセッションからログアウトします。
  4. Linux の <example_user> ユーザーとしてログインします。ログインすると、PAM モジュール pam_selinux は Linux ユーザーを SELinux ユーザー (この場合は unconfined_u) に自動的にマッピングし、作成された SELinux コンテキストを設定します。Linux ユーザーのシェルはこのコンテキストで起動します。

検証

  1. <example_user> ユーザーとしてログインしたら、Linux ユーザーのコンテキストを確認します。

    $ id -Z
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

3.6. 新規ユーザーを SELinux で制限されたユーザーとして追加する

SELinux で制限された新しいユーザーをシステムに追加するには、ユーザーアカウントを作成する際に使用したコマンドと同じコマンドを使用できます。ユーザーを staff_u などの制限付きユーザーにマッピングすることで、システムを潜在的なセキュリティー侵害から保護することができます。

前提条件

  • root ユーザーは、Red Hat Enterprise Linux のデフォルト設定と同様に、制限なしで実行されています。

手順

  1. 次のコマンドを入力して、<example_user> という名前の新しい Linux ユーザーを作成し、それを SELinux staff_u ユーザーにマッピングします。

    # useradd -Z staff_u <example_user>
  2. Linux の <example_user> ユーザーにパスワードを割り当てるには、次のコマンドを実行します。

    # passwd <example_user>
    Changing password for user <example_user>.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
  3. 現在のセッションからログアウトします。
  4. Linux の <example_user> ユーザーとしてログインします。ユーザーのシェルは staff_u コンテキストで起動します。

検証

  1. <example_user> ユーザーとしてログインしたら、Linux ユーザーのコンテキストを確認します。

    $ id -Z
    uid=1000(<example_user>) gid=1000(<example_user>) groups=1000(<example_user>) context=staff_u:staff_r:staff_t:s0-s0:c0.c1023

3.7. SELinux で一般ユーザーの制限

すべての RHEL 10 一般ユーザーを制限された user_u SELinux プロファイルにマッピングすることで、システムセキュリティーを強化します。この設定により、ユーザーアカウントの特権が制限され、不正なタスクを実行できないようにします。

デフォルトでは、管理者権限を持つユーザーを含め、Red Hat Enterprise Linux のすべての Linux ユーザーは、制限のない SELinux ユーザー unconfined_u にマッピングされます。SELinux の制限のあるユーザーにユーザーを割り当てることで、システムのセキュリティーを強化できます。これは、V-71971 Security Technical Implementation Guide に準拠するのに役立ちます。

手順

  1. SELinux ログインレコードのリストを表示します。このリストには、SELinux ユーザーへの Linux ユーザーのマッピングが表示されます。

    # semanage login -l
    
    Login Name    SELinux User  MLS/MCS Range   Service
    
    __default__   unconfined_u  s0-s0:c0.c1023       *
    root          unconfined_u  s0-s0:c0.c1023       *
  2. 明示的なマッピングのないすべてのユーザーを表す __default__ ユーザーを、SELinux ユーザー user_u にマッピングします。

    # semanage login -m -s user_u -r s0 __default__

検証

  1. __default__ ユーザーが SELinux ユーザー user_u にマッピングされていることを確認します。

    # semanage login -l
    
    Login Name    SELinux User   MLS/MCS Range    Service
    
    __default__   user_u         s0               *
    root          unconfined_u   s0-s0:c0.c1023   *
  2. 新規ユーザーのプロセスが SELinux コンテキスト user_u:user_r:user_t:s0 で実行されることを確認します。

    1. 新しいユーザーを作成します。

      # adduser <example_user>
    2. <example_user> のパスワードを定義します。

      # passwd <example_user>
    3. root としてログアウトし、新規ユーザーとしてログインします。
    4. ユーザーの ID のセキュリティーコンテキストを表示します。

      [<example_user>@localhost ~]$ id -Z
      user_u:user_r:user_t:s0
    5. ユーザーの現在のプロセスのセキュリティーコンテキストを表示します。

      [<example_user>@localhost ~]$ ps axZ
      LABEL                           PID TTY      STAT   TIME COMMAND
      -                                 1 ?        Ss     0:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 18
      -                              3729 ?        S      0:00 (sd-pam)
      user_u:user_r:user_t:s0        3907 ?        Ss     0:00 /usr/lib/systemd/systemd --user
      -                              3911 ?        S      0:00 (sd-pam)
      user_u:user_r:user_t:s0        3918 ?        S      0:00 sshd: <example_user>@pts/0
      user_u:user_r:user_t:s0        3922 pts/0    Ss     0:00 -bash
      user_u:user_r:user_dbusd_t:s0  3969 ?        Ssl    0:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
      user_u:user_r:user_t:s0        3971 pts/0    R+     0:00 ps axZ

3.8. sysadm_u へのマッピングによる管理者の制限

SELinux ユーザー sysadm_u に直接マッピングすることで、管理者権限を持つユーザーを制限できます。ユーザーがログインすると、セッションは SELinux コンテキスト sysadm_u:sysadm_r:sysadm_t で実行されます。これにより、管理者アカウントが侵害された場合の潜在的な影響を最小限に抑えることができます。

デフォルトでは、管理者権限を持つユーザーを含め、Red Hat Enterprise Linux のすべての Linux ユーザーは、制限のない SELinux ユーザー unconfined_u にマッピングされます。SELinux の制限のあるユーザーにユーザーを割り当てることで、システムのセキュリティーを強化できます。これは、V-71971 Security Technical Implementation Guide に準拠するのに役立ちます。

前提条件

  • root ユーザーは制限なしで実行します。これは、Red Hat Enterprise Linux のデフォルトです。

手順

  1. 必要に応じて、sysadm_u ユーザーが SSH を使用してシステムに接続できるようにするには、次のコマンドを実行します。

    # setsebool -P ssh_sysadm_login on
  2. 新しいユーザーまたは既存のユーザーを sysadm_u SELinux ユーザーにマッピングします。

    • 新規ユーザーをマッピングするには、新規ユーザーを wheel ユーザーグループに追加し、そのユーザーを SELinux ユーザー sysadm_u にマッピングします。

      # adduser -G wheel -Z sysadm_u <example_user>
    • 既存のユーザーをマッピングするには、ユーザーを wheel ユーザーグループに追加し、そのユーザーを SELinux ユーザー sysadm_u にマッピングします。

      # usermod -G wheel -Z sysadm_u <example_user>
  3. ユーザーのホームディレクトリーのコンテキストを復元します。

    # restorecon -R -F -v /home/<example_user>

検証

  1. <example_user> が、SELinux ユーザー sysadm_u にマッピングされていることを確認します。

    # semanage login -l | grep <example_user>
    <example_user>     sysadm_u    s0-s0:c0.c1023   *
  2. SSH などを使用して <example_user> としてログインし、ユーザーのセキュリティーコンテキストを表示します。

    [<example_user>@localhost ~]$ id -Z
    sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  3. root ユーザーに切り替えます。

    $ sudo -i
    [sudo] password for <example_user>:
  4. セキュリティーコンテキストが変更されていないことを確認します。

    # id -Z
    sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  5. sshd サービスを再起動するなど、管理タスクを実行します。

    # systemctl restart sshd

    出力がない場合は、コマンドが正常に完了します。

    コマンドが正常に完了しない場合は、以下のメッセージが表示されます。

    Failed to restart sshd.service: Access denied
    See system logs and 'systemctl status sshd.service' for details.

3.9. sudo および sysadm_r ロールを使用した管理者の制限

管理者権限を持つ特定のユーザーを SELinux ユーザー staff_u にマッピングし、ユーザーが SELinux 管理者ロール sysadm_r を取得できるように sudo を設定できます。このロールでは、ユーザーは SELinux による拒否を受けることなく管理タスクを実行できます。

ユーザーがログインすると、セッションは SELinux コンテキスト staff_u:staff_r:staff_t で実行されますが、ユーザーが sudo を使用してコマンドを入力すると、セッションは staff_u:sysadm_r:sysadm_t コンテキストに変更されます。

デフォルトでは、管理者権限を持つユーザーを含め、Red Hat Enterprise Linux のすべての Linux ユーザーは、制限のない SELinux ユーザー unconfined_u にマッピングされます。SELinux の制限のあるユーザーにユーザーを割り当てることで、システムのセキュリティーを強化できます。これは、V-71971 Security Technical Implementation Guide に準拠するのに役立ちます。

前提条件

  • root ユーザーは制限なしで実行します。これは、Red Hat Enterprise Linux のデフォルトです。

手順

  1. 新規または既存のユーザーを staff_u SELinux ユーザーにマッピングします。

    1. 新規ユーザーをマッピングするには、新規ユーザーを wheel ユーザーグループに追加し、そのユーザーを SELinux ユーザー staff_u にマッピングします。

      # adduser -G wheel -Z staff_u <example_user>
    2. 既存のユーザーをマッピングするには、ユーザーを wheel ユーザーグループに追加し、そのユーザーを SELinux ユーザー staff_u にマッピングします。

      # usermod -G wheel -Z staff_u <example_user>
  2. ユーザーのホームディレクトリーのコンテキストを復元します。

    # restorecon -R -F -v /home/<example_user>
  3. <example_user> が SELinux 管理者ロールを取得できるようにするには、/etc/sudoers.d/ ディレクトリーに新規ファイルを作成します。以下に例を示します。

    # visudo -f /etc/sudoers.d/<example_user>
  4. 以下の行を新規ファイルに追加します。

    <example_user> ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL

検証

  1. <example_user> が SELinux ユーザー staff_u にマッピングされていることを確認します。

    # semanage login -l | grep <example_user>
    <example_user>     staff_u    s0-s0:c0.c1023   *
  2. たとえば SSH を使用して <example_user> としてログインし、root ユーザーに切り替えます。

    [<example_user>@localhost ~]$ sudo -i
    [sudo] password for <example_user>:
  3. root セキュリティーコンテキストを表示します。

    # id -Z
    staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  4. sshd サービスを再起動するなど、管理タスクを実行します。

    # systemctl restart sshd

    出力がない場合は、コマンドが正常に完了します。

    コマンドが正常に完了しない場合は、以下のメッセージが表示されます。

    Failed to restart sshd.service: Access denied
    See system logs and 'systemctl status sshd.service' for details.

第4章 非標準設定でのアプリケーションとサービスの SELinux 設定

アプリケーションが標準以外のポートやディレクトリーを使用するように設定する場合は、SELinux のターゲットポリシーを調整します。これにより、SELinux によるアクセス拒否を防ぎ、enforcing モードでサービスが正しく実行されるようになります。

SELinux が Enforcing モードの場合、デフォルトのポリシーはターゲットポリシーになります。ポート、データベースの場所、プロセスのファイルシステム権限など、デフォルト設定を変更した後に、さまざまなサービスに対して SELinux ポリシーをセットアップおよび設定する方法を説明します。このような変更には、非標準ポートの SELinux タイプの変更、デフォルトディレクトリーの変更に伴う誤ったラベルの特定と修正、および SELinux ブール値を使用したポリシーの調整が必要です。

4.1. 非標準設定での Apache HTTP サーバーの SELinux ポリシーのカスタマイズ

Apache HTTP サーバーで標準以外のポートやディレクトリーを使用するように設定する場合は、SELinux ポリシーを調整します。これにより、アクセス拒否を防ぎ、Web サーバーが enforcing モードでセキュアに動作されるようにします。

前提条件

  • httpd パッケージがインストールされ、Apache HTTP サーバーが TCP ポート 3131 をリッスンし、デフォルトの /var/www/ ディレクトリーの代わりに /var/test_www/ ディレクトリーを使用するように設定されています。
  • policycoreutils-python-utils および setroubleshoot-server パッケージがシステムにインストールされています。

手順

  1. httpd サービスを起動して、ステータスを確認します。

    # systemctl start httpd
    # systemctl status httpd
    …
    httpd[14523]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:3131
    …
    systemd[1]: Failed to start The Apache HTTP Server.
    …
  2. SELinux ポリシーは、httpd がポート 80 で実行していることを前提としています。

    # semanage port -l | grep http
    http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
    http_cache_port_t              udp      3130
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
    pegasus_http_port_t            tcp      5988
    pegasus_https_port_t           tcp      5989
  3. ポート 3131 の SELinux タイプを、ポート 80 に一致させるように変更します。

    # semanage port -a -t http_port_t -p tcp 3131
  4. httpd を再度起動します。

    # systemctl start httpd
  5. ただし、コンテンツにはアクセスできません。

    # wget localhost:3131/index.html
    …
    HTTP request sent, awaiting response... 403 Forbidden
    …

    sealert ツールを使用して理由を確認します。

    # sealert -l "*"
    …
    SELinux is preventing httpd from getattr access on the file /var/test_www/html/index.html.
    …
  6. matchpathcon ツールを使用して、標準パスと新規パスの SELinux タイプを比較します。

    # matchpathcon /var/www/html /var/test_www/html
    /var/www/html       system_u:object_r:httpd_sys_content_t:s0
    /var/test_www/html  system_u:object_r:var_t:s0
  7. 新しい /var/test_www/html/ コンテンツディレクトリーの SELinux タイプを、デフォルトの /var/www/html ディレクトリーのタイプに変更します。

    # semanage fcontext -a -e /var/www /var/test_www
  8. 再帰的に、/var ディレクトリーのラベルを再設定します。

    # restorecon -Rv /var/
    …
    Relabeled /var/test_www/html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    Relabeled /var/test_www/html/index.html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

検証

  1. httpd サービスが実行していることを確認します。

    # systemctl status httpd
    …
    Active: active (running)
    …
    systemd[1]: Started The Apache HTTP Server.
    httpd[14888]: Server configured, listening on: port 3131
    ...
  2. Apache HTTP サーバーが提供するコンテンツがアクセスできることを確認します。

    # wget localhost:3131/index.html
    …
    HTTP request sent, awaiting response... 200 OK
    Length: 0 [text/html]
    Saving to: 'index.html'
    …

4.2. SELinux ブール値で NFS ボリュームおよび CIFS ボリュームの共有に関するポリシーの調整

実行時にブール値を使用して SELinux ポリシーを変更し、サービスが NFS および CIFS ボリュームにアクセスできるようにします。この機能により、ポリシー全体を再読み込みまたは再コンパイルすることなく、ポリシーを迅速に調整できます。

SELinux のブール値を使用すると、SELinux ポリシーの作成に関する知識がなくても、実行時にポリシーの一部を変更できます。これにより、SELinux ポリシーの再読み込みや再コンパイルを行わずに、サービスが NFS ボリュームにアクセスするのを許可するなどの変更が可能になります。

この手順例では、SELinux ブール値のリストを表示して、ポリシーで必要な変更を実現するように設定します。

クライアント側の NFS マウントは、NFS ボリュームのポリシーで定義されたデフォルトのコンテキストでラベル付けされます。RHEL では、このデフォルトのコンテキストは nfs_t タイプを使用します。また、クライアント側にマウントされた Samba 共有には、ポリシーで定義されたデフォルトのコンテキストがラベル付けされます。このデフォルトのコンテキストは cifs_t タイプを使用します。ブール値を有効または無効にすると、nfs_t タイプおよび cifs_t タイプにアクセスできるサービスを制御できます。

使用されているコマンドの詳細は、システムの semanage-boolean(8)sepolicy-booleans(8)getsebool(8)setsebool(8)booleans(5)、および booleans(8) の man ページを参照してください。

前提条件

  • 必要に応じて、selinux-policy-devel パッケージをインストールして、semanage boolean -l コマンドの出力で SELinux ブール値の詳細を、より明確で詳細な形で取得します。

手順

  1. NFS、CIFS、および Apache に関する SELinux ブール値を特定します。

    # semanage boolean -l | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs                 (off  ,  off)  Allow httpd to access cifs file systems
    httpd_use_nfs                  (off  ,  off)  Allow httpd to access nfs file systems
  2. ブール値の現在の状態をリスト表示します。

    $ getsebool -a | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs --> off
    httpd_use_nfs --> off
  3. 指定されたブール値を有効にします。

    # setsebool httpd_use_nfs on
    # setsebool httpd_use_cifs on
    注記

    setsebool-P オプションを使用すると、システムを再起動しても変更が持続します。setsebool -P コマンドは、ポリシー全体を再構築する必要がありますが、設定によっては少し時間がかかる場合があります。

検証

  1. ブール値が on になっていることを確認します。

    $ getsebool -a | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs --> on
    httpd_use_nfs --> on

4.3. 非標準ディレクトリーへのアクセスを管理するための適切な SELinux タイプを見つける

デフォルトポリシーで対応されていないディレクトリーへのアクセスを管理するには、適切な SELinux タイプを特定します。これには、適切なブール値や一致するタイプを検索するか、必要に応じてローカルポリシーモジュールを定義することが含まれます。

デフォルトの SELinux ポリシーに含まれないアクセス制御ルールを設定する必要がある場合は、まずユースケースに合ったブール値を検索します。適切なブール値が見つからない場合は、適切な SELinux タイプを使用するか、ローカルポリシーモジュールを作成します。

使用されているコマンドの詳細やその他の例は、システム上の sesearch(1)semanage-fcontext(8)semanage-boolean(8)、および getsebool(8) の man ページを参照してください。

前提条件

  • selinux-policy-doc および setools-console パッケージがシステムにインストールされている。

手順

  1. SELinux 関連のすべてのトピックをリスト表示し、設定するコンポーネントに結果を絞り込みます。以下に例を示します。

    # man -k selinux | grep samba
    samba_net_selinux (8) - Security Enhanced Linux Policy for the samba_net processes
    samba_selinux (8)    - Security Enhanced Linux Policy for the smbd processes
    …

    お客様の状況に関連する man ページで、関連する SELinux ブール値、ポートタイプ、およびファイルタイプを見つけます。

    man -k selinux または apropos selinux コマンドを使用するには、先に selinux-policy-doc パッケージをインストールする必要があることに注意してください。

  2. オプション: semanage fcontext -l コマンドを使用すると、デフォルトの場所にあるプロセスのデフォルトのマッピングを表示できます。次に例を示します。

    # semanage fcontext -l | grep samba
    …
    /var/cache/samba(/.*)?                             all files          system_u:object_r:samba_var_t:s0
    …
    /var/spool/samba(/.*)?                             all files          system_u:object_r:samba_spool_t:s0
    …
  3. sesearch コマンドを使用して、デフォルトの SELinux ポリシーのルールを表示します。対応するルールをリスト表示することで、使用するタイプとブール値を見つけることができます。次に例を示します。

    $ sesearch -A | grep samba | grep httpd
    …
    allow httpd_t cifs_t:dir { getattr open search }; [ use_samba_home_dirs && httpd_enable_homedirs ]:True
    …
  4. 場合によっては、SELinux ブール値が、設定の問題に対する最も簡単な解決策であることがあります。getsebool -a コマンドを使用すると、使用可能なすべてのブール値とその値を表示できます。次に例を示します。

    $ getsebool -a | grep homedirs
    git_cgi_enable_homedirs --> off
    git_system_enable_homedirs --> off
    httpd_enable_homedirs --> off
    mock_enable_homedirs --> off
    mpd_enable_homedirs --> off
    openvpn_enable_homedirs --> on
    ssh_chroot_rw_homedirs --> off
  5. sesearch コマンドを使用すると、選択したブール値が意図するとおりに機能するかどうかを確認できます。次に例を示します。

    $ sesearch -A | grep httpd_enable_homedirs
    …
    allow httpd_suexec_t autofs_t:dir { getattr open search }; [ use_nfs_home_dirs && httpd_enable_homedirs ]:True
    allow httpd_suexec_t autofs_t:dir { getattr open search }; [ use_samba_home_dirs && httpd_enable_homedirs ]:True
    …
  6. お客様の環境に合ったブール値がない場合は、状況に合った SELinux タイプを見つけます。sesearch を使用してデフォルトのポリシーから対応するルールを照会することで、ファイルのタイプを見つけることができます。次に例を示します。

    $ sesearch -A -s httpd_t -c file -p read
    …
    allow httpd_t httpd_t:file { append getattr ioctl lock open read write };
    allow httpd_t httpd_tmp_t:file { append create getattr ioctl link lock map open read rename setattr unlink write };
    …
  7. 以上の解決策がどれもお客様の状況に当てはまらない場合は、SELinux ポリシーにカスタムルールを追加できます。詳細は、ローカル SELinux ポリシーモジュールの作成 セクションを参照してください。

4.4. 権限のない SELinux ユーザーの非標準共有ディレクトリーへのアクセスを管理する

非特権 SELinux ユーザー user_u に対して、非標準の共有ディレクトリーへのアクセスを設定します。このプロセスでは、ディレクトリに対して適切な SELinux ファイルタイプを特定、マッピングすることで、アクセス制限を行います。

user_u ユーザーには、デフォルトのロール user_r とデフォルトのドメイン user_t が付与されています。関連するコマンドと汎用的な非特権 SELinux ユーザー user_u の詳細は、システム上の seinfo(1)semanage-fcontext(8)user_selinux(8) の man ページを参照してください。

前提条件

  • selinux-policy-doc および setools-console パッケージがシステムにインストールされている。

手順

  1. ターミナルで user_selinux(8) man ページを開きます。

    $ man user_selinux

    MANAGED FILES セクションで、お客様の状況に合った属性またはタイプを見つけます。たとえば、user_home_type 属性です。

  2. オプション: 属性に割り当てられているすべてのタイプをリスト表示するには、-x および -a オプションを指定した seinfo コマンドを使用します。次に例を示します。

    $ seinfo -x -a user_home_type
    
    Type Attributes: 1
       attribute user_home_type;
    …
    	chrome_sandbox_home_t
    	config_home_t
    	cvs_home_t
    	data_home_t
    	dbus_home_t
    	fetchmail_home_t
    	gconf_home_t
    	git_user_content_t
    …
  3. 対応するタイプの候補 (この例では data_home_t タイプ) を特定したら、その SELinux マッピングを確認します。

    $ semanage fcontext -l | grep data_home_t
    …
    /root/\.local/share(/.*)?                          all files          system_u:object_r:data_home_t:s0
    …
  4. 対応するタイプを、user_u からアクセス可能にするディレクトリー (例: /shared-data) にマップします。

    $ semanage fcontext -a -t data_home_t '/shared-data(/.*)?'

検証

  1. 設定したディレクトリーのマッピングを確認します。

    # semanage fcontext -l | grep "shared-data"
    /shared-data(/.*)?                             	all files      	system_u:object_r:data_home_t:s0
  2. user_u SELinux ユーザーにマップされた Linux ユーザーとしてログインし、ディレクトリーにアクセスできることを確認します。

第6章 MLS (Multi-Level Security) の使用

SELinux の Multi-Level Security (MLS) および Multi-Category Security (MCS) 機能を使用して、アクセス制御を強化します。MLS と MCS を使用すると、データの機密性や組織のカテゴリーに基づいてアクセスを制限できます。

MLS ポリシーは、米国の国防コミュニティーが最初に設計したクリアランスの レベル を使用します。MLS は、軍隊など、厳格に管理された環境での情報管理をベースにした、非常に限定的なセキュリティー要件を満たしています。

MLS の利用は複雑で、一般的なユースケースには適切に対応できません。

6.1. Multi-Level Security (MLS)

マルチレベルセキュリティー (MLS) は、Bell-La Padula Model を用いて、データの機密性レベルに基づいてユーザーとプロセスを制限します。この設定は、「閲覧禁止、書き込み禁止」の原則を徹底することで、機密性の高い情報への不正アクセスを防止します。

Multi-Level Security (MLS) テクノロジーは、以下の情報セキュリティーレベルを使用して、データを階層に分類します。

  • [lowest] Unclassified
  • [low] Confidential
  • [high] Secret
  • [highest] Top secret

デフォルトでは、MLS SELinux ポリシーは機密レベルを 16 個使用します。

  • s0 は、最も機密レベルが低く、
  • s15 は、最も機密レベルが高くなります。

MLS は特定の用語を使用して機密レベルに対応します。

  • ユーザーおよびプロセスは サブジェクト と呼ばれ、その機密レベルは クリアランス と呼ばれます。
  • システムのファイル、デバイス、およびその他のパッシブコンポーネントは オブジェクト と呼ばれ、その機密レベルは 区分 と呼ばれます。

SELinux は Bell-La Padula Model (BLP) モデルを使用して、MLS を実装します。このモデルは、各サブジェクトおよびオブジェクトに割り当てられたラベルに基づいてシステム内で情報をフローする方法を指定します。

BLP の基本原則は、"No read up, no write down." (上位からの読み取り禁止、下位への書き込み禁止) です。つまり、ユーザーは自分の機密レベル以下のファイルしか読み取れず、データは下位レベルから上位レベルへのみ流れることが許され、その逆は決して許されないということです。

MLS SELinux ポリシー (RHEL 上の MLS の実装) では、書き込み等価を使用した Bell-La Padula と呼ばれる修正済みの原則を適用します。つまり、ユーザーは自分の機密レベル以下のファイルを読み取ることができますが、書き込みは自分のレベルと完全に一致する場合にのみ可能です。これにより、クリアランスが低いユーザーがコンテンツを Top secret ファイルに書き込めないようにします。

たとえば、デフォルトではクリアランスレベル s2 を持つユーザーには以下が適用されます。

  • 機密レベルが s0s1、および s2 のファイルを読み取ることができます。
  • 機密レベルが s3 以上のファイルを読み取ることはできません。
  • 機密レベルが s2 のファイルを変更できます。
  • 機密レベルが s2 以外のファイルは変更できません。
注記

セキュリティー管理者は、システムの SELinux ポリシーを変更することで、この動作を調整できます。たとえば、ユーザーがより低いレベルでファイルを変更できるようにすることで、ファイルの機密レベルをユーザーのクリアランスレベルまで引き上げることができます。

実際には、ユーザーは通常、s1-s2 などの範囲のクリアランスレベルに割り当てられます。ユーザーは、自分の最大レベルよりも低い機密レベルのファイルの読み取りと、その範囲内の任意のファイルへの書き込みが可能です。

たとえば、デフォルトではクリアランス範囲が s1-s2 のユーザーには以下が適用されます。

  • 機密レベル s0s1 のファイルを読み取ることができます。
  • 機密レベル s2 以上のファイルを読み取ることはできません。
  • 機密レベル s1 のファイルを変更できます。
  • 機密レベルが s1 以外のファイルは変更できません。
  • 自分のクリアランスレベルを s2 に変更できます。

MLS 環境における非特権ユーザーのセキュリティーコンテキストは次のとおりです。

user_u:user_r:user_t:s1

詳細は、以下のようになります。

user_u
SELinux ユーザーです。
user_r
SELinux ロールです。
user_t
SELinux タイプです。
s1
MLS 機密レベルの範囲です。

システムは、MLS アクセス制御ルールと従来のファイルアクセスパーミッションを常に組み合わせます。たとえば、セキュリティーレベルが "Secret" のユーザーが、Discretionary Access Control (DAC) を使用して他のユーザーによるファイルへのアクセスをブロックすると、“Top Secret” ユーザーであってもそのファイルにアクセスできなくなります。セキュリティーのクリアランスが高くても、ユーザーはファイルシステム全体を自動的に閲覧できません。

トップレベルの許可があるユーザーは、マルチレベルのシステムで自動的に管理者権限を取得しません。システムに関するすべての機密情報にアクセスできる場合もありますが、これは管理者権限を持つこととは異なります。

さらに、管理者権限があっても機密情報にアクセスできるわけではありません。たとえば、root としてログインした場合でも、Top secret 情報を読み込めません。

カテゴリーを使用して MLS システム内でアクセスをさらに調整できます。Multi-Category Security (MCS) を使用すると、プロジェクトや部門などのカテゴリーを定義でき、ユーザーは割り当てられたカテゴリーのファイルにしかアクセスできません。詳細は、データの機密性に MCS (Multi-Category Security) を使用する を参照してください。

6.2. MLS の SELinux ロール

SELinux ポリシーは、各 Linux ユーザーを SELinux ユーザーにマッピングします。これにより、Linux ユーザーは SELinux ユーザーの制限を継承できます。MLS ポリシーはデフォルトの非制限モジュールを削除し、root ユーザーに対しても特権を制限することに注意してください。

重要

MLS ポリシーには、制限のないユーザー、タイプ、ロールなど、unconfined モジュールは含まれません。そのため、root など制限のないユーザーは、すべてのオブジェクトにアクセスして、ターゲットポリシーで実行可能なアクションをすべて実行できるわけではありません。

ポリシーのブール値を調整することで、SELinux ポリシーの制限ユーザーの権限を、特定のニーズに合わせてカスタマイズできます。semanage boolean -l コマンドを使用すると、このブール値の現在の状態を確認できます。すべての SELinux ユーザー、SELinux ロール、および MLS/MCS レベルおよび範囲を一覧表示するには、rootsemanage user -l コマンドを使用します。

Expand
表6.1 MLS での SELinux ユーザーのロール
Userデフォルトロール追加のロール

guest_u

guest_r

 

xguest_u

xguest_r

 

user_u

user_r

 

staff_u

staff_r

auditadm_r

secadm_r

sysadm_r

staff_r

sysadm_u

sysadm_r

 

root

staff_r

auditadm_r

secadm_r

sysadm_r

system_r

system_u

system_r

 

system_u は、システムプロセスおよびオブジェクトの特別なユーザー ID であり、system_r は関連付けられたロールであることに注意してください。管理者は、この system_u ユーザーと system_r ロールを Linux ユーザーに関連付けることはできません。また、unconfined_u および root は制限のないユーザーです。このため、この SELinux ユーザーに関連付けられたロールは、以下の表の SELinux ロールの種類とアクセスには含まれていません。

各 SELinux ロールは SELinux のタイプに対応しており、特定のアクセス権限を提供します。

Expand
表6.2 MLS での SELinux ロールのタイプおよびアクセス
ロールX Window System を使用したログインsu および sudoホームディレクトリーおよび /tmp (デフォルト) での実行ネットワーク

guest_r

guest_t

いいえ

いいえ

はい

いいえ

xguest_r

xguest_t

はい

いいえ

はい

Web ブラウザーのみ (Mozilla Firefox、GNOME Web)

user_r

user_t

はい

いいえ

はい

はい

staff_r

staff_t

はい

sudo のみ

はい

はい

auditadm_r

auditadm_t

 

はい

はい

はい

secadm_r

secadm_t

 

はい

はい

はい

sysadm_r

sysadm_t

xdm_sysadm_login のブール値が on の場合のみ

はい

はい

はい

  • デフォルトでは、sysadm_r ロールには secadm_r ロールの権限があります。つまり、sysadm_r ロールを持つユーザーは、セキュリティーポリシーを管理できることを意味します。ユースケースが一致しない場合は、ポリシーの sysadm_secadm モジュールを無効にすることで、2 つのロールを分離できます。詳細は、MLS でのシステム管理とセキュリティー管理の分離 を参照してください。
  • ログイン権限を持たないロールの dbadm_rlogadm_r、および webadm_r は、管理タスクのサブセットに使用できます。デフォルトでは、これらのロールは SELinux ユーザーに関連付けられていません。

6.3. SELinux ポリシーの MLS への切り替え

SELinux ポリシーをターゲットモードから Multi-Level Security (MLS) モードに切り替えます。起動時の潜在的なエラーを防ぐため、まず permissive モードに切り替えてファイルのラベルを変更します。

重要

X Window System を実行しているシステムでは、MLS ポリシーを使用しないでください。さらに、MLS ラベルでファイルシステムのラベルを変更すると、制限のあるドメインにアクセスできなくなる可能性があるため、システムが正常に起動しなくなる可能性があります。したがって、ファイルに再ラベルする前に、SELinux を Permissive モードに切り替えます。ほとんどのシステムでは、MLS に切り替えた後、SELinux によるアクセス拒否が多数発生し、その多くは簡単に解決できるものではありません。

手順

  1. selinux-policy-mls パッケージをインストールします。

    # dnf install selinux-policy-mls
  2. 任意のテキストエディターで /etc/selinux/config ファイルを開きます。以下に例を示します。

    # vi /etc/selinux/config
  3. SELinux モードを Enforcing から Permissive に変更し、ターゲットポリシーから MLS に切り替えます。

    SELINUX=permissive
    SELINUXTYPE=mls

    変更を保存し、エディターを終了します。

  4. MLS ポリシーを有効にする前に、MLS ラベルでファイルシステム上の各ファイルに再度ラベル付けする必要があります。

    # fixfiles -F onboot
    System relabels on next boot
  5. システムを再起動します。

    # reboot
  6. SELinux 拒否を確認します。

    # ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent -i

    上記のコマンドはあらゆる状況に対応したものではありません。そのため、SELinux に関連する問題のトラブルシューティング を参照し、SELinux 拒否の特定、分析、修正のガイダンスを確認してください。

  7. システムに SELinux に関連する問題がないことを確認したら、/etc/selinux/config で該当するオプションを変更して、SELinux を Enforcing モードに切り替えます。

    SELINUX=enforcing
  8. システムを再起動します。

    # reboot
    重要

    システムが起動しなかったり、MLS に切り替えた後にログインできない場合は、enforcing=0 パラメーターをカーネルコマンドラインに追加します。詳細は、システム起動時の SELinux モードの変更 を参照してください。

    また、MLS では、sysadm_r SELinux ロールにマッピングされた root ユーザーとしての SSH ログインは staff_rroot としてログインするのとは異なります。MLS で初めてシステムを起動する前に、SELinux ブール値 ssh_sysadm_login1 に設定して、SSH ログインを sysadm_r として許可することを検討してください。後で ssh_sysadm_login を有効にするには、すでに MLS が有効な状態で、staff_rroot としてログインし、newrole -r sysadm_r コマンドを使用して sysadm_rroot に切り替え、ブール値を 1 に設定する必要があります。

検証

  1. SELinux が Enforcing モードで実行されていることを確認します。

    # getenforce
    Enforcing
  2. SELinux のステータスが mls の値を返すことを確認します。

    # sestatus | grep mls
    Loaded policy name:             mls

6.4. MLS でのユーザークリアランスの確立

MLS を有効にした後、制限付き SELinux ユーザーに特定のセキュリティークリアランスレベルを割り当てます。これによりアクセスが制御され、上位レベルのオブジェクトを読み取ったり、異なる機密レベルのファイルに書き込んだりすることが防止されます。

デフォルトでは、セキュリティークリアランスが指定されているユーザーには以下が適用されます。

  • 機密レベルが高いオブジェクトを読み取ることはできません。
  • 機密レベルが異なるオブジェクトに書き込むことはできません。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが enforcing に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • SELinux の制限のあるユーザーに割り当てられているユーザー:

    • 非特権ユーザーの場合、user_u (以下の手順では example_user) に割り当てられます。
    • 特権ユーザーの場合、staff_u (以下の手順では staff) に割り当てられます。
重要

MLS ポリシーがアクティブな時に、ユーザーが作成されていることを確認します。他の SELinux ポリシーで作成されたユーザーは MLS で使用できません。

手順

  1. オプション: SELinux ポリシーの設定ミスを防ぐために、トラブルシューティングが容易になる permissive SELinux モードに切り替えます。

    # setenforce 0

    permissive モードでは、SELinux はアクティブなポリシーを適用せず、Access Vector Cache (AVC) メッセージをログに記録するだけです。このログは、トラブルシューティングやデバッグに使用できます。

  2. SELinux ユーザー staff_u のクリアランスの範囲を定義します。たとえば、このコマンドは、クリアランスの範囲を s1 から s15 に、デフォルトのクリアランスレベルを s1 に設定します。

    # semanage user -m -L s1 -r s1-s15 staff_u
  3. ユーザーのホームディレクトリー用の SELinux ファイルコンテキスト設定エントリーを生成します。

    # genhomedircon
  4. ファイルセキュリティーコンテキストをデフォルトに復元します。

    # restorecon -R -F -v /home/
    Relabeled /home/staff from staff_u:object_r:user_home_dir_t:s0 to staff_u:object_r:user_home_dir_t:s1
    Relabeled /home/staff/.bash_logout from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1
    Relabeled /home/staff/.bash_profile from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1
    Relabeled /home/staff/.bashrc from staff_u:object_r:user_home_t:s0 to staff_u:object_r:user_home_t:s1
  5. ユーザーにクリアランスレベルを割り当てます。

    # semanage login -m -r s1 example_user

    ここで、s1 は、ユーザーに割り当てられたクリアランスレベルです。

  6. ユーザーのホームディレクトリーのラベルをユーザーのクリアランスレベルに付け直します。

    # chcon -R -l s1 /home/example_user
  7. オプション: 以前に permissive SELinux モードに切り替えた場合は、すべてが想定どおりに動作することを確認したら、enforcing SELinux モードに戻します。

    # setenforce 1

検証

  1. ユーザーが正しい SELinux ユーザーにマッピングされ、クリアランスレベルが正しく割り当てられていることを確認します。

    # semanage login -l
    Login Name      SELinux User         MLS/MCS Range        Service
    __default__     user_u               s0-s0                *
    example_user    user_u               s1                   *
    …
  2. MLS 内のユーザーとしてログインします。
  3. ユーザーのセキュリティーレベルが正しく機能していることを確認します。

    警告

    検証に使用するファイルには、設定が間違っており、ユーザーが実際に認証なしにファイルにアクセスできてしまう場合に備え、機密情報を含めないようにしてください。

    1. ユーザーが機密レベルの高いファイルを読み取れないことを確認します。
    2. ユーザーが同じ機密レベルのファイルに書き込めることを確認します。
    3. ユーザーが機密レベルの低いファイルを読み取れることを確認します。

6.5. MLS で定義されたセキュリティー範囲内におけるユーザーのクリアランスレベルの変更

MLS における現在のクリアランスレベルを、管理者によって割り当てられた事前定義範囲内で変更します。この機能を使えば、機密性の低いファイルを、意図せず最高レベルのセキュリティークリアランスにまで分類レベルを引き上げることなく変更できます。

Multi-Level Security (MLS) を使用する場合、範囲の上限を超えたり、範囲の下限を超えてレベルを下げることはできません。これにより、たとえば、機密レベルを最高のクリアランスレベルまで上げることなく、機密性の低いファイルを変更できます。

たとえば、s1-s3 の範囲に割り当てられたユーザーには以下が適用されます。

  • レベル s1s2、および s3 に移行できます。
  • s1-s2 および s2-s3 の範囲に切り換えることができます。
  • s0-s3 または s1-s4 の範囲に切り替えることはできません。

別のレベルに切り替えると、異なるクリアランスで新しいシェルが開きます。つまり、下げる場合と同じ方法で元のクリアランスレベルに戻すことはできません。ただし、exit を入力すると、いつでも前のシェルに戻ることができます。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが enforcing に設定されている。
  • MLS クリアランスレベルの範囲に割り当てられたユーザーとしてログインできます。

手順

  1. セキュアな端末からユーザーとしてログインします。

    セキュアな端末は、、/etc/selinux/mls/contexts/securetty_types ファイルで定義されています。デフォルトでは、コンソールはセキュアな端末ですが、SSH はセキュアではありません。

  2. 現在のユーザーのセキュリティーコンテキストを確認します。

    $ id -Z
    user_u:user_r:user_t:s0-s2

    この例では、ユーザーは user_u SELinux ユーザー、user_r ロール、user_t タイプ、s0-s2 の MLS セキュリティーファイルに割り当てられます。

  3. 現在のユーザーのセキュリティーコンテキストを確認します。

    $ id -Z
    user_u:user_r:user_t:s1-s2
  4. ユーザーのクリアランス範囲内で別のセキュリティークリアランス範囲に切り替えます。

    $ newrole -l s1

    最大が割り当てられた範囲以下の範囲に切り替えることができます。単一レベルの範囲を入力すると、割り当てられた範囲の下限が変更されます。たとえば、範囲が s0-s2 のユーザーとして newrole -l s1 を入力することは、newrole -l s1-s2 を入力することに相当します。

検証

  1. 現在のユーザーのセキュリティーコンテキストを確認します。

    $ id -Z
    user_u:user_r:user_t:s1-s2
  2. 現在のシェルを終了し、元の範囲で前のシェルに戻ります。

    $ exit

6.6. MLS におけるファイル機密レベルの引き上げ

ローカル SELinux ポリシーモジュールを追加することで、MLS ユーザーがファイルの機密レベルを引き上げられるようにします。ユーザーがファイルを変更すると、そのファイルの機密レベルは自動的に、ユーザーの現在のセキュリティー範囲の中で最も低い値に引き上げられます。

デフォルトでは、MLS (Multi-Level Security) ユーザーはファイル機密レベルを高くすることはできません。ただし、セキュリティー管理者 (secadm_r) は、システムの SELinux ポリシーにローカルモジュール mlsfilewrite を追加することで、デフォルトの動作を変更し、ユーザーによるファイルの機密レベルの引き上げを許可できます。次に、ポリシーモジュールで定義された SELinux タイプに割り当てられたユーザーは、ファイルを変更することで、ファイルの分類レベルを引き上げることができます。ユーザーがファイルを変更すると、ユーザーの現在のセキュリティー範囲の下限値までファイルの機密性レベルが引き上げられます。

セキュリティー管理者は、secadm_r ロールに割り当てられたユーザーとしてログインすると、chcon -l s0 /path/to/file コマンドを使用してファイルのセキュリティーレベルを変更できます。詳細は、MLS でのファイル機密レベルの変更 を参照してください。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが enforcing に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • mlsfilewrite ローカルモジュールが SELinux MLS ポリシーにインストールされている。
  • MLS のユーザーとしてログインしている。つまり:

    • 定義済みのセキュリティー範囲に割り当てられている。以下の例は、セキュリティー範囲が s0-s2 のユーザーを示しています。
    • mlsfilewrite モジュールで定義されているのと同じ SELinux タイプに割り当てられている。この例では、(typeattributeset mlsfilewrite (user_t)) モジュールが必要です。

手順

  1. オプション: 現在のユーザーのセキュリティーコンテキストを表示します。

    $ id -Z
    user_u:user_r:user_t:s0-s2
  2. ユーザーの MLS クリアランス範囲の下位レベルを、ファイルに割り当てるレベルに変更します。

    $ newrole -l s1-s2
  3. オプション: 現在のユーザーのセキュリティーコンテキストを表示します。

    $ id -Z
    user_u:user_r:user_t:s1-s2
  4. オプション: ファイルのセキュリティーコンテキストを表示します。

    $ ls -Z /path/to/file
    user_u:object_r:user_home_t:s0 /path/to/file
  5. ファイルを変更して、ファイルの機密レベルをユーザーのクリアランス範囲の下位レベルに変更します。

    $ touch /path/to/file
    重要

    システムで restorecon コマンドを使用すると、分類レベルはデフォルト値に戻ります。

  6. オプション: シェルを終了して、ユーザーの以前のセキュリティー範囲に戻ります。

    $ exit

検証

  • ファイルのセキュリティーコンテキストを表示します。

    $ ls -Z /path/to/file
    user_u:object_r:user_home_t:s1 /path/to/file

6.7. MLS でのファイル機密レベルの変更

管理者として、ファイルの MLS 区分を手動で引き上げます。このアクションにより、ファイルをより高い機密レベルで処理することが可能になり、クリアランスの低いユーザーからのデータ保護に役立ちます。

MLS SELinux ポリシーでは、ユーザーは自分の機密レベルのファイルしか変更できません。これは、クリアランスレベルが低いユーザーに極秘情報が公開されないようにすること、またクリアランスレベルの低いユーザーが機密レベルの高いドキュメントを作成できないようにすることが目的です。ただし、管理者は、ファイルをより高いレベルで処理するなど、ファイル区分を手動で増やすことができます。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが Enforcing に設定されている。
  • セキュリティー管理者権限が割り当てられている。以下のいずれかに割り当てます。

    • secadm_r ロール。
    • sysadm_secadm モジュールが有効になっている場合は、sysadm_r ロール。sysadm_secadm モジュールはデフォルトで有効になっています。
  • policycoreutils-python-utils パッケージがインストールされている。
  • クリアランスレベルが割り当てられているユーザー。詳細は、MLS でのユーザークリアランスレベルの設定 を参照してください。

    この例では、User1 のクリアランスレベルは s1 です。

  • 区分レベルが割り当てられ、アクセスできるファイル。

    この例では、/path/to/file の区分レベルは s1 です。

手順

  1. ファイルの区分レベルを確認します。

    # ls -lZ /path/to/file
    -rw-r-----. 1 User1 User1 user_u:object_r:user_home_t:s1 0 12. Feb 10:43 /path/to/file
  2. ファイルのデフォルトの区分レベルを変更します。

    # semanage fcontext -a -r s2 /path/to/file
  3. ファイルの SELinux コンテキストのラベルを強制的につけ直します。

    # restorecon -F -v /path/to/file
    Relabeled /path/to/file from user_u:object_r:user_home_t:s1 to user_u:object_r:user_home_t:s2

検証

  1. ファイルの区分レベルを確認します。

    # ls -lZ /path/to/file
    -rw-r-----. 1 User1 User1 user_u:object_r:user_home_t:s2 0 12. Feb 10:53 /path/to/file
  2. オプション: クリアランスが低いユーザーがファイルを読み込めないことを確認します。

    $ cat /path/to/file
    cat: file: Permission denied

6.8. MLS でのシステム管理とセキュリティー管理の分離

MLS で sysadm_secadm モジュールを無効にすることで、システム管理とセキュリティー管理を分離します。これは、secadm_r ロールを特定のセキュリティー管理者ユーザーに明示的に割り当てることで、セキュリティ認可の制御をより厳格化できます。

デフォルトでは、sysadm_r ロールには secadm_r ロールの権限があります。つまり、sysadm_r ロールを持つユーザーは、セキュリティーポリシーを管理できることを意味します。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが enforcing に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • secadm_r ロールに割り当てられる Linux ユーザー。

    • ユーザーは、staff_u SELinux ユーザーに割り当てられます。
    • このユーザーのパスワードが定義されています。
    警告

    secadm ロールに割り当てられるユーザーでログインできることを確認してください。そうでない場合は、システムの SELinux ポリシーの将来の変更を防ぐことができます。

手順

  1. ユーザー向けに、新しい sudoers ファイルを /etc/sudoers.d ディレクトリーに作成します。

    # visudo -f /etc/sudoers.d/<sec_adm_user>

    sudoers ファイルを整理しておくには、<sec_adm_user>secadm ロールに割り当てられる Linux ユーザーに置き換えます。

  2. /etc/sudoers.d/<sec_adm_user> ファイルに、以下の内容を追加します。

    <sec_adm_user> ALL=(ALL) TYPE=secadm_t ROLE=secadm_r ALL

    この行は、すべてのホスト上の <sec_adm_user> が、すべてのコマンドを実行することを許可し、デフォルトでユーザーを secadm SELinux タイプとロールにマップします。

  3. <sec_adm_user> ユーザーでログインします。

    SELinux コンテキスト (SELinux のユーザー、ロール、タイプで構成) が変更されていることを確認するために、ssh、コンソール、または xdm を使用してログイン します。su および sudo などの他の方法では、SELinux コンテキスト全体を変更することはできません。

  4. ユーザーのセキュリティーコンテキストを確認します。

    $ id
    uid=1000(<sec_adm_user>) gid=1000(<sec_adm_user>) groups=1000(<sec_adm_user>) context=staff_u:staff_r:staff_t:s0-s15:c0.c1023
  5. root ユーザーの対話型シェルを実行します。

    $ sudo -i
    [sudo] password for <sec_adm_user>:
  6. 現在のユーザーのセキュリティーコンテキストを確認します。

    # id
    uid=0(root) gid=0(root) groups=0(root) context=staff_u:secadm_r:secadm_t:s0-s15:c0.c1023
  7. ポリシーから sysadm_secadm モジュールを無効にします。

    # semodule -d sysadm_secadm
    重要

    semodule -r コマンドを使用してシステムポリシーモジュールを削除する代わりに、semodule -d コマンドを使用します。semodule -r コマンドは、システムのストレージからモジュールを削除します。これは、selinux-policy-mls パッケージを再インストールしないと、モジュールを再び読み込むことができないことを意味します。

検証

  1. secadm ロールに割り当てられたユーザーとして、root ユーザーの対話型シェルで、セキュリティーポリシーデータにアクセスできることを確認します。

    # seinfo -xt secadm_t
    
    Types: 1
       type secadm_t, can_relabelto_shadow_passwords, (…) userdomain;
  2. root シェルからログアウトします。

    # logout
  3. <sec_adm_user> ユーザーからログアウトします。

    $ logout
    Connection to localhost closed.
  4. 現在のセキュリティーコンテキストを表示します。

    # id
    uid=0(root) gid=0(root) groups=0(root) context=root:sysadm_r:sysadm_t:s0-s15:c0.c1023
  5. sysadm_secadm モジュールの有効化を試してください。コマンドは失敗するはずです。

    # semodule -e sysadm_secadm
    SELinux:  Could not load policy file /etc/selinux/mls/policy/policy.31:  Permission denied
    /sbin/load_policy:  Can't load policy:  Permission denied
    libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory).
    SELinux:  Could not load policy file /etc/selinux/mls/policy/policy.31:  Permission denied
    /sbin/load_policy:  Can't load policy:  Permission denied
    libsemanage.semanage_reload_policy: load_policy returned error code 2. (No such file or directory).
    semodule:  Failed!
  6. sysadm_t SELinux タイプに関する詳細の表示を試してください。コマンドは失敗するはずです。

    # seinfo -xt sysadm_t
    [Errno 13] Permission denied: '/sys/fs/selinux/policy'

6.9. MLS でのセキュアな端末の定義

MLS ポリシーでセキュアでないとみなされる特定の端末からのログインを許可するには、それらの端末のタイプを /etc/selinux/mls/contexts/securetty_types ファイルに追加します。これは、MLS が一般的な端末タイプからのユーザーログインを禁止する場合に必要となります。

SELinux ポリシーは、ユーザーが接続している端末のタイプをチェックし、特定の SELinux アプリケーション (newrole など) の実行をセキュアな端末からのみ許可します。セキュアでない端末からこれを実行すると、Error: you are not allowed to change levels on a non secure terminal; のエラーが発生します。

/etc/selinux/mls/contexts/securetty_types ファイルは、MLS (Multi-Level Security) ポリシーのセキュアな端末を定義します。

ファイルのデフォルトコンテンツ:

console_device_t
sysadm_tty_device_t
user_tty_device_t
staff_tty_device_t
auditadm_tty_device_t
secureadm_tty_device_t
警告

端末タイプをセキュアな端末リストに追加すると、システムがセキュリティーリスクにさらされる可能性があります。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • すでにセキュアな端末から接続しているか、SELinux が Permissive モードである。
  • セキュリティー管理者権限が割り当てられている。以下のいずれかに割り当てます。

    • secadm_r ロール。
    • sysadm_secadm モジュールが有効になっている場合は、sysadm_r ロール。sysadm_secadm モジュールはデフォルトで有効になっています。
  • policycoreutils-python-utils パッケージがインストールされている。

手順

  1. 現在の端末タイプを確認します。

    # ls -Z `tty`
    root:object_r:user_devpts_t:s0 /dev/pts/0

    この出力例では、user_devpts_t が現在の端末タイプです。

  2. /etc/selinux/mls/contexts/securetty_types ファイルの新しい行に、関連する SELinux タイプを追加します。
  3. オプション: SELinux を enforcing モードに切り替えます。

    # setenforce 1

検証

  • /etc/selinux/mls/contexts/securetty_types ファイルに追加した、以前はセキュアでなかった端末からログインします。

6.10. MLS ユーザーによる下位レベルのファイルの編集を許可する

デフォルトでは、MLS ユーザーは、クリアランス範囲の下限を下回る機密レベルのファイルには書き込むことができません。ユーザーによる下位レベルのファイルの編集を許可する必要がある場合は、ローカル SELinux モジュールを作成することで実行できます。

ただし、ファイルへの書き込みにより、機密レベルがユーザーの現在の範囲の下限まで上昇します。

前提条件

  • SELinux ポリシーが mls に設定されている。
  • SELinux モードが enforcing に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • 検証用の setools-console パッケージおよび audit パッケージ。

手順

  1. オプション: トラブルシューティングを実施しやすくするために、Permissive モードに切り替えます。

    # setenforce 0
  2. ~/local_mlsfilewrite.cil などのテキストエディターで新しい .cil ファイルを開き、以下のカスタムルールを挿入します。

    (typeattributeset mlsfilewrite (_staff_t_))

    staff_t は、別の SELinux タイプに置き換えることができます。ここで SELinux タイプを指定することで、下位レベルのファイルを編集できる SELinux ロールを制御できます。

    ローカルモジュールをより適切に整理するには、ローカル SELinux ポリシーモジュール名で接頭辞 local_ を使用します。

  3. ポリシーモジュールをインストールします。

    # semodule -i ~/local_mlsfilewrite.cil
    注記

    ローカルポリシーモジュールを削除するには、semodule -r ~/local_mlsfilewrite を使用します。モジュール名を参照する場合は、接頭辞 .cil なしで参照する必要がある点に注意してください。

  4. オプション: 以前に permissive モードに戻した場合は、enforcing モードに戻ります。

    # setenforce 1

検証

  1. インストールされている SELinux モジュールのリストでローカルモジュールを検索します。

    # semodule -lfull | grep "local_mls"
    400 local_mlsfilewrite  cil

    ローカルモジュールの優先度は 400 であるため、semodule -lfull | grep -v ^100 コマンドを使用してリスト表示することもできます。

  2. カスタムルールで定義されているタイプ (staff_t など) に割り当てられたユーザーとしてログインします。
  3. 機密レベルが低いファイルに書き込みを試みます。これにより、ファイルの区分レベルがユーザーのクリアランスレベルまで上昇します。

    重要

    検証に使用するファイルには、設定が間違っており、ユーザーが実際に認証なしにファイルにアクセスできてしまう場合に備え、機密情報を含めないようにしてください。

第7章 データの機密性に MCS (Multi-Category Security) を使用する

MCS を使用すると、データのカテゴリーを分類し、特定のプロセスやユーザーに特定のカテゴリーへのアクセスを許可することで、システムのデータの機密性を高めることができます。

7.1. Multi-Category Security (MCS)

Multi-Category Security (MCS) を使用して、プロジェクトや部門ラベルなどのカテゴリー識別子に基づいて、対象やオブジェクトへのアクセスを制限します。MCS は、異なるドメイン間の効果的な分離と機密性を確保するのに役立ちます。

MCS (Multi-Category Security) は、プロセスおよびファイルに割り当てられたカテゴリーを使用するアクセス制御メカニズムです。その後、同じカテゴリーに割り当てられているプロセスのみがファイルにアクセスできます。MCS の目的は、システムでデータの機密性を維持することです。

MCS のカテゴリーは c0 から c1023 までの値で定義されます。ただし、各カテゴリーまたはカテゴリーの組み合わせに対して、"Personnel"、"ProjectX”、"ProjectX.Personnel” などのテキストラベルを定義することもできます。その後、ユーザーがこれらのラベルをカテゴリーの値の代わりに使用できるように、システムの入力と出力において、MCS 変換サービス (mcstrans) によってカテゴリーの値が適切なラベルに置き換えられます。

ユーザーは、カテゴリーに割り当てられているときに、割り当てられているカテゴリーのいずれかでファイルにラベルを付けることができます。

MCS は単純な原則に基づいて動作します。ファイルにアクセスするには、ファイルに割り当てられたすべてのカテゴリーにユーザーを割り当てる必要があります。MCS チェックは、通常の Linux DAC (Discretionary Access Control) ルールおよび SELinux TE (Type Enforcement) ルールの後に適用されるため、既存のセキュリティー設定をさらに制限する必要があります。

7.1.1. Multi-Level Security (MLS) における MCS

MCS は、単独で非階層システムとして使用することも、マルチレベルセキュリティー (MLS) と組み合わせて、階層システム内の非階層レイヤーとして使用することもできます。

MLS 内での MCS の活用例として、機密情報を扱う研究機関が挙げられます。そこでは、ファイルは以下の表に示すように分類されています。

Expand
表7.1 セキュリティーレベルとカテゴリーの組み合わせの例

セキュリティーレベル

カテゴリー

Not specified

プロジェクト X

プロジェクト Y

プロジェクト Z

Unclassified

s0

s0:c0

s0:c1

s0:c2

Confidential

s1

s1:c0

s1:c1

s1:c2

Secret

s2

s2:c0

s2:c1

s2:c2

Top secret

s3

s3:c0

s3:c1

s3:c2

注記

範囲が s0:c0.1023 のユーザーは、DAC や Type Enforcement ポリシールールなどの他のセキュリティーメカニズムでアクセスが禁止されていない限り、レベル s0 のすべてのカテゴリーに割り当てられたすべてのファイルにアクセスできます。

ファイルまたはプロセスのセキュリティーコンテキストは、以下の組み合わせになります。

  • SELinux ユーザー
  • SELinux ロール
  • SELinux タイプ
  • MLS 機密レベル
  • MCS カテゴリー

たとえば、MLS/MCS 環境で機密レベル 1 およびカテゴリー 2 にアクセスできる非特権ユーザーは、以下の SELinux コンテキストを持つことができます。

user_u:user_r:user_t:s1:c2

7.2. データの機密性にマルチカテゴリーセキュリティーを設定

targeted ポリシーおよび MLS ポリシーにおけるデータ機密性を確保するために、ユーザー向けに Multi-Category Security (MCS) を設定します。これには、MCS ルールによってユーザー領域を制限するローカル SELinux モジュールを作成する作業が含まれます。

デフォルトでは、Multi-Category Security (MCS) は、SELinux ポリシー targeted および mls でアクティブになっていますが、ユーザーに対しては設定されていません。targeted ポリシーでは、MCS は以下の場合にのみ設定されます。

  • OpenShift
  • virt
  • サンドボックス (sandbox)
  • ネットワークラベリング
  • コンテナー (container-selinux)

Type Enforcement に加え、MCS ルールで user_t SELinux タイプを制約するルールを使用して、ローカルの SELinux モジュールを作成することにより、ユーザーを分類するように MCS を設定できます。

警告

特定のファイルのカテゴリーを変更すると、一部のサービスが動作しなくなる可能性があります。専門家でない場合は、Red Hat の営業担当者に連絡し、コンサルティングサービスを依頼してください。

前提条件

  • SELinux モードが `enforcing に設定されている。
  • SELinux のポリシーは targeted または mls に設定されている。
  • policycoreutils-python-utils パッケージおよび setools-console パッケージがインストールされている。

手順

  1. 新しいファイルを作成します (例: local_mcs_user.cil)。

    # touch local_mcs_user.cil
  2. テキストエディターに、次のルールを挿入します。

    (typeattributeset mcs_constrained_type (user_t))
  3. ポリシーモジュールをインストールします。

    # semodule -i local_mcs_user.cil

検証

  • 各ユーザードメインに、すべてのコンポーネントの詳細を表示します。

    # seinfo -xt user_t
    
    Types: 1
    type user_t, application_domain_type, nsswitch_domain, corenet_unlabeled_type, domain, kernel_system_state_reader, mcs_constrained_type, netlabel_peer_type, privfd, process_user_target, scsi_generic_read, scsi_generic_write, syslog_client_type, pcmcia_typeattr_1, user_usertype, login_userdomain, userdomain, unpriv_userdomain, userdom_home_reader_type, userdom_filetrans_type, xdmhomewriter, x_userdomain, x_domain, dridomain, xdrawable_type, xcolormap_type;

次のステップ

7.3. MCS でのカテゴリーラベルの定義

setrans.conf ファイルを編集して、MCS カテゴリーまたは MLS レベルの組み合わせに対して、人間が読みやすいラベルを定義します。これらのラベルを定義することで、ユーザーはカテゴリーの管理と使用が容易になりますが、MCS の機能は変わりません。

setrans.conf を編集することで、MCS カテゴリーのラベル、または MCS カテゴリーと MLS レベルの組み合わせを管理および維持できます。このファイルでは、SELinux は、内部の機密レベルとカテゴリーレベル、および人間が判読できるラベルとの間でマッピングを維持しています。お使いのシステムの setrans.conf(5) の man ページを参照してください。

注記

カテゴリーラベルは、ユーザーがカテゴリーを使いやすくするためだけのものです。MCS は、ラベルを定義するかどうかに関係なく同じように機能します。

前提条件

  • SELinux モードが enforcing に設定されている。
  • SELinux のポリシーは targeted または mls に設定されている。
  • policycoreutils-python-utils パッケージおよび mcstrans パッケージがインストールされている。

手順

  1. テキストエディターで /etc/selinux/<selinux_policy>/setrans.conf ファイルを編集して、既存のカテゴリーを修正するか、新しいカテゴリーを作成します。使用する SELinux ポリシーに応じて、<selinux_policy>targeted または mls に置き換えます。以下に例を示します。

    # vi /etc/selinux/targeted/setrans.conf
  2. ポリシーの setrans.conf ファイルで、構文 s_<security_level>_:c_<category_number>_=<category_name> を使用して、シナリオで必要なカテゴリーの組み合わせを定義します。以下に例を示します。

    s0:c0=Marketing
    s0:c1=Finance
    s0:c2=Payroll
    s0:c3=Personnel
    • カテゴリー番号は、c0 から c1023 まで使用できます。
    • targeted ポリシーでは、s0 セキュリティーレベルを使用します。
    • mls ポリシーでは、機密レベルとカテゴリーの組み合わせにラベルを付けることができます。
  3. 必要に応じて、setrans.conf ファイル内で、MLS 機密レベルにラベルを付けることもできます。
  4. ファイルを保存し、終了します。
  5. 変更を有効にするには、MCS 変換サービスを再起動します。

    # systemctl restart mcstrans

検証

  • 現在のカテゴリーを表示します。

    # chcat -L

    上の例の出力は、以下となります。

    s0:c0                          Marketing
    s0:c1                          Finance
    s0:c2                          Payroll
    s0:c3                          Personnel
    s0
    s0-s0:c0.c1023                 SystemLow-SystemHigh
    s0:c0.c1023                    SystemHigh

7.4. MCS でのユーザーへのカテゴリーの割り当て

Linux ユーザーにカテゴリーを割り当てることで、ユーザー認証を定義できます。カテゴリーが割り当てられているユーザーは、そのユーザーのカテゴリーのサブセットを持つファイルにアクセスして修正できます。また、ユーザーは自分が所有するファイルを、割り当てられたカテゴリーに割り当てることもできます。

Linux ユーザーは、関連する SELinux ユーザーに定義されたセキュリティー範囲外のカテゴリーに割り当てることはできません。

注記

カテゴリーアクセスは、ログイン時に割り当てられます。そのため、ユーザーは再度ログインするまで、新しく割り当てられたカテゴリーにアクセスできません。同様に、カテゴリーへのユーザーのアクセスを取り消した場合は、ユーザーが再度ログインしないと有効になりません。

前提条件

  • SELinux モードが enforcing に設定されている。
  • SELinux のポリシーは targeted または mls に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • Linux ユーザーが SELinux で制限されたユーザーに割り当てられている。

    • 特権のないユーザーは、user_u に割り当てられます。
    • 特権ユーザーは、staff_u に割り当てられます。

手順

  1. SELinux ユーザーのセキュリティー範囲を定義します。

    # semanage user -m -rs0:c0,c1-s0:c0.c9 <user_u>

    setrans.conf ファイルで定義されているように、c0 から c1023 までのカテゴリー番号またはカテゴリーラベルを使用します。詳細は、MCS でのカテゴリーラベルの定義 を参照してください。

  2. Linux ユーザーに MCS カテゴリーを割り当てます。指定できるのは、関連する SELinux ユーザーに定義された範囲内でのみです。

    # semanage login -m -rs0:c1 <Linux.user1>

    chcat コマンドを使用して、Linux ユーザーにカテゴリーを追加または削除できます。以下の例では、<category1> を追加し、<Linux.user1> および <Linux.user2> から <category2> を削除します。

    # chcat -l -- +<category1>,-<category2> <Linux.user1>,<Linux.user2>

    -<category> 構文を使用する前に、コマンドラインで -- を指定する必要があります。指定しないと、chcat コマンドは、カテゴリーの削除をコマンドオプションであると誤って解釈します。詳細は、お使いのシステムの chcat(8) の man ページを参照してください。

検証

  • Linux ユーザーに割り当てられているカテゴリーのリストを表示します。

    # chcat -L -l <Linux.user1>,<Linux.user2>
    <Linux.user1>: <category1>,<category2>
    <Linux.user2>: <category1>,<category2>

7.5. MCS でのファイルへのカテゴリーの割り当て

ファイルに Multi-Category Security (MCS) カテゴリーを割り当てることで、アクセスを特定のカテゴリーに割り当てられたユーザーのみに制限できます。これにより、組織内の異なるドメイン間での情報共有を制限し、機密性をさらに向上させることができます。

カテゴリーをユーザーに割り当てるには、管理者特権が必要です。ユーザーはカテゴリーをファイルに割り当てることができます。ファイルのカテゴリーを変更するには、そのファイルへのアクセス権が必要です。ユーザーは、割り当てられているカテゴリーにのみファイルを割り当てることができます。

注記

このシステムは、カテゴリーアクセスルールと従来のファイルアクセス権限を組み合わせています。たとえば、bigfoot のカテゴリーを持つユーザーが DAC (Discretionary Access Control) を使用して他のユーザーによるファイルへのアクセスをブロックすると、他の bigfoot ユーザーはそのファイルにアクセスできなくなります。利用可能なすべてのカテゴリーに割り当てられたユーザーであっても、ファイルシステム全体にアクセスできるとは限りません。

前提条件

  • SELinux モードが enforcing に設定されている。
  • SELinux のポリシーは targeted または mls に設定されている。
  • policycoreutils-python-utils パッケージがインストールされている。
  • 以下に該当する Linux ユーザーのアクセスおよびパーミッション

  • カテゴリーに追加するファイルへのアクセスと権限。
  • 検証目的: このカテゴリーに割り当てられていない Linux ユーザーへのアクセスとパーミッション

手順

  • カテゴリーをファイルに追加します。

    $ chcat -- +<category1>,+<category2> <path/to/file1>

    setrans.conf ファイルで定義されているように、c0 から c1023 までのカテゴリー番号またはカテゴリーラベルを使用します。詳細は、MCS でのカテゴリーラベルの定義 を参照してください。

    同じ構文を使用して、ファイルからカテゴリーを削除できます。

    $ chcat -- -<category1>,-<category2> <path/to/file1>
    注記

    カテゴリーを削除する場合は、コマンドラインで -- を指定してから -<category> 構文を使用する必要があります。指定しないと、chcat コマンドは、カテゴリーの削除をコマンドオプションであると誤って解釈します。

検証

  1. ファイルのセキュリティーコンテキストを表示して、カテゴリーが正しいことを確認します。

    $ ls -lZ <path/to/file>
    -rw-r--r--  <LinuxUser1> <Group1> root:object_r:user_home_t:_<sensitivity>_:_<category>_ <path/to/file>

    ファイルの具体的なセキュリティー状況は異なる場合があります。

  2. (必要に応じて) ファイルと同じカテゴリーに割り当てられていない Linux ユーザーとしてログインしたときに、ファイルにアクセスしようとします。

    $ cat <path/to/file>
    cat: <path/to/file>: Permission Denied

第8章 カスタム SELinux ポリシーの作成

カスタム SELinux ポリシーを作成して使用して、アプリケーションの動作範囲を制限し、ホストシステムのセキュリティーを向上させることができます。カスタムポリシーは、アプリケーションの要件に合わせてカスタマイズされた、正確なアクセスルールを定義します。

8.2. カスタムアプリケーション用の SELinux ポリシーの作成および実施

SELinux ポリシーをカスタマイズして適用することで、カスタムアプリケーションを制限し、ホストシステムとユーザーデータのセキュリティーを強化できます。

各アプリケーションには特定の要件があるため、ユースケースに応じてこの手順を変更してください。ここでは例として、単純なデーモンを制限する SELinux ポリシーを作成します。手順で使用されるコマンドの詳細は、システム上の sepolgen(8)ausearch(8)audit2allow(1)audit2why(1)sealert(8)、および restorecon(8) の man ページを参照してください。

前提条件

  • selinux-policy-devel パッケージとその依存関係がシステムにインストールされている。

手順

  1. この手順例では、/var/log/messages ファイルを開いて書き込みを行う簡単なデーモンを準備します。

    1. 新しいファイルを作成し、任意のテキストエディターで開きます。例:

      $ vi mydaemon.c
    2. 以下のコードを挿入します。

      #include <unistd.h>
      #include <stdio.h>
      
      FILE *f;
      
      int main(void)
      {
      while(1) {
      f = fopen("/var/log/messages","w");
              sleep(5);
              fclose(f);
          }
      }
    3. ファイルをコンパイルします。

      $ gcc -o mydaemon mydaemon.c
    4. デーモンの systemd ユニットファイルを作成します。

      $ vi mydaemon.service
      [Unit]
      Description=Simple testing daemon
      
      [Service]
      Type=simple
      ExecStart=/usr/local/bin/mydaemon
      
      [Install]
      WantedBy=multi-user.target
    5. デーモンをインストールして起動します。

      # cp mydaemon /usr/local/bin/
      # cp mydaemon.service /usr/lib/systemd/system
      # systemctl start mydaemon
      # systemctl status mydaemon
      ● mydaemon.service - Simple testing daemon
         Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled)
         Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago
       Main PID: 4117 (mydaemon)
          Tasks: 1
         Memory: 148.0K
         CGroup: /system.slice/mydaemon.service
                 └─4117 /usr/local/bin/mydaemon
      
      May 23 16:56:01 localhost.localdomain systemd[1]: Started Simple testing daemon.
    6. 新しいデーモンが SELinux によって制限されていないことを確認します。

      $ ps -efZ | grep mydaemon
      system_u:system_r:unconfined_service_t:s0 root 4117    1  0 16:56 ?        00:00:00 /usr/local/bin/mydaemon
  2. デーモンのカスタムポリシーを生成します。

    $ sepolicy generate --init /usr/local/bin/mydaemon
    Created the following files:
    /home/example.user/mysepol/mydaemon.te # Type Enforcement file
    /home/example.user/mysepol/mydaemon.if # Interface file
    /home/example.user/mysepol/mydaemon.fc # File Contexts file
    /home/example.user/mysepol/mydaemon_selinux.spec # Spec file
    /home/example.user/mysepol/mydaemon.sh # Setup Script
  3. 直前のコマンドで作成した設定スクリプトを使用して、新しいポリシーモジュールでシステムポリシーを再構築します。

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

    セットアップスクリプトは、restorecon コマンドを使用してファイルシステムの該当箇所にラベルを付け直すことに注意してください。

    restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/system
  4. デーモンを再起動して、SELinux が制限のあるデーモンを実行していることを確認します。

    # systemctl restart mydaemon
    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  5. デーモンは SELinux によって制限されているため、SELinux はこのデーモンが /var/log/messages にアクセスできないようにします。対応する拒否メッセージを表示します。

    # ausearch -m AVC -ts recent
    ...
    type=AVC msg=audit(1590247112.719:5935): avc:  denied  { open } for  pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1
    ...
  6. sealert ツールを使用して追加情報を取得することもできます。

    $ sealert -l "*"
    SELinux is preventing mydaemon from open access on the file /var/log/messages.
    
    *****  Plugin catchall (100. confidence) suggests   **************************
    
    If you believe that mydaemon should be allowed open access on the messages file by default.
    Then you should report this as a bug.
    You can generate a local policy module to allow this access.
    Do allow this access for now by executing:
    # ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon
    # semodule -X 300 -i my-mydaemon.pp
    
    Additional Information:
    Source Context                system_u:system_r:mydaemon_t:s0
    Target Context                unconfined_u:object_r:var_log_t:s0
    Target Objects                /var/log/messages [ file ]
    Source                        mydaemon
    …
  7. audit2allow ツールを使用して、変更を提案します。

    $ ausearch -m AVC -ts recent | audit2allow -R
    
    require {
    	type mydaemon_t;
    }
    
    #============= mydaemon_t ==============
    logging_write_generic_logs(mydaemon_t)
  8. audit2allow が提案するルールは特定のケースでは正しくない可能性があるため、出力の一部のみを使用して対応するポリシーインターフェイスを見つけます。macro-expander ツールを使用して logging_write_generic_logs(mydaemon_t) マクロを検査し、マクロが提供するすべての許可ルールを確認します。

    $ macro-expander "logging_write_generic_logs(mydaemon_t)"
    allow mydaemon_t var_t:dir { getattr search open };
    allow mydaemon_t var_log_t:dir { getattr search open read lock ioctl };
    allow mydaemon_t var_log_t:dir { getattr search open };
    allow mydaemon_t var_log_t:file { open { getattr write append lock ioctl } };
    allow mydaemon_t var_log_t:dir { getattr search open };
    allow mydaemon_t var_log_t:lnk_file { getattr read };
  9. ここでは、提案されたインターフェイスを使用できます。このインターフェイスは、ログファイルとその親ディレクトリーへの読み取りおよび書き込みアクセスのみを提供するためです。Type Enforcement ファイルに対応するルールを追加します。

    $ echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te

    または、インターフェイスを使用する代わりに、このルールを追加することもできます。

    $ echo "allow mydaemon_t var_log_t:file { open write getattr };" >> mydaemon.te
  10. ポリシーを再インストールします。

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

検証

  1. アプリケーションが SELinux によって制限されて実行されていることを確認します。以下に例を示します。

    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  2. カスタムアプリケーションが SELinux 拒否を生じさせないことを確認します。

    # ausearch -m AVC -ts recent
    <no matches>

第9章 コンテナーの SELinux ポリシーの作成

udica ツールを使用して、コンテナー向けにカスタマイズされた SELinux ポリシーを生成します。これらのポリシーは、コンテナーがストレージやネットワーク機器などのホストシステムリソースにアクセスする方法を厳密に制御することで、コンテナーのセキュリティーを強化します。

udica を使用すると、セキュリティー違反に対してコンテナーのデプロイメントを強化でき、規制コンプライアンスの実現や維持も簡単になります。

9.1. udica の SELinux ポリシージェネレーターの概要

udica ユーティリティーを使用すると、カスタムコンテナー用の新しい SELinux ポリシーを作成できます。このツールを使用すると、Linux の機能、マウントポイント、ポート定義を含むコンテナーの JSON ファイルを検査して、ポリシーを作成できます。

このツールは、検査結果から生成されたルールと、指定された SELinux 共通中間言語 (CIL) ブロックから継承されたルールを組み合わせます。

udica を使用してコンテナーの SELinux ポリシーを生成するプロセスは、主に 3 つの部分から設定されます。

  1. JSON 形式のコンテナー仕様ファイルを解析する。
  2. 最初の部分の結果に基づいて適切な許可ルールを見つける。
  3. 最終的な SELinux ポリシーを生成する。

解析フェーズでは、udica が Linux 機能、ネットワークポート、およびマウントポイントを探します。

この結果に基づいて、udica はコンテナーに必要な Linux 機能を検出し、これらすべての機能を許可する SELinux ルールを作成します。コンテナーが特定のポートにバインドする場合は、udica が SELinux ユーザー空間ライブラリーを使用して、検査対象のコンテナーが使用するポートの正しい SELinux ラベルを取得します。

その後、udica はホストからコンテナーファイルシステムの名前空間にマウントされているディレクトリーを検出します。

CIL ブロック継承機能により、udica は特定のアクションに焦点を当てた SELinux 許可ルール のテンプレートを作成できます。たとえば、次のようになります。

  • ホームディレクトリーへのアクセスを許可する。
  • ログファイルへのアクセスを許可する。
  • X サーバーとの通信に対するアクセスを許可する

このようなテンプレートはブロックと呼ばれ、最終的な SELinux ポリシーはブロックをマージして作成されます。

9.2. カスタムコンテナーの SELinux ポリシーを作成して使用

udica によって生成された SELinux ポリシーモジュールを作成し、それを使用してコンテナーのホストシステムへのアクセスを制限します。このポリシーは、コンテナーに必要なリソースのみを制限することで、コンテナーが侵害された場合の潜在的な影響を最小限に抑えます。

前提条件

  • コンテナーを管理する podman ツールがインストールされている。そうでない場合は、dnf install podman を使用します。
  • カスタムの Linux コンテナー - この例では ubi8 です。

手順

  1. udica パッケージをインストールします。

    # dnf install -y udica

    udica を含むコンテナーソフトウェアパッケージセットを提供する container-tools モジュールをインストールします。

    # dnf module install -y container-tools
  2. /home ディレクトリーを読み取り権限でマウントする ubi8 コンテナーと、読み取りおよび書き込みの権限で /var/spool ディレクトリーをマウントします。コンテナーはポート 21 を公開します。

    # podman run --env container=podman -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash

    コンテナーは、SELinux のタイプが container_t で実行されることに注意してください。このタイプは、SELinux ポリシー内のすべてのコンテナーの汎用ドメインであり、シナリオに対して厳密すぎるか緩すぎる可能性があります。

  3. 新しいターミナルを開き、podman ps コマンドを入力して、コンテナーの ID を取得します。

    # podman ps
    CONTAINER ID   IMAGE                                   COMMAND   CREATED          STATUS              PORTS   NAMES
    37a3635afb8f   registry.access.redhat.com/ubi8:latest  bash      15 minutes ago   Up 15 minutes ago           heuristic_lewin
  4. コンテナーの JSON ファイルを作成し、udica を使用して JSON ファイルの情報に基づいてポリシーモジュールを作成します。

    # podman inspect 37a3635afb8f > container.json
    # udica -j container.json my_container
    Policy my_container with container id 37a3635afb8f created!
    …

    または、次のようになります。

    # podman inspect 37a3635afb8f | udica my_container
    Policy my_container with container id 37a3635afb8f created!
    
    Please load these modules using:
    # semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
    
    Restart the container with: "--security-opt label=type:my_container.process" parameter
  5. 前の手順の udica の出力で提案されているように、ポリシーモジュールを読み込みます。

    # semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
  6. コンテナーを停止し、--security-opt label=type:my_container.process オプションを使用して再起動します。

    # podman stop 37a3635afb8f
    # podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash

検証

  1. コンテナーが、my_container.process タイプで実行されることを確認します。

    # ps -efZ | grep my_container.process
    unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023 root 2275 434  1 13:49 pts/1 00:00:00 podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash
    system_u:system_r:my_container.process:s0:c270,c963 root 2317 2305  0 13:49 pts/0 00:00:00 bash
  2. SELinux が、マウントポイント /home および /var/spool へのアクセスを許可していることを確認します。

    [root@37a3635afb8f /]# cd /home
    [root@37a3635afb8f home]# ls
    username
    [root@37a3635afb8f ~]# cd /var/spool/
    [root@37a3635afb8f spool]# touch test
    [root@37a3635afb8f spool]#
  3. SELinux がポート 21 へのバインドのみを許可していることを確認します。

    [root@37a3635afb8f /]# dnf install nmap-ncat
    [root@37a3635afb8f /]# nc -lvp 21
    …
    Ncat: Listening on :::21
    Ncat: Listening on 0.0.0.0:21
    ^C
    [root@37a3635afb8f /]# nc -lvp 80
    …
    Ncat: bind to :::80: Permission denied. QUITTING.

第10章 複数のシステムへの同じ SELinux 設定のデプロイメント

テスト済みで検証済みの SELinux 設定を、複数のシステムに効率的にデプロイします。デプロイメントを自動化することで、インフラストラクチャー全体で一貫したセキュリティーポリシーを確保できます。

次のいずれかの方法を使用して、検証済みの SELinux 設定を複数のシステムにデプロイできます。

  • RHEL システムロールおよび Ansible の使用
  • RHEL Web コンソールの使用
  • スクリプトで semanage の export コマンドおよび import コマンドの使用

10.1. RHEL システムロールを使用した SELinux の設定

selinux RHEL システムロールを使用すると、SELinux 権限をリモートで設定および管理できます。

たとえば、次のタスクには selinux ロールを使用してください。

  • SELinux ブール値、ファイルコンテキスト、ポート、およびログインに関連するローカルポリシーの変更の消去
  • SELinux ポリシーブール値、ファイルコンテキスト、ポート、およびログインの設定
  • 指定されたファイルまたはディレクトリーのファイルコンテキストの復元
  • SELinux モジュールの管理

10.1.1. selinux RHEL システムロールを使用したディレクトリーの SELinux コンテキストの復元

ディレクトリーの SELinux コンテキストをリモートでリセットするには、selinux RHEL システムロールを使用できます。SELinux コンテキストが正しくないと、アプリケーションがファイルにアクセスできなくなる可能性があります。

前提条件

手順

  1. 次の内容を含む Playbook ファイル (例: ~/playbook.yml) を作成します。

    ---
    - name: Managing SELinux
      hosts: managed-node-01.example.com
      tasks:
        - name: Restore SELinux context
          ansible.builtin.include_role:
            name: redhat.rhel_system_roles.selinux
          vars:
            selinux_restore_dirs:
              - /var/www/
              - /etc/

    サンプル Playbook で指定されている設定は次のとおりです。

    selinux_restore_dirs: <list>
    ロールによって SELinux コンテキストをリセットするディレクトリーのリストを定義します。

    Playbook で使用されるすべての変数の詳細は、コントロールノードの /usr/share/ansible/roles/rhel-system-roles.selinux/README.md ファイルを参照してください。

  2. Playbook の構文を検証します。

    $ ansible-playbook --syntax-check ~/playbook.yml

    このコマンドは構文を検証するだけであり、有効だが不適切な設定から保護するものではないことに注意してください。

  3. Playbook を実行します。

    $ ansible-playbook ~/playbook.yml

検証

  • コンテキストをリセットしたファイルまたはディレクトリーの SELinux コンテキストを表示します。たとえば、/var/www/ ディレクトリーのコンテキストを表示するには、次のように入力します。

    # ansible rhel10.example.com -m command -a 'ls -ldZ /var/www/'
    drwxr-xr-x. 4 root root system_u:object_r:httpd_sys_content_t:s0 33 Feb 28 13:20 /var/www/

10.1.2. selinux RHEL システムロールを使用した SELinux ネットワークポートラベルの管理

標準以外のポートでサービスを実行する場合は、SELinux がサービスへのアクセス権を拒否しないように、対応する SELinux タイプラベルをそのポートに設定する必要があります。selinux RHEL システムロールを使用すると、このタスクを自動化し、ポートにタイプラベルをリモートで割り当てることができます。

前提条件

手順

  1. 次の内容を含む Playbook ファイル (例: ~/playbook.yml) を作成します。

    ---
    - name: Managing SELinux
      hosts: managed-node-01.example.com
      tasks:
        - name: Set http_port_t label on network port
          ansible.builtin.include_role:
            name: redhat.rhel_system_roles.selinux
          vars:
            selinux_ports:
              - ports: <port_number>
                proto: tcp
                setype: http_port_t
                state: present

    サンプル Playbook で指定されている設定は次のとおりです。

    ports: <port_number>
    SELinux ラベルを割り当てるポート番号を定義します。複数の値はコンマで区切ります。
    setype: <type_label>
    SELinux タイプラベルを定義します。

    Playbook で使用されるすべての変数の詳細は、コントロールノードの /usr/share/ansible/roles/rhel-system-roles.selinux/README.md ファイルを参照してください。

  2. Playbook の構文を検証します。

    $ ansible-playbook --syntax-check ~/playbook.yml

    このコマンドは構文を検証するだけであり、有効だが不適切な設定から保護するものではないことに注意してください。

  3. Playbook を実行します。

    $ ansible-playbook ~/playbook.yml

検証

  • http_port_t ラベルが割り当てられているポート番号を表示します。

    # ansible managed-node-01.example.com -m shell -a 'semanage port --list | grep http_port_t'
    http_port_t      tcp     80, 81, 443, <port_number>, 488, 8008, 8009, 8443, 9000

10.1.3. selinux RHEL システムロールを使用した SELinux モジュールのデプロイ

デフォルトの SELinux ポリシーがお客様の要件に合わない場合は、カスタムモジュールを作成して、アプリケーションに必要なリソースへのアクセスを許可できます。selinux RHEL システムロールを使用すると、このプロセスを自動化し、SELinux モジュールをリモートでデプロイできます。

前提条件

  • コントロールノードと管理対象ノードの準備が完了している
  • 管理対象ノードで Playbook を実行できるユーザーとしてコントロールノードにログインしている。
  • 管理対象ノードへの接続に使用するアカウントに、そのノードに対する sudo 権限がある。
  • デプロイする SELinux モジュールが、Playbook と同じディレクトリーに保存されている。
  • SELinux モジュールが Common Intermediate Language (CIL) またはポリシーパッケージ (PP) 形式で利用できる。

    PP モジュールを使用している場合は、管理対象ノード上の policydb バージョンが、PP モジュールのビルドに使用されたバージョン以降であることを確認してください。

手順

  1. 次の内容を含む Playbook ファイル (例: ~/playbook.yml) を作成します。

    ---
    - name: Managing SELinux
      hosts: managed-node-01.example.com
      tasks:
        - name: Deploying a SELinux module
          ansible.builtin.include_role:
            name: redhat.rhel_system_roles.selinux
          vars:
            selinux_modules:
              - path: <module_file>
    	    priority: <value>
                state: enabled

    サンプル Playbook で指定されている設定は次のとおりです。

    path: <module_file>
    コントロールノード上のモジュールファイルへのパスを設定します。
    priority: <value>
    SELinux モジュールの優先度を設定します。デフォルトは 400 です。
    state: <value>

    モジュールの状態を定義します。

    • enabled: モジュールをインストールまたは有効にします。
    • disabled: モジュールを無効にします。
    • absent: モジュールを削除します。

    Playbook で使用されるすべての変数の詳細は、コントロールノードの /usr/share/ansible/roles/rhel-system-roles.selinux/README.md ファイルを参照してください。

  2. Playbook の構文を検証します。

    $ ansible-playbook --syntax-check ~/playbook.yml

    このコマンドは構文を検証するだけであり、有効だが不適切な設定から保護するものではないことに注意してください。

  3. Playbook を実行します。

    $ ansible-playbook ~/playbook.yml

検証

  • SELinux モジュールのリストをリモートで表示し、Playbook で使用したモジュールをフィルタリングします。

    # ansible managed-node-01.example.com -m shell -a 'semodule -l | grep <module>'

    モジュールがリストされている場合、そのモジュールはインストールされ、有効になっています。

10.2. Web コンソールで SELinux 設定の Ansible Playbook の作成

RHEL の Web コンソールから直接、現在の SELinux 設定を取得する Ansible Playbook を生成します。このスクリプトをコピーして複数のシステムに適用することで、一貫性のある設定を迅速にデプロイできます。

前提条件

手順

  1. RHEL 10 Web コンソールにログインします。
  2. SELinux をクリックします。
  3. View the automation script をクリックします。

    自動化スクリプトの表示ボタンによって表示される Ansible Playbook と SELinux 設定のシェルスクリプト

    生成されたスクリプトを含むウィンドウが開きます。シェルスクリプトと Ansible Playbook の生成オプションタブ間を移動できます。

  4. Copy to clipboard ボタンをクリックし、スクリプトまたは Playbook を選択して適用します。

    これにより、他のマシンに適用できる自動スクリプトがあります。詳細は、お使いのシステムの ansible-playbook(1) の man ページを参照してください。

10.3. semanage で別のシステムへの SELinux 設定の転送

semanage exportsemanage import コマンドを使用して、検証済みのカスタム SELinux 設定を RHEL 10 システム間で転送します。これは、セキュリティー設定を再現するための信頼できる方法です。

前提条件

  • policycoreutils-python-utils パッケージがシステムにインストールされている。

手順

  1. 検証された SELinux 設定をエクスポートします。

    # semanage export -f ./<my-selinux-settings.mod>
  2. 設定を含むファイルを新しいシステムにコピーします。

    # scp ./<my-selinux-settings.mod> <new-system-hostname>:
  3. 新しいシステムにログインします。

    $ ssh root@<new-system-hostname>
  4. 新しいシステムに設定をインポートします。

    <new-system-hostname># semanage import -f ./<my-selinux-settings.mod>

第11章 ポリインスタンス化されたディレクトリーの設定

競合状態攻撃や情報漏洩を防ぐため、/tmp/var/tmp、およびホームディレクトリーに対して、複数のインスタンス化されたディレクトリーを設定します。この設定では、ユーザーごとに個別の隔離されたマウントが作成されるため、共有の一時ストレージの悪用を防ぐことができます。

デフォルトでは、すべてのプログラム、サービス、およびユーザーは、一時ストレージとして /tmp/var/tmp、およびホームディレクトリーを使用します。これにより、これらのディレクトリーは、ファイル名に基づく競合状態攻撃や情報漏洩に対して脆弱になります。/tmp//var/tmp/、およびホームディレクトリーをインスタンス化して、これらがすべてのユーザー間で共有されないようにし、各ユーザーの /tmp-inst および /var/tmp/tmp-inst/tmp および /var/tmp ディレクトリーに個別にマウントされるようにすることができます。詳細は、pam-docs パッケージに同梱されている /usr/share/doc/pam-docs/txts/README.pam_namespace ファイルを参照してください。

手順

  1. SELinux でポリインスタンス化を有効にする:

    # setsebool -P allow_polyinstantiation 1

    getsebool allow_polyinstantiation コマンドを入力すると、SELinux でポリインスタンス化が有効になっているかどうかを確認できます。

  2. 必要な権限を使用して、再起動後もデータが永続的になるようにディレクトリー構造を作成します。

    # mkdir /tmp-inst /var/tmp/tmp-inst --mode 000
  3. SELinux ユーザー部分を含むセキュリティーコンテキスト全体を復元します。

    # restorecon -Fv /tmp-inst /var/tmp/tmp-inst
    Relabeled /tmp-inst from unconfined_u:object_r:default_t:s0 to system_u:object_r:tmp_t:s0
    Relabeled /var/tmp/tmp-inst from unconfined_u:object_r:tmp_t:s0 to system_u:object_r:tmp_t:s0
  4. システムで fapolicyd アプリケーション制御フレームワークを使用している場合は、/etc/fapolicyd/fapolicyd.conf 設定ファイルで allow_filesystem_mark オプションを有効にして、基礎となるファイルシステムがバインドマウントされているときに、fapolicyd がファイルアクセスイベントを監視できるようにします。

    allow_filesystem_mark = 1
  5. /tmp/var/tmp/、およびユーザーのホームディレクトリーのインスタンス化を有効にします。

    重要

    pam_namespace_helper プログラムは /etc/security/namespace.d 内の追加ファイルを読み取らないため、/etc/security/namespace.d/ ディレクトリー内の別のファイルではなく、/etc/security/namespace.conf を使用します。

    1. マルチレベルセキュリティー (MLS) を備えたシステムでは、/etc/security/namespace.conf ファイルの最後の 3 行のコメントを解除します。

      /tmp     /tmp-inst/   		   level 	 root,adm
      /var/tmp /var/tmp/tmp-inst/    level 	 root,adm
      $HOME    $HOME/$USER.inst/     level
    2. マルチレベルセキュリティー (MLS) のないシステムでは、/etc/security/namespace.conf ファイルに次の行を追加します。

      /tmp     /tmp-inst/            user 	 root,adm
      /var/tmp /var/tmp/tmp-inst/    user 	 root,adm
      $HOME    $HOME/$USER.inst/     user
  6. セッションに pam_namespace.so モジュールが設定されていることを確認します。

    $ grep namespace /etc/pam.d/login
    session    required     pam_namespace.so
  7. オプション: クラウドユーザーが SSH キーを使用してシステムにアクセスできるようにします。

    1. openssh-keycat パッケージをインストールします。
    2. /etc/ssh/sshd_config.d/ ディレクトリーに次の内容のファイルを作成します。

      AuthorizedKeysCommand /usr/libexec/openssh/ssh-keycat
      AuthorizedKeysCommandRunAs root
    3. sshd_configPubkeyAuthentication 変数が yes に設定されているかどうかを確認して、公開鍵認証が有効になっていることを確認します。デフォルトでは、sshd_config の行がコメントアウトされているにもかかわらず、PubkeyAuthentication は yes に設定されています。

      $ grep -r PubkeyAuthentication /etc/ssh/
      /etc/ssh/sshd_config:#PubkeyAuthentication yes
  8. ポリインスタンス化を適用する各サービスのモジュールに、session required pam_namespace.so unmnt_remnt エントリーを、session include system-auth 行の後に追加します。たとえば、/etc/pam.d/su/etc/pam.d/sudo/etc/pam.d/ssh、および /etc/pam.d/sshd: の場合:

    …
    session        include        system-auth
    session        required    pam_namespace.so unmnt_remnt
    …

検証

  1. 非 root ユーザーとしてログインします。ポリインスタンス化が設定される前にログインしていたユーザーは、変更が有効になる前にログアウトしてログインする必要があります。
  2. /tmp/ ディレクトリーが /tmp-inst/ の下にマウントされていることを確認します。

    $ findmnt --mountpoint /tmp/
    TARGET SOURCE                 	FSTYPE OPTIONS
    /tmp   /dev/vda1[/tmp-inst/<user>] xfs	rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota

    SOURCE の出力は環境によって異なります。* 仮想システムでは、/dev/vda_<number>_ と表示されます。* ベアメタルシステムでは、/dev/sda_<number>_ または /dev/nvme* が表示されます。

Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

Red Hat ドキュメントについて

Legal Notice

Theme

© 2026 Red Hat
トップに戻る