Securing MySQL on LinuxHow to install MySQL securely with Apache on a Linux server.
by Mike Peters, August 2004 Introduction MySQL is a very popular open source database. Due to its speed and stability it is used on millions of servers world wide. MySQL has a simple and effective security mechanism, however, many measures need to be taken to make a default installation secure. Whilst the measures described below will enable you to secure your database it is also important that you secure the underlying operating system as much as possible too. Installation It is important to run MySQL as its own user. In order to do so we need to create such a user and group. # groupadd mysql # useradd -c "MySQL Server" -d /dev/null -g mysql -s /bin/false mysql Install MySQL in
./configure --prefix=/usr/local/mysql --with-mysqld-user=mysql \
--with-unix-socket-path=/tmp/mysql.sock --with-mysqld-ldflags=-all-static
make
su
make install
strip /usr/local/mysql/libexec/mysqld
scripts/mysql_install_db
chown -R root /usr/local/mysql
chown -R mysql /usr/local/mysql/var
chgrp -R mysql /usr/local/mysql
The configure option
Copy the example configuration file from the MySQL source, Once we have MySQL installed, test the installation. Start MySQL with
Chrooting MySQL First, create the necessary directory structure for the database.
Now set the correct directory permissions chown -R root:sys /chroot/mysql chmod -R 755 /chroot/mysql chmod 1777 /chroot/mysql/tmp Once the directories are set up, copy the server's files: cp /usr/local/mysql/libexec/mysqld /chroot/mysql/usr/local/mysql/libexec/ cp /usr/local/mysql/share/mysql/english/errmsg.sys /chroot/mysql/usr/local/mysql/share/mysql/english/ cp -r /usr/local/mysql/share/mysql/charsets /chroot/mysql/usr/local/mysql/share/mysql/ cp /etc/hosts /chroot/mysql/etc/ cp /etc/host.conf /chroot/mysql/etc/ cp /etc/resolv.conf /chroot/mysql/etc/ cp /etc/group /chroot/mysql/etc/ cp /etc/master.passwd /chroot/mysql/etc/passwords cp /etc/my.cnf /chroot/mysql/etc/ Finally, copy the cp -R /usr/local/mysql/var/ /chroot/mysql/usr/local/mysql/var chown -R mysql:mysql /chroot/mysql/usr/local/mysql/var As with Apache, we need to create null device: mknod /chroot/mysql/dev/null c 2 2 chown root:sys /chroot/mysql/dev/null chmod 666 /chroot/mysql/dev/null We need to edit the password and groups files to remove any entries bar the mysql user and group. /etc/passwd: mysql:x:12347:12348:MySQL Server:/dev/null:/bin/false /etc/group: mysql:x:12347: In order for PHP to be able to access MySQL we need to create a link to
mysql.sock, To run MySQL in a chrooted environment as a user other than root, we need the
chrootuid program. Once we have
installed chrootuid, test the server: The MySQL root User and Default Accounts The MySQL root user should not be confused with the system root user. By default, the MySQL root user has no
password. You can check this with To set the initial root password open a
mysql> UPDATE user SET Password=PASSWORD('new_password')
-> WHERE user='root';
mysql> FLUSH PRIVILEGES;
Don't forget to As well as setting the root password, we should remove anonymous accounts: mysql> DELETE FROM user WHERE User = ''; mysql> FLUSH PRIVILEGES; Alternatively set a password for the anonymous accounts:
mysql> UPDATE user SET Password = PASSWORD('new_password')
-> WHERE User = '';
mysql> FLUSH PRIVILEGES;
MySQL Privilege System and MySQL Users The MySQL privilege system allows for authentication of users connecting from specific hosts. Authenticated users can be assigned privileges such as SELECT, INSERT, UPDATE, DELETE etc on a per database, table, column or host basis. When a user connects, MySQL first checks if that user is authorized to connect, based on the host and supplied password. If the user is allowed to connect, MySQL will then check each statement to see if the user is allowed to perform the requested action. When creating new MySQL users, always give the user a strong password and never store passwords as plain text. Only allow the minimum amount of privileges for a user to accomplish a task and set those privileges on a per database basis. Some extra time spent planning what privileges to assign to users will go a long way in ensuring the security of your data. You can create a new user with specific privileges using the
GRANT USAGE ON myapp.* TO 'someuser'@'localhost' IDENTIFIED BY 'some_pass'; FLUSH PRIVILEGES; This statement will create a user MySQL named
MySQL access privileges are stored in the grant tables of the The You can change privileges using an SQL
UPDATE user SET Host='localhost', Password=PASSWORD('new_pass'),
Reload_priv='Y', Process_priv='Y' WHERE
User='admin';
FLUSH PRIVILEGES;
Of the different privileges, most are self-explanatory, however some bear
special consideration. The The Privileges which system administrative rights or database administrative rights,
such as The other tables in the
One final thing to note is that, if you don't completely trust your DNS, use IP numbers in grant tables in place of host names. This makes it more difficult to spoof hosts. Local Security There are a number of measures we need to take to improve security on the
local machine. Most importantly, never run mysqld as root as, among other
risks, any user with the We should also make sure that only the The mysql command history is stored in $HOME/.mysql_history. This may show up sensitive
information such as passwords. You should clear the file with
If you are only using MySQL on the local machine, for example, for PHP web based
applications, in We can also disable the use of the LOAD DATA LOCAL INFILE command which
allows reading of local files and is potentially dangerous. Add the line
Finally, add the line Securing Remote Access The most important step in securing remote access to your MySQL server is in having a firewall. Your firewall should only allow trusted hosts access to MySQL's port, 3306. Better still, is to firewall off your MySQL server altogether and only allow access through an SSH tunnel as described below. Always use passwords for user accounts, even for trusted client programs. The password in a mysql connection is sent encrypted, however, in versions prior to 4.1.1 encryption was not particularly strong. In version 4.1.1 the encryption algorithm was much improved. Even though the password is sent encrypted, data is sent as
plain text. If you are connecting across an untrusted network, you should use an SSH
encrypted tunnel. SSH tunneling allows us to connect to a MySQL server from behind a firewall, even when
the MySQL port is blocked. To set up tunnel, use the command
Backup It is important to make regular backups of your databases. MySQL includes two
utilities which make this easy, To use
mysqldump [options] db_name [tables] mysqldump [options] --databases DB1 [DB2 DB3...] mysqldump [options] --all-databases For example, you can back-up all your databases and compress them in one go
with the command:
The To restore a database from a file created by mysqldump you just need
Server Startup The following script can be used for starting your MySQL server.
#!/bin/sh
CHROOT_MYSQL=/chroot/mysql
CHROOT_PHP=/chroot/httpd
SOCKET=/tmp/mysql.sock
MYSQLD=/usr/local/mysql/libexec/mysqld
PIDFILE=/usr/local/mysql/var/`hostname`.pid
CHROOTUID=/usr/local/sbin/chrootuid
echo -n " mysql"
case "$1" in
start)
rm -rf ${CHROOT_PHP}/${SOCKET}
nohup ${CHROOTUID} ${CHROOT_MYSQL} mysql ${MYSQLD} >/dev/null 2>&1 &
sleep 5 && ln ${CHROOT_MYSQL}/${SOCKET} ${CHROOT_PHP}/${SOCKET}
;;
stop)
kill `cat ${CHROOT_MYSQL}/${PIDFILE}`
rm -rf ${CHROOT_MYSQL}/${SOCKET}
;;
*)
echo ""
echo "Usage: `basename $0` {start|stop}" >&2
exit 64
;;
esac
exit 0
Summary The procedures we have seen will reduce the risk of a potential break in to our database server. MySQL's extensive privilege system allows us to protect the data stored within our database. As always we should remain diligent, and be sure to apply patches and upgrades to our server as and when they become available. |
Save This Page
|
|


Save This Page