CentOS 7.x で MariaDB Galera Cluster に参加できない ( SELinux で拒否される )場合の対処方法!

事象

# service mysql start
Starting MySQL............. ERROR!

/var/lib/mysql/hostaname.err を確認すると以下のようなエラーが確認できる。

160811 22:37:33 [Note] WSREP: Running: 'wsrep_sst_rsync --role 'joiner' --address '192.168.202.91' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '7401'  '' '
160811 22:37:33 [ERROR] WSREP: Failed to read 'ready ' from: wsrep_sst_rsync --role 'joiner' --address '192.168.202.91' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '7401'  '' 
        Read: '(null)'
160811 22:37:33 [ERROR] WSREP: Process completed with error: wsrep_sst_rsync --role 'joiner' --address '192.168.202.91' --datadir '/var/lib/mysql/' --defaults-file '/etc/my.cnf' --defaults-group-suffix '' --parent '7401'  '' : 2 (No such file or directory)
160811 22:37:33 [ERROR] WSREP: Failed to prepare for 'rsync' SST. Unrecoverable.
160811 22:37:33 [ERROR] Aborting

必要な TCP ポートは解放済みだが /var/log/audit/audit.log を確認すると AVC ログの出力が確認できる。

type=AVC msg=audit(1470922653.291:164791): avc:  denied  { setpgid } for  pid=7411 comm="mysqld" scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=unconfined_u:system_r:mysqld_t:s0 tclass=process
type=SYSCALL msg=audit(1470922653.291:164791): arch=c000003e syscall=109 success=no exit=-13 a0=0 a1=0 a2=1 a3=8 items=0 ppid=7401 pid=7411 auid=0 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=22960 comm="mysqld" exe="/usr/sbin/mysqld" subj=unconfined_u:system_r:mysqld_t:s0 key=(null)

対策

上記 type=AVC で始まるのが avc ログです。SELinux を無効にするとか Permissive してログだけチェックするのも動作上はありなんだけど、この avc ログを活用して簡単に許可することができるので Enforcing のままいきます。
まず、avc ログをコピペして別ファイル ( /tmp/galera-avc.log など ) にペーストしておきます。

# cat /tmp/galera-avc.log 
type=AVC msg=audit(1470922653.291:164791): avc:  denied  { setpgid } for  pid=7411 comm="mysqld" scontext=unconfined_u:system_r:mysqld_t:s0 tcontext=unconfined_u:system_r:mysqld_t:s0 tclass=process
type=SYSCALL msg=audit(1470922653.291:164791): arch=c000003e syscall=109 success=no exit=-13 a0=0 a1=0 a2=1 a3=8 items=0 ppid=7401 pid=7411 auid=0 uid=995 gid=993 euid=995 suid=995 fsuid=995 egid=993 sgid=993 fsgid=993 tty=(none) ses=22960 comm="mysqld" exe="/usr/sbin/mysqld" subj=unconfined_u:system_r:mysqld_t:s0 key=(null)

次に、audit2allow コマンドを利用して、この avc ログからアクセス違反となった処理の動作を許可するためのポリシーモジュールを作成し semodule -i で適用していきます。
便利なツールなので是非インストールしておきましょう。audit2allow コマンドは、policycoreutils-python パッケージをインストールすることで利用可能となります。

ポリシーモジュールの作成

policycoreutils-python パッケージをインストールし audit2allow が利用できるようになったら、avc ログを食わせます。すると galera-avc.pp と galera-avc.te というファイルが生成されます。
-M オプションの意味はモジュール名の指定です。モジュール名は基本的に好きな名称でよいです。

# yum install -y policycoreutils-python
# audit2allow -M galera-avc < /tmp/galera-avc.log

.te ファイルと .pe ファイル

.te ファイルはポリシーパッケージを作るためのソースコード、.pp ファイルはポリシーパッケージ。ぐらいの理解で OK。
この例では、galera-avc.pp ファイルは galera-avc.te から生成されているというわけです。

# cat galera-avc.te 

module galera-avc 1.0;

require {
        type mysqld_t;
        class process setpgid;
}

#============= mysqld_t ==============
allow mysqld_t self:process setpgid;

これを semodule コマンドでインストールすることで拒否されていた動作を許可することができます。
Galera Cluster 10.0 だと wsrep を利用するので mysqld だけ許可しても rsync の処理が拒否されたりします。
そのため上記の手順を繰り返してポリシーモジュールを育てていきます(笑)

# semodule -i galera-avc.pp
# service mysql start
Starting MySQL….SST in progress, setting sleep higher…….

無事 Galera Cluster に参加することができました。
最終的には以下のような .te ファイルでいけました。

module galera-avc 1.0;

require {
        type rsync_exec_t;
        type mysqld_t;
        class process setpgid;
        class file getattr;
}

#============= mysqld_t ==============
allow mysqld_t rsync_exec_t:file getattr;
allow mysqld_t self:process setpgid;

トラブルシューティング

semodule -i でポリシーパッケージを指定したけど以下のようなメッセージが表示される場合、そのモジュール名は既に利用されている可能性がある。
mysql.pp とかにしてるとすでに OS が利用しているので利用できないということです。そのためモジュール名は local のように指定しておくとよいでしょう。
その他、モジュール名に my- を接頭辞としてつけるとかも方法だけど、my-mysql とかあまりいけてない気がします。その辺はお好みで。

すでにそのモジュール名が利用されているかどうかは -l オプションで一覧を確認できます。

# semodule -i mysql.pp
libsepol.print_missing_requirements: mysql's global requirements were not met: type/attribute mysqld_t (No such file or directory).
libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
semodule:  Failed!

こんな感じで重複していなければ OK です。

# semodule -l |grep mysql
mysql-avc       1.0 
mysql   1.14.1 

また、許可したポリシーモジュールを削除したい場合は -r で削除できます。

# semodule -r mysql-avc
スポンサーリンク