「nc(1)」-

连接任意TCP和UDP,及侦听

命令语法格式

nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] [-m minttl] [-O length] [-P proxy_username] [-p source_port] [-q seconds] [-s source] [-T keyword] [-V rtable] [-W recvlimit] [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [-Z peercertfile] [destination] [port]

命令描述

命令nc(netcat)几乎可用于任何涉及TCP,UDP,UNIX域套接字。它可以打开TCP连接,发送UDP数据包,侦听任意TCP、UDP端口,进行端口扫描,处理IPv4和IPv6报文。与telnet(1)不同,在脚本中使用nc很好,并将错误消息分离为标准错误,而不是将它们发送到标准输出,正如telnet(1)所做的那样。

常见用途包括:

  • 简单的TCP代理
  • 基于Shell脚本的HTTP客户端和服务器
  • 网络守护进程测试
  • 用于ssh(1)的SOCKS或HTTP ProxyCommand(1)

还有更多其他的用法。

命令行选项

命令支持的选项如下:

-4
强制使用「IPv4地址」。

-6
强制使用「IPv6地址」。

-U
指定使用「UNIX域套接字」。

-u
使用UDP,而不是默认TCP选项。对于UNIX域套接字,请使用数据报套接字,而不是流套接字。如果使用UNIX域套接字,则在/tmp中创建临时接收套接字,除非给出-s标志。

-b
允许广播。

-C
将CRLF作为行尾发送。输入数据中的每个换行(LF)字符在写入套接字之前都会转换为CR+LF。在转换前已带有回车符(CR)的换行符不受影响。收到的数据不受影响。

-D
在socket上启用调试。

-d
不要尝试从标准输入中读取。

-F
使用sendmsg(2)将第一个连接的套接字传递给标准输出并退出。这与-X结合使用,以使nc与代理执行连接设置,但是将剩余的连接留给另一个程序(例如使用ssh_config(5)ProxyUseFdpass选项的ssh(1))。

-I length
指定TCP接收缓冲的大小。

-i interval
指定发送和接收的文本行之间的延迟时间间隔。还会导致连接到多个端口之间的延迟时间。

-k
强制nc在当前连接完成后继续侦听另一个连接。如果没有-l选项,则使用此选项会出错。与-u选项一起使用时,服务器套接字未连接,它可以从多个主机接收UDP数据报。

-l
用于指定nc应侦听传入连接,而不是启动与远程主机的连接。要侦听的目标和端口可以指定为非可选参数,也可以使用-s和-p选项指定。将-l与-z选项结合使用是错误的。此外,将忽略使用-w选项指定的任何超时。

-M ttl
设置输出报文的TTL /跳数限制。

-m minttl
要求内核丢弃其TTL/跳数限制在minttl以下的传入数据包。

-N
关闭(2)在输入中得到EOF后,shutdown(2)网络套接字。有些服务器需要这样才能完成工作。

-n
不要对任何指定的地址,主机名或端口执行任何DNS或服务查找。

-O length
设置TCP发送缓存大小。

-P proxy_username
指定要提供给需要身份验证的代理服务器的用户名。如果未指定用户名,则不会尝试进行身份验证。目前仅支持HTTP CONNECT代理的代理身份验证。

-p source_port
指定nc应使用的源端口,受特权限制和可用性的限制。

-q seconds
在标准输入上遇到EOF后,等待指定的秒数然后退出。如果秒为负数,则永远等待(默认)。指定非负秒隐含了”-N“选项。

-r
指定应该随机选择源端口和目标端口,而不是按顺序在系统分配范围内或按顺序选择。

-S
启用RFC 2385 TCP MD5签名选项。

-s source
指定用于发送数据包的接口的IP地址。对于UNIX域数据报套接字,指定要创建和使用的本地临时套接字文件,以便可以接收数据报。

-T keyword
更改IPv4的TOS值。参数:keyword可以是critical, inetcontrol, lowcost, lowdelay, netcontrol, throughput, reliability,或者DiffServ代码点之一:ef, af11 … af43, cs0 … cs7;或十六进制或十进制数。

-t
导致nc发送RFC 854 DO NOT,并且不会响应RFC 854 DO和WILL请求。这使得使用nc编写telnet会话脚本成为可能。

-V rtable
设置要使用的路由表。

-W recvlimit
从网络接收recvlimit数据包后终止。

-w timeout
在timemout秒后,无法建立或空闲超时的连接。选项-w对-l选项没有影响,即nc将永远监听连接,不管有或没有-w标志。默认为无超时。

-X proxy_protocol
请求nc在与代理服务器通信时应使用指定的协议。支持的协议是“4”(SOCKS v.4),“5”(SOCKS v.5),“connect”(HTTPS代理)。如果未指定协议,则使用SOCKS版本5。

-x proxy_address[:port]
要求nc应使用proxy_address和port上的代理连接到目标。如果未指定端口,则使用代理协议的已知端口(对于SOCKS为1080,对于HTTPS为3128)。通过将proxy_address包含在方括号中,可以明确指定IPv6地址。

-Z
使用DCCP模式。

-z
指定nc应该只扫描在侦听中的守护进程,而不向它们发送任何数据。将此选项与-l选项结合使用是错误的。

调试选项

-v
让nc给出更详细的输出。

其他选项

-h
显示nc帮助。

命令行参数

destination
可以是数字IP地址或符号主机名(除非给出-n选项)。通常,必须指定destination,除非给出了-l选项(在这种情况下使用本地主机)。对于UNIX域套接字,需要一个destination,它是连接到的套接字路径(或者如果给出了-l选项,则监听)。

port
可以指定为「数字端口号」,也可以指定为「服务名称」。可以在nn-mm形式的范围内指定端口。通常,必须指定目标端口,除非给出-U选项。

该命令的几种典型用法

客户端/服务端模型

使用nc构建一个非常基本的客户端/服务器模型非常简单。在一个控制台上,启动nc侦听特定端口以进行连接。例如:

# nc -l 1234

之后,nc现在正在端口1234上侦听连接。在第二个控制台(或第二台计算机)上,连接到正在侦听的计算机和端口:

# nc 127.0.0.1 1234

现在应该在端口之间建立连接。在第二个控制台输入的任何内容都将连接到第一个控制台,反之亦然。在建立连接之后,命令nc并不真正关心哪一方被用作“服务器”以及哪一方被用作“客户端”。可以使用EOF(’^ D’)终止连接。

此netcat中没有-c或-e选项,但你仍可以在通过重定向文件描述符建立连接后执行命令。在这里要小心,因为打开一个端口并让任何连接的人在你的网站上执行任意命令是危险的。如果你真的需要这样做,这是一个例子:

在服务端:

# rm -f /tmp/f; mkfifo /tmp/f

# cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f

在客户端:

# nc host.example.com 1234

# (shell prompt from host.example.com)

通过这样做,你在/tmp/f创建一个fifo,并在’服务器’端的地址127.0.0.1的端口1234上进行nc监听,当’客户端’成功建立到该端口的连接时,在“服务器”端/bin/sh被执行,shell提示符被提供给“客户端”。

当连接终止时,nc也会退出。如果你希望它继续侦听,请使用-k,但如果该命令退出此选项,则不会重新启动它或保持nc运行。一旦你不再需要文件描述符也不要忘记删除:rm -f /tmp/f

数据传输模型

可以扩展上一节中的示例,构建一个基本数据传输模型。输入到连接一端的任何信息都将输出到另一端,并且可以轻松捕获输入和输出以模拟文件传输。

首先使用nc监听特定端口,并将输出捕获到文件中:

# nc -l 1234 > filename.out

使用第二台机器,连接到监听nc进程,向其提供要传输的文件:

# nc -N host.example.com 1234 < filename.in

传输文件后,连接将自动关闭。

与服务器交谈

有时可以“手动”而不是通过用户界面与服务器通信。当可能需要验证服务器发送的数据以响应客户端发出的命令时,它可以帮助进行故障排除。例如,要检索网站的主页:

# printf “GET / HTTP/1.0\r\n\r\n” | nc host.example.com 80

请注意,这还会显示Web服务器发送的标头。如有必要,可以使用sed(1)等工具对其进行过滤。

当用户知道服务器所需的请求格式时,可以构建更复杂的示例。作为另一个示例,可以使用以下方式:

# nc [-C] localhost 25 << EOF

HELO host.example.com

MAIL FROM:<user@host.example.com>

RCPT TO:<user2@host.example.com>

DATA

Body of email.

.

QUIT

EOF

将电子邮件提交给SMTP服务器

端口扫描

了解哪些端口在目标计算机上打开并运行服务可能很有用。标志-z可用于告诉nc报告开放的端口,而不是发起连接。通常,通过将此选项与-v选项结合使用,可以将详细输出打开到标准错误。

例如:

# nc -zv host.example.com 20-30

Connection to host.example.com 22 port [tcp/ssh] succeeded!

Connection to host.example.com 25 port [tcp/smtp] succeeded!

指定端口范围以将搜索限制为端口20-30,并按递增顺序扫描。

你还可以指定要扫描的端口列表,例如:

# nc -zv host.example.com 80 20 22

nc: connect to host.example.com 80 (tcp) failed: Connection refused

nc: connect to host.example.com 20 (tcp) failed: Connection refused

Connection to host.example.com port [tcp/ssh] succeeded!

端口按你给出的顺序扫描。

或者,了解哪个服务器软件正在运行以及哪些版本可能很有用。此信息通常包含在问候语横幅中。为了检索这些,必须首先建立连接,然后在检索到横幅时断开连接。这可以通过使用-w标志指定一个小的超时,或者通过向服务器发出“QUIT”命令来完成:

# echo “QUIT” | nc host.example.com 20-30

SSH-1.99-OpenSSH_3.6.1p2

Protocol mismatch.

220 host.example.com IMS SMTP Receiver Version 0.84 Ready

除此之外,nc还有更多其他的用法。

注意事项

使用-uz组合标志的UDP端口扫描将始终报告成功,而与目标计算机的状态无关。但是,与目标机器或中间设备上的流量嗅探器一起使用时,-uz组合可用于通信诊断。请注意,由于硬件资源和配置设置,生成的UDP流量可能会受到限制。

使用示例

使用端口31337作为源端口,打开到host.example.com端口42的TCP连接,超时为5秒:

# nc -p 31337 -w 5 host.example.com 42

打开与host.example.com端口53的UDP连接:

# nc -u host.example.com 53

使用10.1.2.3作为连接本地端的IP,打开与host.example.com端口42的TCP连接:

# nc -s 10.1.2.3 host.example.com 42

在UNIX域流套接字上创建和侦听:

# nc -lU /var/tmp/dsocket

通过HTTP代理10.2.3.4,端口8080连接到host.example.com的42端口。此示例也可以由ssh(1)使用;有关更多信息,请参阅ssh_config(5)中的ProxyCommand指令。

# nc -x10.2.3.4:8080 -Xconnect host.example.com 42

再次使用相同的示例,如果代理需要,则使用用户名“ruser”启用代理身份验证:

# nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42

如上示例。

相关手册

cat(1), ssh(1)

参考文献

  • man 1 nc, Version 1.190-2

更新日志

  • 11/03/2018 创建文章