Often it is convenient to have an easy access to your database through some client like phpMyAdmin on the server where your app or website is installed. This helps us to quickly check the database, run few queries or do some maintenance work.
However having just a password protected phpMyAdmin access on a public URL is very risky as you are potentially giving a full database access of your app to some intruder. In this article I am going to show you how you can secure your phpMyAdmin installation from the outside unauthorized access but still available online over the Internet just for you to access.
For the purpose of this article I have setup a LEMP stack (Linux, Nginx, MySQL & PHP) on an Amazon EC2 instance which basically hosts a tiny WordPress website.
I have setup phpMyAdmin on the same server so that I can quickly do some database stuff for my website. Normally without any security (or with some basic security) in place it would be available openly on some public URL like this http://www.mycoolwebsite.com/phpmyadmin. This is scary!
Ideally I would like to make it accessible only to me from anywhere (from my home or office) but not make it available to other preying eyes. We can make it possible through some Nginx configurations (or Apache if you have one) and through some SSH tunneling.
Step 1: Create a Public/Private Key pair to securely access your Server
This is the first important step. You should be able to access your remote server through SSH using a public-private key pair. If you don’t know how to generate a public/private key pair for your server an quick google search will give you lot of nice tutorials on this topic.
In my case it is an AWS EC2 instance and when I launch an instance it prompts to create a key pair (or use existing key pair), through which I can access the server through SSH client like Putty on windows or equivalent tools in Linux.
Ensure you are able to connect successfully with your server through SSH
Step 2: Create a separate virtual-host for phpMyAdmin
I have created a separate port based virtual host in Nginx for phpmyadmin so that I can access it over a special port. In my case it is 8010. Here is the Nginx configuration to do the same.
server { listen 8010; server_name _; allow 127.0.0.1; deny all; root /var/www/html/phpmyadmin; index index.php; location ~ \.php$ { include snippets/fastcgi-php.conf; # # # With php5-cgi alone: # fastcgi_pass 127.0.0.1:9000; # # With php5-fpm: fastcgi_pass unix:/var/run/php5-fpm.sock; # include the fastcgi_param setting include fastcgi_params; } }
Quick explanation of the above configuration :
– My server would listen to port 8010 [listen 8010;] and it will map all requests coming to this port to my phpMyAdmin installation at
[root /var/www/html/phpmyadmin;]
Notice that my virtual host blocks all the access from all IPs [deny all;] except the local IP [allow 127.0.0.1;]
At this moment if I reload nginx [sudo service nginx reload] and try to access my phpMyAdmin installation I will get a 403 Forbidden error [eg. EC2 instance public url http://ec2-xx-xxx-xx-xx.eu-west-2.compute.amazonaws.com:8010/ ].
Note for AWS users. If you are configuring this on the EC2 instance make sure to update your security group rules to allow connections through the port that you configured. This is required if you choose to have non-standard port to access your webserver like in our case.
So now essentially I have completely blocked the public URL access to my phpmyadmin installation.
Step 3: SSH tunneling
The only way to access my phpMyAdmin now is through localhost due to my directive [allow 127.0.0.1;] above. To access a remote server as if I am accessing a local server is made possible through SSH tunneling.
Inside your Putty client load the Session that connects to your server and then on left panel expand Connection > SSH > Tunnels and then Add the Source Port and Destination.
– In my case I have kept both Source and Destination ports same – 8010 but you can keep it different. Destination is your server where phpMyAdmin is installed and the source is the port that you will use locally to connect.
– Click on the “Add” button to add the forwarded ports and then go back to your main session screen and save these changes.
– Once you are done, connect to your server using Putty. If everything goes well a tunnel should have been established which you can see in the putty event log.
– Load up http://localhost:8010/ in your browser. You should now be able to access your phpMyAdmin from your remote server locally. (Change the port as per your settings.)
So now you have secured your phpMyAdmin installation on the remote server by making it accessible over the Internet only through localhost.