はじめに
MySQLのmy.cnf
サーバー構成ファイルで、log_error
システム変数にインストール時のデフォルト値以外のパスを指定しているとエラーになりました。
Security Enhanced Linux (SELinux)によって拒否されているのが原因と分かりました。
MySQL ディレクトリまたはファイルの SELinux コンテキストが正しくない場合、アクセスが拒否される可能性があります。 この問題は、MySQL がデフォルト以外のディレクトリまたはファイルに対して読取りまたは書込みを行うように構成されている場合に発生することがあります。
MySQL :: MySQL 8.0 リファレンスマニュアル :: 6.7.4 SELinux ファイルコンテキスト
今回はSELinuxの設定方法について調べたことを紹介していきたいと思います。
検証環境
- Oracle Linux 9.3
- MySQL Ver 8.0.36 for Linux on x86_64 (MySQL Community Server – GPL)
- RPMパッケージを使用してインストールしました
目次
- エラーとなった操作
- 原因分析
- SELinuxのトラブルシューティング
エラーとなった操作
log_error
システム変数をインストール時のデフォルト値から変更したときに、mysqld
の起動エラーとなりました。
今回はRPMパッケージからインストールし、デフォルト値は/var/log/mysqld.log
でした。これを任意のパスに変えました。
1 |
$ sudo vi /etc/my.cnf |
1 |
log-error=/var/log/8.0/mysqld.log |
ディレクトリとファイルを新規作成しました。
1 2 3 |
$ sudo mkdir /var/log/8.0 $ sudo touch /var/log/8.0/mysqld.log $ sudo chown -R mysql:mysql /var/log/8.0 |
mysqld
起動時にエラーとなりました。
1 2 3 |
$ sudo systemctl restart mysqld Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xeu mysqld.service" for details. |
「See~」で2通りのコマンドが提示されているので、そのままコマンドを打ってみます。
systemctl
コマンドを打つと、Permission denied
と表示されました。
1 2 3 4 |
$ systemctl status mysqld.service ... Error: 13 (Permission denied) ... |
journalctl
コマンドを打つと、こちらもPermission denied
と表示されました。権限が無いことを示すエラーのようです。
1 2 3 4 |
$ sudo journalctl -xeu mysqld.service ... Feb 01 18:27:08 oracle9.localdomain mysqld[2008]: 2024-02-01T09:27:08.618445Z 0 [ERROR] [MY-010187] [Server] Could not open file '/var/log/8.0/mysqld.log' for error logging: Permission denied ... |
原因分析
Auditログを見ると、具体的にどのファイルが権限エラーとなっているのか確認ができます。
AuditログおよびAuditシステムの説明は下記をご参照ください。
Linux の Audit システムは、システムのセキュリティー関連情報を追跡する方法を提供します。事前設定されたルールに基づき、Audit は、ログエントリーを生成し、システムで発生しているイベントに関する情報をできるだけ多く記録します。この情報は、ミッションクリティカルな環境でセキュリティーポリシーの違反者と、違反者によるアクションを判断する上で必須のものです。
第12章 システムの監査 Red Hat Enterprise Linux 9 | Red Hat Customer Portalデフォルトでは、Audit システムはログエントリーを /var/log/audit/audit.log ファイルに保存します。
12.5. Audit ログファイルについて Red Hat Enterprise Linux 9 | Red Hat Customer Portal
ausearch
コマンドを使用してAuditログ内の検索をすることができます。
1 2 3 4 5 6 7 |
$ sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR ... ---- time->Thu Feb 1 18:27:08 2024 type=PROCTITLE msg=audit(1706779628.609:524): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1706779628.609:524): arch=c000003e syscall=21 success=no exit=-13 a0=3920720 a1=2 a2=7fff36fbbd10 a3=7fec1b0160b0 items=0 ppid=1 pid=2008 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1706779628.609:524): avc: denied { write } for pid=2008 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=0 |
SELinuxコンテキストが正しく設定されておらず、write
拒否でエラーになったことが分かりました。
必要な部分だけを細かく見ていきます。
denied { write } for
write
拒否を示します。
comm="mysqld"
- ソースプロセスを開始した実行可能ファイルを示します。
name="mysqld.log"
- ソースプロセスがアクセスを試みたターゲットを示します。
scontext=system_u:system_r:mysqld_t:s0
- ソースプロセスのSELinuxコンテキストを示します。
tcontext=unconfined_u:object_r:var_log_t:s0
- ターゲットのSELinuxコンテキストを示します。
permissive=0
- Permissiveモードであるかどうかを示します。
SELinuxコンテキストの説明
SELinuxコンテキストの説明は下記をご参照ください。
このスキーマが示すように、SELinux は、httpd_t として実行している Apache プロセスが /var/www/html/ ディレクトリーにアクセスするのは許可しますが、同じ Apache プロセスが /data/mysql/ ディレクトリーにアクセスするのは拒否します。これは、httpd_t タイプコンテキストと mysqld_db_t タイプコンテキストに許可ルールがないのが原因です。一方、mysqld_t として実行する MariaDB プロセスは /data/mysql/ ディレクトリーにアクセスできますが、SELinux により、mysqld_t タイプを持つプロセスが、httpd_sys_content_t とラベルが付いた /var/www/html/ ディレクトリーにアクセスするのは拒否されます。
第1章 SELinux の使用 Red Hat Enterprise Linux 9 | Red Hat Customer Portal
端的に言えばSELinuxとは、(ソース)プロセスが(ターゲット)ファイルにアクセスするのを許可/拒否する機能です。
SELinuxでアクセス可否の際に参照している情報がSELinuxコンテキストになります。
今回のエラーでは、mysqld_t
のタイプコンテキストを持つmysqld
(ソース)プロセスが、var_log_t
のタイプコンテキストを持つmysqld.log
(ターゲット)ファイルにアクセスしようとして拒否されています。
mysqld_t
がアクセス可能なSELinuxコンテキストの一覧はman selinux_mysqld
コマンドで確認できます。説明は後述する「補足:mysqld_selinux
のmanページを生成する」をご参照ください。
SELinuxコンテキストの確認コマンド
ps
コマンド、ls
コマンドに-Z
オプションを使用してSELinuxコンテキストを確認することができます。
1 2 3 4 5 6 |
$ ps -eZ | grep mysqld system_u:system_r:mysqld_t:s0 3291 ? 00:00:01 mysqld ### (mysqldが起動している必要があります) $ ls -lZ /var/log/8.0/mysqld.log -rw-r--r--. 1 mysql mysql unconfined_u:object_r:var_log_t:s0 5800 Feb 2 17:39 /var/log/8.0/mysqld.log |
mysqld
プロセスのSELinuxコンテキストがAuditログのscontext
と、mysqld.log
ファイルのSELinuxコンテキストがAuditログのtcontext
とそれぞれ一致していることが確認できたと思います。
SELinuxのトラブルシューティング目次
4つの方法を紹介します。
- SELinuxを無効にする(方法1)
- SELinuxは有効のまま:
- プロセスに対してSELinuxを無効にする(方法2)
- プロセスに対してSELinuxは有効のまま:
- ファイルのSELinuxコンテキストを修正する(方法3)
- ファイルのSELinuxコンテキストを修正しないまま:
- ファイルに対するSELinux許可設定をする(方法4)
方法1:SELinuxを無効にする
SELinuxのモード
SELinux は、3 つのモード (Enforcing、Permissive、または Disabled) のいずれかで実行できます。
1.5. SELinux のステータスおよびモード Red Hat Enterprise Linux 9 | Red Hat Customer Portal
基本的には下記の2つです。(Disabledモードは非推奨とされています)
- Enforcingモード(有効)
- Permissiveモード(無効、Auditログは出る)
一時的な変更
setenforce
コマンドで、一時的にSELinuxの有効無効を切り替えられます。
有効にする場合
1 2 3 |
$ sudo setenforce 1 $ getenforce Enforcing |
無効にする場合
1 2 3 |
$ sudo setenforce 0 $ getenforce Permissive |
永続的な変更
setenforce
コマンドではシステム再起動後にリセットされてしまいます。
/etc/selinux/config
ファイルを編集して、永続的にSELinuxの有効無効を切り替えられます。
1 |
$ sudo vi /etc/selinux/config |
有効にする場合
1 |
SELINUX=enforcing |
無効にする場合
1 |
SELINUX=permissive |
システムの再起動後に反映されます。
1 2 3 |
$ sudo reboot $ getenforce Permissive |
log_error
システム変数をデフォルトから変更した状態でmysqld
の起動に成功しました。
1 |
$ sudo systemctl restart mysqld |
Permissiveに設定されているのでAuditログにはpermissive=1
のログが出力されます。(write,open,read
で3回出ています。)
permissive=1
は許可したという意味なのでこのログは気にする必要はありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ sudo ausearch -c 'mysqld' ---- time->Mon Feb 5 16:48:28 2024 type=PROCTITLE msg=audit(1707119308.031:2582): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119308.031:2582): arch=c000003e syscall=21 success=yes exit=0 a0=3920720 a1=2 a2=7ffd60e410f0 a3=7f4eccc160b0 items=0 ppid=1 pid=7511 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119308.031:2582): avc: denied { write } for pid=7511 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ---- time->Mon Feb 5 16:48:28 2024 type=PROCTITLE msg=audit(1707119308.037:2583): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119308.037:2583): arch=c000003e syscall=257 success=yes exit=4 a0=ffffff9c a1=3920720 a2=441 a3=1b6 items=0 ppid=1 pid=7511 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119308.037:2583): avc: denied { open } for pid=7511 comm="mysqld" path="/var/log/8.0/mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ---- time->Mon Feb 5 16:48:28 2024 type=PROCTITLE msg=audit(1707119308.037:2584): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119308.037:2584): arch=c000003e syscall=21 success=yes exit=0 a0=3920720 a1=4 a2=5de49e6e12c2c9b2 a3=460 items=0 ppid=1 pid=7511 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119308.037:2584): avc: denied { read } for pid=7511 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 |
SELinuxモードの確認
/etc/selinux/config
ファイルの状態は、sestatus
コマンドでも有効無効を確認できます。
policycoreutils-python-utils
をインストールします。
1 |
$ sudo dnf install policycoreutils-python-utils |
sestatus
コマンドを実行します。
1 2 3 4 5 6 7 8 9 10 11 |
$ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: permissive Mode from config file: permissive Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: actual (secure) Max kernel policy versio |
方法2:プロセスに対してSELinuxを無効にする
policycoreutils-python-utils
をインストールします。
1 |
$ sudo dnf install policycoreutils-python-utils |
semanage permissive
コマンドでmysqld_t
をPermissiveに設定します。
1 2 3 4 5 6 |
$ sudo semanage permissive -a mysqld_t $ sudo semanage permissive -l ... Customized Permissive Types mysqld_t |
log_error
システム変数をデフォルトから変更した状態でmysqld
の起動に成功しました。
1 |
$ sudo systemctl restart mysqld |
Permissiveに設定されているのでAuditログにはpermissive=1
のログが出力されます。(write,open,read
で3回出ています。)
permissive=1
は許可したという意味なのでこのログは気にする必要はありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ sudo ausearch -c 'mysqld' ---- time->Mon Feb 5 16:44:22 2024 type=PROCTITLE msg=audit(1707119062.547:2511): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119062.547:2511): arch=c000003e syscall=21 success=yes exit=0 a0=3920720 a1=2 a2=7fff460099d0 a3=7fdeed6160b0 items=0 ppid=1 pid=7349 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119062.547:2511): avc: denied { write } for pid=7349 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ---- time->Mon Feb 5 16:44:22 2024 type=PROCTITLE msg=audit(1707119062.552:2512): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119062.552:2512): arch=c000003e syscall=257 success=yes exit=4 a0=ffffff9c a1=3920720 a2=441 a3=1b6 items=0 ppid=1 pid=7349 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119062.552:2512): avc: denied { open } for pid=7349 comm="mysqld" path="/var/log/8.0/mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 ---- time->Mon Feb 5 16:44:22 2024 type=PROCTITLE msg=audit(1707119062.553:2513): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1707119062.553:2513): arch=c000003e syscall=21 success=yes exit=0 a0=3920720 a1=4 a2=be0b9da597d5a8e9 a3=460 items=0 ppid=1 pid=7349 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1707119062.553:2513): avc: denied { read } for pid=7349 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1 |
設定の削除方法
Permissiveから元に戻すコマンドは下記です。
1 |
$ sudo semanage permissive -d mysqld_t |
方法3:ファイルのSELinuxコンテキストを修正する
エラー対象のファイル(mysqld.log
)に正しいSELinuxコンテキスト(mysqld_log_t
)を設定します。
一時的な設定
- 参考リファレンスマニュアル
- 4.7. SELinux コンテキスト – ファイルのラベル付け Red Hat Enterprise Linux 7 | Red Hat Customer Portal
- Red Hat 7 マニュアルの説明のほうがわかりやすかったので参考にしています。
- 4.7. SELinux コンテキスト – ファイルのラベル付け Red Hat Enterprise Linux 7 | Red Hat Customer Portal
chcon
コマンドでSELinuxコンテキストを一時的に変更できます。システム再起動でリセットされます。
1 2 3 |
$ sudo chcon -t mysqld_log_t /var/log/8.0/mysqld.log $ sudo ls -lZ /var/log/8.0/mysqld.log -rw-r--r--. 1 mysql mysql unconfined_u:object_r:mysqld_log_t:s0 1218 Feb 1 14:35 mysqld.log |
永続的な設定
- 参考リファレンスマニュアル
- 4.7.2. 永続的な変更 – semanage fcontext Red Hat Enterprise Linux 7 | Red Hat Customer Portal
- Red Hat 7 マニュアルの説明のほうがわかりやすかったので参考にしています。
- MySQL :: MySQL 8.0 リファレンスマニュアル :: 6.7.4 SELinux ファイルコンテキスト
- 4.7.2. 永続的な変更 – semanage fcontext Red Hat Enterprise Linux 7 | Red Hat Customer Portal
policycoreutils-python-utils
をインストールします。
1 |
$ sudo dnf install policycoreutils-python-utils |
semanage fcontext
コマンドでSELinuxコンテキストを永続的に変更できます。
1 2 3 4 5 6 7 8 9 10 |
$ sudo semanage fcontext -l | grep mysqld_log /var/log/mariadb(/.*)? all files system_u:object_r:mysqld_log_t:s0 /var/log/mysql(/.*)? all files system_u:object_r:mysqld_log_t:s0 /var/log/mysql.* regular file system_u:object_r:mysqld_log_t:s0 $ sudo semanage fcontext -a -f f -t mysqld_log_t "/var/log/8.0/mysqld\.log" $ sudo semanage fcontext -l | grep mysqld_log /var/log/8.0/mysqld\.log regular file system_u:object_r:mysqld_log_t:s0 /var/log/mariadb(/.*)? all files system_u:object_r:mysqld_log_t:s0 /var/log/mysql(/.*)? all files system_u:object_r:mysqld_log_t:s0 /var/log/mysql.* regular file system_u:object_r:mysqld_log_t:s0 |
リストに一行増えているのが確認できました。
restorecon
コマンドでファイルに対してSELinuxコンテキスト設定を反映させます。
1 2 3 4 |
$ sudo restorecon -Rv /var/log/8.0/mysqld.log Relabeled /var/log/8.0/mysqld.log from unconfined_u:object_r:var_log_t:s0 to unconfined_u:object_r:mysqld_log_t:s0 $ sudo ls -lZ /var/log/8.0/mysqld.log -rw-r--r--. 1 mysql mysql unconfined_u:object_r:mysqld_log_t:s0 1218 Feb 1 14:35 mysqld.log |
log_error
システム変数をデフォルトから変更した状態でmysqld
の起動に成功しました。
1 |
$ sudo systemctl restart mysqld |
設定の削除方法
作成したSELinuxコンテキストの削除コマンドは下記です。
1 |
$ sudo semanage fcontext -d -f f -t mysqld_log_t "/var/log/8.0/mysqld\.log" |
方法4:ファイルに対するSELinux許可設定をする
注意として、今回のように原因がSELinuxコンテキストの誤りであると判明しているときは、audit2allow
コマンドを最初に使用しないようにとリファレンスマニュアルに記載があります。
ツールが、audit2allow ツールを使用して設定変更を提案している場合は注意が必要です。audit2allow を使用して、SELinux 拒否を確認する際に、最初のオプションとしてローカルポリシーモジュールを生成することはできません。トラブルシューティングは、ラベル付けの問題があるかどうかを最初に確認します。2 番目に多いのが、SELinux が、プロセスの設定変更を認識していない場合です。
5.3. 分析した SELinux 拒否の修正 Red Hat Enterprise Linux 9 | Red Hat Customer Portal
一応、手順を知るという名目で紹介しておきます。
audit2allow
コマンドでローカルポリシーモジュールを生成、インポートすることで特定のファイルに対するアクセス許可ルールを追加することができます。
policycoreutils-python-utils
をインストールします。
1 |
$ sudo dnf install policycoreutils-python-utils |
setroubleshoot-server
をインストールします。
1 |
$ sudo dnf install setroubleshoot-server |
sealert
コマンドでエラーを許可するコマンドの提案がされます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$ sudo sealert -l "*" SELinux is preventing /usr/sbin/mysqld from write access on the file /var/log/8.0/mysqld.log. ***** Plugin catchall (100. confidence) suggests ************************** If you believe that mysqld should be allowed write access on the mysqld.log 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 'mysqld' --raw | audit2allow -M my-mysqld # semodule -X 300 -i my-mysqld.pp Additional Information: Source Context system_u:system_r:mysqld_t:s0 Target Context unconfined_u:object_r:var_log_t:s0 Target Objects /var/log/8.0/mysqld.log [ file ] Source mysqld Source Path /usr/sbin/mysqld Port <Unknown> Host oracle9.localdomain Source RPM Packages mysql-community-server-8.0.36-1.el9.x86_64 Target RPM Packages SELinux Policy RPM selinux-policy-targeted-38.1.23-1.0.1.el9.noarch Local Policy RPM selinux-policy-targeted-38.1.23-1.0.1.el9.noarch Selinux Enabled True Policy Type targeted Enforcing Mode Enforcing Host Name oracle9.localdomain Platform Linux oracle9.localdomain 5.14.0-362.13.1.el9_3.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 21 22:34:57 PST 2023 x86_64 x86_64 Alert Count 1 First Seen 2024-02-01 18:27:08 JST Last Seen 2024-02-01 18:27:08 JST Local ID 6145cb7f-13a7-466e-9bcf-9712a9e0cf60 Raw Audit Messages type=AVC msg=audit(1706779628.609:524): avc: denied { write } for pid=2008 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=0 type=SYSCALL msg=audit(1706779628.609:524): arch=x86_64 syscall=access success=no exit=EACCES a0=3920720 a1=2 a2=7fff36fbbd10 a3=7fec1b0160b0 items=0 ppid=1 pid=2008 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm=mysqld exe=/usr/sbin/mysqld subj=system_u:system_r:mysqld_t:s0 key=(null) Hash: mysqld,mysqld_t,var_log_t,file,write |
提案されているaudit2allow
コマンドをそのまま使用して、ローカルポリシーモジュールmy-mysqld
を生成します。
1 2 3 4 5 6 |
$ sudo ausearch -c 'mysqld' --raw | audit2allow -M my-mysqld ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i my-mysqld.pp |
カレントディレクトリにファイルが2つ生成されました。その内の.te
ファイルはテキスト形式でしたので一応内容を確認してみます。
write
許可がされているのがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ ls my-mysqld.pp my-mysqld.te $ cat my-mysqld.te module my-mysqld 1.0; require { type var_log_t; type mysqld_t; class file write; } #============= mysqld_t ============== allow mysqld_t var_log_t:file write; |
生成されたローカルポリシーモジュールをsemodule
コマンドでインポートします。
1 2 3 |
$ sudo semodule -X 300 -i my-mysqld.pp $ sudo semodule -l | grep mysqld my-mysqld |
mysqld
を起動します。
1 2 3 4 5 6 7 8 9 |
$ sudo systemctl restart mysqld Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xeu mysqld.service" for details. $ sudo ausearch -c 'mysqld' | tail ---- time->Thu Feb 1 17:54:27 2024 type=PROCTITLE msg=audit(1706777667.809:269): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1706777667.809:269): arch=c000003e syscall=257 success=no exit=-13 a0=ffffff9c a1=3920720 a2=441 a3=1b6 items=0 ppid=1 pid=1308 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1706777667.809:269): avc: denied { open } for pid=1308 comm="mysqld" path="/var/log/8.0/mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=0 |
起動に失敗し、今度はopen
拒否でエラーが出ています。
再度audit2allow
コマンドでSELinuxポリシーモジュールを作成、semodule
コマンドでインポートします。(同名でも問題なく上書きできました。)
1 2 3 4 5 6 |
$ sudo ausearch -c 'mysqld' --raw | audit2allow -M my-mysqld ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i my-mysqld.pp |
.te
ファイルの中身を確認してみるとopen write
の2つが許可されているのがわかります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ cat my-mysqld.te module my-mysqld 1.0; require { type var_log_t; type mysqld_t; class file { open write }; } #============= mysqld_t ============== #!!!! This avc is allowed in the current policy allow mysqld_t var_log_t:file write; allow mysqld_t var_log_t:file open; |
生成されたローカルポリシーモジュールをsemodule
コマンドでインポートします。
1 2 3 |
$ sudo semodule -X 300 -i my-mysqld.pp $ sudo semodule -l | grep mysqld my-mysqld |
open write
許可がある状態でmysqld
を起動してみます。
1 2 3 4 5 6 7 |
$ sudo systemctl restart mysqld $ sudo ausearch -c 'mysqld' | tail ---- time->Thu Feb 1 18:01:36 2024 type=PROCTITLE msg=audit(1706778096.286:313): proctitle="/usr/sbin/mysqld" type=SYSCALL msg=audit(1706778096.286:313): arch=c000003e syscall=21 success=no exit=-13 a0=7ffec7820670 a1=4 a2=2 a3=22 items=0 ppid=1 pid=1381 auid=4294967295 uid=27 gid=27 euid=27 suid=27 fsuid=27 egid=27 sgid=27 fsgid=27 tty=(none) ses=4294967295 comm="mysqld" exe="/usr/sbin/mysqld" subj=system_u:system_r:mysqld_t:s0 key=(null) type=AVC msg=audit(1706778096.286:313): avc: denied { read } for pid=1381 comm="mysqld" name="mysqld.log" dev="dm-0" ino=67131334 scontext=system_u:system_r:mysqld_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=0 |
一応mysqld
の起動に成功しましたが、Auditログを見るとread
拒否のエラーが出ていて少し気味が悪いので、再度SELinuxポリシーモジュールを上書きしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ sudo ausearch -c 'mysqld' --raw | audit2allow -M my-mysqld ******************** IMPORTANT *********************** To make this policy package active, execute: semodule -i my-mysqld.pp $ cat my-mysqld.te module my-mysqld 1.0; require { type var_log_t; type mysqld_t; class file { open read write }; } #============= mysqld_t ============== #!!!! This avc is allowed in the current policy allow mysqld_t var_log_t:file { open write }; allow mysqld_t var_log_t:file read; $ sudo semodule -X 300 -i my-mysqld.pp $ sudo semodule -l | grep mysqld my-mysqld |
open read write
許可がある状態でmysqld
を起動してみます。
1 |
$ sudo systemctl restart mysqld |
log_error
システム変数をデフォルトから変更した状態でmysqld
の起動に成功しました。また、これ以上Auditログにエラーは出なくなりました。
設定の削除方法
インポートしたモジュールの削除コマンドは下記です。
1 |
$ sudo semodule -d my-mysqld |
補足:mysqld_selinux
のmanページを生成する
モジュールがインストールされているかどうか確認する
mysqld_selinux
というモジュールがインストールされている場合はman selinux_mysqld
コマンドが使えるそうですが、今回の環境では無いのでエラーになりました。
1 2 |
$ man selinux_mysqld No manual entry for selinux_mysqld |
念のため、sumodule
コマンドで一覧表示しましたが、mysqld_selinux
というモジュールはありませんでした。
1 |
$ sudo semodule -l | grep mysqld_selinux |
手動でmanページを生成する
- 参考リファレンスマニュアル
- 第5章 sepolicy スイート Red Hat Enterprise Linux 7 | Red Hat Customer Portal
- Red Hat 7 マニュアルの説明のほうがわかりやすかったので参考にしています。
- 第5章 sepolicy スイート Red Hat Enterprise Linux 7 | Red Hat Customer Portal
手動でmanページを生成します。
policycoreutils-devel
パッケージをインストールします。
1 |
$ sudo dnf install policycoreutils-devel |
- 参考リファレンスマニュアル
- 5.4. 手動ページの生成: sepolicy manpage Red Hat Enterprise Linux 7 | Red Hat Customer Portal
- Red Hat 7 マニュアルの説明のほうがわかりやすかったので参考にしています。
- 5.4. 手動ページの生成: sepolicy manpage Red Hat Enterprise Linux 7 | Red Hat Customer Portal
sepolicy manpage
コマンドでmanページを生成します。ファイルは/tmp
ディレクトリに生成されました。
1 2 |
$ sudo sepolicy manpage -d mysqld_t /tmp/mysqld_selinux.8 |
man
コマンドを実行する
ファイルを指定し、man
コマンドで開きます。
1 |
$ man /tmp/mysqld_selinux.8 |
該当マニュアルの109行目MANAGED FILES
からmysqld_t
プロセスが編集できるファイルが列挙されています。(先頭から一部を抜粋してあります。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
MANAGED FILES The SELinux process type mysqld_t can manage files labeled with the following file types. The paths listed are the default paths for these file types. Note the processes UID still need to have DAC permissions. cluster_conf_t /etc/cluster(/.*)? cluster_var_lib_t /var/lib/pcsd(/.*)? /var/lib/cluster(/.*)? /var/lib/openais(/.*)? /var/lib/pengine(/.*)? /var/lib/corosync(/.*)? /usr/lib/heartbeat(/.*)? /var/lib/heartbeat(/.*)? /var/lib/pacemaker(/.*)? ... |
まとめ
SELinuxを使用にするにあたって、どのスコープで有効無効にするのかを選択できるようにするため、今回色々なSELinuxの設定方法を調べてみました。
SELinuxを活用することで、プロセスが予期しないファイルにアクセスするパストラバーサル攻撃などの予防になります。適切な設定を心掛けてセキュリティの強化に取り組みましょう。