Skip to main content

Configuración de Headers de Seguridad en Nginx con DirectAdmin

Configuración de Headers de Seguridad en Nginx con DirectAdmin

Introducción

Esta guía documenta cómo configurar headers de seguridad en servidores con DirectAdmin, tanto a nivel global como para dominios específicos que requieran exclusiones.

Última actualización: 25/12/2024 GMT+1

Índice

Configuración Global

La configuración global se aplica a todos los dominios del servidor mediante el archivo:

/usr/local/directadmin/data/templates/custom/cust_nginx.CUSTOM.post

Crear el directorio custom (si no existe)

mkdir -p /usr/local/directadmin/data/templates/custom

Ejemplo de configuración global

# Security Headers - Global
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self' https:; frame-src 'self' https://www.youtube.com https://www.google.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;

# Custom error pages for nginx-only domains
error_page 400 /error/400.html;
error_page 401 /error/401.html;
error_page 403 /error/403.html;
error_page 404 /error/404.html;
error_page 405 /error/405.html;
error_page 406 /error/406.html;
error_page 413 /error/413.html;
error_page 422 /error/422.html;
error_page 429 /error/429.html;
error_page 431 /error/431.html;
error_page 500 /error/500.html;
error_page 502 /error/502.html;
error_page 503 /error/503.html;
error_page 504 /error/504.html;

location ^~ /error/ {
    alias |DOCROOT|/error/;
    internal;
    # Repetir headers en este location block
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data: https:; connect-src 'self' https:; frame-src 'self' https://www.youtube.com https://www.google.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;
}

Aplicar cambios

Después de crear o modificar el archivo, reconstruir las configuraciones de nginx:

cd /usr/local/directadmin/custombuild
./build rewrite_confs

Personalización por Dominio

Para dominios que requieren configuraciones diferentes (CSP más permisivo, exclusiones de headers, etc.), DirectAdmin permite crear archivos de personalización por dominio.

Ubicación de archivos

/usr/local/directadmin/data/users/<USUARIO>/domains/<DOMINIO>.cust_nginx
/usr/local/directadmin/data/users/<USUARIO>/domains/<DOMINIO>.cust_nginx.2
/usr/local/directadmin/data/users/<USUARIO>/domains/<DOMINIO>.cust_nginx.3
/usr/local/directadmin/data/users/<USUARIO>/domains/<DOMINIO>.cust_nginx.4

Archivo de configuración personalizada en home del usuario

Para configuraciones más complejas, se puede crear un archivo .conf en el directorio del usuario e incluirlo:

/home/<USUARIO>/nginx/<nombre>.conf

Puntos de Inserción en DirectAdmin

DirectAdmin utiliza tokens en la plantilla nginx_server.conf para insertar configuraciones personalizadas:

Token Archivo por Dominio Ubicación en nginx
CUSTOM1 .cust_nginx Antes del bloque server {}
CUSTOM (interno) Inicio del bloque server {}
CUSTOM2 .cust_nginx.2 Dentro de location / {}
CUSTOM3 .cust_nginx.3 Después de locations, antes de webapps
CUSTOM4 .cust_nginx.4 Final del bloque server {}

Archivo .cust_nginx (CUSTOM1)

Se usa principalmente para:

  • Cambiar el DOCROOT (aplicaciones Laravel, etc.)
  • Configuraciones que van antes del bloque server

Ejemplo - Cambiar DOCROOT para Laravel:

|?DOCROOT=`HOME`/domains/`DOMAIN`/mi-app/public|

Archivo .cust_nginx.3 (CUSTOM3)

Se usa para:

  • Configuraciones de cache
  • Location blocks adicionales
  • Headers específicos para tipos de archivo

Ejemplo - Cache de assets:

location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}
location ~* \.(jpg|jpeg|gif|png|svg)$ {
    expires 365d;
}
location ~* \.(pdf|css|html|js|swf)$ {
    expires 2d;
}

Archivo .cust_nginx.4 (CUSTOM4)

Se usa para:

  • Incluir archivos de configuración externos
  • Location blocks complejos
  • Reglas de rewrite específicas

Ejemplo - Incluir configuración WHMCS:

include /home/intranet/nginx/whmcs.conf;

Ejemplos Prácticos

Ejemplo 1: Dominio con CSP relajado

Para un dominio que necesita permitir scripts de terceros (ej: pasarelas de pago, widgets):

Archivo: /usr/local/directadmin/data/users/usuario/domains/tienda.com.cust_nginx.4

# Sobrescribir CSP global con uno más permisivo
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https: blob:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https: blob:; font-src 'self' data: https:; connect-src 'self' https: wss:; frame-src 'self' https:; frame-ancestors 'self'; base-uri 'self'; form-action 'self' https:;" always;

Ejemplo 2: Dominio que permite iframes externos

Para un dominio que necesita ser embebido en otros sitios:

Archivo: /usr/local/directadmin/data/users/usuario/domains/widget.com.cust_nginx.4

# Permitir que el sitio sea embebido
add_header X-Frame-Options "" always;
add_header Content-Security-Policy "default-src 'self'; frame-ancestors https://sitio-padre.com https://otro-sitio.com;" always;

Ejemplo 3: Aplicación Laravel con DOCROOT personalizado

Archivo: /usr/local/directadmin/data/users/develop/domains/larafactu.com.cust_nginx

|?DOCROOT=`HOME`/domains/`DOMAIN`/larafactu/public|

Ejemplo 4: BookStack Wiki

Archivo: /usr/local/directadmin/data/users/castris/domains/wiki.castris.com.cust_nginx

|?DOCROOT=`HOME`/domains/`DOMAIN`/BookStack/public|

Ejemplo 5: Configuración compleja con archivo externo

Crear archivo de configuración en home del usuario:

Archivo: /home/intranet/nginx/whmcs.conf

# WHMCS CONFIG
location ~ /announcements/?(.*)$ {
    rewrite ^/(.*)$ /index.php?rp=/announcements/$1;
}

location ~ /download/?(.*)$ {
    rewrite ^/(.*)$ /index.php?rp=/download$1;
}

location ~ /knowledgebase/?(.*)$ {
    rewrite ^/(.*)$ /index.php?rp=/knowledgebase/$1;
}

# ... más reglas de rewrite ...

# Security Advisory
location ^~ /vendor/ {
    deny all;
    return 403;
}

Archivo: /usr/local/directadmin/data/users/intranet/domains/intranet.castris.com.cust_nginx.4

include /home/intranet/nginx/whmcs.conf;

Ejemplo 6: Deshabilitar todos los headers de seguridad (NO RECOMENDADO)

Solo para debugging o situaciones muy específicas:

Archivo: /usr/local/directadmin/data/users/usuario/domains/debug.com.cust_nginx.4

# TEMPORAL - Solo para debugging
add_header X-Content-Type-Options "" always;
add_header X-Frame-Options "" always;
add_header X-XSS-Protection "" always;
add_header Referrer-Policy "" always;
add_header Permissions-Policy "" always;
add_header Strict-Transport-Security "" always;
add_header Content-Security-Policy "" always;

Troubleshooting

Verificar sintaxis de nginx

nginx -t

Ver configuración generada para un dominio

cat /etc/nginx/conf.d/usuario.dominio.com.conf

Reconstruir todas las configuraciones

cd /usr/local/directadmin/custombuild
./build rewrite_confs

Recargar nginx sin reiniciar

systemctl reload nginx

Verificar headers de un sitio

curl -I https://dominio.com

Logs de errores

tail -f /var/log/nginx/domains/dominio.com.error.log

Notas importantes

  1. Orden de precedencia: Los headers definidos en location blocks más específicos sobrescriben los globales.

  2. Keyword always: Usar siempre always al final del add_header para que se aplique en todas las respuestas (incluyendo errores).

  3. Reconstruir después de cambios: Siempre ejecutar ./build rewrite_confs después de modificar archivos .cust_nginx*.

  4. Permisos: Los archivos deben tener permisos correctos para que DirectAdmin pueda leerlos.

  5. Variables de DirectAdmin: Se pueden usar variables como |DOCROOT|, |DOMAIN|, |HOME| en las configuraciones.

Variables Disponibles en Templates

Variable Descripción
|DOMAIN| Nombre del dominio
|HOME| Directorio home del usuario
|DOCROOT| Document root del dominio
|IP| IP del servidor
|PORT_80| Puerto HTTP
|PORT_443| Puerto HTTPS

Referencias

Aviso

Esta documentación se entrega tal y como está, basada en configuración del servidor dar.tabratino.com.