本章では、 openSUSE Leap 上で SELinux を使用する際の、設定と管理の方法について説明しています。下記のトピックをカバーしています:
なぜ SELinux を使用するのか
SELinux とは
SELinux の設定方法
SELinux の管理
SELinux は Linux カーネル内でセキュリティフレームワークを使用する追加のセキュリティソリューションとして開発されてきました。従来型の標準ファイルパーミッション (所有者、グループ、全体に対して、それぞれ読み込み、書き込み、実行を許可する仕組み) という随意アクセス制御 (DAC) の範疇を超えた、きめ細かいセキュリティポリシーを構築できる仕組みを目指しています。
下記の例では、なぜ SELinux (もしくはその同等品である AppArmor) が必要となるのかについて、説明しています:
「ある朝、私はサーバがクラックされていることに気がついた。サーバは openSUSE Leap ですべての修正 (パッチ) が適用され動作していた。ファイアウオールについても正しく設定が行われ、そのサーバでは不要なサービスは全く提供していなかった。より詳しく調査を行うと、クラッカーはサーバ内の Apache 仮想ホスト内の 1 つに設置された、脆弱性のある PHP スクリプトを通して侵入を行っていた。クラッカーはその後、 Apache Web サーバで使用されている wwwrun
を利用して、シェルへのアクセスを取得していた。この wwwrun
での侵入後、 /var/tmp
および /tmp
の各ディレクトリ内に複数のスクリプトを作成し、これを様々なサーバへの分散型サービス拒否攻撃のボットネットとして動作させていた。」
ここで注目すべき点は、このクラッキングでは、サーバ側の設定を誤っているわけではない、という点です。すべてのパーミッションの設定が正しいにも関わらず、侵入者はシステム内に入り込むことができてしまっています。上記の例は、場合によっては追加のセキュリティ機構が必要となることを示しているわけです。
SELinux ではオブジェクト (ファイルやネットワークソケット) に対してラベルを設定し、このラベルを権限の判断基準として使用します。
SELinux フレームワークは openSUSE Leap 15.7 でもサポート対象となっています。つまり openSUSE Leap では、お使いのサーバ内で SELinux を使用するのに必要な、すべてのバイナリやライブラリが提供されます。
ただし、ポリシーは添付されていませんので、要件に合わせて構築していかなければなりません。サードパーティ製のポリシーを使用してもかまいません。 39.3項 「SELinux パッケージのインストール」 や 39.4項 「SELinux ポリシーのインストール」 では、テスト用に openSUSE のポリシーをインストールするための情報が示されています。
SELinux の設定を始める前に、まずは SELinux の構成について知っておく必要があります。 SELinux では、下記の 3 種類から構成されています:
Linux カーネル内にあるセキュリティフレームワーク
SELinux のライブラリとバイナリ
SELinux のポリシー
openSUSE Leap の既定のカーネルであれば SELinux に対応していますので、ツールを使用するだけで管理を行うことができます。そのため、管理者にとって最も重要な作業は、 SELinux のポリシー管理ということになります。
SELinux のポリシーでは、 Linux サーバ内の様々なオブジェクトに対して、セキュリティラベルを設定します。これらのオブジェクトには、ユーザやポート、プロセスやファイルなどが含まれます。このようなセキュリティラベルを使用することで、サーバ内での許可を判断することになります。ただし、既定の SELinux ではすべてのものを拒否する仕組みであることから、どうしても必要なアクセスのみを許可する適切なルール構築が重要となります。そのため、ルールはシステム内で使用するすべてのプログラムに対して存在していなければならないことになります。
それ以外にも、システム内の一部 (特定のポートやプログラム、ユーザやファイル、ディレクトリなど) を無制限モードで動作させることもできます。無制限モードは SELinux での保護を外すための仕組みで、システム内の重要なサービスにのみ SELinux の保護を働かせるような用途で便利な仕組みです。もちろんこの仕組みでは保護が不完全になりますので、可能な限り SELinux をシステム全体に適用しておいたほうが適切です。
お使いのシステムに対して適切な保護を実現するには、 SELinux のポリシーを設定する必要があります。これはすべてのファイルに対してラベルを提供するよう仕立て上げられたポリシーでなければならず、すべてのサービスやユーザに対してセキュリティラベルを設定し、サーバ内でどのファイルやディレクトリにアクセスを許可するのかを設定するものでなければなりません。このようなポリシーの作成には、途方もない労力が必要となります。
なお、無償で提供されている様々な SELinux ポリシーは、お使いのサーバでも問題なく動作するとは思いますが、独自にポリシーを構築するのに比べると、保護レベルが落ちることがほとんどであることに注意してください。また、 SUSE ではサードパーティ製のポリシーへのサポートは行っておりません。
ポリシーとは SELinux における主要なコンポーネントです。 SELinux のポリシーは、特定のオブジェクトがシステム内のどのファイルやディレクトリ、ポートやプロセスなどにアクセスできるのかを示すためのもので、これら全てに対してセキュリティコンテキストを設定することで、この仕組みを実現しています。ポリシーが適用され、ファイルシステムにラベルが設定されている SELinux システムであれば、 ls -Z
コマンドを実行することで、ディレクトリ内のセキュリティコンテキストを表示することができます。例 39.1: 「ls -Z
を利用したセキュリティコンテキストの表示」 では、 SELinux によってラベルが設定された openSUSE Leap システムにおいて、 /
ディレクトリ内のセキュリティコンテキストを表示した場合の例を示しています。
ls -Z
を利用したセキュリティコンテキストの表示 #>
ls -Z /
system_u:object_r:bin_t bin
system_u:object_r:boot_t boot
system_u:object_r:device_t dev
system_u:object_r:etc_t etc
system_u:object_r:home_root_t home
system_u:object_r:lib_t lib
system_u:object_r:lib_t lib64
system_u:object_r:lost_found_t lost+found
system_u:object_r:mnt_t media
system_u:object_r:mnt_t mnt
system_u:object_r:usr_t opt
system_u:object_r:proc_t proc
system_u:object_r:default_t root
system_u:object_r:bin_t sbin
system_u:object_r:security_t selinux
system_u:object_r:var_t srv
system_u:object_r:sysfs_t sys
system_u:object_r:tmp_t tmp
system_u:object_r:usr_t usr
system_u:object_r:var_t var
セキュリティコンテキストで最も重要な箇所は、コンテキストタイプ (種類) です。これはしばしば _t
で終わるセキュリティコンテキストとして示され、 SELinux が対象のオブジェクトに対して、どのような種類のアクセスを許可するのかを示しています。ポリシー側では、どのような種類のユーザまたはロールに対して、どの種類のコンテキストにアクセスを許可するのかを指定します。たとえば下記のようなルールがあります:
allow user_t bin_t:file {read execute gettattr};
上記のルールでは、 user_t
というコンテキストタイプのユーザ (これをソースオブジェクトと呼びます) に対して、 bin_t
というコンテキストタイプが設定された "ファイル" (これをターゲットと呼びます) へのアクセスを許可しています。ただし、許可されるアクセスは read
(読み込み) , execute
(実行) , getattr
(属性取得) の 3 種類だけです。
SELinux のポリシーには数多くのルールが含まれています。管理をやりやすくするには、ポリシーをモジュールとして分割したほうがよい場合があります。これにより、システム内の様々な箇所で、保護の有無を切り替えることができるようになります。
お使いのシステムでポリシーを構築する場合、モジュール型のポリシーを構築するのか、もしくはモノリシックな (1 つの巨大なポリシーでシステム全体を保護する) ポリシーを構築するのかを選択することができますが、通常はモジュール型のポリシーを構築しておくことを強くお勧めします。それは、モジュール型のほうが管理がやりやすいためです。
コマンドラインを利用して下記のパッケージをインストールします:
>
sudo
zypper in restorecond policycoreutils setools-console
ただし、これではポリシーがインストールされません。テスト用に openSUSE のポリシーをインストールしたい場合は、 39.4項 「SELinux ポリシーのインストール」 を参照してください。
ポリシーは SELinux で必須の部品です。 openSUSE Leap 15.7 では、既定のポリシーは 同梱されておりません ので、お使いの環境に合わせてポリシーを構築しなければなりません。これは、 SELinux が要件に合わせてカスタマイズしなければならない特性があるためです。支援を求めたい場合は、 SUSE 社のコンサルタントサービスにお問い合わせください。なお、 SELinux を完全にサポートするコンテナ環境や仮想環境を必要とするお客様やパートナー様には、 slemicro
をお勧めします。こちらであればサポート済みポリシーも提供されます。
テスト用 のポリシーは https://download.opensuse.org/repositories/security:/SELinux_legacy/ で公開されています。ここでは openSUSE Leap に対応したポリシーと追加パッケージが提供されています。
お使いの openSUSE Leap バージョンに合ったリポジトリリンクをコピーして、 zypper に追加してください:
>
sudo
zypper ar -f \ https://download.opensuse.org/repositories/security:/SELinux/15.7/ \ SELinux-Legacy
あとは下記のパッケージをインストールします:
>
sudo
zypper in selinux-policy-targeted selinux-policy-devel
許容モードでは、 SELinux はサーバを保護しませんが、ログファイル内への記録は変わらず行われます。このモードはシステムの動作テストや設定時に使用します。
既定では、 SELinux は /etc/selinux/config
ファイル内で許容モードに設定されています。
なお、お使いのシステムで SELinux の使用を開始したい場合は、 GRUB 2 のブートローダの設定を変更します。具体的には、 /etc/default/grub
ファイル内にある GRUB_CMDLINE_LINUX_DEFAULT=
という行内に、下記 2 つの項目を追加してください:
lsm=selinux,bpf selinux=1
最初のパラメータは、セキュリティシステムに AppArmor ではなく SELinux を使用する設定で、 2 つめのパラメータは SELinux を有効化する設定です。これらのパラメータを追加したあとは、下記を実行して GRUB 2 の設定ファイルを再構築します:
grub2-mkconfig -o /boot/grub2/grub.cfg
あとはシステムを再起動するだけです。ここまでの作業で SELinux システムを動作させるための準備が整いましたが、最後にやるべき作業が残っています。ここまでの設定では動作の拒否は行わず、ポリシーへの違反を全て記録するだけであるためです。まずはログファイルの内容を確認して、どのような違反が発生していたのかを確認してください。
SELinux を許容モードで動作させていると、ユーザやプロセスの処理によってファイルシステム内のオブジェクトが適切にラベル付けされなくなる場合があります。 SELinux はファイルシステムの各オブジェクトへのラベル付けによって動作する仕組みであることから、強制モードに移行した際に最も問題となる点でもあります。
このようなことを防ぐため、強制モードに移行する前にセキュリティコンテキスト (拡張属性) のリセットを行っておいてください:
>
sudo
restorecon -R /
あとは SELinux を強制モードに移行するだけです。 /etc/selinux/config
ファイルを編集して、 SELINUX=enforcing
を設定してください。
設定が終わったらサーバを再起動し、問題なく起動できるかと、ログインできるかを確認します。
ログイン後は sestatus -v
を実行して、正しく動作していることを確認してください。問題なく動作していれば、 例 39.2: 「SELinux が動作していることの確認」 のような出力が現れるはずです。
>
sudo
sestatus -v
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: requested(insecure) Max kernel policy version: 33 Process contexts: Current context: unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 Init context: system_u:system_r:init_t:s0 /usr/sbin/sshd system_u:system_r:sshd_t:s0-s0:c0.c1023 File contexts: Controlling terminal: unconfined_u:object_r:user_tty_device_t:s0 /etc/passwd system_u:object_r:passwd_file_t:s0 /etc/shadow system_u:object_r:shadow_t:s0 /bin/bash system_u:object_r:shell_exec_t:s0 \ -> system_u:object_r:shell_exec_t:s0 /bin/login system_u:object_r:login_exec_t:s0 /bin/sh system_u:object_r:bin_t:s0 \ -> system_u:object_r:shell_exec_t:s0 /sbin/agetty system_u:object_r:bin_t:s0 \ -> system_u:object_r:getty_exec_t:s0 /sbin/init system_u:object_r:bin_t:s0 -> \ system_u:object_r:init_exec_t:s0 /usr/sbin/sshd system_u:object_r:sshd_exec_t:s0
強制モードでサーバが想定通りに起動できない場合は、許容モードに戻して再設定を行います。まずは less /var/log/audit/audit.log
ファイルを確認してください。詳しくは 39.9項 「トラブルシューティング」 をお読みください。
サーバの調整作業を行う場合、まずは SELinux のインストールを確認します。既に sestatus -v
というコマンドを使用していますので、ここに表示されている現在のモードとプロセス、ファイルコンテキストをそれぞれ確認します。あとは下記のように実行して、利用可能な可否設定を確認します:
>
sudo
semanage boolean -l
この可否設定の一覧を表示することで、ポリシーへのアクセスも同時に検証することができます。 例39.3「可否設定の一覧表示とポリシーアクセスの確認」 には、このコマンドの出力例が示されています:
>
sudo
semanage boolean -l
SELinux boolean Description ftp_home_dir -> off ftp_home_dir mozilla_read_content -> off mozilla_read_content spamassassin_can_network -> off spamassassin_can_network httpd_can_network_relay -> off httpd_can_network_relay openvpn_enable_homedirs -> off openvpn_enable_homedirs gpg_agent_env_file -> off gpg_agent_env_file allow_httpd_awstats_script_anon_write -> off allow_httpd_awstats_script_anon_write httpd_can_network_connect_db -> off httpd_can_network_connect_db allow_ftpd_full_access -> off allow_ftpd_full_access samba_domain_controller -> off samba_domain_controller httpd_enable_cgi -> off httpd_enable_cgi virt_use_nfs -> off virt_use_nfs
この時点で有用なコマンドがもう 1 つあります。それは下記のとおりです:
>
sudo
semanage fcontext -l
上記は、ポリシーによって提供される既定のファイルコンテキスト設定を表示することができます (詳しくは 例 39.4: 「ファイルのコンテキスト情報の取得」 をご覧ください) 。
>
sudo
semanage fcontext -l
/var/run/usb(/.*)? all files system_u:object_r:hotplug_var_run_t /var/run/utmp regular file system_u:object_r:initrc_var_run_t /var/run/vbe.* regular file system_u:object_r:hald_var_run_t /var/run/vmnat.* socket system_u:object_r:vmware_var_run_t /var/run/vmware.* all files system_u:object_r:vmware_var_run_t /var/run/watchdog\.pid regular file system_u:object_r:watchdog_var_run_t /var/run/winbindd(/.*)? all files system_u:object_r:winbind_var_run_t /var/run/wnn-unix(/.*) all files system_u:object_r:canna_var_run_t /var/run/wpa_supplicant(/.*)? all files system_u:object_r:NetworkManager_var_run_t /var/run/wpa_supplicant-global socket system_u:object_r:NetworkManager_var_run_t /var/run/xdmctl(/.*)? all files system_u:object_r:xdm_var_run_t /var/run/yiff-[0-9]+\.pid regular file system_u:object_r:soundd_var_run_t
ここまでの作業で SELinux を動作させることができましたので、次は設定作業に移ります。 SELinux では、プロセスやユーザがどのファイルやディレクトリ、ポートなどにアクセスできるのかを、正確に定義するための追加のルールセットを使用します。ルールセットの設定を行うにあたって、 SELinux はそれぞれのファイルやディレクトリ、プロセスやポートに対してコンテキストを設定し、それをセキュリティラベルとして使用します。セキュリティラベルは、それらをどのように扱うべきかを示しているもので、 SELinux のポリシー側から指定が行われます。既定では、ポリシーは全てのアクセスを拒否するように設定されていますので、お使いのシステムが何らかの動作を必要とする場合、管理者はルールを作成してポリシー内に配置する必要があります。
上述のとおり、ファイルやディレクトリ、ポートなどに対してラベルを設定することができます。ラベル内では様々なコンテキストを使用します。管理者が日々の作業を実施できるようにするためには、コンテキストタイプについて最も知識を持っておく必要があります。様々なコマンドに用意された -Z
オプションを使用することで、現在のコンテキスト設定を表示することができるようになります。 例 39.5: 「ルートディレクトリ内でのディレクトリ向け既定コンテキスト」 には、ルートディレクトリ内でのコンテキスト設定の例を示しています。
>
sudo
ls -Z
dr-xr-xr-x. root root system_u:object_r:bin_t:s0 bin dr-xr-xr-x. root root system_u:object_r:boot_t:s0 boot drwxr-xr-x. root root system_u:object_r:cgroup_t:s0 cgroup drwxr-xr-x+ root root unconfined_u:object_r:default_t:s0 data drwxr-xr-x. root root system_u:object_r:device_t:s0 dev drwxr-xr-x. root root system_u:object_r:etc_t:s0 etc drwxr-xr-x. root root system_u:object_r:home_root_t:s0 home dr-xr-xr-x. root root system_u:object_r:lib_t:s0 lib dr-xr-xr-x. root root system_u:object_r:lib_t:s0 lib64 drwx------. root root system_u:object_r:lost_found_t:s0 lost+found drwxr-xr-x. root root system_u:object_r:mnt_t:s0 media drwxr-xr-x. root root system_u:object_r:autofs_t:s0 misc drwxr-xr-x. root root system_u:object_r:mnt_t:s0 mnt drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mnt2 drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mounts drwxr-xr-x. root root system_u:object_r:autofs_t:s0 net drwxr-xr-x. root root system_u:object_r:usr_t:s0 opt dr-xr-xr-x. root root system_u:object_r:proc_t:s0 proc drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 repo dr-xr-x---. root root system_u:object_r:admin_home_t:s0 root dr-xr-xr-x. root root system_u:object_r:bin_t:s0 sbin drwxr-xr-x. root root system_u:object_r:security_t:s0 selinux drwxr-xr-x. root root system_u:object_r:var_t:s0 srv -rw-r--r--. root root unconfined_u:object_r:swapfile_t:s0 swapfile drwxr-xr-x. root root system_u:object_r:sysfs_t:s0 sys drwxrwxrwt. root root system_u:object_r:tmp_t:s0 tmp -rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp2.tar -rw-r--r--. root root unconfined_u:object_r:etc_runtime_t:s0 tmp.tar drwxr-xr-x. root root system_u:object_r:usr_t:s0 usr drwxr-xr-x. root root system_u:object_r:var_t:s0 var
上述の一覧に書かれているとおり、全てのディレクトリに対してコンテキストが設定されていることがわかります。ここにはユーザと役割、タイプがそれぞれ示されています。残る s0 はマルチレベルセキュリティ環境でのセキュリティレベルを示すもので、ここでは説明していません。このような環境では s0 が設定されていることを確認してください。コンテキストの種類は、そのディレクトリ内でどのような種類の動作を許可するのかを表しています。たとえば /root
ディレクトリには admin_home_t
というコンテキストタイプが割り当てられ、 /home
ディレクトリには admin_home_t
というコンテキストタイプが割り当てられています。 SELinux のポリシーでは、これらのコンテキストタイプに対して様々な種類のアクセスが定義されています。
セキュリティラベルはファイルに対して割り当てられるだけでなく、ポートやプロセスなどにも割り当てられます。 例 39.6: 「ps Zaux
によるプロセス向け SELinux 設定の表示」 では、サーバ内のプロセスに対するコンテキスト設定の表示例を示しています。
ps Zaux
によるプロセス向け SELinux 設定の表示 #>
sudo
ps Zaux
LABEL USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND system_u:system_r:init_t root 1 0.0 0.0 10640 808 ? Ss 05:31 0:00 init [5] system_u:system_r:kernel_t root 2 0.0 0.0 0 0 ? S 05:31 0:00 [kthreadd] system_u:system_r:kernel_t root 3 0.0 0.0 0 0 ? S 05:31 0:00 [ksoftirqd/0] system_u:system_r:kernel_t root 6 0.0 0.0 0 0 ? S 05:31 0:00 [migration/0] system_u:system_r:kernel_t root 7 0.0 0.0 0 0 ? S 05:31 0:00 [watchdog/0] system_u:system_r:sysadm_t root 2344 0.0 0.0 27640 852 ? Ss 05:32 0:00 /usr/sbin/mcelog --daemon --config-file /etc/mcelog/mcelog.conf system_u:system_r:sshd_t root 3245 0.0 0.0 69300 1492 ? Ss 05:32 0:00 /usr/sbin/sshd -o PidFile=/var/run/sshd.init.pid system_u:system_r:cupsd_t root 3265 0.0 0.0 68176 2852 ? Ss 05:32 0:00 /usr/sbin/cupsd system_u:system_r:nscd_t root 3267 0.0 0.0 772876 1380 ? Ssl 05:32 0:00 /usr/sbin/nscd system_u:system_r:postfix_master_t root 3334 0.0 0.0 38320 2424 ? Ss 05:32 0:00 /usr/lib/postfix/master system_u:system_r:postfix_qmgr_t postfix 3358 0.0 0.0 40216 2252 ? S 05:32 0:00 qmgr -l -t fifo -u system_u:system_r:crond_t root 3415 0.0 0.0 14900 800 ? Ss 05:32 0:00 /usr/sbin/cron system_u:system_r:fsdaemon_t root 3437 0.0 0.0 16468 1040 ? S 05:32 0:00 /usr/sbin/smartd system_u:system_r:sysadm_t root 3441 0.0 0.0 66916 2152 ? Ss 05:32 0:00 login -- root system_u:system_r:sysadm_t root 3442 0.0 0.0 4596 800 tty2 Ss+ 05:32 0:00 /sbin/mingetty tty2
SELinux では、 3 種類のモードを使用します:
こちらが既定のモードです。 SELinux では、ポリシー内のルールに従ってサーバを保護します。合わせて SELinux では、監査ログ内に動作状況を記録します。
このモードはトラブルシューティングで有用な仕組みです。許容モードでは、 SELinux はサーバを保護しませんが、ログファイル内への記録は変わらず行われます。
このモードでは、 SELinux は完全に無効化され、ログへの記録も行われません。ファイルシステム内に設定されたラベルについては、ファイルシステムから削除されることはありません。
SELinux のモードの設定方法については前述のとおり、システム起動時の GRUB 2 でパラメータを指定して行います。
管理者の作業として重要なものとして、 SELinux を正しく動作させるため、ファイルにコンテキストタイプを設定する作業があります。
ファイルが特定のディレクトリ内に作成されると、既定では親のディレクトリのコンテキストタイプを継承します。ですが、ファイルが一方のディレクトリから他方のディレクトリに移動されると、以前の場所でのコンテキストタイプをそのまま適用し続けます。
ファイルに対してコンテキストタイプを設定するには、 semanage fcontext
コマンドを使用します。このコマンドでは、新しいコンテキストタイプをポリシー内に書き込むまでは行うものの、実際のコンテキストタイプを即時に反映することは行いません。ポリシー内のコンテキストタイプを実際に反映させるには、設定後に restorecon
コマンドを実行します。
semanage fcontext
を利用してみる前に、まずは実際にどのようなコンテキストが必要なのかを確認します。具体的には下記のように実行します:
>
sudo
semanage fcontext -l
上記のように実行することで、ポリシー内に設定されている全てのコンテキストを表示することができます。ですが、出力は比較的長いものであるため、実際に必要なコンテキストを知るには少し面倒ではあります (例 39.7: 「既定のファイルコンテキストの表示」 をご覧ください) 。
>
sudo
semanage fcontext -l | less
SELinux fcontext type Context / directory system_u:object_r:root_t:s0 /.* all files system_u:object_r:default_t:s0 /[^/]+ regular file system_u:object_r:etc_runtime_t:s0 /\.autofsck regular file system_u:object_r:etc_runtime_t:s0 /\.autorelabel regular file system_u:object_r:etc_runtime_t:s0 /\.journal all files X:>>None>> /\.suspended regular file system_u:object_r:etc_runtime_t:s0 /a?quota\.(user|group) regular file system_u:object_r:quota_db_t:s0 /afs directory system_u:object_r:mnt_t:s0 /bin directory system_u:object_r:bin_t:s0 /bin/.* all files system_u:object_r:bin_t:s0
お使いのサービスでどのようなコンテキスト設定が利用できるのかを確認する方法には、下記の 3 つの方法があります:
サービスをインストールして、使用されている既定のコンテキストを判別する方法。この方法が最も簡単であり、推奨される方法です。
特定のサービスに対してマニュアルページを確認します。サービスによっては _selinux
で終わる名前のマニュアルページを用意しているものがあり、必要なコンテキスト設定の情報を取得できるものがあります。
正しいコンテキスト設定を見つけることができたら、 semanage fcontext
を利用して設定を適用します。このコマンドでは -t
のコンテキストタイプの指定を最初のパラメータとして指定し、その後ろに適用したい先のディレクトリやファイルを指定します。コンテキストを適用したいディレクトリ内に存在する全てに対して、コンテキストを適用したい場合は、ディレクトリ名の箇所に (/.*)?
を指定します。これは正規表現で、スラッシュに続いて任意の文字が続くものを表しています。このほかにも、 semanage
のマニュアルページ内の examples セクションには、 semanage
を使用する際の様々な便利な例が示されています。正規表現に関する詳しい情報については、 https://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE をお読みください。
お使いのシステムで利用可能な全てのコンテキストタイプを一覧表示する方法:
>
sudo
seinfo -t
コマンドそれ自身は非常に多くの情報を出力します。そのため、 grep
などのコマンドを併用して、必要な情報だけを取得するようにしてください。
SELinux のコンテキストを正しく適用するため、下記の手順では semanage fcontext
と restorecon
を使用して、コンテキストを設定する方法を示しています。ここまでの説明でご存じのとおり、既定のドキュメントルート以外を使用した場合、 Web サーバが動作しません。 SELinux の設定を変更して、正しく動作するようにするまでの手順を示します:
/web
ディレクトリを作成し、そのディレクトリに移動します:
>
sudo
mkdir /web && cd /web
テキストエディタを利用して、 /web/index.html
ファイルを作成し、どんなものでもかまいませんのでコンテンツを作成します。
/etc/apache2/default-server.conf
ファイルをエディタで開いて、 DocumentRoot の行を DocumentRoot /web
のように変更します。
Apache Web サーバを再起動します:
>
sudo
systemctl start apache2
ローカルの Web サーバが表示できるかどうか、テストを行います:
>
w3m localhost
Connection refused (接続が拒否されました) のようなメッセージが表示されるかと思います。 Enter を押したあと、 q
を押して w3m を終了します。
Apache Web サーバ既定の ドキュメントルート
に対して、コンテキストタイプを表示します。このディレクトリは /srv/www/htdocs
になっています。このディレクトリに対しては、 httpd_sys_content_t
が設定されているはずです:
>
sudo
ls -Z /srv/www
ポリシー内に新しいコンテキストを設定します。下記のとおり入力して Enter を押します:
>
sudo
semanage fcontext -a -f "" -t httpd_sys_content_t '/web(/.*) ?'
新しいコンテキストタイプを適用します:
>
sudo
restorecon /web
/web
ディレクトリ内のファイルのコンテキスト情報を表示します。/web
ディレクトリには正しく設定されているものの、そのディレクトリ内のファイルには設定されていないはずです:
>
sudo
ls -Z /web
今度は新しいコンテキストを、 /web
ディレクトリ以下の全てに対して再帰的に適用します。これでファイルにも新しいコンテキストが適用されるようになります:
>
sudo
restorecon -R /web
Web サーバを再起動します:
>
sudo
systemctl restart apache2
これで /web
ディレクトリ内のコンテンツについても、問題なくアクセスできるようになっているはずです。
ポリシーの動作を変更する際、最も簡単なものは可否設定 (boolean) です。可否設定はオンとオフを切り替えることのできる項目で、ポリシー内で変更することのできるものです。利用可能な設定の一覧を取得するには、下記のように入力して実行します:
>
sudo
semanage boolean -l
上記を実行すると、可否設定の長い一覧と共に、それぞれの可否設定に対する短い説明文が表示されます。必要な可否設定を見つけることができたら、あとは setsebool -P
を利用して、設定作業を行います。このコマンドの後ろには可否設定の名前を指定します。このとき、 setsebool
に -P
というオプションを指定していることに注目してください。このオプションは、ディスク上にあるポリシーファイル内に設定を書き込むためのもので、システムを再起動しても設定を残すように設定するための唯一の方法でもあります。
下記の手順では、可否設定の変更例を示しています:
まずは FTP サーバに関連する可否設定を一覧表示します:
>
sudo
semanage boolean -l | grep ftp
可否設定をオフにします:
>
sudo
setsebool allow_ftpd_anon_write off
なお、変更を書き込むのにそれほど時間はかかりません。設定を書き込んだら、本当にオフになっているのかを確認します:
>
sudo
semanage boolean -l|grep ftpd_anon
あとはサーバを再起動します。
再起動後、 allow_ftpd_anon_write
の設定がオンに戻っていることを確認します。これは、ポリシーがファイルには書き込まれなかったためです。
再度可否設定を切り替えて、今度はポリシーファイルにも書き込みます:
>
sudo
setsebool -P allow_ftpd_anon_write
既定では、 SELinux はモジュール型のポリシーを使用します。これは、 SELinux の機能が単一の巨大なポリシーとして作られているのではなく、多数の小さいモジュールとして構成されていることを意味しています。それぞれのモジュールには、それぞれ対応する SELinux の設定パートがあります。このような SELinux の仕組みにより、サードパーティのベンダがサービスを提供する場合でも、自身のサービスを SELinux に対応できるようにすることができます。 SELinux のモジュールの一覧を取得するには、 semodule -l
コマンドを実行します。このコマンドは、 SELinux で使用されている全てのモジュールと、そのバージョン番号を表示します。
管理者の権限を使用すると、モジュールを個別にオンもしくはオフにすることができます。これは SELinux の一部の機能のみを無効化したい場合や、全てのサービスを SELinux で保護する必要がない場合に便利な仕組みです。特に openSUSE Leap では、 SELinux ポリシーを完全にサポートしているわけではないので、全てのモジュールをいったんオフに設定して、必要なサービスにのみ SELinux の保護を適用したほうが都合がよいことがあります。 SELinux のモジュールをオフにしたい場合は、下記のように入力して実行します:
>
sudo
semodule -d モジュール名
オンに戻したい場合は、下記のように入力して実行します:
>
sudo
semodule -e モジュール名
既定では、 SELinux が何らかの理由で動作しない場合、ログメッセージが /var/log/audit/audit.log
ファイル内に記録されます。ただし、このファイルに書き込みを行うには、 auditd サービスを動作させて置かなければなりません。 /var/log/audit
ディレクトリ内に何もファイルが存在しない場合は、下記のように入力して実行し、 auditd サービスを開始してください:
>
sudo
systemctl start auditd
また、システムの起動時に開始するように設定したい場合は、下記のように入力して実行します:
>
sudo
systemctl enable auditd
下記に /var/log/audit/audit.log
の内容の出力例を示します:
/etc/audit/audit.log
の出力例 #type=DAEMON_START msg=audit(1348173810.874:6248): auditd start, ver=1.7.7 format=raw kernel=6.4.0-150600.9-default auid=0 pid=4235 subj=system_u:system_r:auditd_t res=success type=AVC msg=audit(1348173901.081:292): avc: denied { write } for pid=3426 comm="smartd" name="smartmontools" dev=sda6 ino=581743 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:293): avc: denied { remove_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:294): avc: denied { unlink } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:295): avc: denied { rename } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582373 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:296): avc: denied { add_name } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir type=AVC msg=audit(1348173901.081:297): avc: denied { create } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:298): avc: denied { write open } for pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.081:299): avc: denied { getattr } for pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file type=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316
はじめて audit.log
をお読みになる方にとっては、少しわかりにくいと感じることでしょう。しかしながら、読み方がわかればそれほど難しくはありません。各行はそれぞれセクションに分割することができます。たとえば末尾の行の意味は下記のようになります:
type=AVC
:それぞれの SELinux 関連の監査ログ行には、 type=AVC
という種類判別用の記述が書き込まれます。
msg=audit(1348173901.309:300)
:これはタイムスタンプを意味しています。ただし、エポック秒と呼ばれる、 1970 年 1 月 1 日からの経過秒数で書かれています。整数部分については、 date -d
コマンドで日時に変換することができます:
>
date -d @1348173901
2012年 9月 21日 金曜日 05:45:01 JST
avc: denied { append }
:拒否された処理の内容を示しています。この場合、システムはデータをファイルに追記する処理が拒否されたことを表しています。監査ログファイル内では、ファイルを開いたり属性を取得したりなど、様々な処理が記録されることになります。
for pid=1316
:その処理を実施したコマンドもしくはプロセスのプロセス ID です。
comm="rsyslogd"
:その PID に結びつけられたコマンドを表しています。
name="smartmontools"
:処理を実行しようとしたアプリケーションの名前を表しています。
dev=sda6 ino=582296
:対象となるファイルが存在するブロックデバイス名と inode 番号です。
scontext=system_u:system_r:syslogd_t
:ソースコンテキストと呼ばれ、処理を実行しようとした側のコンテキストを表しています。
tclass=file
:処理内容の分類名を表しています。
audit.log 内の各イベントの意味を自分自身で解釈する以外の方法もあります。それは、 audit2allow
というコマンドです。このコマンドは、わかりにくい /var/log/audit/audit.log
内のメッセージを分析するための支援を行うソフトウエアです。下記に示す 3 種類の形態が用意されています。 1 つめは audit2allow -w -a
のような実行形態で、より読みやすい形式で監査情報を表示することができます。 audit2allow -w -a
は、既定では audit.log ファイルを読み込みます。 audit.log ファイル内の特定のメッセージのみを分析したい場合は、一時ファイルにコピーして下記のように入力して実行してください:
>
sudo
audit2allow -w -i ファイル名
>
sudo
audit2allow -w -i testfile
type=AVC msg=audit(1348173901.309:300): avc: denied { append } for pid=1316 comm="rsyslogd" name="acpid" dev=sda6 ino=582296 scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
タイプ強制 (Type Enforcement; TE) の許可ルールが存在しないためです。
このアクセスを許可するような読み込みモジュールを生成するには、下記のように入力して実行します:
>
sudo
audit2allow
アクセスを拒否したルールを見つけたい場合は、 audit2allow -a
と入力して実行し、 audit.log
ファイル内に記録された全てのメッセージから、対応する強制ルールを表示することができるほか、 audit2allow -i ファイル名
のように入力して実行することで、指定したファイル内に保存されているメッセージに対する強制ルールを表示することもできます。
>
sudo
audit2allow -i testfile
#============= syslogd_t ============== allow syslogd_t apmd_log_t:file append;
mymodule
という名前の SELinux モジュールを作成し、以前は拒否されていたアクセスを許可するように設定したい場合は、下記のように入力して実行します:
>
sudo
audit2allow -a -R -M mymodule
audit.log に記録されている全てのイベントに対して、同様のことを行いたい場合は、パラメータに -a -M
を追加します。また、特定のファイル内のメッセージに対してのみ実施したい場合は、下記のように -i -M
を追加します:
>
sudo
audit2allow -i testfile -M example
******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i example.pp
audit2allow
コマンドの出力にもあるとおり、この後に semodule -i
コマンドの後ろにモジュール名指定して、実行します。このとき、モジュール名は audit2allow
で指定した名前となります (上記の例では example.pp
です) 。