11.9.4.1. MySQL Changing Database Location
When using Fedora 12, the default location for MySQL to store its database is /var/lib/mysql
. This is where SELinux expects it to be by default, and hence this area is already labeled appropriately for you, using the mysqld_db_t
type.
The area where the database is located can be changed depending on individual environment requirements or preferences, however it is important that SELinux is aware of this new location - that it is labeled accordingly. This example explains how to change the location of a MySQL database and then how to label the new location so that SELinux can still provide its protection mechanisms to the new area based on its contents.
Note that this is an example only and demonstrates how SELinux can affect MySQL. Comprehensive documentation of MySQL is beyond the scope of this document. Refer to the official
MySQL documentation for further details. This example assumes that the
mysql-server package is installed and that there is a valid database in the default location of
/var/lib/mysql
.
Run
ls -lZ /var/lib/mysql
to view the SELinux context of the default database location for
mysql
:
# ls -lZ /var/lib/mysql
drwx------. mysql mysql unconfined_u:object_r:mysqld_db_t:s0 mysql
This shows mysqld_db_t
which is the default context element for the location of database files. This context will have to be manually applied to the new database location that will be used in this example in order for it to function properly.
Enter
mysqlshow -u root -p
and enter the
mysqld
root password to show the available databases:
# mysqlshow -u root -p
Enter password: *******
+--------------------+
| Databases |
+--------------------+
| information_schema |
| mysql |
| test |
| wikidb |
+--------------------+
Shut down the
mysqld
daemon with
service mysqld stop
as the root user:
# service mysqld stop
Stopping MySQL: [ OK ]
Create a new directory for the new location of the database(s). In this example,
/opt/mysql
is used:
# mkdir -p /opt/mysql
Copy the database files from the old location to the new location:
# cp -R /var/lib/mysql/* /opt/mysql/
Change the ownership of this location to allow access by the mysql user and group. This sets the traditional Unix permissions which SELinux will still observe.
# chown -R mysql:mysql /opt/mysql
Run
ls -lZ /opt
to see the initial context of the new directory:
# ls -lZ /opt
drwxr-xr-x. mysql mysql unconfined_u:object_r:usr_t:s0 mysql
The context usr_t
of this newly created directory is not currently suitable to SELinux as a location for MySQL database files. Once the context has been changed, MySQL will be able to function properly in this area.
Open the main MySQL configuration file
/etc/my.cnf
with a text editor and modify the
datadir
option so that it refers to the new location. In this example the value that should be entered is
/opt/mysql
.
[mysqld]
datadir=/opt/mysql
Save this file and exit.
Run
service mysqld start
as the root user to start
mysqld
. At this point a denial will be logged to
/var/log/messages
:
# service mysqld start
Timeout error occurred trying to start MySQL Daemon.
Starting MySQL: [FAILED]
# tail -f /var/log/messages
localhost setroubleshoot: SELinux is preventing mysqld (mysqld_t) "write" usr_t. For complete SELinux messages. run sealert -l 50d8e725-994b-499c-9caf-a676c50fb802
The reason for this denial is that /opt/mysql
is not labeled correctly for MySQL data files. SELinux is stopping MySQL from having access to the content labeled as usr_t
. Perform the following steps to resolve this problem:
Run the
semanage
command to add a context mapping for
/opt/mysql
:
semanage fcontext -a -t mysqld_db_t "/opt/mysql(/.*)?"
This mapping is written to the
/etc/selinux/targeted/contexts/files/file_contexts.local
file:
# grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local
/opt/mysql(/.*)? system_u:object_r:mysqld_db_t:s0
Now use the
restorecon
command to apply this context mapping to the running system:
restorecon -R -v /opt/mysql
Now that the
/opt/mysql
location has been labeled with the correct context for MySQL, the
mysqld
daemon starts:
# service mysqld start
Starting MySQL: [ OK ]
Confirm the context has changed for
/opt/mysql
:
ls -lZ /opt
drwxr-xr-x. mysql mysql system_u:object_r:mysqld_db_t:s0 mysql
The location has been changed and labeled, and the mysqld
daemon has started successfully. At this point all running services should be tested to confirm normal operation.