Instalar y asegurar phpMyAdmin con Nginx en Debian 13
Gestionar tus bases de datos MySQL/MariaDB desde la línea de comandos es poderoso, pero no siempre práctico. phpMyAdmin te proporciona una interfaz web para visualizar, modificar y administrar tus bases sin tener que escribir consultas SQL a mano. El problema es que, si está mal configurado, phpMyAdmin se convierte en una puerta de entrada para ataques.
Esta guía te muestra cómo instalar phpMyAdmin correctamente detrás de Nginx en Debian 13 (Trixie), con HTTPS, restricciones de acceso y protecciones contra ataques de fuerza bruta. Una configuración pensada para producción, no solo para un laboratorio de pruebas.
Lo que necesitas antes de comenzar
- Un servidor Debian 13 (Trixie) con acceso sudo
- Los puertos 80 y 443 abiertos
- Un nombre de dominio apuntando a tu servidor (recomendado para HTTPS)
Debian 13 incluye PHP 8.3 por defecto. Verifica tu versión:
php -v
Anota el número de versión, lo necesitarás para las rutas de los archivos de configuración.
Actualizar el sistema
Siempre comenzamos por esto:
sudo apt update && sudo apt -y full-upgrade
sudo reboot
Instalar Nginx, PHP-FPM y las extensiones necesarias
sudo apt install -y nginx php-fpm php-cli php-mbstring php-xml php-zip php-curl php-mysql php-gd php-intl php-bcmath
sudo apt install -y php-imagick php-apcu
Verifica que el socket PHP-FPM existe:
ls -l /run/php/ | grep fpm
# Deberías ver algo como: php8.3-fpm.sock
Instalar y asegurar MariaDB
sudo apt install -y mariadb-server mariadb-client
sudo mysql_secure_installation
Durante el asistente de seguridad:
- Define una contraseña root SQL sólida
- Elimina los usuarios anónimos
- Desactiva el inicio de sesión root remoto
- Elimina la base de prueba
- Recarga los privilegios
Crear un usuario dedicado para phpMyAdmin
Usar la cuenta root SQL para phpMyAdmin es una mala idea. Crea una cuenta de administrador dedicada:
sudo mysql
En el shell SQL:
CREATE USER 'pma_admin'@'localhost' IDENTIFIED BY '¡TuContraseñaSólida!';
GRANT ALL PRIVILEGES ON *.* TO 'pma_admin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
Esta es la cuenta que usarás para conectarte a phpMyAdmin.
Instalar phpMyAdmin
Dos opciones según tus preferencias.
Opción A: a través de apt (sencillo y rápido)
sudo apt install -y phpmyadmin
Durante la instalación:
- En la pregunta sobre el servidor web, no marques nada (configuramos Nginx manualmente)
- Acepta dbconfig-common y define una contraseña para el usuario interno
pma
Los archivos se instalan en /usr/share/phpmyadmin.
Opción B: a través del archivo oficial (versión más reciente)
cd /var/www
sudo mkdir -p pma && cd pma
wget https://files.phpmyadmin.net/phpMyAdmin/5.2.1/phpMyAdmin-5.2.1-all-languages.tar.gz
sudo tar xzf phpMyAdmin-*-all-languages.tar.gz
sudo mv phpMyAdmin-*-all-languages phpmyadmin
sudo chown -R www-data:www-data /var/www/pma/phpmyadmin
Crea el archivo de configuración:
sudo -u www-data cp /var/www/pma/phpmyadmin/config.sample.inc.php /var/www/pma/phpmyadmin/config.inc.php
sudo -u www-data nano /var/www/pma/phpmyadmin/config.inc.php
Genera una clave secreta de al menos 32 caracteres y añádela:
$cfg['blowfish_secret'] = '¡PonAquíUnaFraseSecretaLargaYÚnica!!!!';
Configurar Nginx
Dos enfoques posibles: un alias /phpmyadmin en un vhost existente, o un subdominio dedicado pma.tudominio.com. El segundo es más limpio para gestionar las restricciones de acceso.
Opción A: Alias en un vhost existente
Agrega estos bloques en tu configuración Nginx existente:
location /phpmyadmin {
alias /usr/share/phpmyadmin; # o /var/www/pma/phpmyadmin si usas el método B
index index.php;
try_files $uri $uri/ /phpmyadmin/index.php?$args;
}
location ~ ^/phpmyadmin/(.+\.php)$ {
alias /usr/share/phpmyadmin;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_read_timeout 120s;
}
location ~* ^/phpmyadmin/(.+\.(?:png|jpg|jpeg|gif|css|js|ico|svg))$ {
alias /usr/share/phpmyadmin;
access_log off;
expires 7d;
}
Opción B: Subdominio dedicado (recomendado)
Crea /etc/nginx/sites-available/pma.conf:
server {
listen 80;
server_name pma.tudominio.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name pma.tudominio.com;
ssl_certificate /etc/letsencrypt/live/pma.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/pma.tudominio.com/privkey.pem;
root /usr/share/phpmyadmin;
index index.php;
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy no-referrer-when-downgrade always;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 120s;
}
location ~* \.(?:css|js|ico|gif|jpe?g|png|svg)$ {
access_log off;
expires 7d;
}
}
Activa la configuración y prueba:
sudo ln -s /etc/nginx/sites-available/pma.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
Activar HTTPS con Let's Encrypt
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d pma.tudominio.com
Verifica que la renovación automática esté activa:
systemctl status certbot.timer Asegurar phpMyAdmin
Bloquear el acceso a /setup
location ^~ /phpmyadmin/setup { deny all; }
# o para un vhost dedicado:
location ^~ /setup { deny all; }
Desactivar AllowArbitraryServer
En config.inc.php, asegúrate de que esta opción esté desactivada para evitar ataques SSRF:
$cfg['AllowArbitraryServer'] = false;
Ajustar los límites de PHP
Para poder importar bases de datos grandes, edita /etc/php/8.3/fpm/php.ini:
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 300
memory_limit = 512M
Reinicia PHP-FPM:
sudo systemctl restart php8.3-fpm
Restringir el acceso por IP y contraseña HTTP
Lista blanca de IP
location /phpmyadmin {
allow 203.0.113.10; # tu IP fija
deny all;
alias /usr/share/phpmyadmin;
index index.php;
}
Autenticación HTTP Básica
Crea el archivo de contraseñas:
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd-pma admin
Agrega en la configuración de Nginx:
location /phpmyadmin {
auth_basic "Acceso restringido";
auth_basic_user_file /etc/nginx/.htpasswd-pma;
alias /usr/share/phpmyadmin;
index index.php;
try_files $uri $uri/ /phpmyadmin/index.php?$args;
}
Consejo: Combina la lista blanca de IP + autenticación HTTP para una doble capa de seguridad.
Proteger contra ataques de fuerza bruta con Fail2ban
Limitar la tasa en Nginx
En /etc/nginx/nginx.conf, agrega en el bloque http:
limit_req_zone $binary_remote_addr zone=pma_limit:10m rate=5r/s;
En tu bloque server:
location /phpmyadmin/ {
limit_req zone=pma_limit burst=20 nodelay;
}
Configurar Fail2ban
sudo apt install -y fail2ban
Crea el filtro /etc/fail2ban/filter.d/nginx-phpmyadmin.conf:
[Definition]
failregex = ^<HOST> - .* "(GET|POST) /phpmyadmin.*" .* (401|403) .*$
ignoreregex =
Crea la cárcel /etc/fail2ban/jail.d/nginx-phpmyadmin.local:
[nginx-phpmyadmin]
enabled = true
port = http,https
filter = nginx-phpmyadmin
logpath = /var/log/nginx/access.log
maxretry = 8
findtime = 10m
bantime = 1h
Reinicia Fail2ban:
sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-phpmyadmin
Activar el cortafuegos UFW
sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status
Resolución de problemas comunes
Error 502 Bad Gateway
El socket PHP-FPM no es accesible. Verifica:
ls -l /run/php/php8.3-fpm.sock
sudo systemctl status php8.3-fpm
Error 403 Forbidden
Problema de permisos o de configuración alias/root. Verifica que la carpeta pertenezca a www-data:
sudo chown -R www-data:www-data /usr/share/phpmyadmin
Timeout en las importaciones grandes
Aumenta client_max_body_size en el bloque server de Nginx y fastcgi_read_timeout.
Token CSRF inválido
Verifica que el blowfish_secret esté definido, que las cookies funcionen y que el reloj del sistema esté sincronizado (timedatectl).
Lista de verificación final
- Sistema Debian 13 actualizado
- Nginx y PHP-FPM 8.3 funcionales
- MariaDB asegurado con
mysql_secure_installation - phpMyAdmin accesible por HTTPS
- Acceso restringido (IP y/o Autenticación HTTP)
- Limitación de tasa y Fail2ban activos
- Cortafuegos UFW configurado
- Copias de seguridad programadas
En resumen
Instalar phpMyAdmin en Debian 13 con Nginx es bastante directo. El verdadero valor añadido de esta guía es la parte de seguridad: HTTPS, restricciones de acceso, protección contra fuerza bruta. Un phpMyAdmin expuesto sin protección es un objetivo fácil para los bots que escanean la web constantemente.
¿Necesitas un VPS para alojar todo esto? OuiHeberg ofrece VPS Linux con Debian preinstalado, listos para acoger tu stack LEMP y phpMyAdmin en pocos minutos.

