SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor · Actualizado 2026-08-21

Cómo comprobar si un puerto está abierto en Linux

Aprenda a verificar puertos con ss, nc y nmap. Diferencie entre procesos en escucha local y bloqueos de firewall. Entienda por qué una conexión se cuelga o es rechazada.

Comprobar si un puerto está abierto en Linux: elija primero la pregunta correcta

Para comprobar si un puerto está abierto en Linux, decida primero qué pregunta está planteando, ya que "abierto" significa algo distinto según dónde se encuentre. En el propio servidor, abierto significa que un proceso está vinculado a ese puerto y a la espera. Desde otra máquina, abierto significa que un paquete llega a ese proceso y recibe una respuesta. Cuando no se recibe respuesta, la verdadera pregunta es qué dispositivo descartó el paquete. sudo ss -ltnp responde a la primera pregunta. nc -z o nmap responden a la segunda. Los contadores del firewall y tcpdump responden a la tercera.

Ejecutar la comprobación incorrecta es lo que hace perder una tarde. Una prueba realizada en el servidor nunca toca el firewall de red de su proveedor, ya que ese filtro se encuentra fuera del equipo. Si los números de puerto aún son nuevos para usted, cómo funcionan los puertos y sockets en Linux cubre el modelo que el resto de esta guía asume.

¿Qué está escuchando en este equipo? Lea la salida de ss

ss se distribuye con iproute2, por lo que está presente en todas las distribuciones actuales. netstat proviene de net-tools, que Ubuntu no instala por defecto desde hace años, por lo que netstat -tulpn suele responder netstat: command not found. Aprenda ss y evite decepciones.

sudo ss -ltnp

-l muestra solo los sockets en escucha. -t limita la lista a TCP. -n imprime números en lugar de resolver nombres, por lo que el comando devuelve el resultado al instante. -p nombra al proceso propietario y requiere root: sin sudo, la columna Process aparecerá vacía para cualquier proceso que no sea de su propiedad. Cambie -t por -u para ver UDP.

State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
LISTEN 0      4096   127.0.0.53%lo:53    0.0.0.0:*   users:(("systemd-resolve",pid=612,fd=14))
LISTEN 0      128    0.0.0.0:22          0.0.0.0:*   users:(("sshd",pid=921,fd=3))
LISTEN 0      511    127.0.0.1:8080      0.0.0.0:*   users:(("node",pid=1442,fd=19))
LISTEN 0      128    [::]:22             [::]:*      users:(("sshd",pid=921,fd=4))

La columna Local Address decide todo, y es la columna que la gente suele pasar por alto.

  • 0.0.0.0:22 significa todas las direcciones IPv4 de la máquina, por lo que es accesible desde el exterior si el firewall lo permite.
  • [::]:22 es lo mismo para IPv6.
  • 127.0.0.1:8080 significa solo loopback. Nada fuera de esta máquina puede alcanzarlo.
  • 10.20.0.5:5432 significa esa dirección de interfaz y ninguna otra, lo cual es común en configuraciones de red privada.
  • Una columna Process vacía suele indicar falta de sudo, no la ausencia de un proceso.

Para consultar un puerto específico, filtre dentro de ss en lugar de usar grep sobre toda la lista:

sudo ss -ltnp 'sport = :8080'
sudo lsof -nP -iTCP:8080 -sTCP:LISTEN
sudo fuser 8080/tcp

Una salida vacía en los tres casos significa que nada ocupa ese puerto. El servicio está detenido, falló al iniciar o está escuchando en otro lugar. Lea systemctl status <unit> y journalctl -u <unit> -n 50 antes de tocar una sola regla del firewall.

Por qué 127.0.0.1 en Local Address hace perder una tarde

Un socket vinculado a 127.0.0.1 no puede ser alcanzado desde otro host, y ninguna regla de firewall cambia eso. El kernel enruta 127.0.0.0/8 únicamente a la interfaz de loopback, y cualquier paquete que llegue a una tarjeta de red física con esa dirección de destino es descartado por considerarse un paquete marciano. Por lo tanto, el proceso se ejecuta, ss muestra que está escuchando, ufw allow 8080 informa de un éxito, y la conexión desde su portátil sigue fallando. Falla con un Connection refused instantáneo, porque el paquete llega a su dirección pública, no encuentra ningún socket vinculado allí, y el kernel responde con un TCP reset.

Muchos programas se vinculan al loopback a propósito, y para una base de datos o una interfaz de administración ese es el valor predeterminado correcto. Usted tiene dos opciones válidas. Cambie la dirección de vinculación en la propia configuración del programa (listen_addresses en postgresql.conf, bind en redis.conf, o el argumento host que acepte su aplicación) y luego abra el firewall. O déjelo en loopback y acceda a él a través de otro medio, como un reverse proxy de nginx, o un túnel SSH desde su portátil:

ssh -L 8080:127.0.0.1:8080 user@203.0.113.10

Docker mantiene la misma distinción en su flag de publicación. -p 8080:8080 vincula 0.0.0.0 y expone el contenedor a internet. -p 127.0.0.1:8080:8080 vincula el loopback y lo mantiene local.

Cómo comprobar si un puerto está abierto en Linux desde otra máquina

Ejecute esta prueba desde una red distinta. Una prueba desde el propio servidor solo confirma que la ruta de loopback funciona. Incluso conectarse a su propia IP pública desde el servidor omite el firewall de red de su proveedor, ya que ese filtro opera fuera del VPS.

nc -zv -w 3 203.0.113.10 443

-z se conecta y cierra sin enviar datos. -w 3 desiste tras tres segundos, y ese flag es importante: sin un tiempo de espera, un paquete descartado hace que el cliente reintente el SYN durante más de dos minutos antes de que el kernel se detenga. El éxito se muestra así:

Connection to 203.0.113.10 443 port [tcp/https] succeeded!

Si la herramienta no está instalada (nc: command not found), instale netcat-openbsd en Debian o Ubuntu, o utilice la redirección de red integrada en bash, que no requiere ningún paquete:

timeout 3 bash -c '</dev/tcp/203.0.113.10/443' && echo open || echo "no answer"

Esa sintaxis es una funcionalidad de bash, así que ejecútela con bash. /bin/sh en Debian y Ubuntu es dash, que no tiene /dev/tcp e informa de que la ruta no existe. Para un rango de puertos, o cuando desee que se le indique el estado, utilice nmap contra los hosts de los que sea responsable:

sudo nmap -Pn -p 22,80,443 203.0.113.10
sudo nmap -Pn -p 1-1024 203.0.113.10

-Pn omite el descubrimiento de hosts. La mayoría de los proveedores de VPS descartan el eco ICMP, por lo que sin -Pn nmap determina que el host está caído y no escanea nada. nmap imprime open cuando algo respondió y aceptó la conexión, closed cuando algo respondió con un reinicio, y filtered cuando no hubo respuesta alguna. Para un servicio web, curl -sS -o /dev/null -w '%{http_code}\n' https://example.com separa un fallo de red de un fallo de la aplicación, ya que un código de estado demuestra que toda la ruta funcionó.

Por qué un puerto bloqueado se queda colgado y uno cerrado rechaza la conexión de inmediato

Un rechazo instantáneo. El paquete llegó a la máquina y algo respondió.

nc: connect to 203.0.113.10 port 443 (tcp) failed: Connection refused

Dos causas distintas producen exactamente ese resultado. O bien no hay ningún proceso vinculado a esa dirección y puerto, por lo que el kernel respondió con un reset TCP, o bien una regla del firewall rechazó el paquete con un reset o un mensaje ICMP de puerto inalcanzable. Un rechazo es una respuesta definitiva y se recibe en un solo viaje de ida y vuelta.

Una pausa, seguida de un tiempo de espera agotado (timeout). Algo descartó el paquete y no devolvió nada.

nc: connect to 203.0.113.10 port 443 (tcp) timed out: Operation now in progress

Eso es lo que hace una regla DROP, y es lo que hace un firewall de proveedor o un grupo de seguridad en la nube. El silencio es la firma de un descarte, ya que el emisor no puede distinguir entre un descarte y un host inactivo.

El síntoma indica dónde investigar a continuación. Si la conexión es rechazada, los paquetes atraviesan la red correctamente; vuelva a ss -ltnp y verifique la dirección de enlace y el número de puerto. Si se agota el tiempo de espera, los paquetes están siendo descartados; revise los firewalls desde el exterior hacia el interior. conexión rechazada frente a tiempo de espera agotado en SSH analiza esta misma distinción para el puerto 22, que es donde la mayoría de los usuarios se encuentran con este problema.

ufw ofrece ambos comportamientos a propósito: ufw deny 8080 descarta los paquetes, y ufw reject 8080 envía un rechazo. En nftables, los dos destinos son drop y reject, y en iptables son -j DROP y -j REJECT. Las políticas por defecto son casi siempre de descarte, razón por la cual una regla ausente produce un cuelgue en lugar de un mensaje de error.

¿Quién bloquea el puerto? Trabaje desde fuera hacia adentro

sudo ufw status verbose
sudo iptables -L INPUT -n -v --line-numbers
sudo nft list ruleset

Los contadores de -v son la parte útil. Ejecute su prueba nc desde el exterior, vuelva a ejecutar el comando iptables y busque el contador que cambió: la regla cuyo conteo de paquetes aumenta es la que gestiona su tráfico. Esto sustituye las suposiciones por evidencia.

La prueba decisiva se ejecuta en el servidor, observando la red mientras usted se conecta desde fuera:

sudo tcpdump -ni any tcp port 8080

Un SYN que llega sin un SYN-ACK de respuesta significa que el paquete alcanzó su VPS y el host lo descartó, por lo que el firewall del proveedor funciona correctamente y sus reglas locales no. La ausencia total de salida significa que el paquete nunca llegó, por lo que la causa es el firewall del proveedor, un grupo de seguridad o una dirección IP incorrecta. Esa distinción elimina la mayor parte del trabajo.

Dos capas producen resultados que parecen imposibles. Primero, IPv6: si el nombre de host tiene un registro AAAA, su cliente puede conectarse mediante IPv6 mientras su regla solo cubre IPv4, así que pruebe cada familia con nc -4 y nc -6 antes de confiar en cualquier resultado. reglas de ufw y puertos IPv6 en un VPS cubre ese desajuste. Segundo, Docker: un puerto de contenedor publicado responde desde Internet incluso cuando ufw status lista ese puerto como denegado, porque esos paquetes se procesan antes de que la cadena de ufw los vea. por qué Docker publica puertos saltándose ufw contiene el mecanismo y la solución, y las reglas de ufw a configurar en un VPS nuevo es el conjunto base que conviene tener primero.

Por qué las respuestas UDP son ambiguas por diseño

UDP no tiene un proceso de negociación (handshake), por lo que una sonda no tiene nada en lo que tener éxito. nc -zu 203.0.113.10 53 termina con código 0 tan pronto como el paquete sale, lo cual prueba que su propia máquina lo envió, pero no prueba nada sobre el extremo remoto. Cuando un puerto UDP está cerrado, el host normalmente responde con un mensaje ICMP de puerto inalcanzable, y el kernel informa de ese error a un socket conectado solo en la siguiente escritura, por lo que una sonda de un solo paquete lo pasa por alto. Los firewalls descartan ICMP por costumbre, lo que elimina incluso esa pista. Esta es la razón por la que nmap muestra open|filtered para la mayoría de los puertos UDP: la ausencia de respuesta es exactamente lo que producen tanto un servicio abierto y silencioso como un puerto filtrado.

Pruebe UDP utilizando el protocolo que le interesa. Un servidor DNS responde a dig +short @203.0.113.10 example.com con una dirección o con nada. Un par de WireGuard muestra una línea reciente de latest handshake en sudo wg show. Luego, verifique la llegada en el lado del servidor:

sudo tcpdump -ni any udp port 51820

Si los paquetes aparecen mientras el cliente envía, significa que llegan, por lo que el problema está en el servicio o en la cadena de entrada (input chain). Si no hay paquetes en absoluto, significa que nunca llegaron allí.

Lista de comprobación para localizar fallos rápidamente

  1. En el servidor, ejecute sudo ss -ltnp 'sport = :8080'. Si no hay salida, significa que ningún proceso está escuchando; solucione primero el servicio.
  2. Si hay salida, lea la columna Local Address. 127.0.0.1 significa que el acceso externo es imposible hasta que cambie el enlace o coloque un proxy delante.
  3. Desde otra red, ejecute nc -zv -w 3 <public ip> 8080.
  4. Un rechazo le devuelve al paso 1. La dirección, el puerto o la máquina no son los que usted cree.
  5. Un tiempo de espera (timeout) indica que se están descartando paquetes. Inicie sudo tcpdump -ni any tcp port 8080 en el servidor y repita la prueba.
  6. Si llega el SYN pero no hay respuesta, el problema es el firewall del host. Encuentre la regla cuyo contador aumenta en sudo iptables -L INPUT -n -v.
  7. Si no llega ningún SYN, el problema es el firewall del proveedor, un grupo de seguridad o una dirección IP incorrecta.

FAQ

¿Cómo verifico qué puertos están abiertos en mi propio servidor Linux?

Ejecute sudo ss -ltnp para TCP y sudo ss -lunp para UDP. Cada línea representa un socket en escucha, y la columna Local Address le indica quién puede alcanzarlo: 0.0.0.0 y [::] aceptan conexiones desde cualquier lugar que el firewall permita, mientras que 127.0.0.1 solo acepta conexiones desde la propia máquina. La columna Process requiere privilegios de root, por lo que debe ejecutarlo con sudo o aparecerá vacía. ss es parte de iproute2 y siempre está instalado; netstat es parte de net-tools y generalmente no lo está.

¿Por qué ss muestra que mi servicio está escuchando pero aún no puedo conectarme?

Existen dos causas comunes y un comando permite distinguirlas. Si la Local Address es 127.0.0.1, el servicio está vinculado a la interfaz loopback y es inalcanzable desde cualquier otro host, ya que el kernel solo enruta ese rango a la interfaz local. Si es 0.0.0.0 y las conexiones siguen fallando, ejecute sudo tcpdump -ni any tcp port <port> en el servidor y conéctese desde el exterior. Un paquete SYN que llega sin respuesta significa que una regla local del firewall lo está descartando. Si no llega nada, el paquete está siendo detenido antes de alcanzar su VPS, generalmente por un firewall del proveedor o un grupo de seguridad.

¿Cuál es la diferencia entre una conexión rechazada y una que agota el tiempo de espera?

Un rechazo es una respuesta. El paquete llegó al host y recibió un reset TCP o un mensaje ICMP de puerto inalcanzable, lo que significa que no hay nada escuchando en esa dirección y puerto, o que una regla lo rechazó. Un tiempo de espera (timeout) es silencio: una regla descartó el paquete y no envió nada, por lo que su cliente reintenta hasta desistir. Un rechazo le indica que debe revisar el servicio y su dirección de enlace. Un tiempo de espera le indica que debe revisar el firewall, empezando por el más cercano al exterior.

¿Cómo verifico si un puerto UDP está abierto?

No puede obtener un "sí" fiable mediante un sondeo genérico, ya que UDP no tiene un handshake y un servicio silencioso se ve igual que un paquete descartado. nc -zu devuelve éxito tan pronto como envía el paquete, y nmap reporta open|filtered por la misma razón. Pruebe interactuando con el protocolo directamente: dig +short @<host> example.com para DNS, o sudo wg show para un peer de WireGuard con un handshake reciente. Para confirmar que los paquetes llegan, ejecute sudo tcpdump -ni any udp port <port> en el servidor mientras el cliente envía tráfico.

¿Puedo seguir usando telnet host port para probar un puerto?

Funciona para TCP, y Escape character is '^]' significa que la conexión fue aceptada. Salga con Ctrl+] y luego quit. Dos razones hacen que nc -z sea una herramienta superior: telnet no está instalado en la mayoría de las imágenes de servidor actuales, y nc permite definir un tiempo de espera con -w y establece un estado de salida que puede evaluar en un script. Cuando ninguno de los anteriores está disponible, timeout 3 bash -c '</dev/tcp/<host>/<port>' no requiere instalar ningún paquete.