Skip to content
logo
Percona Server for MySQL
Working with SELinux
Initializing search
    percona/psmysql-docs
    percona/psmysql-docs
    • Home
      • The Percona XtraDB storage engine
      • List of features available in Percona Server for MySQL releases
      • Percona Server for MySQL feature comparison
      • Changed in Percona Server 8.0
      • Understand version numbers
      • Install Percona Server for MySQL
        • Install using APT repository
        • Files in DEB package
        • Build APT packages
        • Install from downloaded DEB packages
        • Apt pinning
        • Run Percona Server for MySQL
        • Uninstall
        • Install using a RPM repository
        • Files in RPM package
        • Install from downloaded RPM packages
        • Run Percona Server for MySQL
        • Uninstall
        • Install with binary tarballs
        • Binary tarballs available
        • Install Percona Server for MySQL from a source tarball
        • Compile Percona Server for MySQL 8.0 from source
      • Post-installation
      • Percona Server for MySQL in-place upgrading guide: from 5.7 to 8.0
      • Upgrade using the Percona repositories
      • Upgrade from systems that use the MyRocks or TokuDB storage engine and partitioned tables
      • Upgrade using Standalone Packages
      • Downgrade Percona Server for MySQL
      • Running Percona Server for MySQL in a Docker Container
      • Docker environment variables
      • Improved InnoDB I/O scalability
      • Adaptive network buffers
      • Multiple page asynchronous I/O requests
      • Thread pool
      • XtraDB performance improvements for I/O-bound highly-concurrent workloads
      • Prefix index queries optimization
      • Limit the estimation of records in a Query
      • Jemalloc memory allocation profiling
      • The ProcFS plugin
      • Binary logs and replication improvements
      • Compressed columns with dictionaries
      • Extended SELECT INTO OUTFILE/DUMPFILE
      • Extended SET VAR optimizer hint
      • Improved MEMORY storage engine
      • Suppress warning messages
      • Limiting the disk space used by binary log files
      • Support for PROXY protocol
      • SEQUENCE_TABLE(n) function
      • Slow query log rotation and expiration
      • Trigger updates
      • Extended mysqlbinlog
      • Extended mysqldump
      • InnoDB full-text search improvements
      • Too many connections warning
      • Handle corrupted tables
      • Percona Toolkit UDFs
      • Kill idle transactions
      • XtraDB changed page tracking
      • Enforcing storage engine
      • Expanded fast index creation
      • Backup locks
      • Audit log plugin
      • Start transaction with consistent snapshot
      • Extended SHOW GRANTS
      • Utility user
      • Working with SELinux
        • SELinux context example
        • List SELinux types or domains associated with files
        • SELinux modes
        • Policy types
        • Check the SELinux mode
        • Disable SELinux
        • Additional SELinux tools
        • Switch the mode in the configuration file
        • Switch the mode until the next reboot
        • Switch the mode for a service
        • Relabel the entire file system
        • Set a custom data directory
        • Set a custom log location
        • Set secure_file_priv directory
      • Working with AppArmor
      • PAM authentication plugin
      • Server variables
      • SSL improvements
      • Data masking
        • Using LDAP authentication plugins
        • LDAP authentication plugin system variables
        • Data at Rest Encryption
        • Use the keyring component or keyring plugin
          • Using the Key Management Interoperability Protocol (KMIP)
          • Use the Amazon Key Management Service (AWS KMS)
          • FIDO authentication plugin
        • Encryption functions
        • Encrypt File-Per-Table Tablespace
        • Encrypt schema or general tablespace
        • Encrypt system tablespace
        • Encrypt temporary files
        • Encrypt Binary Log Files and Relay Log Files
        • Encrypting the Redo Log data
        • Encrypt the undo tablespace
        • Rotate the master key
        • Advanced encryption key rotation
        • Encrypt doublewrite buffers
        • Verify the encryption for tables, tablespaces, and schemas
      • User statistics
      • Slow query log
      • Extended show engine InnoDB status
      • Show storage engines
      • Process list
      • Misc. INFORMATION_SCHEMA tables
      • Thread based profiling
      • InnoDB page fragmentation counters
      • Stacktrace
      • Libcoredumper
      • Manage group replication flow control
      • Group replication system variables
      • Percona MyRocks introduction
      • Percona MyRocks installation guide
      • Updated supported features
      • MyRocks limitations
      • Differences between Percona MyRocks and Facebook MyRocks
      • MyRocks Information Schema tables
      • MyRocks server variables
      • MyRocks status variables
      • Gap locks detection
      • Data loading
      • Installing and configuring Percona Server for MySQL with ZenFS support
      • TokuDB introduction
      • TokuDB installation
      • Use TokuDB
      • Fast updates with TokuDB
      • TokuDB files and file types
      • TokuDB file management
      • TokuDB background ANALYZE TABLE
      • TokuDB variables
      • TokuDB status variables
      • TokuDB fractal tree indexing
      • TokuDB troubleshooting
      • TokuDB Performance Schema integration
      • Frequently asked questions
      • Migrate and removing the TokuDB storage engine
      • Percona TokuBackup
      • Release notes index
      • Percona Server for MySQL 8.0.32-24 (2023-03-20)
      • Percona Server for MySQL 8.0.31-23 (2023-02-09)
      • Percona Server for MySQL 8.0.30-22 Update (2022-11-21)
      • Percona Server for MySQL 8.0.30-22 (2022-11-21)
      • Percona Server for MySQL 8.0.29-21 (2022-08-08)
      • Percona Server for MySQL 8.0.28-20 (2022-06-20)
      • Percona Server for MySQL 8.0.28-19 (2022-05-12)
      • Percona Server for MySQL 8.0.27-18 (2022-03-02)
      • Percona Server for MySQL 8.0.26-17 (2022-01-26)
      • Percona Server for MySQL 8.0.26-16 (2021-10-20)
      • Percona Server for MySQL 8.0.25-15 (2021-07-13)
      • Percona Server for MySQL 8.0.23-14 (2021-05-12)
      • Percona Server for MySQL 8.0.22-13 (2020-12-14)
      • Percona Server for MySQL 8.0.21-12 (2020-10-13)
      • Percona Server for MySQL 8.0.20-11 (2020-07-21)
      • Percona Server for MySQL 8.0.19-10 (2020-03-23)
      • Percona Server for MySQL 8.0.18-9
      • Percona Server for MySQL 8.0.17-8
      • Percona Server for MySQL 8.0.16-7
      • Percona Server for MySQL 8.0.15-6
      • Percona Server for MySQL 8.0.15-5
      • Percona Server for MySQL 8.0.14
      • Percona Server for MySQL 8.0.13-4
      • Percona Server for MySQL 8.0.13-3
      • Percona Server for MySQL 8.0.12-2rc1
      • List of variables introduced in Percona Server for MySQL 8.0
      • Development of Percona Server for MySQL
      • Trademark policy
      • Index of INFORMATION_SCHEMA tables
      • Frequently asked questions
      • Copyright and licensing information
      • Glossary

    • SELinux context example
    • List SELinux types or domains associated with files
    • SELinux modes
    • Policy types
    • Check the SELinux mode
    • Disable SELinux
    • Additional SELinux tools
    • Switch the mode in the configuration file
    • Switch the mode until the next reboot
    • Switch the mode for a service
    • Relabel the entire file system
    • Set a custom data directory
    • Set a custom log location
    • Set secure_file_priv directory

    Working with SELinux¶

    The Linux kernel, through the Linux Security Module (LSM), supports Security-Enhanced Linux (SELinux). This module provides a way to support mandatory access control policies. SELinux defines how confined processes interact with files, network ports, directories, other processes, and additional server components.

    An SELinux policy defines the set of rules, the types for files, and the domains for processes. Rules determine how a process interacts with another type. SELinux decides whether to allow or deny an action based on the subject’s context, what object initiates the action and what object is the action’s target.

    A label represents the context for administrators and users.

    CentOS 7 and CentOS 8 contain a MySQL SELinux policy. Percona Server for MySQL is a drop-in replacement for MySQL and can use this policy without changes.

    SELinux context example¶

    To view the SELinux context, add the -Z switch to many of the utilities. Here is an example of the context for mysqld:

    $ ps -eZ | grep mysqld_t
    
    Expected output
    system_u:system_r:mysqld_t:s0    3356 ?        00:00:01 mysqld
    

    The context has the following properties:

    • User - system_u

    • Role - system_r

    • Type or domain - mysqld_t

    • Sensitivity level - s0 3356

    Most SELinux policy rules are based on the type or domain.

    List SELinux types or domains associated with files¶

    The security property that SELinux relies on is the Type security property. The type name often end with a _t. A group of objects with the same type security value belongs to the same domain.

    To view the mysqldb_t types associated with the MySQL directories and files, run the following command:

    $ ls -laZ /var/lib/ | grep mysql
    
    Expected output
    drwxr-x--x. mysql   mysql   system_u:object_r:mysqld_db_t:s0 mysql
    drwxr-x---. mysql   mysql   system_u:object_r:mysqld_db_t:s0 mysql-files
    drwxr-x---. mysql   mysql   system_u:object_r:mysqld_db_t:s0 mysql-keyring
    

    Note

    If a policy type does not define the type property for an object, the default value is unconfined_t.

    SELinux modes¶

    SELinux has the following modes:

    • Disabled - No SELinux policy modules loaded, which disables policies. Nothing is reported.

    • Permissive - SELinux is active, but policy modules are not enforced. A policy violation is reported but does not stop the action.

    • Enforcing - SELinux is active, and violations are reported and denied. If there is no rule to allow access to a confined resource, SELinux denies the access.

    Policy types¶

    SELinux has several policy types:

    • Targeted - Most processes operate without restriction. Specific services are contained in security domains and defined by policies.

    • Strict - All processes are contained in security domains and defined by policies.

    SELinux has confined processes that run in a domain and restricts everything unless explicitly allowed. An unconfined process in an unconfined domain is allowed almost all access.

    MySQL is a confined process, and the policy module defines which files are read, which ports are opened, and so on. SELinux assumes the Percona Server for MySQL installation uses the default file locations and default ports.

    If you change the default, you must also edit the policy. If you do not update the policy, SELinux, in enforcing mode, denies access to all non-default resources.

    Check the SELinux mode¶

    To check the current SELinux mode, use either of the following commands:

    $ sestatus
    
    Expected output
    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
    

    or

    $ grep ^SELINUX= /etc/selinux/config
    
    Expected output
    SELINUX=enforcing
    

    Note

    Add the -b parameter to sestatus to display the Policy booleans. The boolean values for each parameter is shown. An example of using the b parameter is the following:

    $ sestatus -b | grep mysql
    
    Expected output
    mysql_connect_any                           off
    selinuxuser_mysql_connect_enabled
    

    The /etc/selinux/config file controls if SELinux is disabled or enabled, and if enabled, whether SELinux operates in enforcing mode or permissive mode.

    Disable SELinux¶

    If you plan to use the enforcing mode at another time, use the permissive mode instead of disabling SELinux. During the time that SELinux is disabled, the system may contain mislabeled objects or objects with no label. If you re-enable SELinux and plan to set SELinux to enforcing, you must follow the steps to Relabel the entire file system.

    On boot, to disable SELinux, set the selinux=0 kernel option. The kernel does not load the SELinux infrastructure. This option has the same effect as changing the SELINUX=disabled instruction in the configuration file and then rebooting the system.

    Additional SELinux tools¶

    Install the SELinux management tools, such as semanage or sesearch, if needed.

    On RHEL 7 or compatible operating systems, use the following command as root:

    $ yum -y install policycoreutils-python
    

    On RHEL 8 or compatible operating systems, use the following command as root:

    $ yum -y install policycoreutils-python-utils
    

    Note

    You may need root privileges to run SELinux management commands.

    Switch the mode in the configuration file¶

    Switching between modes may help when troubleshooting or when modifying rules.

    To permanently change the mode, edit the /etc/selinux/config file and change the SELINUX= value. You should also verify the change.

    $ cat /etc/selinux/config | grep SELINUX= | grep -v ^#
    
    Expected output
    SELINUX=enforcing
    SELINUX=enforcing
    
    $ sudo sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
    
    $ cat /etc/selinux/config | grep SELINUX= | grep -v ^#
    
    Expected output
    SELINUX=permissive
    SELINUX=permissive
    

    Reboot your system after the change.

    If switching from either disabled mode or permissive mode to enforcing, see Relabel the entire file system.

    Switch the mode until the next reboot¶

    To change the mode until the next reboot, use either of the following commands as root:

    $ setenforce Enforcing
    

    or

    $ setenforce 1
    

    The following setenforce parameters are available:

    setenforce parameters Also Permitted
    0 Permissive
    1 Enforcing

    You can view the current mode by running either of the following commands:

    $ getenforce
    
    Expected output
    Enforcing
    

    or

    $ sestatus | grep -i mode
    
    Expected output
    Current mode:                   permissive
    Mode from config file:          enforcing
    

    Switch the mode for a service¶

    You can move one or more services into a permissive domain. The other services remain in enforcing mode.

    To add a service to the permissive domain, run the following as root:

    $ sudo semanage permissive -a mysqld_t
    

    To list the current permissive domains, run the following command:

    $ sudo semanage permissive -l
    
    Expected output
    ...
    Customized Permissive Types
    
    mysqld_t
    
    Builtin Permissive Types
    

    To delete a service from the permissive domain, run the following:

    $ sudo semanage permissive -d mysqld_t
    

    The service returns to the system’s SELinux mode. Be sure to follow the steps to Relabel the entire file system.

    Relabel the entire file system¶

    Switching from disabled or permissive to enforcing requires additional steps. The enforcing mode requires the correct contexts, or labels, to function. The permissive mode allows users and processes to label files and system objects incorrectly. The disabled mode does not load the SELinux infrastructure and does not label resources or processes.

    RHEL and compatible systems, use the fixfiles application for relabeling. You can relabel the entire file system or the file contexts of an application.

    For one application, run the following command:

    $ fixfiles -R mysqld restore
    

    To relabel the file system without rebooting the system, use the following command:

    $ fixfiles -f -F relabel
    

    Another option relabels the file system during a reboot. You can either add a touch file, read during the reboot operation, or configure a kernel boot parameter. The completion of the relabeling operation automatically removes the touch file.

    Add the touch file as root:

    $ touch /.autorelabel
    

    To configure the kernel, add the autorelabel=1 kernel parameter to the boot parameter list. The parameter forces a system relabel. Reboot in permissive mode to allow the process to complete before changing to enforcing.

    Note

    Relabeling an entire filesystem takes time. When the relabeling is complete, the system reboots again.

    Set a custom data directory¶

    If you do not use the default settings, SELinux, in enforcing mode, prevents access to the system.

    For example, during installation, you have used the following configuration:

    datadir=/var/lib/mysqlcustom
    socket=/var/lib/mysqlcustom/mysql.sock
    

    Restart the service.

    $ service mysqld restart
    
    Expected output
      Redirecting to /bin/systemctl restart 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.
    

    Check the journal log to see the error code.

    $ journalctl -xe
    
    Expected output
    ...
    SELinux is preventing mysqld from getattr access to the file /var/lib/mysqlcustom/ibdata1.
    ...
    

    Check the SELinux types in /var/lib/mysqlcustom.

    ls -1aZ /var/lib/mysqlcustom
    
    Expected output
      total 164288
      drwxr-x--x.  6 mysql mysql system_u:object_r:var_lib_t:s0       4096 Dec  2 07:58  .
      drwxr-xr-x. 38 root  root  system_u:object_r:var_lib_t:s0       4096 Dec  1 14:29  ..
      ...
      -rw-r-----.  1 mysql mysql system_u:object_r:var_lib_t:s0   12582912 Dec  1 14:29  ibdata1
      ...
    

    To solve the issue, use the following methods:

    • Set the proper labels for mysqlcustom files

    • Change the mysqld SELinux policy to allow mysqld access to var_lib_t files.

    The recommended solution is to set the proper labels. The following procedure assumes you have already created and set ownership to the custom data directory location:

    1. To change the SELinux context, use semanage fcontext. In this step, you define how SELinux deals with the custom paths:

      $ semanage fcontext -a -e /var/lib/mysql /var/lib/mysqlcustom
      

      SELinux applies the same labeling schema, defined in the mysqld policy, for the /var/lib/mysql directory to the custom directory. Files created within the custom directory are labeled as if they were in /var/lib/mysql.

    2. To restorecon command applies the change.

      $ restorecon -R -v /var/lib/mysqlcustom
      
    3. Restart the mysqld service:

      $ service mysqld start
      

    Set a custom log location¶

    If you do not use the default settings, SELinux, in enforcing mode, prevents access to the location. Change the log location to a custom location in my.cnf:

    log-error=/logs/mysqld.log
    

    Verify the log location with the following command:

    $ ls -laZ /
    
    Expected output
      ...
      drwxrwxrwx.   2 root root unconfined_u:object_r:default_t:s0    6 Dec  2 09:16 logs
      ...
    

    Starting MySQL returns the following message:

    $ service mysql start
    
    Expected output
    Redirecting to /bin/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.
    
    $ journalctl -xe
    ...
    SELinux is preventing mysqld from write access to the directory logs.
    ...
    

    The default SELinux policy allows mysqld to write logs into a location tagged with var_log_t, which is the /var/log location. You can solve the issue with either of the following methods:

    • Tag the /logs location properly

    • Edit the SELinux policy to allow mysqld access to all directories.

    To tag the custom /logs location is the recommended method since it locks down access. Run the following commands to tag the custom location:

    $ semanage fcontext -a -t var_log_t /logs
    $ restorecon -v /logs
    

    You may not be able to change the /logs directory label. For example, other applications, with their own rules, use the same directory.

    To adjust the SELinux policy when a directory is shared, follow these steps:

    1. Create a local policy:

      ausearch -c 'mysqld' --raw | audit2allow -M my-mysqld
      
    2. This command generates the my-mysqld.te and the my-mysqld.pp files. The mysqld.te is the type enforcement policy file. The my-mysqld.pp is the policy module loaded as a binary file into the SELinux subsystem.

      An example of the my-myslqd.te file:

      module my-mysqld 1.0;
      
      require {
          *type mysqld_t*;
          type var_lib_t;
          *type default_t*;
          class file getattr;
          *class dir write*;
      }
      
      #============= mysqld_t ==============
      *allow mysqld_t default_t:dir write*;
      allow mysqld_t var_lib_t:file getattr;
      

      The policy contains rules for the custom data directory and the custom logs directory. We have set the proper labels for the data directory location, and applying this auto-generated policy would loosen our hardening by allowing mysqld to access var_lib_t tags.

    3. SELinux-generated events are converted to rules. A generated policy may contain rules for recent violations and include unrelated rules. Unrelated rules are generated from actions, such as changing the data directory location, that are not related to the logs directory. Add the --start parameter to use log events after a specific time to filter out the unwanted events. This parameter captures events when the time stamp is equal to the specified time or later. SELinux generates a policy for the current actions.

      $ ausearch --start 10:00:00 -c 'mysqld' --raw | audit2allow -M my-mysqld
      
    4. This policy allows mysqld writing into the tagged directories. Open the my_mysqld file:

      module my-mysqld 1.0;
      
      require {
          type mysqld_t;
          type default_t;
          class dir write;
      }
      
      #============= mysqld_t ==============
      allow mysqld_t default_t:dir write;
      
    5. Install the SELinux policy module:

      $ semodule -i my-mysqld.pp
      

    Restart the service. If you have a failure, check the journal log and follow the same procedure.

    If SELinux prevents mysql from creating a log file inside the directory. You can view all the violations by changing the SELinux mode to permissive and then running mysqld. All violations are logged in the journal log. After this run, you can generate a local policy module, install it, and switch SELinux back to enforcing mode. Follow this procedure:

    1. Unload the current local my-mysqld policy module:

      $ semodule -r my-mysqld
      
    2. You can put a single domain into permissive mode. Other domains on the system to remain in enforcing mode. Use semanage permissive with the -a parameter to change mysqld_t to permissive mode:

      $ semanage permissive -a mysqld_t
      
    3. Verify the mode change:

      $ semdule -l | grep permissive
      
      Expected output
      ...
      permissive_mysqld_t
      ...
      
    4. To make searching the log easier, return the time:

      $ date
      
    5. Start the service.

      $ service mysqld start
      
    6. MySQL starts, and SELinux logs the violations in the journal log. Check the journal log:

      $ journalctl -xe
      
    7. Stop the service:

      $ service mysqld stop
      
    8. Generate a local mysqld policy, using the time returned from step 4:

      $ ausearch --start <date-c 'mysqld' --raw | audit2allow -M my-mysqld
      
    9. Review the policy (the policy you generate may be different):

      $ cat my-mysqld.te
      
      Expected output
      module my-mysqld 1.0;
      
      require {
      type default_t;
          type mysqld_t;
          class dir { add_name write };
          class file { append create open };
      }
      
      #============= mysqld_t ==============
      allow mysqld_t default_t:dir { add_name write };
      allow mysqld_t default_t:file { append create open };
      
    10. Install the policy:

      $ semodule -i my-mysqld.pp
      
    11. Use semanage permissive with the -d parameter, which deletes the permissive domain for the service:

      $ semanage permissive -d mysqld_t
      
    12. Restart the service:

      $ service mysqld start
      

    Note

    Use this procedure to adjust the local mysqld policy module. You should review the changes which are generated to ensure the rules are not too tolerant.

    Set secure_file_priv directory¶

    Update the SELinux tags for the /var/lib/mysql-files/ directory, used for SELECT ... INTO OUTFILE or similar operations, if required. The server needs only read/write access to the destination directory.

    To set secure_file_priv to use this directory, run the following commands to set the context:

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

    Edit the path for a different location, if needed.

    Contact us

    For free technical help, visit the Percona Community Forum.

    To report bugs or submit feature requests, open a JIRA ticket.

    For paid support and managed or consulting services , contact Percona Sales.


    Last update: 2023-01-17
    Percona LLC and/or its affiliates, © 2023
    Made with Material for MkDocs

    Cookie consent

    We use cookies to recognize your repeated visits and preferences, as well as to measure the effectiveness of our documentation and whether users find what they're searching for. With your consent, you're helping us to make our documentation better.