有效测试Linux上是否打开了端口(没有nmap或netcat)

Ama*_*ain 192 linux bash shell port

从bash脚本中,如何快速查明端口是否445在服务器上打开/侦听.

我尝试了几个选项,但我想要一些快速的东西:
1.lsof -i :445 (需要几秒钟)
2. netstat -an |grep 445 |grep LISTEN(需要几秒钟)
3. telnet(它不会返回)
4. nmap,netcat在服务器上不可用

知道一种不首先枚举的方法和之后的greps会很高兴.

Spe*_*bun 154

我最近发现的一个惊喜是Bash本身支持tcp连接作为文件描述符.使用:

exec 6<>/dev/tcp/ip.addr.of.server/445
echo -e "GET / HTTP/1.0\n" >&6
cat <&6
Run Code Online (Sandbox Code Playgroud)

我使用6作为文件描述符,因为0,1,2是stdin,stdout和stderr.Bash有时会将5 用于子进程,因此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
Run Code Online (Sandbox Code Playgroud)

要确定某人是否正在侦听,请尝试通过环回进行连接.如果失败,则关闭端口或不允许访问.然后,关闭连接.

根据您的使用情况对此进行修改,例如发送电子邮件,在失败时退出脚本或启动所需服务.

  • 这只是挂在我身上。 (2认同)
  • 这不是一个可靠的方法,因为并非所有操作系统(例如我今天发现的 ubuntu 16)都附带了为构建“/dev/tcp/IP/PORT”树而编译的 bash (2认同)

小智 105

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

$ nc -z <host> <port>; echo $?
Run Code Online (Sandbox Code Playgroud)

我用127.0.0.1作为"远程"地址.

  • 与直觉相反,如果端口打开则返回"0",如果端口关闭则返回"1". (8认同)
  • 这似乎是最简单的方法,谢谢.示例脚本链接不再起作用了,但无论如何它都是非常自我解释的. (2认同)
  • -z标志在最近的发行版附带的基于nmap的ncat中不可用:Fedora,Centos等(nmap-ncat-6.01-9.fc18.x86_64) (2认同)
  • @Sean Unix命令通常返回“ 0”表示成功,对于失败则返回非零。因此,“ 0”表示成功连接,非零表示由于某种原因未连接。但是请注意,某些“ nc”版本不支持“ -z”参数,因此http://stackoverflow.com/a/25793128/6773916可以说是一个更好的解决方案。 (2认同)

anu*_*ava 89

您可以通过这种方式使用netstat以获得更快的结果:

在Linux上:

netstat -lnt | awk '$6 == "LISTEN" && $4 ~ /\.445$/'
Run Code Online (Sandbox Code Playgroud)

在Mac上:

netstat -anp tcp | awk '$6 == "LISTEN" && $4 ~ /\.445$/'
Run Code Online (Sandbox Code Playgroud)

这将输出监听端口的进程列表(在此示例中为445),或者如果端口空闲则不输出任何内容.

  • 这没什么输出. (21认同)
  • 实际上它是正确的语法,但可能你正在使用Linux,我在Mac上.对于Linux,请使用:`netstat -lnt | awk'$ 6 =="LISTEN"&& $ 4~".445"'` (6认同)

Ton*_*ony 38

你可以使用netcat.

nc ip port < /dev/null
Run Code Online (Sandbox Code Playgroud)

连接到服务器并再次直接关闭连接.如果netcat无法连接,则返回非零退出代码.退出代码存储在变量$?中.举个例子,

nc ip port < /dev/null; echo $?
Run Code Online (Sandbox Code Playgroud)

当且仅当netcat可以成功连接到端口时才会返回0.

  • `nc`为此目的有`-z`标志,它不需要从`/ dev/null`获取输入.使用上面的`-z`标志已经有了答案. (5认同)
  • 这个答案需要更多的赞成票。nc 非常适合这种情况。/dev/tcp 技巧很聪明,但似乎很难实现带有信号中断的脚本。 (2认同)
  • @AbeVoelker并非所有版本的nc都支持-z标志.我在CentOS 7上,发现Tony的解决方案是我需要的. (2认同)

and*_*oke 15

它们列在/ 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  
Run Code Online (Sandbox Code Playgroud)

所以我想:50第三列中的其中一个必须是stackoverflow:o)

寻找man 5 proc更多细节.并选择与sed等分开,留给温柔的读者练习......


use*_*062 15

根据Spencer Rathbun的回答,使用bash:

true &>/dev/null </dev/tcp/127.0.0.1/$PORT && echo open || echo closed
Run Code Online (Sandbox Code Playgroud)

  • 对于在新连接后不发送数据的服务的最佳解决方案。比调用 netcat 快大约 20 倍。可以缩写为 `: &amp;&gt;/dev/null &lt;/dev/tcp/127.0.0.1/$PORT` (3认同)

leu*_*cos 11

ss -tl4 '( sport = :22 )'
Run Code Online (Sandbox Code Playgroud)

2ms足够快?

添加冒号,这适用于Linux

  • 伟大的,'ss`甚至比`nc`更快.`l`代表_listening_,`4`代表IPv4; `sport`代表(当然)_source port_.上面的命令假设一个侦听TCP端口(`t`选项):对UDP使用`u`选项,或者对两个协议都不使用它们.关于`ss`的更多信息一如既往[Nixcraft](http://www.cyberciti.biz/tips/linux-investigate-sockets-network-connections.html).注意:`s`过滤器在这里不起作用,不知道为什么(bash 4.3.11,ss utility,iproute2-ss131122),必须使用_grep_. (2认同)

Art*_*era 6

这是适用于Mac和Linux的一个:

netstat -aln | awk '$6 == "LISTEN" && $4 ~ "[\\.\:]445$"'
Run Code Online (Sandbox Code Playgroud)


Jos*_*que 5

nc -l 8000
Run Code Online (Sandbox Code Playgroud)

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

nc: Address already in use
Run Code Online (Sandbox Code Playgroud)


raz*_*ang 5

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

$ telnet test2.host.com 8080
Trying 05.066.137.184...
Connected to test2.host.com
Run Code Online (Sandbox Code Playgroud)

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