Chrooting is a verb created from the chroot(2) system call, which is a call made by processes that want to change the root of the file system they will see from then on.
When a process requests to chroot to a given directory, any future system calls issued by the process will see that directory as the file system root. It therefore becomes impossible for that process to access files and binaries outside the tree rooted on the new root directory. This environment is known as a chroot jail.
Running MySQL in a chrooted environment is another layer of security that starts with running your MySQL Cluster process as a different user (mysql). If you have MySQL running in a chrooted environment, you make it exceptionally difficult for a hacker to take the system down or take control of the system, even if the hacker manages to take control of the process via a vulnerability such as a buffer overflow.
It is not currently possible (as far as we can tell) to run the MySQL Cluster daemons in a chrooted environment, but you should run your SQL nodes in such an environment if at all possible. If you are trying to do this, it helps if you compile MySQL by using --with-mysqld-ldflags=-all-static to avoid having to put every library that MySQL Cluster requires in the chroot directory.
Getting MySQL to run in a chrooted enviroment is a very similar process to the process of compiling from source described in Chapter1, although Installation, there are subtle differences, and if you have already compiled from source, we recommend that you recompile. If you have already installed a MySQL binary, we recommend that you remove it by either deleting the folder if you downloaded a binary tarball or removing the RPMs.
To obtain the MySQL Cluster source, you use the following commands:
[root@host] cd /tmp/ [root@host] wget /mysql-5.0.12-beta.tar.gz [root@host] tar -zxvf mysql-5.0.12-beta.tar.gz [root@host] cd mysql-5.0.12-beta
Next, you compile and install it:
[root@host] ./configure --prefix=/usr/local/mysql --with-ndbcluster >--with-mysqld-ldflags=-all-static --with-mysqld-user=mysql >--with-unix-socket-path=/tmp/mysql.sock [root@host] make [user@host] su - [root@host] make test [root@host] make install [root@host] strip /usr/local/mysql/libexec/mysqld [root@host] scripts/mysql_install_db [root@host] cp support-files/my-medium.cnf /etc/my.cnf
Then you create the relevant directories in the chroot folder from which you want mysql to run:
[root@host] mkdir -p /chroot/mysql/dev /chroot/mysql/etc /chroot/mysql/tmp [root@host] mkdir p /chroot/mysql/var/tmp /chroot/mysql/usr/local/mysql/libexec [root@host] mkdir p /chroot/mysql/usr/local/mysql/share/mysql/english
Next, you set the correct directory permissions:
[root@host] chown -R root:sys /chroot/mysql [root@host] chmod -R 755 /chroot/mysql [root@host] chmod 1777 /chroot/mysql/tmp
When the directories are set up, you copy the server's files:
[root@host] cp /usr/local/mysql/libexec/mysqld >/chroot/mysql/usr/local/mysql/libexec/ [root@host] cp /usr/local/mysql/share/mysql/english/errmsg.sys >/chroot/mysql/usr/local/mysql/share/mysql/english/ [root@host] cp -r /usr/local/mysql/share/mysql/charsets >/chroot/mysql/usr/local/mysql/share/mysql/ [root@host] cp /etc/hosts /chroot/mysql/etc/ [root@host] cp /etc/host.conf /chroot/mysql/etc/ [root@host] cp /etc/resolv.conf /chroot/mysql/etc/ [root@host] cp /etc/group /chroot/mysql/etc/ [root@host] cp /etc/my.cnf /chroot/mysql/etc/
Then you copy the mysql databases that contain the grant tables (created by mysql_install_db) that store the MySQL access privileges:
[root@host] cp -R /usr/local/mysql/var/ /chroot/mysql/usr/local/mysql/var [root@host] chown -R mysql:mysql /chroot/mysql/usr/local/mysql/var
Next, you create a null device within the chroot:
[root@host] mknod /chroot/mysql/dev/null c 2 2 [root@host] chown root:sys /chroot/mysql/dev/null [root@host] chmod 666 /chroot/mysql/dev/null
You then need to edit a few files to remove all users and groups apart from mysql in the chroot environment (this prevents any other user from running inside the chroot jail and is critical for the security of the jail).
In the file /chroot/mysql/etc/group, you delete all lines except the following:
root:x:0: mysql:x:500: In file /chroot/mysql/etc/passwords, delete all lines apart from root:x:0:0:MySQL Cluster:/dev/null:/bin/false mysql:x:500:501:MySQL Server:/dev/null:/bin/false
In order to run MySQL as a nonprivileged user, you need to install the chrootuid package:
[root@host] cd /usr/src/ [root@host] wget ftp://ftp.porcupine.org/pub/security/chrootuid1.3.tar.gz [root@host] tar -zxvf chrootuid1.3.tar.gz [root@host] cd chrootuid1.3 [root@host] make [root@host] make install
Now, if you have done all this correctly, you can start mysql by using the following command:
[root@host] chrootuid /chroot/mysql mysql /usr/local/mysql/libexec/mysqld &
Finally, you need to create a symlink from /tmp/mysql.sock to the chroot /tmp/mysql.sock so you can connect to your server locally:
[root@host] ln -s /chroot/mysql/tmp/mysql.sock /tmp/mysql.sock
You should now be able to start the mysql client:
[root@host] mysql Welcome to the MySQL monitor. Commands end with ; or g. Your MySQL connection id is 2 to server version: 5.0.12-beta-log Type 'help;' or 'h' for help. Type 'c' to clear the buffer. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test | +--------------------+ 3 rows in set (0.03 sec) mysql>
Your application should now be able to connect to the chrooted MySQL process, which should still work fine when it comes to connecting to the other nodes in the cluster.
If you consider security as a process of putting up walls for attackers, you should continue to put up walls until such a time as the cost to you (either in terms of time, money, or hassle for your users) becomes greater than the return that the extra wall gives you in terms of extra security. Few users actually run MySQL in a chrooted environment unless they are in a high-risk environment (for example, shared hosting), but it is an option worth considering.