8.3. Server InstallationNow that you''''ve located your database server to protect against TCP exploits, you need to select a safe version of MySQL to guard against any code-based vulnerabilities. 8.3.1. Choosing a VersionBug fixes, security fixes, performance enhancements, new features, and new bugs are part of each new server release. You always want the most recent stable version. At the time of writing, MySQL Server 4.1 is production, and 5.0 is the development tree. Old 3.x releases still abound, the most recent being 3.23.58. If you''''re running an older version of mySQL, make sure it''''s newer than 3.23.55 to avoid a remote MySQL root account (not Linux root) exploit. Make the move to 4.1 if you can, because there are many improvements. Here are some useful links to keep up with new problems as they''''re discovered: Vulnerabilities http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=mysql Bugs http://bugs.mysql.com/search.php Change logs http://dev.mysql.com/doc/mysql/en/Newsl 8.3.2. Installing and Configuring the Server and ClientsMySQL comes standard with Red Hat and Fedora, as RPM packages mysql-server and mysql (clients and libraries). If you install from RPM, it creates the startup script /etc/init.d/mysqld and the links to it from the runlevel directories (/etc/rc[0-6].d). If you want to install from source, see the latest details at http://dev.mysql.com/doc/mysql/en/Installing_sourcel. When the MySQL startup script is run by root, it should call another script called safe_mysqld (server Version 4.0 and newer) or mysqld_safe (pre-4.0), which is typically in /usr/bin. This script then starts the MySQL server as user mysql. The database server should not run as the Unix root user. In fact, mysqld won''''t run as root unless you force it to with --user=root. If you need to run MySQL as root for some reason, you can chroot the server to help contain a successful attack. To conserve space and avoid work here, I''''ll refer you to the article at http://www.securityfocus.com/infocus/1726. 8.3.3. FilesTable 8-1 shows where a Red Hat RPM installation puts things. As with any type of server, file location and ownership can affect security. A little later, I''''ll talk about these files and settings in the my.cnf configuration file(s). 8.3.4. Setting the MySQL root User PasswordMySQL account names look like Unix account names, but they are not related. In particular, MySQL root is the all-powerful MySQL account but has nothing to do with Linux root. If you try to access MySQL without providing a name, it tries your Linux account name as the MySQL account name. So, if the Linux root user types: # mysql it''''s the same as anyone else typing: % mysql -u root The initial configuration of MySQL is wide open. If you can get in with: % mysql -u root then you need to create a MySQL root password. To set it to newpassword: mysqladmin -u root password newpassword You really shouldn''''t use the Linux root password as the MySQL root password. You can even change the name of the MySQL root account, to trip up attackers who might try to crack its password: mysql -u root ... mysql> update user set user = ''''admin'''' where user = ''''root''''; Although Linux has many tools to improve the security of its user accountsincluding a minimum password length, account expirations, login rejection after repeated failures, and password look-ups in dictionariesMySQL does none of these for its database accounts. Also, MySQL''''s fast login process enables a cracker to automate fast password attacks. Passwords are stored as an MD5 hash rather than the original text, so dictionary attacks using precomputed MD5 hashes of common passwords are a threat. If you want to ensure that your passwords are good enough, some MySQL password crackers are: http://packetstormsecurity.nl/Crackers/mysqlpassword.c http://www.openwall.com/john/contrib/john-1.6-mysql-1.diff 8.3.5. Deleting Anonymous Users and Test DatabasesOut of the box, MySQL has a test database and some phantom users that leave open potential risks. Let''''s whack them. Now that you have a MySQL root user password, you''''ll be prompted for it: % mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 8 to server version: 3.23.58 Type ''''help;'''' or ''''\h'''' for help. Type ''''\c'''' to clear the buffer. mysql>use mysql; Database changed mysql>delete from user where user = "; Query OK, 2 rows affected (0.00 sec) mysql>drop database test; Query OK, 0 rows affected (0.01 sec) mysql>quit Bye 8.3.6. Creating MySQL User Accounts and PrivilegesYou can create MySQL accounts and grant privileges at the same time. The simplest form of the command is: GRANT privileges ON what TO whom IDENTIFIED BY "password" The privileges values include, among others, those in Table 8-2. Privileges may be combined with commas: GRANT, SELECT, INSERT, UPDATE ON ... Examples of the scope (what) are in Table 8-3 (* is the wildcard character in this case).
If you don''''t completely trust your DNS name-to-IP look-up, use mysqld''''s --secure option, which resolves a hostname to an IP and then resolves that IP back to a name and checks if they match. Even better, use IP values if possible. The form for whom is user@host. In the examples in Table 8-4, note that the wildcard character is %, not *.
The password in: IDENTIFIED BY ''''password'''' is entered as plain text, and MySQL stores a one-way hash of this text. 8.3.7. Checking Your ServerIf setting up your database server feels like as much work as raising cattle, but without the glamor, you may mix business with pleasure and perform some virtual cow tipping: sneak up on your database server and try to push it over. From outside your firewall, see if nmap can prod port 3306. Have nessus poke MySQL holes, including a missing root password or insecure server version. A search for MySQL at http://cgi.nessus.org/plugins/searchl shows nine separate plug-ins. Some tools that I have not yet tested, yet look promising, include http://www.zone-h.org//image/library/english/10020_49/finger_mysql.c and a commercial vulnerability assessor called AppDetective (http://www.appsecinc.com/products/appdetective/mysql/). 8.3.8. The MySQL Configuration FileThe file /etc/my.cnf contains overall directives for the MySQL server. Here are the contents of a simple one: [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock [mysql.server] user=mysql basedir=/var/lib [safe_mysqld] err-log=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid datadir is the directory containing the database directories and files. socket is the file name of the Unix-domain socket for MySQL to use for local connections. user is the Unix user who runs the database, and should not be root. Some variables may be added under the [mysqld] section to defend against Denial of Service attacks, or just to tune the server. The format is: set-variable=variable=value You can see the current values of all the server variables with the SQL command SHOW VARIABLES. The variables and their meanings are described at http://dev.mysql.com/doc/mysql/en/Server_system_variablesl. The MySQL server can avoid some Denial of Service problems through server settings such as those in Table 8-5. Starting with MySQL 4.0.3, many variables can be changed at runtime without restarting the server. See http://dev.mysql.com/doc/mysql/en/Dynamic_System_Variablesl. |