Linuxカーネルのセキュリティ機能SELinux(Securrity Enhanced Linux)はCentos5以降においてデフォルトで有効になっています。今まではSELinuxを無効にしてサーバ構築の煩雑性を軽減してきましたが昨今のOSやミドルで脆弱性が頻発する状況では、万が一侵入を許したとしても被害を最小限に食い止められるというSELinuxを有効にして運要した方が望ましいことは確実です。また、かつては難しかったSELinuxの設定も各ディストリビューションの対応が進み標準的な機能であれば特に意識しなくても動作するようになっているようです。そこで今回はSELinuxを有効にしてサーバ運用をする際に必要となるSELinuxの設定手順を主なミドルを対象に纏めてみました。
目次
1.SELinuxとは
SELinuxとは「強制アクセス制御(MAC:Mandatory Access Control)と呼ばれる機能をLinuxカーネルに提供するものです。
Linuxでは通常「任意アクセス制御(DAC:Discretionary Access Control)」と呼ばれるファイル所有者に基づく権限チェックが行われています。但し、rootユーザ―はこの任意アクセス制御に基づく権限チェックを回避できます。
一方、SELinuxが提供する「強制アクセス制御」ではセキュリティ-ポリシーの設定に基づき、カーネルレベルでプロセスの動作を制限します。その制限は例えrootユーザでも回避できません。
2.SELinuxの効果
このrootユーザ―でもセキュリティポリシーを回避出来ないというSELinuxが提供する強制アクセス制御は不正侵入対策として有効です。SELinuxそれ自体で不性侵入を防ぐことはできませんが、不正侵入を許した場合に被害を最小限で食い止める効果があります。
例えばゼロデイ攻撃でWebサーバの脆弱性を突かれデーモンが乗っ取られたとしても、攻撃ツールのアップロードはWebサーバのルートディレクトリのコンテキストに「httpd_sys_context_t」タイプを設定することで防ぐことができます。例え攻撃ツールがアップロードされたとしても、ツールの実行は、SELinuxのセキュリティポリシーで制限されておりそれ以上の攻撃を困難にできます。
3.SELinuxの動作確認
(1)有効無効コマンド
SELinuxの動作状況は「getenforce」で確認できます。「setenforce」コマンドで動作状況を変更できます。
1 2 3 4 5 6 7 8 |
# getenforce Enforcing ←動作中 # setenforce 0 ←SELinux一時無効(log出力は有効) # getenforce Permissive ←ログ出力のみ動作 # setenforce 1 ←SELinux有効化 # getenforce Enforcing |
SELinuxを有効としたOS環境下でアプリケーションが動作しない場合、その原因がSELinuxの影響かそうでないかを上記コマンドを使用して切り分けることができます。
「getenforce」で確認した状況がdisabledの場合、SELinuxは無効となっています。
/etc/selinux/configを修正しシステムを再起動することで有効化できます。
1 2 3 4 |
# getenforce Disabled ←SELinuxは無効 # vi /etc/selinux/config SELINUX=enforcing |
(2)SELinuxのログ確認
上記切り分けにおいてSELinuxの影響と判断された場合、詳細原因を確認するためにログファイルを調査します。SELinuxは拒否したアクセスを”/var/log/audit/audit.log”に記録しています。このログを直接参照してもいいのですが時間がunix時間で記録されているなど見にくいため専用のコマンドで確認します。
以下はhttpのアクセスがコンテキストラベルの設定が適切でないため拒否されたログ
1 2 3 4 5 6 |
# ausearch -m AVC |less time->Sun May 13 09:47:54 2018 type=PROCTITLE msg=audit(1525826874.571:43141): proctitle=2F7573722F7362696E2F7068702D66706D002D2D6E6F6461656D6F6E697A65 type=SYSCALL msg=audit(1525826874.571:43141): arch=c000003e syscall=9 success=no exit=-13 a0=557918400000 a1=200000 a2=7 a3=32 items=0 ppid=1 pid=29038 auid=429 4967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="php-fpm" exe="/usr/sbin/php-fpm" subj=system_u:system_r:httpd_t:s0 key=(null) type=AVC msg=audit(1525826874.571:43141): avc: denied { execmem } for pid=29038 comm="php-fpm" scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=process |
4.SELinuxの確認と設定
SELinuxではファイルやポート番号などにタイプを付与します。ファイルとポートへのタイプ付与方法を知っていれば実運用的には十分です。
(1)ファイルタイプの確認
1 2 3 |
# ls -Z /usr/share/nginx/html -rw-r--r--. nginx nginx system_u:object_r:httpd_sys_content_t:s0 50x.html -rw-r--r--. nginx nginx system_u:object_r:httpd_sys_content_t:s0 index.html |
ここでは、上記2ファイルに対し、「object_r」と「httpd_sys_content_t」のタイプが付与されています。「object_r」 コンテキストはファイルに使われる一般的なロール、「httpd_sys_content_t」コンテキストは”httpd”プロセスがこのファイルにアクセスすることを許可するロールです。
(2)コンテキスト管理ツールのインストール
chcon コマンドでもファイルの SELinux コンテキストを変更できますがファイルシステムの再ラベル付けや restorecon コマンドが実行されると消えてしまいます。以下のツールをインストールし、タイプ変更が永続化されるsemanageコマンドを使用できるようにします。
1 |
# yum install policycoreutils-python |
(3)ファイルタイプの変更
インストールしたツールを使用して永続的なタイプ変更を行う手順です。
①semanage fcontextの実行
1 |
# semanage fcontext -a -t options file-name|directory-name |
options:付与するタイプを指定
file-name|directory-name:ファイル名またはディレクトリ名
②restoreconの実行
1 |
# restorecon -v file-name|directory-name |
restoreconコマンドでラベルを付け替えます。
(4)ポートへのタイプ付与
同様にポートに対しタイプを付与します。
1 |
# semanage port -a -t options -p protocol number |
options:付与するタイプを指定
protocol:UDP又はTCPを指定
number:ポート番号を指定
5.具体的な設定例
(1)samba
windowsファイル共有サービスsambaで特定のディレクトリを指定し共有する場合の設定です。ここでは、/samba/public/を共有することとします。
1 2 |
# semanage fcontext -a -t samba_share_t '/samba/public(/.*)?' # restorecon -RF /samba/public |
説明:対象ディレクトリ配下に対し「samba_share_t」タイプを付与しています。
(2)phpmyadmin
特定のディレクトリを指定しWebアクセスをする場合の例です。ここではphpmyadminを/var/www/phpmyadminに設置することとします。
1 2 3 |
# semanage fcontext -a -t httpd_sys_content_t '/var/www/phpmyadmin(/.*)?' # semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/phpmyadmin/tmp(/.*)?' # restorecon -RF /var/www/phpmyadmin |
説明:対象ディレクトリ配下に対し「httpd_sys_content_t」タイプを付与しています。通常はread権限のみのこのロールを付与すればWebアクセスは可能です。今回はphpmyadminの要求としてtmpディレクトリにwrite権限が必要となるのでwriteロールがあるコンテキスト「httpd_sys_rw_content_t」タイプをtmpディレクトリだけに付与しています。
(3)cron
Cron用の自動実行設定ファイルを他のディレクトリで作成し「/etc/cron.d/」に移動した場合、SELinuxによりブロックされ動作しません。ここでは「backup」設定ファイルを移動したこととします。
1 2 |
# semanage fcontext -a -t system_cron_spool_t '/etc/cron.d/backup' # restorecon -RF /etc/cron.d |
説明:対象ファイルに対し「system_cron_spool_t」タイプを付与しています。尚、直接「/etc/cron.d」にファイルを新規作成した場合、ファイルをコピーした場合は自動的に「system_cron_spool_t」のコンテキストが付与されますので上記作業は不要です。
(4)OpenVPN
OpenVPNがデフォルトで使用するポート1194/udpを11194/udpに変更する場合の設定です。
①ポートタイプを確認
1 2 3 |
# semanage port -l | grep openvpn openvpn_port_t tcp 1194 openvpn_port_t udp 1194 |
デフォルトでは1194/udp,1194/tcpだけに「openvpn_port_t」タイプが付与されています。
②ポート追加
以下のコマンドで11194/udpに「openvpn_port_t」タイプを付与しopenvpnから使用できるようにします。
1 |
# semanage port -a -t openvpn_port_t -p udp 11194 |
③確認
再び①のコマンドを使用して確認します。
1 2 3 |
# semanage port -l | grep openvpn openvpn_port_t tcp 1194 openvpn_port_t udp 1194,11194 |
ポート「11194/udp」に「openvpn_port_t」タイプが付与されました。
尚、httpで有効なポートとポートタイプは以下のコマンドで確認できます。
1 2 3 4 5 6 |
# 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 |
6.参考にさせて頂いたサイト
SELinux ユーザーおよび管理者のガイド(Redhatマニュアル)
日経Linux 2017年4月号~7月号
ありがとうございます。