Mejores Prácticas de Seguridad de Nginx: Proteja su Servidor Web
Proteja su servidor web Nginx con mejores prácticas esenciales de seguridad. Esta guía cubre la seguridad de las conexiones SSL/TLS, la implementación de limitación de velocidad efectiva (rate limiting) para prevenir el abuso, la mitigación de ataques web comunes como XSS e inyección SQL, y la importancia crítica de mantener Nginx actualizado. Aprenda pasos prácticos y ejemplos de configuración para mejorar la seguridad de su servidor y salvaguardar su presencia en línea.
Mejores Prácticas de Seguridad en Nginx: Protege tu Servidor Web
Tu servidor Nginx es a menudo el primer servicio público que usuarios y atacantes pueden alcanzar. Estas mejores prácticas de seguridad en Nginx se centran en los controles que Nginx puede aplicar realmente: TLS, límites de solicitudes, cabeceras, reglas de acceso, valores predeterminados más seguros y actualizaciones periódicas.
Nginx no puede corregir por sí mismo el código vulnerable de la aplicación. Trátalo como una capa delante de tu aplicación, base de datos, sistema de autenticación y cortafuegos del host.
Conexiones Seguras con TLS
TLS cifra el tráfico entre el navegador y tu servidor. Utiliza un certificado de confianza, redirige HTTP a HTTPS y desactiva las versiones de protocolo obsoletas.
Obtén un Certificado
Let's Encrypt es común para sitios web públicos, pero cualquier autoridad de certificación de confianza puede funcionar. En muchos servidores Linux, Certbot almacena archivos en /etc/letsencrypt/live/tu_dominio.com/.
Configura HTTPS
Edita el bloque del servidor para tu dominio. La ruta suele ser /etc/nginx/sites-available/ en Debian/Ubuntu o /etc/nginx/conf.d/ en sistemas estilo RHEL.
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name tu_dominio.com www.tu_dominio.com;
ssl_certificate /etc/letsencrypt/live/tu_dominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/tu_dominio.com/privkey.pem;
# Incluye tu configuración TLS compartida
include /etc/nginx/snippets/ssl-params.conf;
# ... otras configuraciones (root, bloques de ubicación, etc.)
}
server {
listen 80;
listen [::]:80;
server_name tu_dominio.com www.tu_dominio.com;
# Redirige HTTP a HTTPS
return 301 https://$host$request_uri;
}
Utiliza Parámetros TLS Conservadores
Puedes mantener la configuración TLS compartida en un fragmento como /etc/nginx/snippets/ssl-params.conf.
# /etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
# Habilita HSTS (HTTP Strict Transport Security)
# Agrega includeSubDomains si corresponde
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Habilita OCSP Stapling para verificaciones de certificados más rápidas
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Parámetros Diffie-Hellman (genera uno fuerte si es necesario)
# ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
Solo agrega includeSubDomains o preload a HSTS después de saber que cada subdominio soporta HTTPS. Una implementación incorrecta de HSTS puede bloquear a los usuarios en subdominios antiguos.
Implementa Limitación de Tasa
La limitación de tasa ayuda a frenar los intentos de fuerza bruta, el scraping y las inundaciones accidentales de solicitudes. No es una solución completa contra DDoS, pero le da a tu aplicación más margen de maniobra.
Ejemplo Básico de Limitación de Tasa
limit_req_zone define el estado compartido, y limit_req aplica el límite a una ubicación.
http {
limit_req_zone $binary_remote_addr zone=milimite:10m rate=5r/s;
server {
# ...
location /login {
limit_req zone=milimite burst=10 nodelay;
# ... tu configuración del manejador de inicio de sesión
}
location / {
limit_req zone=milimite burst=20 nodelay;
# ... tu configuración del sitio principal
}
}
}
En este ejemplo:
$binary_remote_addr clavea el límite por dirección IP del cliente. burst=10 permite un breve estallido por encima de la tasa promedio, y nodelay rechaza las solicitudes excesivas en lugar de retrasarlas.
Ten cuidado detrás de un balanceador de carga o CDN. Si Nginx solo ve la dirección IP del proxy, la limitación de tasa por $binary_remote_addr puede castigar a todos los usuarios como un solo cliente. Configura el manejo de IP real de confianza antes de depender de límites por cliente.
Reduce la Superficie de Ataque Común
Nginx puede reducir la exposición, pero tu aplicación aún necesita validación de entrada, codificación de salida, SQL parametrizado, comprobaciones de autenticación y parches de dependencias.
Agrega Cabeceras de Seguridad
Las cabeceras de seguridad pueden reducir el riesgo del lado del navegador:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
Una Política de Seguridad de Contenido puede ayudar con XSS, pero debe coincidir con los scripts, estilos, imágenes y servicios de terceros de tu aplicación. Comienza en modo solo informe antes de aplicarla en un sitio de producción.
Bloquea Escáneres Obvios con Cuidado
Los bloqueos de patrones simples pueden detener a los escáneres ruidosos, pero no sustituyen a un WAF. Mantenlos limitados para no bloquear a usuarios legítimos.
http {
# Define un mapa para bloquear bots/escáneres maliciosos
map $http_user_agent $bad_bot {
default 0;
"~*patron_bot_malicioso" 1;
"~*otro_agente_sospechoso" 1;
}
server {
# ...
if ($bad_bot) {
return 403;
}
# ...
}
}
Restringe Rutas Sensibles
Usa try_files, mantén autoindex desactivado a menos que necesites listados de directorios, y deniega el acceso a archivos ocultos que nunca deberían servirse.
location / {
root /var/www/html;
index index.html index.htm;
try_files $uri $uri/ =404;
autoindex off; # Desactiva el listado de directorios
}
# Ejemplo de restricción de acceso a archivos sensibles
location ~ /\.ht {
deny all;
}
Oculta la Versión de Nginx
server_tokens off elimina la versión de Nginx de las páginas de error generadas y reduce el detalle en la cabecera de respuesta Server.
http {
server_tokens off;
# ...
}
Limita los Métodos HTTP Donde Corresponda
Si un endpoint solo acepta GET y POST, rechaza otros métodos allí. Hazlo por ubicación para no romper las solicitudes de preflight CORS o los endpoints de API que usan legítimamente PUT, PATCH o DELETE.
location /api/ {
# Permite solo GET y POST
if ($request_method !~ ^(GET|POST)$) {
return 405;
}
# ...
}
Mantén Nginx Actualizado
Las correcciones de seguridad a menudo llegan a través del repositorio de paquetes de tu distribución Linux. Mantén Nginx y los paquetes relacionados con OpenSSL parcheados, y prueba las recargas después de las actualizaciones.
Para Debian/Ubuntu:
sudo apt update
sudo apt upgrade nginx
Para CentOS/RHEL:
sudo dnf update nginx
Usa yum update nginx en versiones antiguas de RHEL/CentOS que aún usen yum.
Agrega Protección a Nivel de Host
La seguridad de Nginx también depende del host que lo rodea:
- Permite solo los puertos necesarios en
ufw,firewalld, grupos de seguridad en la nube o ACL de red. - Monitorea
/var/log/nginx/access.logy/var/log/nginx/error.logen busca de picos, respuestas repetidas 401/403 y rutas sospechosas. - Usa Fail2ban o una herramienta similar cuando los patrones de registro puedan identificar clientes abusivos.
- Ejecuta
sudo nginx -tantes de cada recarga para que un cambio de seguridad no desconecte el sitio.
Conclusión
Comienza con HTTPS, actualizaciones, puertos restringidos, cabeceras seguras y límites de tasa en rutas sensibles como /login. Luego revisa tus registros regularmente. La mayoría de los beneficios de seguridad de Nginx provienen de un mantenimiento constante y una configuración clara, no de un gran archivo de endurecimiento copiado de otro sitio.