Pruebe eficientemente si un puerto está abierto en Linux (sin nmap o netcat)


Desde un script bash ¿cómo puedo averiguar rápidamente si un puerto 445 está abierto/escuchando en un servidor?

He probado un par de opciones, pero quiero algo rápido:
1. lsof -i :445 (Toma segundos)
2. netstat -an |grep 445 |grep LISTEN (Toma segundos)
3. telnet (no regresa)
4. nmap, netcat no están disponibles en el servidor

Será bueno saber de una manera que no enumere primero y greps después de eso.

Author: Aurélien Ooms, 2012-03-08

13 answers

Una sorpresa que descubrí recientemente es que Bash soporta de forma nativa conexiones tcp como descriptores de archivo. Para utilizar:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6

Estoy usando 6 como descriptor de fichero porque 0,1,2 son stdin, stdout y stderr. 5 es usado a veces por Bash para procesos hijos , por lo que 3,4,6,7,8, y 9 deberían ser seguros.

Según el comentario a continuación, para probar la escucha en un servidor local en un script:

exec 6<>/dev/tcp/127.0.0.1/445 || echo "No one is listening!"
exec 6>&- # close output connection
exec 6<&- # close input connection

Para determinar si alguien está escuchando, intente conectarse por loopback. Si falla, entonces el puerto se cierra o no se nos permite el acceso. Después, cierre la conexión.

Modifique esto para su caso de uso, como enviar un correo electrónico, salir del script en caso de error o iniciar el servicio requerido.

 143
Author: Spencer Rathbun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-08 18:47:44

Hay un muy corto con "respuesta rápida" aquí : ¿Cómo probar si el puerto TCP remoto se abre desde el script de shell?

$ nc -z <host> <port>; echo $?

Lo uso con 127.0.0.1 como dirección "remota".

 96
Author: Yosemite Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:15

Puede usar netstat de esta manera para obtener resultados mucho más rápidos:

En Linux:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

En Mac:

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'

Esto generará una lista de procesos que escuchan en el puerto (445 en este ejemplo) o no generará nada si el puerto está libre.

 88
Author: anubhava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-07 20:53:23

Puede usar netcat para esto.

nc ip port < /dev/null

Se conecta al servidor y cierra directamente la conexión de nuevo. Si netcat no puede conectarse, devuelve un código de salida distinto de cero. El código de salida se almacena en la variable $?. Como ejemplo,

nc ip port < /dev/null; echo $?

Devolverá 0 si y solo si netcat pudo conectarse con éxito al puerto.

 35
Author: Tony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 17:21:00

Están listados en /proc/net/tcp.

Es la segunda columna, después del":", en hexadecimal:

> cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 10863 1 ffff88020c785400 99 0 0 10 -1                     
   1: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7983 1 ffff88020eb7b3c0 99 0 0 10 -1                      
   2: 0500010A:948F 0900010A:2328 01 00000000:00000000 02:00000576 00000000  1000        0 10562454 2 ffff88010040f7c0 22 3 30 5 3                   
   3: 0500010A:E077 5F2F7D4A:0050 01 00000000:00000000 02:00000176 00000000  1000        0 10701021 2 ffff880100474080 41 3 22 10 -1                 
   4: 0500010A:8773 16EC97D1:0050 01 00000000:00000000 02:00000BDC 00000000  1000        0 10700849 2 ffff880104335440 57 3 18 10 -1                 
   5: 0500010A:8772 16EC97D1:0050 01 00000000:00000000 02:00000BF5 00000000  1000        0 10698952 2 ffff88010040e440 46 3 0 10 -1                  
   6: 0500010A:DD2C 0900010A:0016 01 00000000:00000000 02:0006E764 00000000  1000        0 9562907 2 ffff880104334740 22 3 30 5 4                    
   7: 0500010A:AAA4 6A717D4A:0050 08 00000000:00000001 02:00000929 00000000  1000        0 10696677 2 ffff880106cc77c0 45 3 0 10 -1  

Así que supongo que uno de esos :50 en la tercera columna debe ser stackoverflow: o)

Busque en man 5 proc para más detalles. y separar eso con sed etc se deja como un ejercicio para el lector amable...

 14
Author: andrew cooke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-07 21:26:13
ss -tl4 '( sport = :22 )'

2ms es lo suficientemente rápido ?

Agregue los dos puntos y esto funciona en Linux

 10
Author: leucos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-07 11:53:42

Basado en la respuesta de Spencer Rathbun, usando bash:

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed
 7
Author: user1338062,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-12 08:51:36
nc -l 8000

Donde 8000 es el número de puerto. Si el puerto está libre, iniciará un servidor que puede cerrar fácilmente. Si no lo es, lanzará un error:

nc: Address already in use
 5
Author: Jose Enrique,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 16:23:28

Quería comprobar si un puerto está abierto en uno de nuestros servidores de prueba de Linux. Pude hacer eso al intentar conectar con telnet desde mi máquina de desarrollo al servidor de prueba. En tu máquina de desarrollo intenta ejecutar:

$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com

En este ejemplo quiero comprobar si el puerto 8080 está abierto en la sede test2.host.com

 5
Author: razvang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-03 09:01:18

Aquí hay uno que funciona tanto para Mac como para Linux:

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'
 4
Author: Artur Bodera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-11 12:26:23

Tcping es una gran herramienta con una muy baja overhead.It también tiene un argumento de tiempo de espera para hacerlo más rápido:

[root@centos_f831dfb3 ~]# tcping 10.86.151.175 22 -t 1
10.86.151.175 port 22 open.
[root@centos_f831dfb3 ~]# tcping 10.86.150.194 22 -t 1
10.86.150.194 port 22 user timeout.
[root@centos_f831dfb3 ~]# tcping 1.1.1.1 22 -t 1
1.1.1.1 port 22 closed.
 1
Author: Payam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 23:58:06

nmap es la herramienta correcta. Simplemente use nmap example.com -p 80

Puede usarlo desde un servidor local o remoto. También le ayuda a identificar si un firewall está bloqueando el acceso.

 -1
Author: zainengineer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-28 09:39:01

Si estás usando iptables prueba:

iptables -nL

O

iptables -nL | grep 445
 -3
Author: Noz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-23 18:43:17