スマートスタイル TECH BLOG

データベース&クラウド技術情報

MySQLのSELinuxでエラーになった際の対処法4つ

はじめに

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でした。これを任意のパスに変えました。

ディレクトリとファイルを新規作成しました。

mysqld起動時にエラーとなりました。

「See~」で2通りのコマンドが提示されているので、そのままコマンドを打ってみます。

systemctlコマンドを打つと、Permission deniedと表示されました。

journalctlコマンドを打つと、こちらも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ログ内の検索をすることができます。

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-intro-apache-mariadb.png
このスキーマが示すように、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コンテキストを確認することができます。

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の有効無効を切り替えられます。

有効にする場合

無効にする場合

永続的な変更

setenforceコマンドではシステム再起動後にリセットされてしまいます。

/etc/selinux/configファイルを編集して、永続的にSELinuxの有効無効を切り替えられます。

有効にする場合

無効にする場合

システムの再起動後に反映されます。

log_errorシステム変数をデフォルトから変更した状態でmysqldの起動に成功しました。

Permissiveに設定されているのでAuditログにはpermissive=1のログが出力されます。(write,open,readで3回出ています。)

permissive=1は許可したという意味なのでこのログは気にする必要はありません。

SELinuxモードの確認

/etc/selinux/configファイルの状態は、sestatusコマンドでも有効無効を確認できます。

policycoreutils-python-utilsをインストールします。

sestatusコマンドを実行します。

方法2:プロセスに対してSELinuxを無効にする

policycoreutils-python-utilsをインストールします。

semanage permissiveコマンドでmysqld_tをPermissiveに設定します。

log_errorシステム変数をデフォルトから変更した状態でmysqldの起動に成功しました。

Permissiveに設定されているのでAuditログにはpermissive=1のログが出力されます。(write,open,readで3回出ています。)

permissive=1は許可したという意味なのでこのログは気にする必要はありません。

設定の削除方法

Permissiveから元に戻すコマンドは下記です。

方法3:ファイルのSELinuxコンテキストを修正する

エラー対象のファイル(mysqld.log)に正しいSELinuxコンテキスト(mysqld_log_t)を設定します。

一時的な設定

chconコマンドでSELinuxコンテキストを一時的に変更できます。システム再起動でリセットされます。

永続的な設定

policycoreutils-python-utilsをインストールします。

semanage fcontextコマンドでSELinuxコンテキストを永続的に変更できます。

リストに一行増えているのが確認できました。

restoreconコマンドでファイルに対してSELinuxコンテキスト設定を反映させます。

log_errorシステム変数をデフォルトから変更した状態でmysqldの起動に成功しました。

設定の削除方法

作成したSELinuxコンテキストの削除コマンドは下記です。

方法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をインストールします。

setroubleshoot-serverをインストールします。

sealertコマンドでエラーを許可するコマンドの提案がされます。

提案されているaudit2allowコマンドをそのまま使用して、ローカルポリシーモジュールmy-mysqldを生成します。

カレントディレクトリにファイルが2つ生成されました。その内の.teファイルはテキスト形式でしたので一応内容を確認してみます。

write許可がされているのがわかります。

生成されたローカルポリシーモジュールをsemoduleコマンドでインポートします。

mysqldを起動します。

起動に失敗し、今度はopen拒否でエラーが出ています。

再度audit2allowコマンドでSELinuxポリシーモジュールを作成、semoduleコマンドでインポートします。(同名でも問題なく上書きできました。)

.teファイルの中身を確認してみるとopen writeの2つが許可されているのがわかります。

生成されたローカルポリシーモジュールをsemoduleコマンドでインポートします。

open write許可がある状態でmysqldを起動してみます。

一応mysqldの起動に成功しましたが、Auditログを見るとread拒否のエラーが出ていて少し気味が悪いので、再度SELinuxポリシーモジュールを上書きしておきます。

open read write許可がある状態でmysqldを起動してみます。

log_errorシステム変数をデフォルトから変更した状態でmysqldの起動に成功しました。また、これ以上Auditログにエラーは出なくなりました。

設定の削除方法

インポートしたモジュールの削除コマンドは下記です。

補足:mysqld_selinuxのmanページを生成する

モジュールがインストールされているかどうか確認する

mysqld_selinuxというモジュールがインストールされている場合はman selinux_mysqldコマンドが使えるそうですが、今回の環境では無いのでエラーになりました。

念のため、sumoduleコマンドで一覧表示しましたが、mysqld_selinuxというモジュールはありませんでした。

手動でmanページを生成する

手動でmanページを生成します。

policycoreutils-develパッケージをインストールします。

sepolicy manpage コマンドでmanページを生成します。ファイルは/tmpディレクトリに生成されました。

manコマンドを実行する

ファイルを指定し、manコマンドで開きます。

該当マニュアルの109行目MANAGED FILESからmysqld_tプロセスが編集できるファイルが列挙されています。(先頭から一部を抜粋してあります。)

まとめ

SELinuxを使用にするにあたって、どのスコープで有効無効にするのかを選択できるようにするため、今回色々なSELinuxの設定方法を調べてみました。

SELinuxを活用することで、プロセスが予期しないファイルにアクセスするパストラバーサル攻撃などの予防になります。適切な設定を心掛けてセキュリティの強化に取り組みましょう。

Return Top