nc
我正在尝试从脚本执行命令,我的脚本正在nc
使用相同的源端口在目标的不同端口上执行命令。
例如:
nc -p 8140 -z -v -n 10.X.X.9 9090
nc -p 8140 -z -v -n 10.X.X.9 9091
nc -p 8140 -z -v -n 10.X.X.9 9092
nc -p 8140 -z -v -n 10.X.X.9 9093
and so on ...
第一次 nc 执行后,对于其余的所有行,我收到下面提到的错误消息。
nc: bind failed: Address already in use
nc: bind failed: Address already in use
nc: bind failed: Address already in use
有什么办法可以避免这种情况吗?
答案1
背景
当您尝试nc
以这种方式使用时,它会继续保持 TCP 端口打开,等待目的地确认接收到已完成的请求。这一点在维基百科上的 TCP 文章。
时间的等待
(服务器或客户端)表示等待足够的时间以确保远程 TCP 收到其连接终止请求的确认。 [根据 RFC 793,连接可以处于 TIME-WAIT 状态最多四分钟,称为 MSL(最大段生存期)。]
当我类似地使用时,你可以看到它的效果nc
:
$ nc -p 8140 -v -n 192.168.1.105 80
查看8140端口的状态:
$ netstat -anpt | grep 8140
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
事实上,在大多数 Linux 系统上,该时间TIME_WAIT
设置为 60 秒。
$ cat /proc/sys/net/ipv4/tcp_fin_timeout
60
如果您想亲自查看效果,可以使用此代码片段来观察端口何时被释放。
$ date; nc -p 8140 -v -n 192.168.1.105 80 -w 1; date; \
while netstat -anpt | grep 8140; do date; sleep 10; done; date
Tue Mar 25 09:46:59 EDT 2014
Connection to 192.168.1.105 80 port [tcp/*] succeeded!
Tue Mar 25 09:47:00 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:00 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:10 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:20 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:30 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:40 EDT 2014
tcp 0 0 192.168.1.3:8140 192.168.1.105:80 TIME_WAIT -
Tue Mar 25 09:47:50 EDT 2014
Tue Mar 25 09:48:00 EDT 2014
$
方法#1 - 使用 nc
8140 端口的释放需要一段时间。您要么需要等到它完全释放(在其间进行一些睡眠是一种简单的方法),要么使用不同的端口。
如果您只想查看端口@主机是否打开,您可以直接删除-p 8140
.
$ nc -zv -n 10.X.X.9 9090-9093
例子
$ nc -zv -n 192.168.1.200 2024-50000 |& grep -v refu
Connection to 192.168.1.200 5672 port [tcp/*] succeeded!
Connection to 192.168.1.200 35766 port [tcp/*] succeeded!
笔记:您可能想尝试将选项添加-w
到nc
,指示它仅等待一段时间。默认情况下nc
将永远等待。因此您的命令将是这样的:
$ nc -p 8140 -zv -n 10.X.X.9 9090 -w 1
然而,在我使用 1.84 在 CentOS 5.9 系统上进行的测试中,此后该端口仍然继续保持使用状态,因此您能做的最好的事情就是使用,因为这是生效-w 60
前的最短时间。TIME_WAIT
方法#2 - 使用 nmap
如果您想使用更合适的应用程序来扫描一组端口,那么我建议您使用它nmap
。
$ sudo nmap -sS --source-port 8140 -p 9090-9093 10.X.X.9
例子
$ sudo nmap -sS --source-port 8140 -p 80-85 homer
Starting Nmap 6.40 ( http://nmap.org ) at 2014-03-24 21:22 EDT
Nmap scan report for homer (192.168.1.105)
Host is up (0.0059s latency).
PORT STATE SERVICE
80/tcp open http
81/tcp closed hosts2-ns
82/tcp closed xfer
83/tcp closed mit-ml-dev
84/tcp closed ctf
85/tcp closed mit-ml-dev
MAC Address: 00:18:51:43:84:87 (SWsoft)
Nmap done: 1 IP address (1 host up) scanned in 11.36 seconds
在这里,我设置了一个过滤器,用于iptraf
证明流量是使用源端口 8140 发送到这些端口的。
笔记:特别注意#1在图中,显示了源端口 8140,而#2显示了我选择的几个目标端口,主要是 80 和 83。
参考
答案2
我想这也可能是一个答案,所以它至少是可读的:
i=0 ; until {
nc -p 8140 -av -n 10.X.X.9 909${i} &&
[ $((i=i+1)) -gt 4 ]
} 2>&-
do sleep 1
done
事实是,@slm 说得有道理nmap
- 对于处理网络和笔测试来说,它是一个不可或缺的工具,绝对值得您花时间来熟悉它。但对于测试 5:1 端口配置中的两台机器之间的连接性来说,可能有点多了。话又说回来,也许这是学习使用它的绝佳机会。
无论如何,如果你还没有可用的东西,netcat
非常灵活。而且,也许更重要的是,nc
不需要su root
去做0 个输入/输出操作一样nmap
。
在上面的答案中我只是使用$i
将目标端口的最后一位数字替换为0
对于你的第一轮和$i
的此后增值。因为,正如我所相信的,nc
应该给你返回一个true
只要它可以绑定你的本地端口,变量$i
仅当 8140 打开并且nc
可以用它来拨出。
$i
在测试中递增,以确保您不会超出9094
你指定的端口范围,此时它最终会返回true
从而满足until
并终止循环。
说到这里,until
你能bind
本地的8140 -p
奥尔特你的循环将sleep 1
第二次(正如 @slm 建议的那样),然后再试一次。
我只是放下stderr
和2>&-
所以你不必看无法绑定...向您的终端发送垃圾邮件。但正如所写,这可能永远没有必要,因为sleep
每次都会被调用$i
也会递增 - 除了循环中断时的最后一个 - 因此迭代之间的 1 秒暂停可能足以删除绑定的本地端口并再次打开它以在下一次迭代中使用。
如果我以某种方式弄错了nc
返回值和它returns false
即使它能在本地保护 8140,但目标端口已关闭,这可以通过更具体的使用来轻松处理$?
- 请让我知道。