CentOS/RedHat: Secured phpMyAdmin on Nginx with SSL only
Introduction:#
This tutorial shows how to setup phpMyAdmin running on Nginx with SSL only. As an extra security measure we’ll limit access to the server by IP and we’ll use web authentication.
Variables:#
OS: CentOS 6.3 64bit
Vhost for phpMyAdmin: pma.example.com
We need some additional repositories. You can also use “yum-priorities” package available on CentOS – the Yum Priorities plugin can be used to enforce ordered protection of repositories, by associating priorities to repositories. Visit the Yum Priorities CentOS Wiki for more information.
Installing extra repositories:#
Extra Packages for Enterprise Linux (EPEL)
# rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-7.noarch.rpm
Remi repository
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
Nginx repository
# rpm -Uvh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
Enable Remi Repository:
/etc/yum.repos.d/remi.repo
[remi]
...
enabled=1
...
We need to exclude some packages from CentOS base repository:
/etc/yum.repos.d/CentOS-Base.repo
[base]
...
exclude=php* mysql*
...
[updates]
...
exclude=php* mysql*
...
[extras]
...
exclude=php* mysql*
...
We need to also exclude Nginx package from EPEL repository:
/etc/yum.repos.d/epel.repo
[epel]
...
exclude=nginx*
...
Install required packages:#
yum install -y nginx php-fpm phpmyadmin php-pecl-apc crypto-utils
YUM will take care of all dependencies.
PHP-FPM configuration (PHP-FPM is running on UNIX File Sockets to avoid TCP overhead):#
/etc/php-fpm.d/www.conf
[www]
listen = /var/run/php-fpm/$pool.sock
listen.allowed_clients = 127.0.0.1
listen.owner = nginx
listen.group = nginx
listen.mode = 0640
user = nginx
group = nginx
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
slowlog = /var/log/php-fpm/www-slow.log
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
php_admin_flag[log_errors] = on
Nginx configuration:#
/etc/nginx/nginx.conf
user nginx;
worker_processes 4;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr $host $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $ssl_cipher $request_time';
access_log /var/log/nginx/access.log main buffer=32k;
error_log /var/log/nginx/error.log warn;
## Timeouts
keepalive_timeout 60 60;
## General Options
charset utf-8;
ignore_invalid_headers on;
max_ranges 0;
recursive_error_pages on;
sendfile on;
server_tokens off;
source_charset utf-8;
## Global SSL options
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
## Compression
gzip on;
gzip_static on;
gzip_buffers 16 8k;
gzip_vary on;
gzip_types text/plain text/css application/json application/x-javascript application/xml application/xml+rss text/javascript image/png image/jpeg image/jpg image/gif text/x-component text/richtext image/svg+xml text/xsd text/xsl text/xml image/x-icon;
## HTTP to HTTPS redirect
server {
listen [::]:80;
root /var/empty;
server_name pma.example.com;
rewrite ^ https://pma.example.com$request_uri permanent;
}
server {
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
add_header Pragma "public";
listen listen [::]:443;
root /usr/share/phpMyAdmin;
index index.php index.html index.htm;
server_name pma.example.com;
## SSL Certs
ssl on;
ssl_certificate /etc/pki/tls/certs/pma.example.com.crt;
ssl_certificate_key /etc/pki/tls/private/pma.example.com.key;
}
location ^~ / {
try_files $uri $uri/ /index.php?$args;
## Restricted Access directory
auth_basic "Authorized Access Only!";
auth_basic_user_file .users;
## Hosts restrictions
allow 192.168.1.1; #Specify your IP here
deny all;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param HTTPS on;
}
}
location /usr/share/phpMyAdmin/libraries {
deny all;
}
location /usr/share/phpMyAdmin/setup/frames {
deny all;
}
location /usr/share/phpMyAdmin/setup/lib {
deny all;
}
## deny access to .htaccess files
location ~ /\. {
access_log off;
log_not_found off;
deny all;
}
include /etc/nginx/conf.d/*.conf;
}
Create self-signed SSL certificate (This will start the genkey graphical user interface):#
# genkey pma.example.com --days 365
Add the following line to phpMyAdmin config file to disable version check as this breaks the SSL connection:
/etc/phpMyAdmin/config.inc.php
$cfg['VersionCheck'] = false;
Create user for web authentication:#
# htpasswd -mc /etc/nginx/.users username
Change the owner and permissions so only “nginx” user can read the file:
# chown nginx /etc/nginx/.users && chmod 600 /etc/nginx/.users
Start nginx and php-fpm daemons:#
# chkconfig nginx on && service nginx start
# chkconfig php-fpm on && service php-fpm start
Done!