MariaDB 10.2 Galera Cluster with SElinux enabled on CentOS 7

Updated at by

SELinux policy changes and MariaDB configuration to allow galera cluster function with SELinux enabled. For SST this example will use mariabackup which is a fork of percona's xtrabackup-v2. Versions used : up to date CentOS Linux release 7.4.1708, MariaDB-server 10.2.13 and MariaDB-backup 10.2.13.

TCP/4444 the reserved port dilemma.

Galera cluster defaults to tcp/4444 for State Snapshot Transfers (SST) which has a SELinux label kerberos_port_t on CentOS 7 and IANA search 4444 defines it as kerberos v5 to v4 ticket conversion service. As a single protocol/port pair cannot have multiple labels it leaves with two options. Allow MariaDB to communicate all kerberos_port_t ports/protocols or change the SST port to a free port. We'll do the latter.

Rightfully policy shipped with MariaDB has commented out allow to kerboros_port_t for mysqld_t but has allow rule for tram_port_t (tcp/4567). This leaves us tcp/4568 (IST port which is base_port + 1) and our new hand picked SST port tcp/4569 blocked by SELinux.

Adding SELinux TCP ports.

Install tools needed.

yum install policycoreutils-python

Add tcp/4568-4569 to mysqld_port_t to allow usage of IST and SST ports.

semanage port -a -t mysqld_port_t -p tcp 4568-4569

Mariabackup

Create a user for mariabackup.

GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'galera-sst'@'localhost' identified by 'hurrdurrherpderp';

Configure mariabackup in /etc/my.cnf. Note the receiving port 4569.

[server]
wsrep_sst_receive_address="10.1.1.150:4569"

[xtrabackup]
# xtrabackup/mariabackup doesn't follow !include directive. Specify datadir in this or [client] block or bust.
datadir=/var/lib/mysql
user=galera-sst
password=hurrdurrherpderp

SELinux audit logs

Now with the server and SST configured we'll try to boostrap the cluster. SST donor gets in a single /var/log/audit/audit.log AVC error.

avc:  denied  { connectto } for  pid=15680 comm="mariabackup" path="/var/lib/mysql/mysql.sock" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:mysqld_t:s0 tclass=unix_stream_socket

and audit2allow gives us strange warning.

#!!!! The file '/var/lib/mysql/mysql.sock' is mislabeled on your system.  
#!!!! Fix with $ restorecon -R -v /var/lib/mysql/mysql.sock
#!!!! This avc can be allowed using the boolean 'daemons_enable_cluster_mode'
allow mysqld_t self:unix_stream_socket connectto;

And after checking.

ls -Z /var/lib/mysql/mysql.sock 
->
srwxrwxrwx. mysql mysql system_u:object_r:mysqld_var_run_t:s0 /var/lib/mysql/mysql.sock

There's nothing wrong the the socket's label mysqld_var_run_t... Enable the boolean.

setsebool -P daemons_enable_cluster_mode 1

And the donor side works fine. What about the joiner node. Well the joiner's audit log is a bit more lengthy :).

avc:  denied  { getattr } for  pid=18038 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:init_t:s0 tclass=process
avc:  denied  { getattr } for  pid=18038 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
avc:  denied  { getattr } for  pid=18038 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:syslogd_t:s0 tclass=process
avc:  denied  { getattr } for  pid=18038 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:lvm_t:s0 tclass=process
...
WALL OF AUDIT LOG.
...

By the looks of it. It's trying to inspect all open sockets on the system. After rigorous trial and error the following denial seems to be the main culprit.

avc:  denied  { bind } for  pid=8689 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:mysqld_t:s0 tclass=netlink_tcpdiag_socket

I might be totally wrong but looks like xtrabackup/mariabackup monitors backup progress or state with ss-TCP-diagnostic-socket-witchery :). Piping that to audit2allow gives us.

allow mysqld_t self:netlink_tcpdiag_socket bind;

After installing the policy snippet SST works but we still have a ton of AVC errors. (timestamps are removed for tidiness)

...
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:postfix_pickup_t:s0 tclass=process
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
avc:  denied  { getattr } for  pid=16012 comm="ss" scontext=system_u:system_r:mysqld_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=process
....

Feeding these into audit2allow with -D switch to create dontaudit rules.

#============= mysqld_t ==============

dontaudit mysqld_t NetworkManager_t:process getattr;
dontaudit mysqld_t auditd_t:process getattr;
dontaudit mysqld_t chronyd_t:process getattr;
dontaudit mysqld_t crond_t:process getattr;
dontaudit mysqld_t getty_t:process getattr;
dontaudit mysqld_t init_t:process getattr;
dontaudit mysqld_t irqbalance_t:process getattr;
dontaudit mysqld_t kernel_t:process getattr;
dontaudit mysqld_t lvm_t:process getattr;
dontaudit mysqld_t policykit_t:process getattr;
dontaudit mysqld_t postfix_master_t:process getattr;
dontaudit mysqld_t postfix_pickup_t:process getattr;
dontaudit mysqld_t postfix_qmgr_t:process getattr;
dontaudit mysqld_t self:netlink_tcpdiag_socket create;
dontaudit mysqld_t self:process { getattr setpgid };
dontaudit mysqld_t sshd_t:process getattr;
dontaudit mysqld_t sysctl_net_t:dir search;
dontaudit mysqld_t syslogd_t:process getattr;
dontaudit mysqld_t system_dbusd_t:process getattr;
dontaudit mysqld_t systemd_logind_t:process getattr;
dontaudit mysqld_t tuned_t:process getattr;
dontaudit mysqld_t udev_t:process getattr;
dontaudit mysqld_t unconfined_t:process getattr;

And after installation no more AVC errors during IST or SST.


Share on FacebookShare on Facebook Share on TwitterShare on Twitter

Leave a comment