有效地测试Linux上的端口是否打开?

从一个bash脚本如何快速找到端口445是否在服务器上打开/监听。

我已经尝试了几个选项,但我想要一些快速的:
1. lsof -i :445(花费秒)
2. netstat -an |grep 445 |grep LISTEN(花费秒)
3.telnet(它不返回)
4. nmapnetcat在服务器上不可用

知道一种不先枚举然后再grep的方法将会很好。

444682 次浏览

我最近发现的一个惊喜是Bash原生支持TCP连接作为文件描述符。使用方法:

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

我使用6作为文件描述符,因为0、1、2是stdin、stdout和stderr。5有时被子进程的Bash使用,所以3,4,6,7,8和9应该是安全的。

根据下面的注释,测试监听脚本中的本地服务器:

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

要确定是否有人正在监听,请尝试通过环回连接。如果失败了,端口就会被关闭,或者我们不允许进入。然后,关闭连接。

根据您的用例修改它,例如发送电子邮件、在失败时退出脚本或启动所需的服务。

它们列在/proc/net/tcp中。

它是十六进制中“:”后面的第二列:

> 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

所以我猜第三列中的:50必须是stackoverflow:o)

更多细节请查看man 5 proc。用sed等把它拆开,留给温和的读者做练习……

你可以这样使用netstat来获得更快的结果:

在Linux上:

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

在Mac:

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

这将输出在端口上侦听的进程列表(本例中为445),如果端口空闲,则不输出任何内容。

这里有一个非常简短的“快速回答”:如何测试远程TCP端口是否从Shell脚本打开?

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

我使用127.0.0.1作为“远程”地址。

如果端口是开放的,返回“0”,如果端口是关闭的,返回“1”

如。

nc -z 127.0.0.1 80; echo $?

- z指定nc只扫描监听守护进程, 没有发送任何数据给他们。使用此选项是错误的 conjunc - 带有-l选项的Tion。

ss -tl4 '( sport = :22 )'

2毫秒够快吗?

添加冒号可以在Linux上工作

下面是一个适用于Mac和Linux的方法:

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'

你可以使用netcat。

nc ip port < /dev/null

连接到服务器,然后直接重新关闭连接。如果netcat不能连接,它将返回一个非零退出码。退出码存储在变量$?举个例子,

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

当且仅当netcat成功连接到端口时返回0。

nc -l 8000

其中8000是端口号。如果端口是空闲的,它将启动一个可以轻松关闭的服务器。如果不是,它将抛出一个错误:

nc: Address already in use

如果你使用的是iptables,试试:

iptables -nL

iptables -nL | grep 445

nmap是正确的工具。 简单地使用nmap example.com -p 80

您可以从本地或远程服务器使用它。 它还可以帮助您识别是否有防火墙阻止访问

我想检查一个端口是否在我们的linux测试服务器上打开。 我可以通过尝试通过telnet从我的开发机器连接到测试服务器来做到这一点。在您的开发机器上尝试运行:

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

在这个例子中,我想检查主机test2.host.com上的端口8080是否打开

基于Spencer Rathbun的回答,使用bash:

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed

tcp是一个开销非常低的好工具。它还有一个timeout参数,以使它更快:

[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.

您也可以使用netcat命令

[location of netcat]/netcat -zv [ip] [port]

nc -zv [ip] [port]

-z -设置nc简单地扫描监听守护进程,而不实际向它们发送任何数据 -v -开启详细模式