This article explains how to install phpMyAdmin on your Nginx server using a Ubuntu PPA (Personal Package Archives), and self-signing an SSL certificate for added security. It assumes you are running Nginx and PHP-FPM.
The motivations for using this setup:
- No need to manually update phpMyAdmin
- Take advantage of SSL
Install phpMyAdmin
The PPA ppa:vincent-c/ppa holds stable upstream versions of phpMyAdmin and seems to be updated fairly often.
Install the PPA and the phpMyAdmin package:
sudo add-apt-repository ppa:vincent-c/ppa
sudo apt-get update
sudo apt-get install phpmyadmin
Say yes when it asks whether to use dbconfig-common.
Create a PHP-FPM Pool
PHP-FPM creates a master process that that forwards HTTP requests to one or more child processes. A PHP-FPM pool is a collection of related PHP child processes, and it's not uncommon to have one such pool for each PHP application.
We'll create a dedicated PHP-FPM pool and socket for phpMyAdmin. This pool will run as the user pma
.
First, create the user:
adduser pma
Then create a new PHP-FPM pool config file file based on the default www.conf
:
cd /etc/php5/fpm/pool.d/
sudo cp www.conf pma.conf
Edit pma.conf
(I'm only showing the directives I've changed):
[pma]
user = pma
group = pma
listen = /var/run/php5-fpm-pma.sock
pm = ondemand
pm.max_children = 4
pm.process_idle_timeout = 15s;
security.limit_extensions = .php
php_admin_value[error_log] = /var/log/fpm-php.pma.log
Notice the first line: Each pool configuration begins with [pool-name]
, hence pma
is the name of our new pool.
These settings are probably not recommended for your typical PHP website or app; the phpMyAdmin installation will not generate a lot of traffic, so it has been deliberately allocated a small amount of resources (see pm
, pm.max_children
, pm.process_idle_timeout
).
Restart PHP-FPM:
sudo service php-fpm restart
Create and install an SSL certificate
Because the only one accessing phpMyAdmin is myself, and because my only concern is that the traffic is encrypted, I'll use a self-signed certificate.
Create a self-signed SSL certificate:
sudo mkdir /etc/ssl/pma
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/pma/pma.key \
-out /etc/ssl/pma/pma.crt
The question that you must answer correctly is the "Common Name". Use your domain name or Server IP Address for this field. I will use pma.myserver.example.com
.
Create a Server Block
The next step is to create an Nginx server block ("Virtual Host") for phpMyAdmin that responds to pma.myserver.example.com.
Create /etc/nginx/sites-available/phpmyadmin.conf
:
# Redirect non-SSL to SSL
server {
listen 80;
listen [::]:80;
server_name pma.myserver.example.com;
return 301 https://pma.myserver.example.com$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/ssl/pma/pma.crt;
ssl_certificate_key /etc/ssl/pma/pma.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK;
ssl_prefer_server_ciphers on;
server_name pma.myserver.example.com;
# The phpMyAdmin installation
root /usr/share/phpmyadmin;
index index.php;
client_max_body_size 2m;
charset utf-8;
access_log /var/log/nginx/pma-access.log;
error_log /var/log/nginx/pma-error.log warn;
# Deny access to "hidden" files, including Apache's .htaccess files.
location ~* (?:^|/)\. {
deny all;
access_log off;
log_not_found off;
}
location / {
try_files $uri $uri/ =404;
}
location ~ /(libraries|setup) {
deny all;
return 404;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi.conf;
fastcgi_pass unix:/var/run/php5-fpm-pma.sock;
}
}
Notes:
- This file actually creates two server blocks: the first is for redirecting non-HTTPS traffic to HTTPS.
- The cipher list (
ssl_ciphers
) is taken from the Mozilla Wiki's Security/Server Side TLS article. Their recommendation is subject to change. - There are many more SSL options that are worth looking into.
Then you must then enable the server block:
sudo ln -s /etc/nginx/sites-available/phpmyadmin.conf /etc/nginx/sites-enabled/phpmyadmin.conf
And reload Nginx's configuration files:
sudo service nginx reload
Configure phpMyAdmin
phpMyAdmin's configuration file is located at /etc/phpmyadmin/config.inc.php
(this path is set in /usr/share/phpmyadmin/ libraries/vendor_config.php
).
However, some of the configuration files that are included by /etc/phpmyadmin/config.inc.php
will not be readable if your PHP-FPM pool runs as a user other than www-data. This is because they're owned by root:www-data
. Fix this:
sudo chown root:pma /var/lib/phpmyadmin/config.inc.php
sudo chown root:pma /var/lib/phpmyadmin/blowfish_secret.inc.php
sudo chown root:pma /etc/phpmyadmin/config-db.php
Force using HTTPS while accessing phpMyAdmin by adding the following to /var/lib/phpmyadmin/config.inc.php
:
$cfg['ForceSSL'] = true;
Notes
- When configuring your Nginx server, you should take a look at HTML5 Boilerplate's Nginx Server Configs documentation. It provides some great tips and best practices.
- For SSL/TLS servers, you should test your configuration with SSL Lab's SSL Server Test. Note that this test will fail if you use a self-signed certificate.
- Your phpMyAdmin installation should be protected with strong passwords. Ideally, you won't need to expose it to the web.