用好你的网络瑞士军刀 netcat
作者:韦易笑
来源:https://zhuanlan.zhihu.com/p/83959309
在 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 版本进行说明。
端口测试
telnet 192.168.1.2 8080
nc -vz 192.168.1.2 8080
nc -v -v -w3 -z 192.168.1.2 8080-8083
两次 -v
是让它报告更详细的内容,-w3
是设置扫描超时时间为 3 秒。
传输测试
nc -l -p 8080
这样就监听了 8080 端口,然后在 B 主机上连接过去:
nc 192.168.1.2 8080
-l
以后可以省略 -p
参数,写做:nc -l 8080
,但在 GNU netcat 下面无法运行,所以既然推荐写法是加上 -p
参数,两个版本都通用。测试 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 测试结果扔给运维/系统管理员,让他们赶快检查网关和防火墙配置,系统自带的工具测试的结果,既简单又权威。
文件传输
nc -l -p 8080 > image.jpg
然后在 B 主机上:
nc 192.168.1.2 8080 < image.jpg
/bin/nc.openbsd -N 192.168.1.2 8080 < image.jpg
你机器上的 nc
命令有可能指向 /bin/nc.traditional
或者 /bin/nc.openbsd
任意一个,这里显示指明调用 openbsd 版本的 netcat。
-N
参数,就不需要再开个终端去手工检查传输是否完成,传输结束了就会自动退出。其实 GNU 版本的 netcat 也有可以加个 -q0
参数,达到和 openbsd 版本 -N
的效果:/bin/nc.traditional -q0 192.168.1.2 8080 < image.jpg
网速吞吐量测试
最简单的方法,GNU 版本的 netcat 加上 -v -v
参数后,结束时会统计接收和发送多少字节,那么此时 A 主机上显示运行 GNU 版本的 nc 监听端口:
/bin/nc.traditional -v -v -n -l -p 8080 > /dev/null
加 n 的意思是不要解析域名,避免解析域名浪费时间造成统计误差,然后 B 主机上:
time nc -n 192.168.1.2 8080 < /dev/zero
对于 OpenBSD 版本的 nc 我们可以用管道搭配 dd 命令进行统计,服务端运行:
nc -l -p 8080 > /dev/null
客户端运行 dd 搭配 nc:
dd if=/dev/zero bs=1MB count=100 | /bin/nc.openbsd -n -N 192.168.1.2 8080
dd if=/dev/zero bs=1MB count=100 | /bin/nc.traditional -n -q0 192.168.1.2 8080
nc -l -p 8080 | pv
然后再 B 主机运行:
nc 192.168.1.2 8080 < /dev/zero
此时 A 主机那端持续收到 B 主机发送过来的数据并通过管道投递给 pv 命令后,你就能看到实时的带宽统计了,pv 会输出一个实时状态:
353MiB 0:00:15 [22.4MiB/s] [ <=> ]
系统后门
假设你用串口登录到 A 主机,上面十分原始,包管理系统都没有,sshd/telnetd 都跑不起来,这时候你想用 B 主机通过网络登录 A 主机有没有办法?
/bin/nc.traditional -l -p 8080 -e /bin/bash
按回车打开系统后门,然后再 B 主机那里照常:
nc 192.168.1.2 8080
mkfifo /tmp/f
cat /tmp/f | /bin/bash 2>&1 | /bin/nc.openbsd -l -p 8080 > /tmp/f
然后 B 主机和刚才一样:
nc 192.168.1.2 8080
即可访问,用完注意将 /tmp/f
这个 fifo 文件删除。
结束
还有很多其他用法,比如你可以用 netcat + shell script 写一个 http 服务器,使用 fifo 搭配两层 nc 可以实现 tcp 端口转发,搭配 openssl 命令行工具和 nc 加管道可以把 ssl 的套接字解码并映射成裸的 socket 端口供没有 ssl 功能的工具访问。
当然你要说,这么多复杂的用法你记不住,大部分你都可以用专业软件来代替,那至少你可以先尝试使用 nc 来做 tcp/udp 端口测试,不要再用 telnet/chrome 来测试端口是否可用了,后者太过业余。其他功能可作为备份手段,在极端恶劣的环境下使用一下,也许能帮助到你很多;再你有心情的情况下可以研究下如何使用管道搭配其他工具进行一些高阶操作就行。
后台回复“加群”,带你进入高手如云交流群
推荐阅读:
喜欢,就给我一个“在看”
10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!