夜间模式暗黑模式
字体
阴影
滤镜
圆角
主题色
使用netcat能够做什么

楔子

今天朋友找我解决一个问题,他的java服务在阿里服务器里监听了某端口(使用的TCP),但通过公网无法连接。我尝试在本地telnet那个端口(跨公网),不通。在他服务器里telnet 127.0.0.1 端口,是通的。说明服务正常监听了端口。但由于我不熟悉他的java服务,无法判断该java服务是否只监听了本地回环地址。

因此公网无法访问大概有两种可能,一,java服务只监听了本地回环地址; 二、防火墙限制了端口

排除第二种情况对我来说比较简单,我通过netcat在服务器监听端口,然后在本地telnet,不通!说明问题的确出在防火墙身上。该服务器为Ubuntu,使用ufw status查看防火墙状态,显示为inactive,也就是关闭状态。再查看阿里云安全组规则,已经开放了tcp/udp的所有端口(-1/-1)。后面我再次执行ufw disable,端口就通了。所以这是ufw的bug?

引子有点长了。主要是为了说明,如果想知道与服务器之间的tcp连接是否通,可以使用netcat工具去判断。下面介绍下netcat ~

 

netcat是什么

是一种计算机网络实用程序,用于使用TCP或UDP读写网络连接,号称 TCP/IP 的瑞士军刀。大家一般简写为nc。总之,涉及到网络的事儿,它几乎都能做。为什么叫瑞士军刀,因为它体积很小,不同版本的nc可执行文件只有几十k到300多k,而且大部分linux发行版都有预安装。

 

各种版本

netcat有许多版本,能力从弱到强为:GUN、BSD、Ncat。基础功能三者都一样,不同的是一些版本额外内置了些高级/有趣的功能(例如Ncat有个参数--chat,可以创建匿名聊天室)。

大部分centos6内置的是BSD版本的nc,我的Centos7里边内置的nc是Ncat(属于nmap工具集里边)

使用man nc,拉到最下边可以看到你的nc版本。(使用man你基本能够查阅所有的用法了,其它软件也是如此,只要是标准安装的)

ps. socat号称是更为强大的nc,有兴趣的小伙伴可以自己去看看。

 

用途

检查端口通不通

以往我一直使用telnet来判断某个端口是否通,但telnet是基于tcp协议的,如果要判断udp端口就无能为力了。这时可以使用nc来判断。为了方便实验,本文统一使用同一台机器模拟服务端和客户端。

# 咱们使用nc创建一个tcp协议监听的端口。-l为listen,默认协议为tcp
nc -l 8088

# 使用nc连上该端口。-v(verbose)用于显示更多信息,-z(zero I/O)表示不发送数据包,仅显示连接状态。
# 下面succeed表示端口是通的
nc -vz 127.0.0.1 8088
Connection to 127.0.0.1 8088 port [tcp/radan-http] succeeded!


# 创建一个udp端口。-u指使用udp协议
nc -lu 8088

# 同样,加一个u表示使用udp连接该端口,同时你会看到服务端打印出若干个X。
# 不是说加了z参数就不会发数据包吗,为什么服务端收到了报文?我认为udp是无连接状态的,通过系统调用write
# 往该套接字发数据,通过返回值才知道包发出去没有,从而判断udp端口是否通
nc -vzu 127.0.0.1 8088
Connection to 127.0.0.1 8088 port [udp/radan-http] succeeded!

端口扫描

# 扫描tcp端口。-w(wait)指定连接超时时间,单位秒。
# 连接成功的端口将作为标准输出
nc -v -w3 -z 127.0.0.1 1-65535 | tee succeed_port.log

# 下面摘抄部分连接成功的端口
 Connection to 127.0.0.1 22 port [tcp/ssh] succeeded!
 Connection to 127.0.0.1 25 port [tcp/smtp] succeeded!
 Connection to 127.0.0.1 80 port [tcp/http] succeeded!
 Connection to 127.0.0.1 443 port [tcp/https] succeeded!
 Connection to 127.0.0.1 1100 port [tcp/mctp] succeeded!
 Connection to 127.0.0.1 1111 port [tcp/lmsocialserver]
 succeeded! Connection to 127.0.0.1 2255 port [tcp/vrtp]
 succeeded! Connection to 127.0.0.1 3001 port [tcp/*]
 succeeded! Connection to 127.0.0.1 3306 port [tcp/mysql]
 succeeded! Connection to 127.0.0.1 4300 port [tcp/corelccam] succeeded!
 Connection to 127.0.0.1 4369 port [tcp/epmd] succeeded!
 Connection to 127.0.0.1 5672 port [tcp/amqp] succeeded!
 Connection to 127.0.0.1 6553 port [tcp/*] succeeded!


# 扫描udp端口。nc -v -zu 127.0.0.1 1-65535
# 以下为我本地扫描结果
Connection to 127.0.0.1 636 port [udp/ldaps] succeeded!
Connection to 127.0.0.1 35157 port [udp/*] succeeded!
Connection to 127.0.0.1 54890 port [udp/*] succeeded!

文件传输

归根到底都是创建一个tcp/udp连接,通过连接收发数据而已。所以,无论数据是ascii字符串,二进制文件都可以发送/接收。

为了加快传输速率/加密,你甚至还可以在发送之前对数据进行压缩/加密。

对于大文件,个人认为还是scp、rsync这类专业的工具靠谱。小文件可以试试这种方法,毕竟简单,不需要ssh认证。

# 接收端监听端口,把数据包重定向到指定文件
nc -l 8085 > file.ext

# 发送方往指定ip:端口发送数据
nc 127.0.0.1 8085 < file.ext

ssh代理

是的,可以用作ssh代理!!如果某台内网机器需要通过代理才能连接,那么给ssh配置个代理是个不错的选择。这样ssh和scp都可以正常访问那台机器。

主要是利用了ssh的ProxyCommand选项,例如你要访问的机器ip为1.2.3.4,代理ip:端口为5.6.7.8:1988,那么编辑 ~/.ssh/config

Host 1.2.3.4
 ProxyCommand nc -X 5 -x 5.6.7.8:1988 %h %p

-X指定代理协议,默认为5 (socks5),还有其他选项:4(socks4)、connect(https)

-x指定代理地址[端口]

具体的使用场景可以参考我的另一篇文章《在挂着VPN的虚拟机搭建代理服务

 

其它

另外还可以做以下事情,但我觉得一般来说用处不大。ps. 有些版本的nc可能参数有所差异或没有对应的特性

  • 远程执行shell/bash。例子:服务端执行 nc -l 8083 -e /bin/bash(或shell),客户端 nc 127.0.0.1 8083,然后客户端就可以执行bash/shell了。但这种用法不要在公网用,否则很危险呐
  • 网速测试。
  • 啊,编不出来了~

 

ps. 有啥实用/有趣的用途,欢迎留言。

 

 

暂无评论

发送评论 编辑评论


				
上一篇
下一篇