6.7 SELinux

Security-Enhanced Linux (SELinux) is a mandatory access control (MAC) system that implements access rights by applying a security label referred to as an SELinux context to each system object. SELinux policy modules use SELinux contexts to define rules for how processes, files, ports, and other system objects interact with each other. Interaction between system objects is only permitted if a policy rule allows it.

An SELinux context (the label applied to a system object) has the following fields: 'user', 'role', 'type', and 'security level'. Type information rather than the entire SELinux context is used most commonly to define rules for how processes interact with other system objects. MySQL SELinux policy modules, for example, define policy rules using 'type' information.

You can view SELinux contexts using operating system commands such as 'ls' and 'ps' with the '-Z' option. Assuming that SELinux is enabled and a MySQL Server is running, the following commands show the SELinux context for the *note 'mysqld': mysqld. process and MySQL data directory:

*note 'mysqld': mysqld. process:

 $> ps -eZ | grep mysqld
 system_u:system_r:mysqld_t:s0    5924 ?        00:00:03 mysqld

MySQL data directory:

 $> cd /var/lib
 $> ls -Z | grep mysql
 system_u:object_r:mysqld_db_t:s0 mysql

where:

For more information about interpreting SELinux contexts, refer to your distribution's SELinux documentation.

 File: manual.info.tmp, Node: selinux-checking, Next: selinux-mode, Prev: selinux, Up: selinux

6.7.1 Check if SELinux is Enabled

SELinux is enabled by default on some Linux distributions including Oracle Linux, RHEL, CentOS, and Fedora. Use the 'sestatus' command to determine if SELinux is enabled on your distribution:

 $> sestatus
 SELinux status:                 enabled
 SELinuxfs mount:                /sys/fs/selinux
 SELinux root directory:         /etc/selinux
 Loaded policy name:             targeted
 Current mode:                   enforcing
 Mode from config file:          enforcing
 Policy MLS status:              enabled
 Policy deny_unknown status:     allowed
 Memory protection checking:     actual (secure)
 Max kernel policy version:      31

If SELinux is disabled or the 'sestatus' command is not found, refer to your distribution's SELinux documentation for guidance before enabling SELinux.

 File: manual.info.tmp, Node: selinux-mode, Next: selinux-policies, Prev: selinux-checking, Up: selinux

6.7.2 Changing the SELinux Mode

SELinux supports enforcing, permissive, and disabled modes. Enforcing mode is the default. Permissive mode allows operations that are not permitted in enforcing mode and logs those operations to the SELinux audit log. Permissive mode is typically used when developing policies or troubleshooting. In disabled mode, polices are not enforced, and contexts are not applied to system objects, which makes it difficult to enable SELinux later.

To view the current SELinux mode, use the 'sestatus' command mentioned previously or the 'getenforce' utility.

 $> getenforce
 Enforcing

To change the SELinux mode, use the 'setenforce' utility:

 $> setenforce 0
 $> getenforce
 Permissive

 $> setenforce 1
 $> getenforce
 Enforcing

Changes made with 'setenforce' are lost when you restart the system. To permanently change the SELinux mode, edit the '/etc/selinux/config' file and restart the system.

 File: manual.info.tmp, Node: selinux-policies, Next: selinux-file-context, Prev: selinux-mode, Up: selinux

6.7.3 MySQL Server SELinux Policies

MySQL Server SELinux policy modules are typically installed by default. You can view installed modules using the 'semodule -l' command. MySQL Server SELinux policy modules include:

For information about MySQL Server SELinux policy modules, refer to the SELinux manual pages. The manual pages provide information about types and Booleans associated with the MySQL service. Manual pages are named in the 'SERVICE-NAME_selinux' format.

 man mysqld_selinux

If SELinux manual pages are not available, refer to your distribution's SELinux documentation for information about how to generate manual pages using the 'sepolicy manpage' utility.

 File: manual.info.tmp, Node: selinux-file-context, Next: selinux-context-tcp-port, Prev: selinux-policies, Up: selinux

6.7.4 SELinux File Context

The MySQL Server reads from and writes to many files. If the SELinux context is not set correctly for these files, access to the files could be denied.

The instructions that follow use the 'semanage' binary to manage file context; on RHEL, it's part of the 'policycoreutils-python-utils' package:

 yum install -y policycoreutils-python-utils

After installing the 'semanage' binary, you can list MySQL file contexts using 'semanage' with the 'fcontext' option.

 semanage fcontext -l | grep -i mysql

Setting the MySQL Data Directory Context

The default data directory location is '/var/lib/mysql/'; and the SELinux context used is 'mysqld_db_t'.

If you edit the configuration file to use a different location for the data directory, or for any of the files normally in the data directory (such as the binary logs), you may need to set the context for the new location. For example:

 semanage fcontext -a -t mysqld_db_t "/path/to/my/custom/datadir(/.*)?"
 restorecon -Rv /path/to/my/custom/datadir

 semanage fcontext -a -t mysqld_db_t "/path/to/my/custom/logdir(/.*)?"
 restorecon -Rv /path/to/my/custom/logdir

Setting the MySQL Error Log File Context

The default location for RedHat RPMs is '/var/log/mysqld.log'; and the SELinux context type used is 'mysqld_log_t'.

If you edit the configuration file to use a different location, you may need to set the context for the new location. For example:

 semanage fcontext -a -t mysqld_log_t "/path/to/my/custom/error.log"
 restorecon -Rv /path/to/my/custom/error.log

Setting the PID File Context

The default location for the PID file is '/var/run/mysqld/mysqld.pid'; and the SELinux context type used is 'mysqld_var_run_t'.

If you edit the configuration file to use a different location, you may need to set the context for the new location. For example:

 semanage fcontext -a -t mysqld_var_run_t "/path/to/my/custom/pidfile/directory/.*?"
 restorecon -Rv /path/to/my/custom/pidfile/directory

Setting the Unix Domain Socket Context

The default location for the Unix domain socket is '/var/lib/mysql/mysql.sock'; and the SELinux context type used is 'mysqld_var_run_t'.

If you edit the configuration file to use a different location, you may need to set the context for the new location. For example:

 semanage fcontext -a -t mysqld_var_run_t "/path/to/my/custom/mysql\.sock"
 restorecon -Rv /path/to/my/custom/mysql.sock

Setting the secure_file_priv Directory Context

For MySQL versions since 5.6.34, 5.7.16, and 8.0.11.

Installing the MySQL Server RPM creates a '/var/lib/mysql-files/' directory but does not set the SELinux context for it. The '/var/lib/mysql-files/' directory is intended to be used for operations such as 'SELECT ... INTO OUTFILE'.

If you enabled the use of this directory by setting 'secure_file_priv', you may need to set the context like so:

 semanage fcontext -a -t mysqld_db_t "/var/lib/mysql-files/(/.*)?"
 restorecon -Rv /var/lib/mysql-files

Edit this path if you used a different location. For security purposes, this directory should never be within the data directory.

For more information about this variable, see the 'secure_file_priv' documentation.

 File: manual.info.tmp, Node: selinux-context-tcp-port, Next: selinux-troubleshooting, Prev: selinux-file-context, Up: selinux

6.7.5 SELinux TCP Port Context

The instructions that follow use the 'semanage' binary to manage port context; on RHEL, it's part of the 'policycoreutils-python-utils' package:

 yum install -y policycoreutils-python-utils

After installing the 'semanage' binary, you can list ports defined with the 'mysqld_port_t' context using 'semanage' with the 'port' option.

 $> semanage port -l | grep mysqld
 mysqld_port_t                  tcp      1186, 3306, 63132-63164

 File: manual.info.tmp, Node: selinux-context-mysqld-tcp-port, Next: selinux-context-mysql-feature-ports, Prev: selinux-context-tcp-port, Up: selinux-context-tcp-port

6.7.5.1 Setting the TCP Port Context for mysqld ...............................................

The default TCP port for *note 'mysqld': mysqld. is '3306'; and the SELinux context type used is 'mysqld_port_t'.

If you configure *note 'mysqld': mysqld. to use a different TCP 'port', you may need to set the context for the new port. For example to define the SELinux context for a non-default port such as port 3307:

 semanage port -a -t mysqld_port_t -p tcp 3307

To confirm that the port is added:

 $> semanage port -l | grep mysqld
 mysqld_port_t                  tcp      3307, 1186, 3306, 63132-63164

 File: manual.info.tmp, Node: selinux-context-mysql-feature-ports, Prev: selinux-context-mysqld-tcp-port, Up: selinux-context-tcp-port

6.7.5.2 Setting the TCP Port Context for MySQL Features .......................................................

If you enable certain MySQL features, you might need to set the SELinux TCP port context for additional ports used by those features. If ports used by MySQL features do not have the correct SELinux context, the features might not function correctly.

The following sections describe how to set port contexts for MySQL features. Generally, the same method can be used to set the port context for any MySQL features. For information about ports used by MySQL features, refer to the MySQL Port Reference (https://dev.mysql.com/doc/mysql-port-reference/en/).

Setting the TCP Port Context for Group Replication

If SELinux is enabled, you must set the port context for the Group Replication communication port, which is defined by the 'group_replication_local_address' variable. *note 'mysqld': mysqld. must be able to bind to the Group Replication communication port and listen there. InnoDB Cluster relies on Group Replication so this applies equally to instances used in a cluster. To view ports currently used by MySQL, issue:

 semanage port -l | grep mysqld

Assuming the Group Replication communication port is 33061, set the port context by issuing:

 semanage port -a -t mysqld_port_t -p tcp 33061

Setting the TCP Port Context for Document Store

If SELinux is enabled, you must set the port context for the communication port used by X Plugin, which is defined by the 'mysqlx_port' variable. *note 'mysqld': mysqld. must be able to bind to the X Plugin communication port and listen there.

Assuming the X Plugin communication port is 33060, set the port context by issuing:

 semanage port -a -t mysqld_port_t -p tcp 33060

 File: manual.info.tmp, Node: selinux-troubleshooting, Prev: selinux-context-tcp-port, Up: selinux

6.7.6 Troubleshooting SELinux

Troubleshooting SELinux typically involves placing SELinux into permissive mode, rerunning problematic operations, checking for access denial messages in the SELinux audit log, and placing SELinux back into enforcing mode after problems are resolved.

To avoid placing the entire system into permissive mode using 'setenforce', you can permit only the MySQL service to run permissively by placing its SELinux domain ('mysqld_t') into permissive mode using the 'semanage' command:

 semanage permissive -a mysqld_t

When you are finished troubleshooting, use this command to place the 'mysqld_t' domain back into enforcing mode:

 semanage permissive -d mysqld_t

SELinux writes logs for denied operations to '/var/log/audit/audit.log'. You can check for denials by searching for 'denied' messages.

 grep "denied" /var/log/audit/audit.log

The following sections describes a few common areas where SELinux-related issues may be encountered.

File Contexts

If a MySQL directory or file has an incorrect SELinux context, access may be denied. This issue can occur if MySQL is configured to read from or write to a non-default directory or file. For example, if you configure MySQL to use a non-default data directory, the directory may not have the expected SELinux context.

Attempting to start the MySQL service on a non-default data directory with an invalid SELinux context causes the following startup failure.

 $> systemctl start mysql.service
 Job for mysqld.service failed because the control process exited with error code.
 See "systemctl status mysqld.service" and "journalctl -xe" for details.

In this case, a 'denial' message is logged to '/var/log/audit/audit.log':

 $> grep "denied" /var/log/audit/audit.log
 type=AVC msg=audit(1587133719.786:194): avc:  denied  { write } for  pid=7133 comm="mysqld"
 name="mysql" dev="dm-0" ino=51347078 scontext=system_u:system_r:mysqld_t:s0
 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir permissive=0

For information about setting the proper SELinux context for MySQL directories and files, see *note selinux-file-context::.

Port Access

SELinux expects services such as MySQL Server to use specific ports. Changing ports without updating the SELinux policies may cause a service failure.

The 'mysqld_port_t' port type defines the ports that the MySQL listens on. If you configure the MySQL Server to use a non-default port, such as port 3307, and do not update the policy to reflect the change, the MySQL service fails to start:

 $> systemctl start mysqld.service
 Job for mysqld.service failed because the control process exited with error code.
 See "systemctl status mysqld.service" and "journalctl -xe" for details.

In this case, a denial message is logged to '/var/log/audit/audit.log':

 $> grep "denied" /var/log/audit/audit.log
 type=AVC msg=audit(1587134375.845:198): avc:  denied  { name_bind } for  pid=7340
 comm="mysqld" src=3307 scontext=system_u:system_r:mysqld_t:s0
 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0

For information about setting the proper SELinux port context for MySQL, see note selinux-context-tcp-port::. Similar port access issues can occur when enabling MySQL features that use ports that are not defined with the required context. For more information, see note selinux-context-mysql-feature-ports::.

Application Changes

SELinux may not be aware of application changes. For example, a new release, an application extension, or a new feature may access system resources in a way that is not permitted by SELinux, resulting in access denials. In such cases, you can use the 'audit2allow' utility to create custom policies to permit access where it is required. The typical method for creating custom policies is to change the SELinux mode to permissive, identify access denial messages in the SELinux audit log, and use the 'audit2allow' utility to create custom policies to permit access.

For information about using the 'audit2allow' utility, refer to your distribution's SELinux documentation.

If you encounter access issues for MySQL that you believe should be handled by standard MySQL SELinux policy modules, please open a bug report in your distribution's bug tracking system.

 File: manual.info.tmp, Node: backup-and-recovery, Next: optimization, Prev: security, Up: Top

7 Backup and Recovery *********************

It is important to back up your databases so that you can recover your data and be up and running again in case problems occur, such as system crashes, hardware failures, or users deleting data by mistake. Backups are also essential as a safeguard before upgrading a MySQL installation, and they can be used to transfer a MySQL installation to another system or to set up replica servers.

MySQL offers a variety of backup strategies from which you can choose the methods that best suit the requirements for your installation. This chapter discusses several backup and recovery topics with which you should be familiar:

Additional Resources

Resources related to backup or to maintaining data availability include the following:

 File: manual.info.tmp, Node: backup-types, Next: backup-methods, Prev: backup-and-recovery, Up: backup-and-recovery