|

Verificar puertos abiertos: 3 estados, no 2

En pocas palabras: Un chequeo de puerto tiene tres respuestas posibles: abierto (handshake TCP completo), cerrado (el host responde con un RST) y desconocido (timeout, fallo de DNS o firewall). Lo documentó Merlonix tras analizar 13.489 chequeos en cinco semanas (corte: agosto de 2026): el timeout jamás indica que el servicio esté caído.

Verificar puertos abiertos tiene tres respuestas posibles, no dos: abierto, cerrado y desconocido. Lo documentó Merlonix tras medir 13.489 chequeos durante cinco semanas (corte: agosto de 2026): todos devolvieron “desconocido” por una restricción de Cloudflare Workers que ningún monitor clasificaba bien.

Verificar puertos abiertos es probar si un servicio TCP acepta conexiones en una dirección y puerto determinados. La práctica tradicional lo reduce a dos resultados, abierto o cerrado, pero un timeout o un fallo de DNS no dicen nada del puerto: avisan que tu sonda no pudo averiguarlo. Según el análisis que Merlonix publicó en dev.to, las respuestas honestas son tres, y la tercera evita la mayoría de las falsas alarmas.

En 30 segundos

  • Son tres estados: abierto (handshake TCP completo), cerrado (el host contesta con un RST) y desconocido (timeout, fallo de DNS o firewall).
  • El timeout no prueba nada: informa que la sonda no obtuvo respuesta, jamás que el servicio esté caído.
  • 13.489 de 13.489 checks ejecutados en cinco semanas (corte: agosto de 2026) dieron “desconocido”: Cloudflare Workers prohíbe sockets crudos hacia los puertos 80 y 443 (sí, en serio).
  • Regla de alertas: paginá solo ante rechazo determinista; el desconocido se registra con su motivo y no despierta a nadie.
  • Cuidado con el SSRF: un monitor que acepta hostnames externos debe resolver una vez, validar la IP y conectar a esa IP.

Cloudflare es una empresa estadounidense fundada en 2009 por Matthew Prince, Lee Holloway y Michelle Zatlyn, que ofrece servicios de infraestructura web como CDN, mitigación de ataques DDoS, seguridad de aplicaciones y resolución DNS para sitios y servicios conectados a internet.

¿Por qué verificar puertos abiertos no da solo dos resultados?

Porque una conexión que no prospera no es un dato: son varios datos mezclados, y apenas uno significa que el servicio cayó. Cuando abrís un socket TCP y lo corrés contra un timeout pueden pasar cuatro cosas distintas: el handshake completa, el host rechaza la conexión, el nombre no resuelve o la respuesta nunca llega. El monitor binario mete las cuatro en la misma bolsa y les canta “caído” a todas.

Ese atajo sale caro.

Pensá el escenario clásico: son las 3 de la mañana, suena el pager, saltás de la cama, abrís el notebook y el puerto estaba perfecto; lo único que pasó es que un probe tuvo cinco segundos malos. Después de la tercera falsa dejás de creerle al sistema y agregás una regla de mute. Ojo: esa regla sigue instalada la noche en que el puerto se cae de verdad. El análisis de Merlonix es tajante en esto: la fatiga de alertas no la causa el exceso de alertas, sino las alertas que aprendiste a no creer.

¿Cuáles son los tres estados reales de un chequeo TCP?

Cada estado corresponde a un resultado concreto del intento de conexión, y cada uno cuenta una historia distinta. Relacionado: proteger las credenciales de tus servicios expuestos.

  • Abierto: el handshake completó. Hay algo escuchando y aceptando conexiones. Este resultado es real y verificable.
  • Cerrado: el host está vivo y respondió con un RST, es decir, te dijo “acá no hay nada en este puerto”. Es el negativo determinista, el único que justifica despertar gente.
  • Desconocido: todo lo demás. Timeout, fallo de resolución DNS, rate-limit, error transitorio del edge. Ninguno informa el estado del puerto; informan que no pudiste saberlo.
EstadoQué pasa a nivel TCPQué te dice¿Suena el pager?
AbiertoHandshake completoHay un servicio aceptando conexionesNo
CerradoEl host responde con RSTEl host vive, pero nada escucha en ese puerto
DesconocidoTimeout, fallo de DNS o bloqueoTu sonda no pudo averiguarloNo
verificar puertos abiertos diagrama explicativo

La analogía que mejor lo resume es la de un sitio web: “el servidor devolvió 404” y “el request se colgó” no significan lo mismo. El rechazo habla del puerto; el timeout habla de tu probe. Un monitor que registra el timeout como caída está afirmando algo que no sabe.

¿Qué significa que un puerto esté “filtrado”?

Filtrado significa que un dispositivo intermedio, típicamente un firewall, descarta tus paquetes sin contestar. Es la causa más común del estado desconocido: la sonda envía el SYN, nadie responde, el timer vence y el chequeo termina sin información útil.

  • Firewall con política DROP: descarta en silencio; desde afuera es indistinguible de una red muerta.
  • Rate limiting: tu proveedor de probing o el destino frenan consultas repetidas.
  • Fallo puntual de DNS: el nombre no resolvió en ese intento.
  • Error transitorio de ruta: la conexión falló cinco segundos y se recuperó sola.

La diferencia con el puerto cerrado es enorme aunque el resultado parezca igual. En el estado cerrado hay una respuesta activa, un RST. En el filtrado, no hay ninguna. La primera es información del host; la segunda, un misterio.

¿Cómo verificar si un puerto está abierto en tu servidor?

Desde dentro del servidor usá ss o netstat para listar lo que escucha; desde fuera, Nmap, Netcat o un verificador online. Te puede servir nuestra cobertura sobre por qué un DNS mal configurado también devuelve silencio.

  • Linux, adentro del server: ss -tulpn lista los puertos en escucha con el proceso dueño de cada uno; la guía de EsGeeks detalla variantes con netstat y lsof.
  • Desde otra máquina: nmap -p 443 tudominio.com responde open, closed o filtered para ese puerto puntual; con -p- barrés el rango completo.
  • Windows: en PowerShell, Test-NetConnection -ComputerName tudominio.com -Port 443 te dice si el TCP llegó a destino.
  • Sin instalar nada: un verificador online confirma desde internet si tu firewall deja pasar el puerto, ideal para validar reglas recién aplicadas.
  • Detrás de un NAT: el resultado mide la configuración del router, no la del servidor; si el port forwarding no existe, vas a ver filtrado aunque el servicio esté vivo.

Si el server corre sobre un VPS administrado (ponele, alguno de los planes de donweb.com), el panel suele traer visor de puertos y firewall que te ahorra media tarea.

¿Nmap o Netcat para chequear un puerto puntual?

Para la pregunta “¿está vivo el 587?”, cualquiera de los dos zafa. Netcat (nc -zv host puerto) es el martillo chico: rápido, sin vueltas, perfecto para un chequeo único o para un script. Nmap suma cuando necesitás rangos de puertos, detección de versión o scripts NSE. Mi criterio después de años haciendo esto: Netcat para diagnóstico puntual, Nmap para auditoría.

¿Cómo evitar que el monitoreo dispare alertas falsas?

Con una regla única: alertá solo cuando el host rechaza la conexión de forma determinista. Todo lo demás se registra como desconocido con su motivo, y nadie se entera hasta que haya certeza.

  • CONNECTION_REFUSED: llegó un RST. Acá sí, página al oncall.
  • TIMEOUT: nadie respondió a tiempo. Se registra, no se alerta.
  • DNS_FAILURE: el nombre no resolvió. Problema de tu probe, no del puerto.
  • FILTERED_OR_DROPPED: descarte silencioso, típico de firewall.
  • PORT_RESTRICTED_BY_RUNTIME: el entorno prohíbe la operación (caso Workers, ya llegamos).

El equipo de Merlonix aprendió esto a las malas: durante un tiempo todos sus hosts alcanzables devolvían desconocido, correcto por cierto, pero sin motivo. Desde afuera era imposible distinguir un problema real de un monitor roto. ¿Timeout? ¿Resolver roto? ¿Alguno guard rechazando el probe? Nadie lo sabía, porque el registro decía “desconocido” y nada más. El arreglo es aburrido y obligatorio: cada resultado persiste un código de motivo estable junto al estado. Un desconocido con motivo se puede debuggear; uno callado solo se mira.

Detalle extra: si el rechazo es permanente, metele backoff en vez de reintentar eternamente. Reintentar para siempre una operación imposible solo quema recursos. Para más detalles técnicos, mirá a veces ese timeout es solo cold start.

¿Por qué tu verificador de puertos es una puerta a SSRF?

Porque un monitor toma un hostname y un puerto de un usuario y abre un socket hacia allá. Leído con ojos de atacante: abre una conexión a una dirección que el usuario controla. Si el usuario apunta el check a 127.0.0.1 o al endpoint de metadata del cloud, tu herramienta se convierte en un escáner de puertos interno, el clásico primitivo de Server-Side Request Forgery. “¿Está abierto el 6379 en esta IP privada?” es una pregunta que tu infraestructura no debería responderle a un desconocido.

La defensa obvia es resolver el hostname y rechazar cualquier IP privada, de loopback, link-local o reservada antes de conectar. Necesario, sí. Suficiente, no. Probamos el guard ingenuo primero (spoiler: no funcionó), porque ahí aparece el DNS rebinding, un bug de tipo time-of-check-to-time-of-use: resolvés, obtenés una IP pública, tu chequeo la aprueba y, milisegundos después, la capa de sockets vuelve a resolver el nombre y el DNS del atacante entrega la IP interna. Validaste una cosa y marcaste otra. ¿Y si igual hiciste el chequeo de IPs privadas? Da igual: ese “escudo” revisó una resolución distinta de la que usa el socket.

La solución cabe en una línea: resolvé una vez, pasá todas las direcciones devueltas por el filtro de IPs privadas y entregale al socket la IP literal que ya validaste, nunca el hostname. Sin segunda resolución no hay nada que envenenar. Y en un probe TCP crudo es gratis: como no hacés TLS, no necesitás SNI ni certificado que justifique conservar el nombre.

Cloudflare Workers y los puertos 80 y 443: el caso de los 13.489 checks

Workers prohíbe abrir sockets crudos hacia los puertos 80 y 443. Si tu probe no lo contempla, va a producir “desconocido” para siempre en los dos puertos más comunes del planeta. Los números lo confirman: 13.489 checks en cinco semanas (corte: agosto de 2026), 13.489 desconocidos (que no es poco), todos provocados por esa restricción. Peor todavía: los archivaron bajo el código genérico “transient, retry”, así que el sistema reintentó durante semanas una operación imposible, y nadie leyó el texto del error, que incluso sugería usar fetch para servicios HTTP. Sobre eso hablamos en guardar el histórico de checks sin costo de egreso.

¿Y qué hizo el checker ingenuo con ese error? Exacto: como la conexión no prosperó y el texto no contenía “refused”, todo aterrizó en desconocido. Técnicamente impecable e inútil por completo.

  • Hacé legible el rechazo: ese error es una propiedad permanente del par runtime/puerto, no un blip. Merece su propio código de motivo y backoff, no el cajón de “transitorio”.
  • Respondé la pregunta por otro camino: sobre HTTP. Un único request con redirects deshabilitados y cuerpo sin leer; cualquier respuesta (200, 401, 503, da igual cuál) prueba que el TCP se estableció y algo está sirviendo en ese puerto, que es justo lo que preguntabas.

Ojo con los redirects: un 301 puede llevarte a otro puerto y convertir una afirmación verdadera sobre el puerto original en mentira. Por eso van deshabilitados. La lección general sobrevive al runtime específico: cuando tu infraestructura rechaza una operación, leé por qué la rechaza. Muchas veces el rechazo es la respuesta a tu pregunta, disfrazada de error.

Errores comunes al verificar puertos abiertos

Estos cuatro aparecen una y otra vez en equipos reales.

  • Tratar el timeout como caída. Es la madre de la fatiga de alertas. Corrección: tres estados y alerta solo ante RST.
  • Validar el hostname y luego marcar el hostname. Clásico TOCTOU por rebinding. Corrección: resolver una vez y conectar a la IP validada.
  • Archivar rechazos permanentes como transitorios. Terminás reintentando para siempre, como los 13.489. Corrección: código de motivo propio más backoff.
  • Registrar desconocido sin motivo. Callejón sin salida garantizado para quien esté de guardia. Corrección: campo de motivo obligatorio, persistido junto al estado.

Preguntas Frecuentes

¿Cómo verifico si un puerto está abierto en mi servidor?

Primero desde adentro: en Linux, ss -tulpn muestra los puertos en escucha con su proceso. Después desde afuera: nmap -p PUERTO tudominio.com devuelve open, closed o filtered. En Windows alcanza con Test-NetConnection en PowerShell. Si el server vive detrás de un NAT, el chequeo externo refleja la configuración del router.

¿Cuál es la diferencia entre un puerto cerrado y un timeout?

Un puerto cerrado respondió: el host mandó un RST y avisó que no hay servicio ahí. Un timeout es ausencia de respuesta: firewall, fallo de DNS o ruta caída. El cierre es información del puerto; el timeout, información de tu sonda. Solo el primero confirma que no hay servicio.

¿Por qué mi monitoreo de puertos dispara alertas falsas?

Casi seguro porque clasifica los timeouts como caídas. Un probe con cinco segundos malos genera una página a las 3 AM por un servicio sano, y tras tres falsas el equipo instala reglas de mute que siguen activas la noche del incidente real. La cura: estado desconocido, motivo obligatorio y alerta solo en rechazo determinista.

¿Qué significa “desconocido” en un verificador de puertos?

Que la sonda no pudo determinar el estado: timeout, error de resolución DNS, rate-limit o bloqueo intermedio. No afirma nada sobre el puerto y debería venir con un código de motivo persistido (CONNECTION_REFUSED, TIMEOUT, DNS_FAILURE) para poder debuggearse. Si tu herramienta solo distingue abierto o cerrado, está adivinando en cada timeout.

¿Cómo evito vulnerabilidades de SSRF en un monitor de puertos?

Resolvé el hostname una sola vez, rechazá toda IP privada, loopback, link-local o reservada y conectate a la IP validada en lugar de re-resolver el nombre. Eso elimina el vector de DNS rebinding, donde el atacante entrega una IP pública a tu chequeo y una privada al socket un instante después.

Conclusión

Lo que dejó plantado Merlonix no exige tecnología nueva: exige honestidad en el instrumento de medición. Un monitor que solo sabe decir abierto o cerrado está adivinando en cada timeout, y gasta ese adivinanza en despertarte de madrugada. Antes de cerrar la pestaña, hacé tres chequeos sobre tus propias herramientas: ¿alertan ante timeouts?, ¿persisten un motivo por cada estado?, ¿marcan la IP validada o vuelven a resolver el hostname? Son diez minutos que evitan tanto el pager falso de las 3 AM como el escaneo interno que un guard mal hecho puede provocarte. Y si estás por exponer un servicio nuevo, mirá los túneles: RedesZone tiene una guía completa de Cloudflare Tunnel para publicar aplicaciones sin abrir puertos de entrada en el firewall.

Fuentes

Te puede interesar...