Site icon GetPageSpeed

NGINX and phpMyAdmin. When you have to…

The phpMyAdmin is the famous web client for MySQL databases.

However, being an open-source product, it is subject to security vulnerabilities.

The best thing is not using it at all. All the modern MySQL GUI clients support connecting via SSH tunneling. So you don’t have to open MYSQL port for outside. Neither you expose the ability to work with MySQL via the web, as phpMyAdmin does.

But if you must make use of phpMyAdmin for some reason (e.g. lazy devs who have no idea about SSH tunneling), you need to set it up properly and in a very secure way.

Here’s how to set it up in CentOS/RHEL 7, with NGINX in mind.

Step 1. Install phpMyAdmin

yum install epel-release
yum install phpMyAdmin

Step 2. Configure NGINX

It’s time to make it web-accessible. But only to specific IPs.

First, create file /etc/nginx/global/allowed-ips-pma.conf.
Then list the IP addresses allowed to access phpMyAdmin in that file:

# single IPs:
allow 2.3.4.5;
allow 3.4.5.6;
# networks:
allow 4.5.6.7/17;
# deny the rest:
deny all;

The phpMyAdmin should never be installed on a URL that is easy to guess. So don’t use any of /pma, /phpmyadmin, etc.
You could, in theory, configure a secret subdomain, e.g. pma-gj4lrxidp.example.com for hosting your phpMyAdmin instance It’s best to set it up on secure subdomain, because it’s easy to switch it off without disturbing the main website you host:

server {
    server_name pma-gj4lrxidp.example.com;
    ...
    include global/allowed-ips-pma.conf;
    root /usr/share/phpMyAdmin;
    location ~ \.php$ {
        # mysqldump can take potentially very long time; adjust as needed
        fastcgi_read_timeout 360;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm-default.sock;
        fastcgi_index index.php;
        include fastcgi_params;

        # no big headers there:
        fastcgi_buffer_size 2k;

        # set client body size to 32M #
        client_max_body_size 32M;
    }
    # These directories do not require access over HTTP
    location ^~ /libraries/ {
        deny all;
    }
    location ^~ /setup/lib/ {
        deny all;
    }
    location ^~ /setup/frames/ {
        deny all;
    }
}   

Separate subdomain just for phpMyAdmin might sound like overkill to some people.
They would desire to set it up onto a subdirectory instead.

But because the name of the installed directory (/usr/share/phpMyAdmin), doesn’t match to the desired directory (e.g. /pma-gj4lrxidp/, we have to prepare special NGINX configuration, namely:

So we end up with:

# using "best non-RE match" so things like `location \.jpg$` elsewhere in the main site will not tamper with our alias
location ^~ /pma-gj4lrxidp/ {
    alias /usr/share/phpMyAdmin/;
    include global/allowed-ips-pma.conf;
    expires max;
    location ~ \.php$ {
        expires -1;
        fastcgi_read_timeout 360;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm-default.sock;
        fastcgi_index index.php;
        # $request_filename makes more sense in combination with alias
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;

        # no big headers there:
        fastcgi_buffer_size 2k;

        # set client body size to 32M #
        client_max_body_size 32M;
    }
}
# These directories do not require access over HTTP
location ^~ /pma-gj4lrxidp/libraries/ {
    deny all;
}
location ^~ /pma-gj4lrxidp/setup/lib/ {
    deny all;
}
location ^~ /pma-gj4lrxidp/setup/frames/ {
    deny all;
}
Exit mobile version