Securing phpMyAdmin on Debian
It all started one day when I was so bored that I started reading the log files of my sites. I was very surprised when I saw hundreds of error lines trying to access http://urldusite/phpmyadmin among other things with different spellings and coming from the same IP over a range of minutes. If a robot can find the address of phpMyAdmin, it can also launch a brute-force attack to find the login and password or exploit a flaw in the app if there is one. So I undertook to secure my phpMyAdmin a little more and that's the subject of this article, applied to a LAMP configuration with Debian Lenny.
1. SSL and SSH alternative
Of course the first thing to do is to use an SSL certificate, this will prevent the login and password from passing in clear on the network. For my part I don't want to pay an SSL certificate just for phpMyAdmin, so I use an SSH tunnel between my server and my browser. Exchanges between the server and the browser are encrypted by the tunnel no worries. But be careful, this solution is only valid if it is always used.
2. Control the access URL
I strongly advise against linking to phpMyAdmin in /var/www as advised a lot of tutorials. Personally I created a subdomain on one of my sites to access phpMyAdmin. Of course the subdomain is not called phpmyadmin, it would be too simple for robots, all that remains is to configure a vhost.
The mistake not to make is to stop there. By default phpMyAdmin is accessible from the url of the first vhost defined in Apache via an alias created in the phpMyAdmin conf, so it must be disabled.
Let's edit the file
> vim /etc/phpmyadmin/apache.conf
and deactivate the alias by commenting on it.
#Alias /phpmyadmin /usr/share/phpmyadmin
Now phpMyAdmin is only accessible via a url that you know and that should be difficult to discover.
We could stop there, but now that we're on...
3. phpMyAdmin setup and password.
Like all 'pre-made' tools, phpMyAdmin comes with a configuration module that can be accessed from the url http://monsite/phpmyadmin/setup. In the Apache configuration delivered by default, this folder is protected with an authentication by htpassword except that the only account created does not define a password. The idea is to replace the account with a new one with password and use the basic config in our vhost.
Creation of a new htpassword file with login and password.
> htpasswd -c htpasswd.setup username
Of course you have to replace username by the username and specify a password to the guest. Beware of the -c option of the command that creates a new file and therefore overwrites the old one.
Looking in the file /etc/phpmyadmin/apache.conf you can see an access restriction on the setup folder. We will copy these lines of code into our vhost and apply them to the complete phpmyadmin folder. So you will have to type 2 passwords, the Apache authentication one and the MySQL one to access phpMyAdmin.
<Directory /usr/share/phpmyadmin> Options FollowSymLinks DirectoryIndex index.php <IfModule mod_php5.c> AddType application/x-httpd-php .php php_flag magic_quotes_gpc Off php_flag track_vars On php_flag register_globals Off php_value include_path . </IfModule> <IfModule mod_authn_file.c> AuthType Basic AuthName "phpMyAdmin Setup" AuthUserFile /etc/phpmyadmin/htpasswd.setup </IfModule> Require valid-user </Directory>
If necessary update the path in the Directory tag.
Because one more copy/paste does not cost more, we will also add to our vhost the rest of the config of the phpMyAdmin apache.conf file
# Disallow web access to directories that don't need it <Directory /usr/share/phpmyadmin/libraries> Order Deny,Allow Deny from All </Directory> <Directory /usr/share/phpmyadmin/setup/lib> Order Deny,Allow Deny from All </Directory>
Things seem a bit more secure, but you have to type 2 login/password which is a bit restrictive and if a brute force attack (for example) works on the first why wouldn't it work on the second? Without transition let's apply to the last point.
4. Automatic ban
Every unsuccessful attempt to connect via Apache authentication is logged. With this information it is possible to automatically ban IPs that fail too often. For this we are going to use the excellent Fail2ban software. I advise you to install it if you have not already done so and at least configure it from ssh
> aptitude install fail2ban
Fail2ban comes with several filters as standard and the one we are interested in is the apache-auth filter that parses apache log files looking for authentication failures. In the vhost that I use for phpMyAdmin I have voluntarily configured a separate log file which allows to isolate errors.
Add the following configuration to the /etc/fail2ban/jail.conf file
[apache-phpmyadmin] enabled = true port = http,https filter = apache-auth logpath = /home/phpmyadmin/logs/error.log maxretry = 3
All that remains is to restart fail2ban:
> /etc/init.d/fail2ban restart
And that's it, you can turn off paranoid mode. You now have an instance of phpMyAdmin that robots will take a long time to find and if you have gone all the way, your access is secured by SSL and a login/password on which Fail2ban runs. There is no risk 0, but rather than breaking their teeth on a few secure things I think hackers (well most of them) will turn to a more accessible server. If you wish we can go even further in the configuration of phpMyAdmin from its setup folder like prohibiting the login to root.