# 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**
## 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)

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

```

### Ejemplo de configuración global

```nginx
# 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:

```bash
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:

```nginx
|?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:

```nginx
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:

```nginx
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`

```nginx
# 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`

```nginx
# 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`

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

### Ejemplo 4: BookStack Wiki

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

```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`

```nginx
# 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`

```nginx
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`

```nginx
# 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

```bash
nginx -t

```

### Ver configuración generada para un dominio

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

```

### Reconstruir todas las configuraciones

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

```

### Recargar nginx sin reiniciar

```bash
systemctl reload nginx

```

### Verificar headers de un sitio

```bash
curl -I https://dominio.com

```

### Logs de errores

```bash
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

- [DirectAdmin Custom Nginx Templates](https://docs.directadmin.com/webservices/nginx/nginx_templates.html)
- [Mozilla Observatory](https://observatory.mozilla.org/) - Para verificar headers de seguridad
- [Security Headers](https://securityheaders.com/) - Análisis de headers

##### Aviso

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