远程主机上一个端口的状态查询

168

我需要一个命令行可以检查远程主机的端口状态。我尝试了ping xxx.xxx.xxx.xxx:161但它无法识别"host"。当我对一个已知打开该端口的主机执行相同的命令时,我认为这是一个"好"答案,直到此时。这是用于Windows批处理文件的,将检查远程端口状态,然后运行使用该远程端口信息的命令,再次进行远程端口检查命令,然后在下一个服务器上使用该端口的命令以获取信息,如此循环。我已经到处找过了,认为ping可能可以解决问题,但我想可能有各种版本的ping,因为我正在执行此操作的服务器上没有显示该选项。

只是为了好玩,我尝试了一个基于Web的远程端口检查器-结果对于"问题"服务器和正确的服务器都是正确的。然而,我不能在批量运行中使用500多个服务器IP。

是否有一些简单的方法?我的Perl技能非常生疏(不用就会丢失),不知道其他基于Windows的语言,除了batch之外。Unix是我的专长,但这必须从Widows Server 2003执行。


5
你或许想要尝试在serverfault.com上询问。 - John Rasch
1
有人已经做过这个了:http://serverfault.com/questions/309357/ping-a-specific-port - Vadzim
1
由于此问题已关闭,我在这里回答了。 - npocmaka
2
在 Windows 中输入 ps> tnc xxx.xxx.xxx.xxx -port 161 - Moslem Shahsavan
黄金标准无疑是 nmap nmap.org,但通常需要 root 权限才能获得“最佳结果”。例如,它会退回到标准的 TCP 连接扫描 (-sT),而不是隐秘的 syn 扫描 (-sS)。这在功能上等同于 netcat,但具有良好的多主机和加速能力。nmap -sT google.com 输出:... ... PORT STATE SERVICE 80/tcp open http 443/tcp open https - Milovan Tomašević
8个回答

163
你似乎在寻找端口扫描器,例如nmapnetcat,它们都可以在Windows、Linux和Mac OS X上使用。
例如,在已知的IP地址上检查telnet:
nmap -A 192.168.0.5/32 -p 23

例如,在 host.example.com 上查找从 20 到 30 的开放端口:
nc -z host.example.com 20-30

1
你的nmap命令应该是"-p23",没有空格。nmap将每个不紧接着标志的单元视为单独的扫描目标。 - Brandon Lebedev
18
应该是 nc -zv host.example.com 20-30。否则就没有输出。 - Aryeh Beitz
1
nc 命令的选项 -z 在 Linux 上不可用。 - valentin_nasta
1
@valentin_nasta 是的,也许取决于您使用的netcat版本(gnu或openbsd)。这是我在Arch Linux系统上使用的nc(openbsd版本)手册中的相关行: -z 指定nc只扫描侦听守护程序,而不向它们发送任何数据。在与-l选项一起使用此选项是错误的。 - pgoetz
我不得不在nc命令中添加一个-w5选项(nc -w5 -zv host.example.com 20-30),这样它才能在合理的时间内超时,从而变得可用。我相信默认的超时时间是“永远”(也许是当网络堆栈决定失败连接请求时?)。无论如何,5秒似乎已经足够长了。 - undefined
显示剩余2条评论

132

在命令提示符中,您可以使用telnet命令。例如,要连接到IP地址为192.168.10.1的80端口:

telnet 192.168.10.1 80

要在Windows 7及以上版本中启用telnet,请点击。根据链接的文章,通过控制面板->程序和功能->Windows功能->telnet客户端启用telnet,或者在管理员提示符中运行此命令:

dism /online /Enable-Feature /FeatureName:TelnetClient

3
如果Windows设备已安装Telnet,这是最简单的方法。 - shonky linux user
30
在Windows系统(例如我使用的是Windows 8.1),将其添加到控制面板的程序中心需要2秒钟,方法是:打开“控制面板”→“程序”→“打开或关闭Windows功能”。 - Chris Moutray
14
仅供参考:如果端口没有打开:连接到#####...无法打开到端口####的主机连接:连接失败;如果端口已经打开,你将进入 telnet(按CTRL+] 然后键入 'quit' 退出)。 - blackstrype

29

为了编写脚本,我发现curl命令可以做到,例如:

$ curl -s localhost:80 >/dev/null && echo Connected. || echo Fail.
Connected.
$ curl -s localhost:123 >/dev/null && echo Connected. || echo Fail.
Fail.

可能并非所有服务都适用,因为curl在某些情况下可以返回不同的错误代码(根据评论),因此添加以下条件可以可靠地工作:

[ "$(curl -sm5 localhost:8080 >/dev/null; echo $?)" != 7 ] && echo OK || echo FAIL

注意:添加-m5以设置最大连接超时时间为5秒。

如果您还想检查主机是否有效,您需要同时检查6的退出代码:

$ curl -m5 foo:123; [ $? != 6 -a $? != 7 ] && echo OK || echo FAIL
curl: (6) Could not resolve host: foo
FAIL

要解决返回的错误代码问题,只需运行:curl host:port,例如:

$ curl localhost:80
curl: (7) Failed to connect to localhost port 80: Connection refused

请查看:man curl 以获取完整的退出码列表。


很遗憾,这对我来说不起作用(至少在OS X的bash中不行)。 - Mike Atlas
1
一个自定义服务。顺便说一下,它有点工作:curl $IP:$PORT 会产生以下结果: curl: (52) Empty reply from server(与 curl: (7) Failed to connect 相比),但就像 nc 一样,我无法像预期的那样使用 | grep Empty 来过滤这些输出语句(可能是关于换行符或缺乏即时输出的问题?)。我假设你的代码行是基于退出代码的条件语句,对吗?我在 El Cap 上;也许在其他版本或操作系统中,失败状态的退出值为 -1 而不是 52 - Mike Atlas
是的,这样就可以了。curl -s $IP:$PORT >/dev/null; if [ $? -eq 52 ]; then echo "已连接."; else echo "失败."; fi - Mike Atlas
1
这个问题是关于Windows的,显然它没有例如/dev/null。 - Arthur Tacca
@ArthurTacca 你可以随时使用Windows子系统Linux(WSL)。 - kenorb

25
< p>按下< kbd > Windows < /kbd > + < kbd > R < /kbd > 键,键入< code > cmd < /code > 然后按< kbd > Enter < /kbd >< /p> < p>在命令提示符中键入

telnet "machine name/ip" "port number"
如果端口未打开,将显示此消息:
"Connecting To "machine name"...Could not open connection to the host, on port "port number":
否则您将被带入打开的端口(将显示空屏幕)。

9
请注意,在现代 Windows 系统中,默认情况下未安装 Telnet。您需要从“添加/删除 Windows 功能”控制面板中安装它。 - Greg
1
请使用@Greg或类似的在线工具,例如http://telnet-online.net/。 - o.z
2
@o.z 是真的,除非你正在检查内部服务器的状态。 - Greg
适用于Windows10。 - Gaurav

21

使用 nc 命令,

nc -zv <hostname/ip> <port/port range>

For example,
nc -zv localhost 27017-27019
or
nc -zv localhost 27017

你也可以使用telnet命令

telnet <ip/host> port

4

nc或“netcat”还有一种扫描模式,可能会有用。


3
在Mac上,“nc -zv server port-range”的意思是检查服务器是否处于活动状态,并测试指定的端口范围是否开放。 - Vijay Kumar

2
在Bash中,您可以使用伪设备文件来打开与关联套接字的TCP连接。语法为/dev/$tcp_udp/$host_ip/$port
下面是一个简单的示例,用于测试Memcached是否正在运行:
</dev/tcp/localhost/11211 && echo Port open || echo Port closed

这里是另一个测试,用于检查特定网站是否可访问:

$ echo "HEAD / HTTP/1.0" > /dev/tcp/example.com/80 && echo Connection successful.
Connection successful.

了解更多信息,请查看:高级Bash脚本编程指南:第29章。/dev/proc

相关内容:在SuperUser上测试远程系统的端口是否可达(无需telnet)

有关更多示例,请参见:如何在Bash shell中打开TCP / UDP套接字(文章)。


2
哇,这太厉害了!我不知道只用 bash 就可以做到这一点。对于像我这样只安装了 Git Bash 在 Windows 上,并且不想安装其他服务的人来说,这太方便了。 - dotslashlu

2
我认为你正在寻找Hping (http://www.hping.org/),它有一个Windows版本。

"该界面受到unix命令ping(8)的启示,但hping不仅能够发送ICMP回显请求。 它还支持TCP,UDP,ICMP..."

如果你想查看TCP端口在路由中被阻止的位置(比如由防火墙),而ICMP可能无法做到这一点,那么它也非常有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接