Problema

En entornos de producción es habitual validar que un balanceador de carga solo exponga los puertos que la arquitectura requiere. Cuando se ejecuta un escáner de puertos (por ejemplo, nmap) contra la dirección DNS o IP de un Network Load Balancer (NLB) y aparecen puertos diferentes a los configurados en los listeners, el resultado genera dudas de seguridad y de configuración. El síntoma típico es:

  • Un listener configurado únicamente en 443/tcp.
  • El escáner muestra puertos adicionales (p. ej. 2000/tcp, 5060/tcp) como open o filtered.
  • El comportamiento se repite en varias ejecuciones y en diferentes rangos de IP.

Este patrón no es exclusivo de un caso puntual; ocurre en cualquier despliegue donde el NLB está delante de instancias EC2, contenedores o servicios en VPC y donde la visibilidad del tráfico se confunde entre el propio NLB y los recursos backend.

Causa

Los puertos inesperados pueden aparecer por varias razones que, combinadas, generan la ilusión de que el NLB “abre” puertos que no están en sus listeners:

  1. Dirección IP compartida
    Un NLB asigna direcciones IP estáticas dentro de la subred. Si la misma IP está asociada a un Elastic IP o a una instancia EC2 (por ejemplo, mediante un NAT Gateway), el escáner puede estar alcanzando directamente el host backend y no el NLB.

  2. Listeners implícitos por health checks
    Los health checks utilizan un puerto definido en el target group. Cuando el NLB recibe tráfico en ese puerto, responde con SYN‑ACK si el objetivo está sano, lo que nmap interpreta como puerto abierto.

  3. Target groups con múltiples puertos
    Un target group puede contener instancias que escuchan en varios puertos. Si el NLB tiene un listener en 443 que reenvía a un target en 443, pero el mismo target también expone 2000/tcp y 5060/tcp, el NLB no filtra esos puertos; simplemente los reenvía si el cliente los solicita directamente a la IP del NLB.

  4. Resolución DNS a varios IPs
    El nombre DNS de un NLB se resuelve a tres IPs (una por zona de disponibilidad). Si una de esas IP pertenece a otro recurso (por ejemplo, un EC2 con IP pública), el escáner verá puertos diferentes según la IP elegida.

  5. Reglas de seguridad en los targets
    Los Security Groups de las instancias backend pueden permitir tráfico en puertos no previstos. Como el NLB no aplica SG, el tráfico atraviesa la regla del target y se muestra como abierto.

  6. Configuración de proxy protocol o TLS termination errónea
    Cuando el NLB termina TLS y reenvía tráfico sin inspección, cualquier puerto que el cliente abra en la conexión TLS puede aparecer como abierto en la capa TCP.

Solución

Una estrategia robusta combina verificación de la configuración del NLB, inspección de los recursos backend y pruebas de red dirigidas. Los pasos siguientes son aplicables a cualquier despliegue de NLB con listeners limitados:

1. Confirmar la IP que está siendo escaneada

dig +short mysite.example.com

Comprueba que todas las direcciones IP devueltas pertenecen al NLB (puedes listarlas con aws elbv2 describe-load-balancers).

2. Listar listeners y target groups

aws elbv2 describe-load-balancers --names my-nlb
aws elbv2 describe-listeners --load-balancer-arn <arn>
aws elbv2 describe-target-groups --load-balancer-arn <arn>

Asegúrate de que solo exista el listener 443 y que los health‑check puertos sean los esperados.

3. Verificar puertos de health check

Revisa la configuración del health check en cada target group:

aws elbv2 describe-target-health --target-group-arn <tg-arn>

Si el health check usa un puerto distinto (p. ej. 2000), considera cambiarlo a traffic-port o a un puerto no expuesto.

4. Auditar Security Groups de los targets

aws ec2 describe-instances --filters "Name=instance-id,Values=$(aws elbv2 describe-target-health --target-group-arn <tg-arn> --query 'TargetHealthDescriptions[*].Target.Id' --output text)" \
  --query 'Reservations[*].Instances[*].SecurityGroups[*].GroupId' --output text | tr '\t' '\n' | sort -u

Revisa que los SG permitan solo el puerto 443 desde el CIDR del NLB.

5. Probar cada IP individualmente

Ejecuta nmap contra cada IP por separado:

for ip in $(dig +short mysite.example.com); do
  echo "Escaneando $ip"
  nmap -Pn -sT -p 0-65535 $ip
done

Si solo una IP muestra puertos extra, esa IP probablemente pertenece a un recurso distinto.

6. Aislar el tráfico con tcpdump en la instancia backend

sudo tcpdump -i any -nn port 2000 or port 5060

Observa si el tráfico proviene del NLB o de clientes externos.

7. Ajustar la configuración

  • Eliminar listeners no deseados: aws elbv2 delete-listener --listener-arn <arn>
  • Cambiar health‑check port a traffic-port o a un puerto interno.
  • Restringir SG a solo 443 desde el CIDR del NLB.
  • Desasociar Elastic IPs que compartan la misma IP del NLB.

Cuándo aplicar esta solución

Aplica este proceso cuando:

  • Un escáner muestra puertos abiertos que no están declarados en los listeners del NLB.
  • Los logs de acceso al NLB (AWS CloudWatch) indican tráfico en puertos inesperados.
  • Se sospecha de una posible exposición de servicios internos (SIP, SCCP, etc.).
  • La auditoría de seguridad requiere confirmar que el NLB actúa como único punto de entrada.

No es necesario seguir todos los pasos si ya se ha verificado que la IP escaneada pertenece exclusivamente al NLB y los SG de los targets están estrictamente limitados; en ese caso basta con revisar la configuración de health checks.

Código

# 1. Obtener ARN del NLB
nlb_arn=$(aws elbv2 describe-load-balancers --names my-nlb --query 'LoadBalancers[0].LoadBalancerArn' --output text)

# 2. Listar listeners
aws elbv2 describe-listeners --load-balancer-arn "$nlb_arn" --query 'Listeners[*].{Port:Port,Protocol:Protocol}' --output table

# 3. Listar target groups y health‑check ports
aws elbv2 describe-target-groups --load-balancer-arn "$nlb_arn" \
  --query 'TargetGroups[*].{TG:TargetGroupName,Port:Port,HealthCheckPort:HealthCheckPort}' --output table

# 4. Cambiar health‑check a traffic‑port (ejemplo)
tg_arn=$(aws elbv2 describe-target-groups --load-balancer-arn "$nlb_arn" --query 'TargetGroups[0].TargetGroupArn' --output text)
aws elbv2 modify-target-group --target-group-arn "$tg_arn" --health-check-port traffic-port

Verificación

  1. Re‑escaneo: Ejecuta nmap contra cada IP del NLB y confirma que solo el puerto 443 aparece como open.
  2. CloudWatch Logs: Busca eventos de conexión a puertos no deseados; deberían haber desaparecido.
  3. Pruebas de aplicación: Accede a la URL HTTPS y verifica que la respuesta es la esperada sin errores de protocolo.

Notas adicionales

  • Los NLB no utilizan Security Groups; la única capa de filtrado está en los targets. Por eso, la auditoría de