必备工具:ping

“ping”这个命名来自于声呐探测,在网络上用来完成对网络连通性的探测
$ ping www.sina.com.cn
PING www.sina.com.cn (202.102.94.124) 56(84) bytes of data.
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=1 ttl=63 time=8.64 ms
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=2 ttl=63 time=11.3 ms
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=3 ttl=63 time=8.66 ms
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=4 ttl=63 time=13.7 ms
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=5 ttl=63 time=8.22 ms
64 bytes from www.sina.com.cn (202.102.94.124): icmp_seq=6 ttl=63 time=7.99 ms
^C
--- www.sina.com.cn ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 5006ms
rtt min/avg/max/mdev = 7.997/9.782/13.795/2.112 ms
在上面的例子中,使用 ping 命令探测了和新浪网的网络连通性。可以看到,每次显示是按照 sequence 序列号排序显示的,一并显示的,也包括 TTL(time to live),反映了两个 IP 地址之间传输的时间。最后还显示了 ping 命令的统计信息,如最小时间平均时间等。

ping 是基于 ICMP 的协议开发的ICMP 又是一种基于 IP 协议的控制协议,翻译为网际控制协议,其报文格式如下图:

ICMP 在 IP 报文后加入了新的内容,这些内容包括:
  • 类型    即 ICMP 的类型, 其中 ping 的请求类型为 8,应答为 0。
  • 代码    进一步划分 ICMP 的类型, 用来查找产生错误的原因。
  • 校验和用于检查错误的数据。
  • 标识符:通过标识符来确认是谁发送的控制协议,可以是进程 ID。
  • 序列号:唯一确定的一个报文,前面 ping 名字执行后显示的 icmp_seq 就是这个值。

基本命令:ifconfig

用来显示当前系统中的所有网络设备,通俗一点的说,就是网卡列表。
vagrant@ubuntu-xenial-01:~$ ifconfig
cni0      Link encap:Ethernet  HWaddr 0a:58:0a:f4:00:01
          inet addr:10.244.0.1  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::401:b4ff:fe51:bcf9/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:2133 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2216 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:139381 (139.3 KB)  TX bytes:853302 (853.3 KB)


docker0   Link encap:Ethernet  HWaddr 02:42:93:0f:f7:11
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:93ff:fe0f:f711/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:653 errors:0 dropped:0 overruns:0 frame:0
          TX packets:685 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:49542 (49.5 KB)  TX bytes:430826 (430.8 KB)


enp0s3    Link encap:Ethernet  HWaddr 02:54:ad:ea:60:2e
          inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
          inet6 addr: fe80::54:adff:feea:602e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7951 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4123 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:5081047 (5.0 MB)  TX bytes:385600 (385.6 KB)
(1) 这段表明这是一个以太网设备,MAC 地址为 02:54:ad:ea:60:2e。
Link encap:Ethernet  HWaddr 02:54:ad:ea:60:2e
(2) 这里显示的是网卡的 IPv4 和 IPv6 地址,其中 IPv4 还显示了该网络的子网掩码以及广播地址。
inet addr:10.0.2.15  Bcast:10.0.2.255  Mask:255.255.255.0
inet6 addr: fe80::54:adff:feea:602e/64 Scope:Link
注:在每个 IPv4 子网中,有一个特殊地址被保留作为 子网广播地址,比如这里的 10.0.2.255 就是这个子网的广播地址。当向这个地址发送请求时,就会向以太网网络上的一组主机发送请求。
(3) 这里显示的是网卡的状态,MTU 是最大传输单元的意思,表示的是链路层包的大小。1500 表示的是字节大小。
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
注:Linux 在一台主机上可以有多个网卡设备,很可能有这么一种情况,多个网卡可以路由到目的地。Metric 就是用来确定多块网卡的优先级的,数值越小,优先级越高,1 为最高级。

对网络状况了如指掌netstat 和 lsof

netstat 可以帮助我们了解当前的网络连接状况,比如我想知道当前所有的连接详情,就可以使用下面这行命令:
netstat -alepn

netstat 会把所有 IPv4 形态的 TCP,IPV6 形态的 TCP、UDP 以及 UNIX 域的套接字都显示出来。

也可以只对 UNIX 套接字进行筛查:
netstat Socket -x -alepn

UNIX 套接字的结果稍有不同,最关键的信息是 Path,这个信息显示了本地套接字监听的文件路径

lsof 的常见用途之一是帮助找出 在指定的IP地址或者端口上 打开套接字的进程,而 netstat 则告诉我们 IP 地址和端口使用的情况,以及各个 TCP 连接的状态。Isof 和 netstst 可以结合起来一起使用。
可以通过 lsof 查看到底是谁打开了这个文件:
lsof /var/run/docker.sock

显示了是 dockerd 打开了这个本地文件套接字。

lsof 还有一个非常常见的用途。可以使用lsof找出 正在使用某个端口的那个进程。
lsof -i :8080

抓包利器:tcpdump

tcpdump 非常强大的过滤和匹配功能
比如说指定网卡:
tcpdump -i eth0
比如说指定来源:
tcpdump src host hostname
复杂一点的例子。这里抓的包是 TCP,且端口是 80,包来自 IP 地址为 192.168.1.25 的主机地址:
tcpdump 'tcp and port 80 and src host 192.168.1.25' 
这里 tcp[13:1]表示的是 TCP 头部开始处偏移为 13 的字节,如果这个值为 2,说明设置了 SYN 分节: (注:这里的偏移是从0开始算起的,tcp[13]其实是报文里的第 14 个字节。)
tcpdump 'tcp and port 80 and tcp[13:1]&2 != 0'

工作原理:
(1) tcpdump 在开启抓包的时候,会自动创建一个类型为 AF_PACKET 的网络套接口,并向系统内核注册。
(2) 当网卡接收到一个网络报文之后,它会遍历系统中所有已经被注册的网络协议,包括其中已经注册了的 AF_PACKET 网络协议。
(3) 系统内核接下来就会将网卡收到的报文 发送给该协议的回调函数进行一次处理,回调函数可以把接收到的报文完完整整地复制一份,假装是自己接收到的报文,然后交给 tcpdump 程序。
(4) tcpdump程序再进行 各种条件的过滤和判断,再对报文进行解析输出。

tcpdump 的输出格式:

首先看到的是时间戳,之后类似 192.168.33.11.41388 > 192.168.33.11.6443 这样的,显示的是源地址(192.168.33.11.41388)到目的地址(192.168.33.11.6443)
Flags[ ]是包的标志,比较常见的包格式如下:
  • [S]:SYN,表示开始连接
  • [.]: 没有标记,一般是确认
  • [P]:PSH,表示数据推送
  • [F]:FIN,表示结束连接
  • [R]:RST,表示重启连接
seq:     包序号,就是 TCP 的确认分组
cksum:校验码
win:     滑动窗口大小
length:承载的数据(payload)长度,如果没有数据则为 0

思考题

1. tcpdump这个工具还可以对 UDP 包进行抓包处理吗?
tcpdump可以抓UDP包,指定端口就可以了。
tcpdump还可以导出文件pcap,放到wireshark中进一步分析。
2. netstat 输出时,监听状态的套接字所对应的 Foreign Address 显示的 *.* 表示的是什么意思呢?
这个套接字正在监听端口等待连接进来,允许任何地址、任何端口来建立连接。