用好你的瑞士军刀/netcat

最初作者是叫做“霍比特人”的网友 Hobbit hobbit@avian.org 于 1995 年在 UNIX 上以源代码的形式发布,Posix 版本的 netcat 主要有 GNU 版本的 netcat 和 OpenBSD 的 netcat 两者都可以在 debian/ubuntu 下面安装,但是 windows 下面只有 GNU 版本的 port 。
不管是程序员还是运维,熟悉这个命令都可以让很多工作事半功倍,然而网上基本 90% 的 netcat 文章说的都是老版本的 OpenBSD 的 netcat,已经没法在主流 linux 上使用了,所以我们先要检查版本:
在 debian/ubuntu 下面:
readlink -f $(which nc)看看,结果会有两种:

  • /bin/nc.traditional: 默认 GNU 基础版本,一般系统自带 。
  • /bin/nc.openbsd: openbsd 版本,强大很多 。
都可以用 apt-get install nc-traditional 或者 apt-get install nc-openbsd 来选择安装 。不管是 gnu 版本还是 openbsd 版本,都有新老的区别,主要是传送文件时 stdin 发生 EOF 了,老版本会自动断开,而新的 gnu/openbsd 还会一直连着,两年前 debian jessie 时统一升过级,导致网上的所有教程几乎同时失效 。
下面主要以最新的 GNU 版本为主同时对照更强大的 openbsd 版本进行说明 。
端口测试你在服务器 A主机(192.168.1.2) 上面 8080 端口启动了一个服务,有没有通用的方法检测服务的 TCP 端口是否启动成功?或者在 B 主机上能不能正常访问该端口?
进一步,如果而 A 主机上用 netstat -an 发现端口成功监听了,你在 B 主机上的客户端却无法访问,那么到底是服务错误还是网络无法到达呢?我们当然可以在 B 主机上用 telnet 探测一下:
telnet 192.168.1.2 8080但 telnet 并不是专门做这事情的,还需要额外安装,所以我们在 B 主机上用 netcat:
nc -vz 192.168.1.2 8080即可,v 的意思是显示多点信息(verbose),z 代表不发送数据 。那么如果 B 主机连不上 A 主机的 8080 端口,此时你就该检查网络和安全设置了,如果连的上那么再去查服务日志去 。
nc 命令后面的 8080 可以写成一个范围进行扫描:
nc -v -v -w3 -z 192.168.1.2 8080-8083两次 -v 是让它报告更详细的内容,-w3 是设置扫描超时时间为 3 秒 。
传输测试你在配置 iptable 或者安全组策略,禁止了所有端口,但是仅仅开放了 8080 端口,你想测试一下该设置成功与否怎么测试?安装个 Nginx 改下端口,外面再用 chrome 访问下或者 telnet/curl 测试下??还是 Python/ target=_blank class=infotextkey>Python -m 启动简单 http 服务 ?其实不用那么麻烦,在需要测试的 A 主机上:
nc -l -p 8080这样就监听了 8080 端口,然后在 B 主机上连接过去:
nc 192.168.1.2 8080两边就可以会话了,随便输入点什么按回车,另外一边应该会显示出来,注意,openbsd 版本 netcat 用了 -l 以后可以省略 -p 参数,写做:nc -l 8080 ,但在 GNU netcat 下面无法运行,所以既然推荐写法是加上 -p 参数,两个版本都通用 。
老版本的 nc 只要 CTRL+D 发送 EOF 就会断开,新版本一律要 CTRL+C 结束,不管是服务端还是客户端只要任意一边断开了,另一端也就结束了,但是 openbsd 版本的 nc 可以加一个 -k 参数让服务端持续工作 。
那么你就可以先用 nc 监听 8080 端口,再远端检查可用,然后又再次随便监听个 8081 端口,远端检测不可用,说明你的安全策略配置成功了,完全不用安装任何累赘的服务 。
(点击 Read more 展开)
 
测试 UDP 会话两台主机 UDP 数据发送不过去,问题在哪呢?你得先确认一下两台主机之间 UDP 可以到达,这时候没有 nginx 给你用了,怎么测试呢?用 python 写个 udp 的 echo 服务??运维不会认你写的工具的,即使连不通他也会认为你的程序有 bug,于是 netcat 又登场了,在 A 主机上:
nc -u -l -p 8080监听 udp 的 8080 端口,然后 B 主机上连上去:
nc -u 192.168.1.2 8080然后像前面测试 tcp 的方法进行检测,结束了 CTRL+C 退出,看看一边输入消息另外一边能否收到,收得到的话可能是你自己的服务原因,收不到的话把 nc 测试结果扔给运维/系统管理员,让他们赶快检查网关和防火墙配置,系统自带的工具测试的结果,既简单又权威 。
文件传输你在一台 B 主机上想往 A 主机上发送一个文件怎么办?不能用 scp / szrz 的话?继续 python 写个 http 上传?装个 ftpd 服务?不用那么麻烦,在 A 主机上监听端口:
nc -l -p 8080 > image.jpg然后再 B 主机上:


推荐阅读