113. nc 命令
Linux nc
, netcat
命令用于设置路由器, 执行本指令可设置路由器的相关参数.
可对任意 TCP 与 UDP 连接和侦听
用法概要
简单语法
1 | nc [-hlnruz][-g<网关...>][-G<指向器数目>][-i<延迟秒数>][-o<输出文件>][-p<通信端口>][-s<来源位址>][-v...][-w<超时秒数>][主机名称][通信端口...] |
参数说明:
-g<网关>
设置路由器跃程通信网关,最多可设置8个。-G<指向器数目>
设置来源路由指向器,其数值为4的倍数。-h
在线帮助。-i<延迟秒数>
设置时间间隔,以便传送信息及扫描通信端口。-l
使用监听模式,管控传入的资料。-n
直接使用IP地址,而不通过域名服务器。-o<输出文件>
指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存。-p<通信端口>
设置本地主机使用的通信端口。-r
乱数指定本地与远端主机的通信端口。-s<来源位址>
设置本地主机送出数据包的IP地址。-u
使用UDP传输协议。-v
显示指令执行过程。-w<超时秒数>
设置等待连线的时间。-z
使用0输入/输出模式,只在扫描通信端口时使用
复杂语法
1 | nc -h |
描述
nc
(或 netcat
)实用程序可用于与 TCP 或 UDP 相关的各种任务。nc
可以打开 TCP 连接,发送 UDP 数据包,侦听任意 TCP 和 UDP 端口,执行端口扫描,以及处理 IPv4 和 IPv6。与 telnet(1) 不同,nc
精细地编写脚本,并将错误消息分隔到标准错误中,而不是将错误消息发送到标准输出。
nc
命令通常用于以下任务:- 简单 TCP 代理
- 基于 HTTP 客户机和服务器的 shell 脚本
- 网络守护进程测试
- 适用于 ssh(1) 的 SOCKS 或 HTTP
ProxyCommand
nc
命令还可以作为 netcat
运行(使用相同选项)。
选项
支持以下选项:
–4
强制
nc
仅使用 IPv4 地址。–6
强制
nc
仅使用 IPv6 地址。–b
bufsize为读取操作指定缓冲区大小。缺省值为
1024
字节。–D
启用对套接字的调试。
–d
不尝试从
stdin
进行读取。–E
使用独占绑定来侦听 TCP 或 UDP 套接字。在没有
–l
选项的情况下单独使用此选项是错误的。此选项与–U
选项结合使用时,不会产生任何影响。–e
program接受连接或建立连接之后执行外部程序。在执行之前,
stdin,stdout,stderr
会重定向到网络描述符。仅有一个端口可供该选项使用。此选项与–R
、–k
或–i
选项结合使用是错误的。–F
在
stdin
上看到EOF
后,不要关闭网络套接字以进行写入。–h
输出
nc
帮助。–I
bufsize设置接收(输入)套接字缓冲区大小。此选项与
–U
选项结合使用时,不会产生任何影响。–i
interval指定发送和接收的文本行之间的延迟时间 interval。以秒为单位指定时间间隔,可能包含小数。此选项还会导致与多个端口的连接之间产生延迟时间,因而也会影响端口扫描模式。
–k
强制
nc
在其当前连接关闭后侦听另一连接。在没有–l
选项的情况下单独使用此选项是错误的。此选项与–e
选项结合使用是错误的。–L
timeout在关闭时逗留 (Linger on close)-在网络描述符关闭后直到指定的超时时间(以秒为单位),等待消息发送。
–l
侦听传入连接,而不是启动到远程主机的连接。此选项与
–s
或–z
选项结合使用是错误的。如果–l
选项与通配符套接字(未指定任何 IP 地址或主机名)一起使用但不与–4
/–6
选项一起使用,则既可接受 IPv4 连接也可接受 IPv6 连接。–m
byte_count接收至少
byte_count
字节后退出。当与–l
选项结合使用时,byte_count
会与从客户机接收的字节数进行比较。byte_count
必须大于0
,而小于INT_MAX
。–N
file在 UDP 端口扫描模式下指定文件。此文件的内容用作每个发出的 UDP 包的有效载荷。在没有
–u
和–z
选项的情况下单独使用此选项是错误的。–n
不对任何地址、主机名或端口执行任何命名或服务查找操作。使用此选项意味着 hostname 和 port 参数被限制为数字值。除了对参数施加限制外,与
–v
选项一起使用时,所有地址和端口都将以数字形式输出。此选项与–U
选项结合使用时,不会产生任何影响。–O
bufsize设置发送(输出)套接字缓冲区大小。此选项与
–U
选项结合使用时,不会产生任何影响。–P
proxy_username指定提供给要求验证的代理服务器的一个用户名 (proxy_username)。如果未指定 proxy_username,则不会尝试进行验证。目前仅
HTTP CONNECT
代理支持代理验证。此选项与–l
选项结合使用是错误的。–p
port未与
–l
选项结合使用时,根据特权限制和可用性指定nc
应使用的源端口。与–l
选项结合使用时,设置侦听端口。仅当未指定全局端口参数时,此选项可与–l
选项结合使用。–q
timeout在
stdin
上接收到EOF
后,等待指定的秒数,然后退出。–R
addr/port[/proto]对指定的 host 和 port 执行端口重定向。接受连接后,
nc
会连接到远程 host/port,并在客户机与远程主机之间传递所有数据。重定向规范的 proto(协议)部分可以是tcp
或udp
。如果未指定 proto,redirector
将使用与服务器相同的协议。此选项与–z
选项结合使用是错误的。–r
在由 port_list 参数指定的所有端口中随机(而非按顺序)选择目标端口。此选项与
–l
选项结合使用是错误的。–s
source_ip_address指定用于发送数据包的接口的 IP。此选项与
–l
选项结合使用是错误的。–S
sla-prop指定为套接字创建的 MAC 流的属性。sla-prop 以属性的 ‘name=value’ 逗号分隔列表的形式提供。当前支持的属性名称为
maxbw
、priority
和inherit
。maxbw
和priority
来自 flowadm(1M) 中定义的属性,表示流的最大带宽和优先级。maxbw
的允许值为整数加上可选的后缀(缺省为 Mega)。priority
的值可以为 ‘high’、’medium’ 和 ‘low’。在创建流时,必须至少指定maxbw
和priority
之一。inherit
的值可以为 ‘on’ 和 ‘off’,缺省值为 ‘off’。缺省情况下,接受的/新的套接字(由 accept(3C) 返回)不会继承侦听器套接字的属性。当将其设置为 ‘on’ 时,新的套接字将继承侦听器套接字的属性。当需要对新套接字实施属性时,这对于–l
选项很有用。此选项需要SYS_FLOW_CONFIG
特权。此选项还要求指定 IP 地址或主机名。–T
dscp为连接指定区分服务代码点。对于 IPv4,此选项指定 IP 服务类型 (Type of Service, ToS) IP 标题字段,参数的有效值为字符串标记
lowdelay
、throughput
、reliability
或前面带有0x
的 8 位十六进制值。对于 IPv6(通信流量类),只能使用十六进制值。–t
使
nc
将 RFC 854DON'T
和WON'T
响应发送到 RFC 854DO
及WILL
请求。这样就可以使用nc
编写telnet
会话脚本。–U
指定使用 Unix 域套接字。如果不与
–l
、nc
一起指定此选项,则它将变成AF_UNIX
客户机。如果与–l
选项一起指定此选项,则会创建AF_UNIX
服务器。使用此选项要求必须向nc
提供单个有效的 Unix 域路径参数,而不是提供主机名或端口。–u
使用 UDP,而不是缺省选项 TCP。
–v
指定详细输出。
–w
timeout如果连接和
stdin
空闲超过了 timeout 秒,则无提示地关闭连接。缺省设置是没有超时。此选项对客户机模式下的连接建立阶段或服务器模式下的等待连接过程没有任何影响。–X
proxy_protocol与代理服务器通信时,使用该指定协议。受支持的协议为
4
(SOCKS v.4
)、5
(SOCKS v.5
) 和connect
(HTTP
代理)。如果未指定协议,则使用SOCKS v. 5
。此选项与–l
选项结合使用是错误的。–x
proxy_address[:port]使用 proxy_address 和 port 上的代理请求到 hostname 的连接。如果未指定 port,则使用代理协议的已知端口(
SOCKS
为1080
,HTTP
为3128
)。此选项与–l
选项结合使用是错误的。此选项不适用于 IPv6 地址的数字表示形式。–Z
在侦听模式下,使用
SO_ALLZONES
套接字选项绑定到所有区域中的地址/端口。此选项需要SYS_NET_CONFIG
特权。–z
执行端口扫描。对于 TCP 端口(缺省),尝试在不发送数据的情况下执行连接扫描(完整三路信号握手)。对于 UDP (
–u
),缺省情况下会发送空 UDP 包。要指定 UDP 有效载荷,可以使用–N
选项。UDP 扫描模式具有估计能力,如果它没有接收到否定响应(”ICMP Destination Port Unreachable”(无法访问 ICMP 目标端口)消息),它会考虑打开一个端口。对于这种模式,使用–w
选项设置的超时时间将用来等待来自远程节点的 ICMP 消息或数据。通过–v
,接收到的任何数据都会作为十六进制字节转储到stderr
。由于大多数操作系统会限制发送 ICMP 消息(以响应输入包)的速率,所以有必要在执行 UDP 扫描时使用–i
,否则结果会不可靠。此选项与–l
选项结合使用是错误的。
操作数
支持下列操作数:
hostname
指定主机名。hostname 可以是数字 IP 地址或者符号主机名(除非已指定
–n
选项)。通常,除非已指定–l
选项或者使用了–U
(在此情况下,参数是一个路径),否则必须指定 hostname。如果随–l
选项指定了 hostname 参数,则还必须给定 port 参数,并且nc
会尝试绑定到该地址和端口。如果没有随–l
选项指定 hostname 参数,则nc
会尝试在给定 port 的通配符套接字上侦听。path
指定路径名。
port
port_list
指定端口。port_list 可以指定为单个整数、范围或两者的组合。请以 nn-mm 形式指定范围。port_list 至少必须有一个成员,但可以有多个以逗号分隔的端口/范围。通常,除非已指定
–U
选项(在此情况下,必须指定 Unix 域套接字路径,而不指定 hostname),否则必须指定目标端口。将包含多个端口的端口列表与 -e 选项结合使用是错误的。
用法
客户机/服务器模型
使用 nc
构建最基本的客户机/服务器模型非常简单。在一个控制台上,启动在特定端口上侦听连接的 nc
。例如,命令:
1 | nc -l 1234 |
在端口 1234
上侦听连接。在另一个控制台上(或另一台计算机上),连接到 nc
正在侦听的计算机和端口:
1 | nc 127.0.0.1 1234 |
现在端口之间应当有一个连接。在第二个控制台上键入的任何内容都将串联到第一个控制台,反之亦然。在连接建立后,nc
不会真正关心哪一端用作服务器,哪一端用作 客户机。可使用 EOF
(Ctrl/d) 终止连接。
数据传输
可以对上一部分中的示例进行扩展,以构建基本的数据传送模型。在连接的一端输入的任何信息都将输出到连接的另一端,并且可以轻松捕获输入和输出,以便模仿文件传送。
通过使用 nc
启动在特定端口上的侦听,并将输出捕获到一个文件中:
1 | nc -l 1234 > filename.out |
使用另一台计算机,连接到正在侦听的 nc
进程,向其馈送要传送的文件:
1 | nc host.example.com 1234 < filename.in |
完成文件传送后,连接将自动关闭。
与服务器通信
有时,通过手工(而不是通过用户界面)与服务器进行通信非常有用。当可能需要验证服务器正在发送什么数据来响应客户机发出的命令时,它可以帮助排除故障。
例如,要检索某个 Web 站点的主页:
1 | echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80 |
这也将显示 Web 服务器发送的标头。如果需要,可以使用 sed(1) 等工具过滤这些标头。
如果用户了解服务器要求的请求格式,可以构造更为复杂的示例。再如,可使用以下方法将电子邮件提交到 SMTP 服务器:
1 | nc localhost 25 << EOF |
端口扫描
知道目标计算机上哪些端口是打开的并正在运行服务可能非常有用。可以使用 –z
标志来指示 nc
报告打开的端口,而不是启动连接。
在此示例中:
1 | nc -z host.example.com 20-30 |
指定了端口范围以将搜索限制在端口 20 至 30 之间。
此外,了解正在运行的服务器软件及版本可能非常有用。该信息通常包含在问候标题内。要检索这些问候标题,首先需要建立连接,然后检索标题,之后断开连接。此操作可通过使用 –w
标志指定较小的超时,或者通过向服务器发出 QUIT
命令来实现。
1 | echo "QUIT" | nc host.example.com 20-30 |
inetd
功能
可能的用途之一是使用 inetd
(1M) 创建简单的服务。
以下示例创建了一个从主机 realwww
上的 TCP 端口 8080 到端口 80 的重定向:
1 | $ cat << EOF >> /etc/services |
特权
要绑定到特权端口号,需要向 nc
授予 net_privaddr
特权。如果配置了 Solaris Trusted Extensions,并且 nc
应侦听的端口被配置为多级别端口,则 nc
还需要具有 net_bindmlp
特权。
通过在 user_attr
(4) 中在帐户的缺省特权集中指定这些特权,可以直接将它们分配给用户或角色。但是,这意味着该用户或角色启动的所有应用程序都拥有这些附加特权。要仅在调用 nc
时授予 privileges
(5),建议创建并分配一个 rbac
(5) 权限配置文件。有关其他信息,请参见``“示例”部分。
示例
示例 1 使用 nc
打开到 host.example.com
的端口 42
的 TCP 连接,使用端口 3141
作为源端口,超时为 5
秒:
1 | nc -p 3141 -w 5 host.example.com 42 |
打开到 host.example.com
的端口 7777
的 TCP 连接,对套接字设置最大 50Mbps 的带宽:
1 | nc -M maxbw=50M host.example.com 7777 |
打开到 host.example.com
的端口 53
的 UDP 连接:
1 | nc -u host.example.com 53 |
打开到 host.example.com
的端口 42 的 TCP 连接,使用 10.1.2.3
作为连接的本地端的 IP:
1 | nc -s 10.1.2.3 host.example.com 42 |
将一个包含端口和端口范围的列表用于针对各种端口的端口扫描:
1 | nc -z host.example.com 21-25,53,80,110-120,443 |
在某个 Unix 域套接字上创建连接并侦听:
1 | nc -lU /var/tmp/dsocket |
在关联端口为 8888
的 UDP 套接字上创建连接并侦听:
1 | nc -u -l -p 8888 |
这等效于:
1 | nc -u -l 8888 |
在关联端口为 2222
的 TCP 套接字上创建连接并侦听,并且只绑定到地址 127.0.0.1
:
1 | nc -l 127.0.0.1 2222 |
在关联端口 2222
上创建 TCP 套接字并进行侦听,并在侦听器和连接的套接字上创建高优先级的 MAC 流:
1 | nc -l -M priority=high,inherit=on host.example.com 2222 |
通过将逗留 (linger) 选项和超时时间设置为 0
,连接到 TCP 端口、发送一些数据然后终止与 TCP RST 段的连接(而不是传统的 TCP 关闭握手):
1 | echo "foo" | nc -L 0 host.example.com 22 |
从本地端口 4545
对主机 host.example.com
上的端口 22
执行端口重定向:
1 | nc -R host.example.com/22 -l 4545 |
在这之后,应该可以运行 ssh(1) 客户机并连接到 host.example.com
(使用运行上述命令的 host redir.example.com
):
1 | ssh -oStrictHostKeyChecking=no -p 4545 redir.example.com |
还可以让 nc
侦听 TCP 端口并将 TCP 数据流转换为 UDP(反之亦然):
1 | nc -R host.example.com/53/udp -l 4666 |
使用 10.2.3.4
的端口 8080
上的 HTTP 代理连接到 host.example.com
的端口 42
。ssh(1)也可使用此示例。有关更多信息,请参见 ssh_config
(4) 中的 ProxyCommand
指令。
1 | nc -x10.2.3.4:8080 -Xconnect host.example.com 42 |
还是同一示例,这一次如果代理要求验证,则使用用户名 ruser
来支持代理验证:
1 | nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42 |
可以按类似如下方式有效地完成基本的 UDP 端口扫描:
1 | nc -z -w 3 -u -i 0.5 host.example.com 11-100 |
在每 2 个端口之间,将暂停 0.5 秒(从而规避 ICMP 消息速率限制)并最多等待 3 秒以接收回复。如果没有接收到回复,端口可能会打开。
要作为具有附加特权的用户或角色(例如缺省的 root
帐户)使用最可能小的特权集运行 nc
,还可以使用 ppriv(1) 来调用它。例如,将其限制为仅以绑定到某个特权端口的特权运行:
1 | ppriv -e -sA=basic,!file_link_any,!proc_exec,!proc_fork,\ |
要允许用户或角色仅以 net_privaddr
特权使用 nc
,则需要创建一个权限配置文件。
1 | /etc/security/exec_attr |
使用 user_attr
(4) 分配该权限配置文件以允许用户或角色运行 nc
,从而允许其在任何端口上侦听。要允许用户或角色使用 nc
仅在特定端口上侦听,则应在权限配置文件中指定一个包装脚本:
1 | /etc/security/exec_attr |
并且编写一个用以限制许可选项的 shell 脚本,例如,编写一个只允许在 42
和 64
之间的端口(不含两者)上绑定的脚本:
1 | /usr/bin/nc-restricted: |
当用户或角色通过配置文件 shell 使用该包装脚本调用 nc
时,这将授予额外的特权。请参见 pfsh(1)、pfksh(1)、pfcsh(1) 和 pfexec(1)。
直接调用 nc
时不会以附加特权运行它,在不使用 pfexec
或配置文件 shell 的情况下调用该脚本时也是如此。
属性
有关下列属性的说明,请参见 attributes
(5):
属性类型属性值可用性network/netcat接口稳定性请参见下文。
数据包名称是 “Committed”(已确定)。–4
、–6
、–l
、–n
、–p
、–u
和 –w
选项及其参数(如果有),命令行语法是 “Committed”(已确定)。name 和 port 列表参数是 “Committed”(已确定)。端口范围语法是 “Uncommitted”(未确定)。所有其他命令行选项及其参数的接口稳定性级别是 “Uncommitted”(未确定)。
另请参见
cat(1)、pfcsh(1)、pfexec(1)、pfksh(1)、pfsh(1)、ppriv(1)、sed(1)、ssh(1)、telnet(1)、inetadm
(1M)、inetconv
(1M)、inetd
(1M)、ssh_config
(4)、user_attr
(4)、attributes
(5)、privileges
(5)、rbac
(5)
作者
nc
的原始实现的作者是 Hobbit (hobbit@avian.org
)。
Eric Jackson (ericj@monkey.org
) 重新编写了 nc
,增加了对 IPv6 的支持。
附注
如果 nc
的实例正在侦听通配符套接字(无论指定的地址族如何),仍可以将其他 nc
进程绑定到具体 IP 地址并接受与该地址的连接。例如,通过运行以下进程:
1 | nc -4 -l 5656 |
可以运行另一个 nc
进程,对特定 IP 地址和同一端口进行侦听:
1 | nc -4 -l 10.20.30.40 5656 |
后一个进程接受与地址 10.20.30.40
以及端口 5656
的 TCP 连接,而前一个进程接受与端口 5656
以及不同地址的所有 TCP 连接。
此外,还可以通过绑定到 IPv4 通配符套接字从侦听通配符套接字(不指定地址族)的进程窃取 IPv4 连接。要禁止出现这种情况以及上述行为,可以使用 –E
选项。
实例
TCP端口扫描
1 | # nc -v -z -w2 192.168.0.3 1-100 |
扫描192.168.0.3 的端口 范围是 1-100
扫描UDP端口
1 | nc -u -z -w2 192.168.0.1 1-1000 //扫描192.168.0.3 的端口 范围是 1-1000 |
扫描指定端口
1 | $ nc -nvv 192.168.0.1 80 # 扫描 80端口 |