Track 2 Workshop PacNOG 7 July 1, 2010 Securing LAMP on Ubuntu ------------------------------------ 1. Verify that MySQL is running in a reasonable manner --------------------------------------------------- A weak point in MySQL is that most programs use "root" as the mysql administrative account name. Attackers can attempt to access MySQL via PHP scripting holes, programs like phpMyAdmin, etc. using this knowledge. Changing the super user for MySQL is not too hard, but it may break other programs that are already installed and that depend on this userid. For this reason, we will not change the root user at this time, but here is a pointer to a page that show you how to do this: http://www.freesoftwaremagazine.com/articles/hardening_linux?page=0%2C10 We have already set your MySQL root password. You should always make sure that this user does have a password. You can do this by typing: $ sudo mysqladmin -u root -h localhost password PASSWORD_FOR_ROOT (don't do this now as it's already been done when you installed your software for LAMP). Let's verify if MySQL came with a sample test database. If it did, we should remove it. $ mysql -uroot -p Enter the MySQL root password when prompted. You will see: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 66 Server version: 5.1.37-1ubuntu5.4 (Ubuntu) Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> Let's check what databases exist by typing: mysql> show databases; You should see: +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | phpmyadmin | +--------------------+ 3 rows in set (0.00 sec) mysql> There is no "test" database so we don't need to worry about this. Let's drop the anonymous user account from MySQL as we are not going to use it. mysql> use mysql; mysql delete from db where User=''; mysql delete from user where User=''; You'll see "Query OK, 0 rows affected (0.00 sec)" - this implies that there was no anonymous account to begin with. Ubuntu has installed MySQL in a prety secure manner. Now type: mysql> flush privileges; mysql> quit You will exit from MySQL at this time. Now let's log back in to be sure we can still use our MySQL environment: $ mysql -uroot -p Assuming you get back to the "mysql>" prompt, then everything is fine. Now do: mysql> quit We could check the file /etc/mysql/my.cnf to verify that it is binding MySQL only to the localhost (127.0.0.1) with the option: bind-address = 127.0.0.1 But, this has been done by Ubuntu. Still, go ahead and look at the file just to get used to how the MySQL server configuration is defined: $ sudo vi /etc/mysql/my.cnf Once you are done quit (don't save) from the file (":q!" in vi). Now let's restart MySQL just to be sure it has picked up on any changes we may have made: $ sudo /etc/init.d/mysql restart 2. Make Apache more secure ----------------------- First we'll turn on an internal firewall for Apache called "mod_security". For more information see: http://www.modsecurity.org/ First we will install this library module for Apache: $ sudo apt-get install libapache-mod-security The module is enabled by default, but we want to configure its use. To do this do the following: $ cd /etc/apache2 $ sudo a2dismod mod-security $ cd mods-available $ sudo wget http://noc/track2/day3/mod-security.conf $ sudo /etc/init.d/apache2 restart Take a look at all the features of security now enabled for Apache: $ sudo vi mod-security.conf When done looking around exit (don't save) by doing ":q!" (in vi). Now let's allow Apache to interpret PHP code in files with the extension ".html" - this lets us hide files with PHP code a bit more: $ cd /etc/apache2/sites-available $ sudo vi default In the default configuration find the line that reads: CustomLog /var/log/apache2/pacnog7_access.log combined And just below this add the lines: >>>> # The PHP engine will interpret all # .php and .html files for php code AddType application/x-httpd-php .php .phtml .html <<<< Then save and exit from the file (":wq" in vi), and restart the Apache web server: $ sudo /etc/init.d/apache2 restart Now create a file with PHP code, but in a file with a ".html" extension: $ cd /var/www/share/pacnog7 $ sudo vi test.html In this file add the text: >>>> <<<< Save and exit from the file. Now open the file in a web browser: http://localhost/test.html You should see the PHP information page. This is _very_ cool! 3. Make sure PHP has reasonable defaults ------------------------------------- Take a look at the file /usr/local/php/php.ini: $ cd /etc/php5/apache2 $ sudo vi php.ini In this file change the following: Change: expose_php = On to: ;expose_php = On expose_php = Off Change: display_errors = On to: ;display_errors = On display_errors = Off Change: log_errors = Off to: ;log_errors = Off log_errors = On Change: ;error_log = filename to: ;error_log = filename error_log = /var/log/php-errors.log That's it. This will have the affect that when debugging your PHP code you will need to look in /var/log/php-errors.log instead of on the screen of your web browser if you are having issues with your code. 4. Enable SSL for your Apache Web Server ------------------------------------- A default configuration for SSL is available here: /etc/apache2/sites-available/default-ssl Let's make changes to this file, then enable it to allow us to use a locally signed certificate to provide secure web connections to our sites. $ cd /etc/apache2/sites-available $ sudo vi default-ssl In this file make the following changes: Change: DocumentRoot /var/www to: DocumentRoot /var/www/share/pacnog7 Change: ErrorLog /var/log/apache2/error.log to: ErrorLog /var/log/apache2/pacnog7_error.log Change: CustomLog /var/log/apache2/ssl_access.log combined to: CustomLog /var/log/apache2/pacnog7-ssl_access.log combined And, under the line that reads: CustomLog /var/log/apache2/pacnog-ssl_access.log combined add the following: >>> # The PHP engine will interpret all # .php and .html files for php code AddType application/x-httpd-php .php .phtml .html <<<< Now save and exit from the file (":wq" in vi). We must enable both the site and the ssl module. To do this do: $ sudo a2ensite default-ssl $ sudo a2enmod ssl Then we need to restart Apache: $ sudo /etc/init.d/apache2 restart Now you should be able to go to: https://localhost/ in a web browser. You'll get a warning about an untrusted certficiate. Accept the certificate and now you can view web pages created on your site securely.