Configuración Catch‑All en Nginx

Artículos Guías Manuales Sistemas Linux Windows Redes MySql Binario 0 Binario Cero Artículos Guías Manuales Sistemas Linux Windows Redes MySql Binario 0 Binario Cero

Guía técnica para capturar y controlar todo el tráfico destinado a hosts no declarados o rutas por defecto, tanto en HTTP como en HTTPS, con ejemplos de archivos de configuración listos para producción.

1. ¿Qué es un catch‑all en Nginx?

Un catch‑all es un bloque server que actúa como destino por defecto cuando:

  • El Host solicitado no coincide con ningún server_name declarado.
  • El puerto solicitado no tiene un bloque más específico.

Su uso típico es:

  • Redirigir tráfico desconocido hacia un dominio canónico.
  • Responder con códigos de control (p. ej., 444 para cortar conexiones indeseadas, 404/410).
  • Mostrar una página de mantenimiento o banner legal.
  • Proteger el origin de un reverse proxy público.

Clave: se implementa con la directiva default_server en la escucha del puerto (listen).

2. Diseño recomendado

  • Separar HTTP y HTTPS: define un catch‑all para :80 y otro para :443 con TLS.
  • Usar server_name _;: el guion bajo es un patrón que no coincidirá con dominios reales y documenta la intención.
  • Respuestas claras: return es preferible a rewrite cuando la lógica es simple.
  • Registro (logs) mínimo en el catch‑all para evitar ruido, con rotación y formato propio.

3. Estructura de ficheros

/etc/nginx/
├── nginx.conf
└── sites-available/
    ├── 00-catch-all-http.conf
    ├── 00-catch-all-https.conf
    └── ... (otros sitios)
└── sites-enabled/ -> enlaces simbólicos

En distribuciones sin sites-available/sites-enabled (p. ej., Alpine por defecto), incluye los server blocks directamente en nginx.conf o crea tu propia convención y include.

4. Ejemplo: catch‑all HTTP (80)

Archivo: /etc/nginx/sites-available/00-catch-all-http.conf

server {
    listen 80 default_server reuseport;
    listen [::]:80 default_server;

    server_name _;

    # Opciones de seguridad y rendimiento mínimas
    keepalive_timeout 10;
    client_body_timeout 10;
    client_header_timeout 10;

    # Logs específicos y discretos
    access_log /var/log/nginx/catch-all.access.log main if=$log_catch_all;
    error_log  /var/log/nginx/catch-all.error.log warn;

    # Flag para reducir ruido en logs
    set $log_catch_all 0;

    # Política por defecto: redirigir todo a dominio canónico (HTTP -> HTTPS)
    # Reemplaza ejemplo.com por tu dominio público
    return 301 https://ejemplo.com$request_uri;
}

Notas:

  • default_server garantiza que este bloque maneje cualquier Host no declarado en :80.
  • Cambia la política si prefieres cerrar en lugar de redirigir (ver sección 6).

5. Ejemplo: catch‑all HTTPS (443) con TLS

Archivo: /etc/nginx/sites-available/00-catch-all-https.conf

server {
    listen 443 ssl http2 default_server reuseport;
    listen [::]:443 ssl http2 default_server;

    server_name _;

    # Certificado barajado por defecto (comodín o cert genérico). Puede ser un "dummy".
    ssl_certificate     /etc/nginx/ssl/catch-all/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/catch-all/privkey.pem;

    # Perfil TLS razonable
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # Logs discretos
    access_log /var/log/nginx/catch-all-https.access.log main if=$log_catch_all;
    error_log  /var/log/nginx/catch-all-https.error.log warn;

    set $log_catch_all 0;

    # Política por defecto: redirigir a dominio canónico en HTTPS
    return 308 https://ejemplo.com$request_uri;
}

Notas:

  • En TLS, Nginx elige el default_server cuando no hay coincidencia SNI.
  • Usa un certificado válido (comodín o SAN) si quieres evitar avisos del cliente cuando la conexión caiga aquí.

6. Políticas alternativas (sustituye return del ejemplo)

6.1 Rechazar tráfico desconocido sin respuesta (desechar)

return 444;  # Corta la conexión sin payload

6.2 Responder 404/410 (ocultar superficie)

return 404;  # o 410 si quieres indicar recurso definitivamente inexistente

6.3 Página de mantenimiento simple

root /var/www/catch-all;
location = / {
    try_files /index.html =503;
}
error_page 503 /maintenance.html;
location = /maintenance.html { internal; }

6.4 Bloquear por Source IP o ASN (ejemplo básico)

# Permite sólo una red interna (ej., para origins detrás de WAF)
allow 10.0.0.0/8;
deny  all;
return 444;

7. Variables, mapas y formato de log para depurar Host desconocidos

Amplía nginx.conf con un map para activar logs sólo cuando el Host no coincida con los tuyos.

Fragmento para http en nginx.conf:

http {
    # ... otras directivas ...

    # Enumera tus dominios "legítimos" para silenciar logs en ellos
    map $host $log_catch_all {
        default 1;                 # Log por defecto
        ejemplo.com 0;
        www.ejemplo.com 0;
        api.ejemplo.com 0;
    }

    log_format main '$remote_addr - $host $request "$status" $body_bytes_sent "$http_referer" "$http_user_agent"';

    # include de sitios
    include /etc/nginx/sites-enabled/*.conf;
}

8. Activación, validación y recarga

# Crear enlaces simbólicos
ln -s /etc/nginx/sites-available/00-catch-all-http.conf  /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/00-catch-all-https.conf /etc/nginx/sites-enabled/

# Validar sintaxis
ginx -t

# Recargar sin cortar conexiones
nginx -s reload
# o
systemctl reload nginx

9. Escenarios comunes y pitfalls

  1. Orden de evaluación: Nginx selecciona server por puerto y SNI; dentro de los candidatos, elige el más específico. Asegúrate de tener default_server sólo en tu catch‑all.
  2. Certificado inválido en catch‑all: si devuelves 308/301 a dominio válido, los navegadores pueden mostrar aviso antes de seguir. Considera usar un comodín (p. ej., *.ejemplo.com) o devolver 444 en su lugar.
  3. Bucles de redirección: valida que el dominio canónico no apunte a este server block.
  4. Proxy inverso/WAF delante: define allow/deny y cabeceras (X-Forwarded-For, Real-IP) si tu catch‑all está expuesto al público.
  5. Multitenant: si alojas muchos server_name, revisa periódicamente el log del catch‑all para detectar typos DNS o intentos maliciosos.

10. Variante: catch‑all como sinkhole anti‑escaneo

server {
    listen 80 default_server;
    server_name _;

    add_header Connection close;
    return 444;
}

Minimiza consumo y visibilidad; útil en origins no pensados para tráfico directo.

11. Variante: redirección canónica multi‑dominio

server {
    listen 80 default_server;
    server_name _;

    # Si llega desde un conjunto de dominios antiguos, redirige a su equivalencia
    if ($host ~* "^(old1\.com|old2\.net)$") { return 301 https://nuevo.com$request_uri; }

    # Resto, 404
    return 404;
}

12. Apéndice: plantilla completa combinada

# /etc/nginx/nginx.conf (extracto)
user  nginx;
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid       /var/run/nginx.pid;

events { worker_connections 4096; }

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;

    # Map para logging selectivo del catch‑all
    map $host $log_catch_all {
        default 1;
        ejemplo.com 0;
        www.ejemplo.com 0;
        api.ejemplo.com 0;
    }

    log_format main '$remote_addr - [$time_local] "$request" $status $body_bytes_sent '
                     '"$http_referer" "$http_user_agent" host=$host';

    include /etc/nginx/sites-enabled/*.conf;
}
# /etc/nginx/sites-available/00-catch-all-http.conf
server {
    listen 80 default_server reuseport;
    listen [::]:80 default_server;
    server_name _;

    access_log /var/log/nginx/catch-all.access.log main if=$log_catch_all;
    error_log  /var/log/nginx/catch-all.error.log warn;

    return 301 https://ejemplo.com$request_uri;
}
# /etc/nginx/sites-available/00-catch-all-https.conf
server {
    listen 443 ssl http2 default_server reuseport;
    listen [::]:443 ssl http2 default_server;

    server_name _;

    ssl_certificate     /etc/nginx/ssl/catch-all/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/catch-all/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;

    access_log /var/log/nginx/catch-all-https.access.log main if=$log_catch_all;
    error_log  /var/log/nginx/catch-all-https.error.log warn;

    return 308 https://ejemplo.com$request_uri;
}

13. Verificación rápida

  1. Resolver un Host aleatorio a tu IP pública y ejecutar:

    curl -I http://IP --header 'Host: noexiste.tld' curl -I https://IP --header 'Host: noexiste.tld' -k
  2. Confirmar que responde según tu política (301/308/404/444).

Compartir:

Binario 0
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.