网络命令原理自我汇总

常用判断网络是否中断的方法:

1.Traceroute,Tracert

traceroute命令用于追踪数据包在网络上的传输时的全部路径,它默认发送的数据包大小是40字节。traceroute 的第一个作用就是故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。

它们用于显示数据包在IP网络中经过的路由器的IP地址,是利用IP数据包的存活时间(TTL)值来实现其功能的。

基于UDP实现

在基于UDP的实现中,客户端发送的数据包是通过UDP协议来传输的,使用了一个大于30000的端口号,服务器在收到这个数据包的时候会返回一个端口不可达的ICMP错误信息,客户端通过判断收到的错误信息是TTL超时还是端口不可达来判断数据包是否到达目标主机,具体的流程如图:

基于UDP实现的traceroute

客户端发送一个TTL为1,端口号大于30000的UDP数据包,到达第一站路由器之后TTL被减去1,返回了一个超时的ICMP数据包,客户端得到第一跳路由器的地址。

客户端发送一个TTL为2的数据包,在第二跳的路由器节点处超时,得到第二跳路由器的地址。

客户端发送一个TTL为3的数据包,数据包成功到达目标主机,返回一个端口不可达错误,traceroute结束。

Linux和macOS系统自带了一个traceroute指令,可以结合Wireshark抓包来看看它的实现原理。首先对百度的域名进行traceroute:traceroute www.baidu.com,每一跳默认发送三个数据包,我们会看到下面这样的输出:

traceroute.png

对该域名的IP:115.239.210.27进行traceroute,此时Wireshark抓包的结果如下:

抓包结果

注意看红框处的内容,跟第一张图对比,可以看到traceroute程序首先通过UDP协议向目标地址115.239.210.27发送了一个TTL为1的数据包,然后在第一个路由器中TTL超时,返回一个错误类型为Time-to-live exceeded的ICMP数据包,此时我们通过该数据包的源地址可知第一站路由器的地址为10.242.0.1。之后只需要不停增加TTL的值就能得到每一跳的地址了。

然而一直跑下去会发现,traceroute并不能到达目的地,当TTL增加到一定大小之后就一直拿不到返回的数据包了:

结果全是丢失

其实这个时候数据包已经到达目标服务器了,但是因为安全问题大部分的应用服务器都不提供UDP服务(或者被防火墙挡掉),所以我们拿不到服务器的任何返回,程序就理所当然的认为还没有结束,一直尝试增加数据包的TTL。

目前在网上找到许多开源iOS traceroute实现大多都是基于UDP的方案,实际用起来并不能达到想要的效果,所以我们需要采用另一种方案来实现。

-I     使用ICMP ECHO进行探测。

       -T    使用TCP SYN进行探测。

       -U     使用UDP报文进行探测(默认情况)。对于无特权用户来说,只允许使用UDP报文进行探测。

       -d     允许进行socket级别的调试(当Linux kernel支持它的时候)Enable socket level debugging (when the Linux kernel supports it)

基于ICMP实现:Tracert

Tracert 命令用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由。

首先,tracert送出一个TTL是1的IP 数据包到目的地,当路径上的第一个路由器收到这个数据包时,它将TTL减1。此时,TTL变为0,所以该路由器会将此数据包丢掉,并送回一个「ICMP time exceeded」消息(包括发IP包的源地址,IP包的所有内容及路由器的IP地址),tracert 收到这个消息后,便知道这个路由器存在于这个路径上,接着tracert 再送出另一个TTL是2 的数据包,发现第2 个路由器...... tracert 每次将送出的数据包的TTL 加1来发现另一个路由器,这个重复的动作一直持续到某个数据包 抵达目的地。当数据包到达目的地后,该主机则不会送回ICMP time exceeded消息,一旦到达目的地,由于tracert通过UDP数据包向不常见端口(30000以上)发送数据包,因此会收到「ICMP port unreachable」消息,故可判断到达目的地。

上述方案失败的原因是由于服务器对于UDP数据包的处理,所以在这一种实现中我们不使用UDP协议,而是直接发送一个ICMP回显请求(echo request)数据包,服务器在收到回显请求的时候会向客户端发送一个ICMP回显应答(echo reply)数据包,在这之后的流程还是跟第一种方案一样。这样就避免了我们的traceroute数据包被服务器的防火墙策略墙掉。

采用这种方案的实现流程如下:

基于ICMP实现的traceroute

客户端发送一个TTL为1的ICMP请求回显数据包,在第一跳的时候超时并返回一个ICMP超时数据包,得到第一跳的地址。

客户端发送一个TTL为2的ICMP请求回显数据包,得到第二跳的地址。

客户端发送一个TTL为3的ICMP请求回显数据包,到达目标主机,目标主机返回一个ICMP回显应答,traceroute结束。

可以看出与第一种实现相比,区别主要在发送的数据包类型以及对于结束的判断上,大体的流程还是一致的。

traceroute是检测到目的主机路由的工具,它并不能保证从本机发出的两个IP数据报有相同的路由。

traceroute 默认发送的是 UDP 包,而非 ICMP,可以通过 -I 参数来使 traceroute 发送 ICMP 包,另外还可以使用 -T 参数来测试 syn 握手。

另外使用 -p 参数可以指定端口,对于 UDP 而言,每进行一个 probe 端口就会在原来的基础上加 1;而对于 ICMP 而言,可以用来初始化 icmp sequence 值,同样的,每进行一次 probe,sequence 会加 1。

对于 TCP 而言则指定发送的端口

主要原因是traceroute的运行方式。它向第一台主机发送TTL为1的UDP(或Windows上的ICMP)数据包,并在收到超时答复(或通过内部超时)后,为具有TTL的下一台主机生成下一个数据包。 2个,依此类推(以此类推(将每个主机的TTL加1)。因此,traceroute的总时间包括依次发送和接收每个主机的数据包。

mtr在确定数据包采用的路径后,并行发送所有ICMP ECHO数据包。

简单总结一下 linode 那边文档的表述,traceroute 的那篇类似。如果只是某一个节点出现丢包,可能是由于路由限制了 ICMP 的流量;如果是从某个点开始接下去的几个点都出现不同程度的丢包,这个就可能是真正意义上的丢包了,可能是由于路由器撑不住了,或者直接把这部分包给过滤掉了,当然,由于去的包跟回来的包走的路由可能不一样,丢包可能是发生在回来的路上。因此最好的办法是 srs/dst 两边同时 mtr,不过这个一般情况下只有一方能实现,而另一方的控制权不在自己的手上。

尽管 TCP 有重传机制,当丢包达到一定的程度的时候还是会影响网路的性能,尤其在 latency 比较大的时候,如果 latency 比较小,比如在几ms之内,出现小部分的丢包也可以接受,但是如果 latency 本身就达到了 3,400ms,再来个 10% 的丢包,效果可想而知了。基本就是 latency 可以接受但是丢包律高就不可以接受了。

2.TCPdump

Linux抓包是通过注册一种虚拟的底层网络协议来完成对网络报文(准确的说是网络设备)消息的处理权。当网卡接收到一个网络报文之后,它会遍历系统中所有已经注册的网络协议,例如以太网协议、x25协议处理模块来尝试进行报文的解析处理,这一点和一些文件系统的挂载相似,就是让系统中所有的已经注册的文件系统来进行尝试挂载,如果哪一个认为自己可以处理,那么就完成挂载。

当抓包模块把自己伪装成一个网络协议的时候,系统在收到报文的时候就会给这个伪协议一次机会,让它来对网卡收到的报文进行一次处理,此时该模块就会趁机对报文进行窥探,也就是把这个报文完完整整的复制一份,假装是自己接收到的报文,汇报给抓包模块。

tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上。

tcpdump

tcpdump -i 网卡

tcpdump -nn 数字的方式显示IP和端口。一个n是ip

tcpdump -c x 抓包数量,x为数字

tcpdump port xx 抓指定端口的包,xx为端口号

tcpdump tcp and port xx 指定协议和端口,xx为端口号,and可以省略不写

tcpdump host xx.xx.xx.xx 指定来源IP或目标IP的包 xx.xx.xx.xx为IP地址。

tcpdump -w xx.txt 把抓的包写入一个文件,xx.txt为文件名

tcpdump -s0 -w xx.txt  抓包时防止包截断,s0的0为数字0,抓一个完整的包必须加s0。

tcpdump -r xx.txt 用户查看-w抓的包,xx.txt为文件名

-w抓的包实际是包的内容,非简单的流向。如果访问一张图片,用-w可以把这张图片抓出来。只看流向的话,可以使用重定向。


tcpdump 的各种参数

option 可选参数:将在后边一一解释,对应本文第四节:可选参数解析

proto 类过滤器:根据协议进行过滤,可识别的关键词有:upd, udp, icmp, ip, ip6, arp, rarp,ether,wlan, fddi, tr, decnet

type 类过滤器:可识别的关键词有:host, net, port, portrange,这些词后边需要再接参数。

direction 类过滤器:根据数据流向进行过滤,可识别的关键字有:src, dst,同时你可以使用逻辑运算符进行组合,比如 src or dst

若你的ip范围是一个网段,可以直接这样指定:

tcpdump net192.168.10.0/24

抓取DNS端口数据

DNS 的默认端口是 53,因此可以通过端口进行过滤

$ tcpdump-i any-s0 port53

控制详细内容的输出

-v:产生详细的输出. 比如包的TTL,id标识,数据包长度,以及IP包的一些选项。同时它还会打开一些附加的包完整性检测,比如对IP或ICMP包头部的校验和。

-vv:产生比-v更详细的输出. 比如NFS回应包中的附加域将会被打印, SMB数据包也会被完全解码。(摘自网络,目前我还未使用过)

-vvv:产生比-vv更详细的输出。比如 telent 时所使用的SB, SE 选项将会被打印, 如果telnet同时使用的是图形界面,其相应的图形选项将会以16进制的方式打印出来(摘自网络,目前我还未使用过)

-A:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据

-l: 基于行的输出,便于你保存查看,或者交给其它工具分析

-q: 简洁地打印输出。即打印很少的协议相关信息, 从而输出行都比较简短.

-c: 捕获 count 个包 tcpdump 就退出

-s:  tcpdump 默认只会截取前96字节的内容,要想截取所有的报文内容,可以使用-s number,number就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。

-S: 使用绝对序列号,而不是相对序列号

-C:file-size,tcpdump 在把原始数据包直接保存到文件中之前, 检查此文件大小是否超过file-size. 如果超过了, 将关闭此文件,另创一个文件继续用于原始数据包的记录. 新创建的文件名与-w 选项指定的文件名一致, 但文件名后多了一个数字.该数字会从1开始随着新创建文件的增多而增加. file-size的单位是百万字节(nt: 这里指1,000,000个字节,并非1,048,576个字节, 后者是以1024字节为1k, 1024k字节为1M计算所得, 即1M=1024 * 1024 = 1,048,576)

-F:使用file 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略.

-D: 显示所有可用网络接口的列表

-e: 每行的打印输出中将包括数据包的数据链路层头部信息

-E: 揭秘IPSEC数据

-L:列出指定网络接口所支持的数据链路层的类型后退出

-Z:后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。

-d:打印出易读的包匹配码

-dd:以C语言的形式打印出包匹配码.

-ddd:以十进制数的形式打印出包匹配码

=:判断二者相等

==:判断二者相等

!=:判断二者不相等

当你使用这两个符号时,tcpdump 还提供了一些关键字的接口来方便我们进行判断,比如

if:表示网卡接口名、

proc:表示进程名

pid:表示进程 id

svc:表示 service class

dir:表示方向,in 和 out

eproc:表示 effective process name

epid:表示 effective process ID

提取 HTTP 请求的 URL

tcpdump-s0-v-n-l|egrep-i"POST /|GET /|Host:"

提取 HTTP 的 User-Agent

tcpdump-nn-A-s1500-l|egrep-i'User-Agent:|Host:'

找出发包数最多的 IP

tcpdump-nnn-t-c200|cut-f1,2,3,4-d'.'|sort|uniq-c|sort-nr|head-n20

cut -f 1,2,3,4 -d '.' : 以 . 为分隔符,打印出每行的前四列。即 IP 地址。

sort | uniq -c : 排序并计数

sort -nr : 按照数值大小逆向排序

 提取 HTTP 请求的 URL

tcpdump-s0-v-n-l|egrep-i"POST /|GET /|Host:"

3.Ping

Ping的原理 

ping程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接。

ping使用的是ICMP协议,它发送icmp回送请求消息给目的主机。ICMP协议规定:目的主机必须返回ICMP回送应答消息给源主机。如果源主机在一定时间内收到应答,则认为主机可达。

ICMP协议通过IP协议发送的,IP协议是一种无连接的,不可靠的数据包协议。在Unix/Linux,序列号从0开始计数,依次递增。而Windowsping程序的ICMP序列号是没有规律。

ICMP协议在实际传输中数据包:20字节IP首部 + 8字节ICMP首部+ 1472字节<数据大小>38字节    

ICMP报文格式:IP首部(20字节)+8位类型+8位代码+16位校验和+(不同的类型和代码,格式也有所不同)

Ping工作过程

Ping 使用ICMP协议,工作在第三层,命令在应用层

假定主机A的IP地址是192.168.1.1,主机B的IP地址是192.168.1.2,都在同一子网内,则当你在主机A上运行“Ping192.168.1.2”后,都发生了些什么呢?

首先,Ping命令会构建一个固定格式的ICMP请求数据包,然后由ICMP协议将这个数据包连同地址“192.168.1.2”一起交给IP层协议(和ICMP一样,实际上是一组后台运行的进程),IP层协议将以地址“192.168.1.2”作为目的地址,本机IP地址作为源地址,加上一些其他的控制信息,构建一个IP数据包,并在一个映射表中查找出IP地址192.168.1.2所对应的物理地址(也叫MAC地址,熟悉网卡配置的朋友不会陌生,这是数据链路层协议构建数据链路层的传输单元——帧所必需的),一并交给数据链路层。后者构建一个数据帧,目的地址是IP层传过来的物理地址,源地址则是本机的物理地址,还要附加上一些控制信息,依据以太网的介质访问规则,将它们传送出去。其中映射表由ARP实现。ARP(Address Resolution Protocol)是地址解析协议,是一种将IP地址转化成物理地址的协议。ARP具体说来就是将网络层(IP层,也就是相当于OSI的第三层)地址解析为数据连接层(MAC层,也就是相当于OSI的第二层)的MAC地址。

主机B收到这个数据帧后,先检查它的目的地址,并和本机的物理地址对比,如符合,则接收;否则丢弃。接收后检查该数据帧,将IP数据包从帧中提取出来,交给本机的IP层协议。同样,IP层检查后,将有用的信息提取后交给ICMP协议,后者处理后,马上构建一个ICMP应答包,发送给主机A,其过程和主机A发送ICMP请求包到主机B一模一样。即先由IP地址,在网络层传输,然后再根据mac地址由数据链路层传送到目的主机。

ICMP主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。

ARP是地址解析协议,是根据IP地址获取物理地址的一个TCP、IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址。

在IP通信中如果某个IP包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负责通知

ICMP 目标不可达消息

如上图例子,主机A向主机B发送了数据包,由于某种原因,途中的路由器2未能发现主机B的存在,这时,路由器2就会向主机A发送一个ICMP目标不可达数据包,说明发往主机B的包未能成功。

回送消息用于进行通信的主机或路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息,ping 命令就是利用这个消息实现的。

IP 路由器无法将 IP 数据包发送给目标地址时,会给发送端主机返回一个目标不可达的 ICMP 消息,并在这个消息中显示不可达的具体原因,原因记录在 ICMP 包头的代码字段。

由此,根据 ICMP 不可达的具体消息,发送端主机也就可以了解此次发送不可达的具体原因

举例 6 种常见的目标不可达类型的代码


附TCP/IP模型


我们重点来看 ping 的发送和接收过程。同个子网下的主机 A 和 主机 B,主机 A 执行ping 主机 B 后的过程


4.MTR

mtr在单个网络诊断工具中结合了traceroute和ping程序的功能。当mtr启动时,它调查运行在主机mtr和主机名之间的网络连接。traceroute默认使用UDP数据包探测,而mtr默认使用ICMP报文探测,ICMP在某些路由节点的优先级要比其他数据包低,所以测试得到的数据可能低于实际情况。

通过发送有目的的低TTL的包。它继续以较低的TTL发送数据包,记录中间路由器。这允许MTR打印Internet路由的响应百分比和响应时间。到主机名。包丢失或响应时间的突然增加通常是坏的(或仅仅是过度的)迹象。已加载)链接。结果通常以往返响应时间(毫秒)和包丢失百分比报告。

mtr -Trwc 300 web14-tzzj.gtarcade.com

mtr -r 202.108.33.94 使用-c参数设置每秒发送数据包数量:

mtr -r -c 30 202.108.33.94 使用-s参数指定ping数据包的大小:

mtr -r -c 30 -s 1024 202.108.33.94 mtr -s 用来指定ping数据包的大小

mtr -n no-dns不对IP地址做域名解析

mtr -a 来设置发送数据包的IP地址 这个对一个主机由多个IP地址是有用的

mtr -i 使用这个参数来设置ICMP返回之间的要求默认是1秒

MTR qq.com 测试界面

具体输出的参数含义为:

第一列是IP地址 丢包率:Loss

已发送的包数:Snt

最后一个包的延时:Last

平均延时:Avg

最低延时:Best

最差延时:Wrst

方差(稳定性):StDev

使用 mtr -r qq.com 来打印报告,如果不使用 -r or --report 参数 mtr 会不断动态运行。使用 report 选项, mtr 会向 qq.com 主机发送 10 个 ICMP 包,然后直接输出结果。通常情况下 mtr 需要几秒钟时间来输出报告。mtr 报告由一系列跳数组成,每一跳意味着数据包通过节点或者路由器来达到目的主机。

一般情况下 mtr 前几跳都是本地 ISP,后几跳属于服务商比如 腾讯数据中心,中间跳数则是中间节点,如果发现前几跳异常,需要联系本地 ISP 服务提供上,相反如果后几跳出现问题,则需要联系服务提供商,中间几跳出现问题,则需要联系运营商进行处理

默认使用 -r 参数来生成报告,只会发送10个数据包,如果想要自定义数据包数量,可以使用 -c 参数

MTR结果分析

当我们分析 MTR 报告时候,最好找出每一跳的任何问题。除了可以查看两个服务器之间的路径之外,MTR 在它的七列数据中提供了很多有价值的数据统计报告。Loss% 列展示了数据包在每一跳的丢失率。Snt 列记录的多少个数据包被送出。使用 –report 参数默认会送出10个数据包。如果使用 –report-cycles=[number-of-packets] 选项,MTR 就会按照 [number-of-packets] 指定的数量发出 ICMP 数据包。

Last, Avg, Best 和 Wrst 列都标识数据包往返的时间,使用的是毫秒( ms )单位表示。Last 表示最后一个数据包所用的时间, Avg 表示评价时间, Best 和 Wrst 表示最小和最大时间。在大多数情况下,平均时间( Avg)列需要我们特别注意。

最后一列 StDev 提供了数据包在每个主机的标准偏差。如果标准偏差越高,说明数据包在这个节点的延时越不相同。标准偏差会让您了解到平均延时是否是真的延时时间的中心点,或者测量数据受到某些问题的干扰。

例如,如果标准偏差很大,说明数据包的延迟是不确定的。一些数据包延迟很小(例如:25ms),另一些数据包延迟很大(例如:350ms)。当10个数据包全部发出后,得到的平均延迟可能是正常的,但是平均延迟是不能很好的反应实际情况的。如果标准偏差很高,使用最好和最坏的延迟来确定平均延迟是一个较好的方案。

在大多数情况下,您可以把 MTR 的输出分成三大块。根据配置,第二或第三跳一般都是您的本地 ISP,倒数第二或第三跳一般为您目的主机的ISP。中间的节点是数据包经过的路由器。

当分析 MTR 的输出时,您需要注意两点:loss 和 latency。

网络丢包

如果在任何一跳上看到 loss 的百分比,这就说明这一跳上可能有问题了。当然,很多服务提供商人为限制 ICMP 发送的速率,这也会导致此问题。那么如何才能指定是人为的限制 ICMP 传输 还是确定有丢包的现象?此时需要查看下一跳。如果下一跳没有丢包现象,说明上一条是人为限制的。如下示例:

MTR丢包截图

从下面的图中,您可以看从第14跳和第17跳都有 10% 的丢包率,从接下来的几跳都有丢包现象,但是最后15,16跳都是100%的丢包率,我们可以猜测到100%的丢包率除了网络糟糕的原因之前还有人为限制 ICMP。所以,当我们看到不同的丢包率时,通常要以最后几跳为准。

还有很多时候问题是在数据包返回途中发生的。数据包可以成功的到达目的主机,但是返回过程中遇到“困难”了。所以,当问题发生后,我们通常需要收集反方向的 MTR 报告。

此外,互联网设施的维护或短暂的网络拥挤可能会带来短暂的丢包率,当出现短暂的10%丢包率时候,不必担心,应用层的程序会弥补这点损失。


网络延迟

除了可以通过MTR报告查看丢包率,我们也还可以看到本地到目的之间的时延。因为是不通的位置,延迟通常会随着条数的增加而增加。所以,延迟通常取决于节点之间的物理距离和线路质量。

从上面的MTR报告截图中,我们可以看到从第11跳到12跳的延迟猛增,直接导致了后面的延迟也很大,一般有可能是11跳到12跳属于不通地域,物理距离导致时延猛增,也有可能是第12条的路由器配置不当,或者是线路拥塞。需要具体问题进行具体的分析。

然而,高延迟并不一定意味着当前路由器有问题。延迟很大的原因也有可能是在返回过程中引发的。从这份报告的截图看不到返回的路径,返回的路径可能是完全不同的线路,所以一般需要进行双向MTR测试。

注:ICMP 速率限制也可能会增加延迟,但是一般可以查看最后一条的时间延迟来判断是否是上述情况。


根据MTR结果解决网络问题

MTR 报告显示的路由问题大都是暂时性的。很多问题在24小时内都被解决了。大多数情况下,如果您发现了路由问题,ISP 提供商已经监视到并且正在解决中了。当您经历网络问题后,可以选择提醒您的 ISP 提供商。当联系您的提供商时,需要发送一下 MTR 报告和相关的数据。没有有用的数据,提供商是没有办法去解决问题的。

然而大多数情况下,路由问题是比较少见的。比较常见的是因为物理距离太长,或者上网高峰,导致网络变的很慢。尤其是跨越大西洋和太平洋的时候,网络有时候会变的很慢。这种情况下,建议就近接入客户的节点。

5.DIG

dig 最基本的功能就是查询域名信息,因此它的名称实际上是“ 域名信息查询工具(Domain Information Groper)”的缩写。dig 向用户返回的内容可以非常详尽,也可以非常简洁,展现内容的多少完全由用户在查询时使用的选项来决定。

在查询的时候发现有的域名会指向多个 IP 地址?这其实是网站提高其可用性的一种措施。

查询过程

虽然只需要返回一个IP地址,但是DNS的查询过程非常复杂,分成多个步骤。

工具软件dig可以显示整个查询过程。

$ dig math.stackexchange.com

上面的命令会输出六段信息。

第一段是查询参数和统计。

第二段是查询内容。

上面结果表示,查询域名math.stackexchange.com的A记录,A是address的缩写。

第三段是DNS服务器的答复。

上面结果显示,math.stackexchange.com 有四个A记录,即四个IP地址。600是TTL值(Time to live 的缩写),表示缓存时间,即600秒之内不用重新查询。

第四段显示stackexchange.com的NS记录(Name Server的缩写),即哪些服务器负责管理stackexchange.com的DNS记录。

上面结果显示stackexchange.com共有四条NS记录,即四个域名服务器,向其中任一台查询就能知道math.stackexchange.com的IP地址是什么。

第五段是上面四个域名服务器的IP地址,这是随着前一段一起返回的。

第六段是DNS服务器的一些传输信息。

上面结果显示,本机的DNS服务器是192.168.1.253,查询端口是53(DNS服务器的默认端口),以及回应长度是305字节。

# 分级查询的实例

dig命令的+trace参数可以显示DNS的整个分级查询过程。

$ dig +trace math.stackexchange.com

上面命令的第一段列出根域名.的所有NS记录,即所有根域名服务器。

根据内置的根域名服务器IP地址,DNS服务器向所有这些IP地址发出查询请求,询问math.stackexchange.com的顶级域名服务器com.的NS记录。最先回复的根域名服务器将被缓存,以后只向这台服务器发请求。

接着是第二段。

上面结果显示.com域名的13条NS记录,同时返回的还有每一条记录对应的IP地址。

然后,DNS服务器向这些顶级域名服务器发出查询请求,询问math.stackexchange.com的次级域名stackexchange.com的NS记录。

上面结果显示stackexchange.com有四条NS记录,同时返回的还有每一条NS记录对应的IP地址。

然后,DNS服务器向上面这四台NS服务器查询math.stackexchange.com的主机名。

上面结果显示,math.stackexchange.com有4条A记录,即这四个IP地址都可以访问到网站。并且还显示,最先返回结果的NS服务器是ns-463.awsdns-57.com,IP地址为205.251.193.207。

# NS 记录的查询

$ dig ns com

$ dig ns stackexchange.com

+short参数可以显示简化的结果。

$ dig +short ns com $ dig +short ns stackexchange.com

1. $ dig networkworld.com +short

151.101.2.165

151.101.66.165

151.101.130.165

151.101.194.165

2. dig @serverip 指定dns服务器进行解析

[root@basic harbor]# dig @8.8.8.8 www.mikezhu.tech

; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.2 <<>> @8.8.8.8 www.mikezhu.tech

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57221

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 512

;; QUESTION SECTION:

;www.mikezhu.tech. IN A

;; ANSWER SECTION:

www.mikezhu.tech. 599 IN A 192.168.137.10

;; Query time: 87 msec

;; SERVER: 8.8.8.8#53(8.8.8.8)

;; WHEN: Mon Aug 05 10:41:48 CST 2019

;; MSG SIZE rcvd: 61

3. 直接dig域名,根据自身网络的dns获取域名解析信息

root@basic harbor]# dig www.mikezhu.tech

; <<>> DiG 9.9.4-RedHat-9.9.4-74.el7_6.2 <<>> www.mikezhu.tech

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33969

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 4096

;; QUESTION SECTION:

;www.mikezhu.tech. IN A

;; ANSWER SECTION:

www.mikezhu.tech. 600 IN A 192.168.137.10

;; Query time: 347 msec

;; SERVER: 202.96.209.133#53(202.96.209.133)

;; WHEN: Mon Aug 05 10:39:59 CST 2019

;; MSG SIZE rcvd: 61

批量查询域名

如果你要查询多个域名,可以把这些域名写入到一个文件内(domains),然后使用下面的 dig 命令遍历整个文件并给出所有查询结果。

$ dig +noall +answer -f domains

networkworld.com.      300    IN      A      151.101.66.165

networkworld.com.      300    IN      A      151.101.2.165

networkworld.com.      300    IN      A      151.101.130.165

networkworld.com.      300    IN      A      151.101.194.165

world.std.com.          77972  IN      A      192.74.137.5

uushenandoah.org.      1982    IN      A      162.241.24.209

amazon.com.            18      IN      A      176.32.103.205

amazon.com.            18      IN      A      176.32.98.166

amazon.com.            18      IN      A      205.251.242.103

Command Test for SNI,Normally used the first one

(1) openssl s_client -servername www.lizhou.fun -connect lizhou.fun:443

(2) openssl s_client -connect 69.164.193.227:443 -tls1

(3) openssl s_client -connect www.lizhou.fun:443 | openssl x509 -noout -text | grep DNS

(4) openssl s_client -connect 69.164.193.227:443 -servername www.lizhou.fun -tls1 (Specify the hostname)

什么是SNI协议?

服务器名称指示(英语:Server Name Indication,简称SNI)是一个扩展的TLS计算机联网协议,在该协议下,在握手过程开始时通过客户端告诉它正在连接的服务器的主机名称。这允许服务器在相同的IP地址和TCP端口号上呈现多个证书,因此允许在相同的IP地址上提供多个安全HTTPS网站(或其他任何基于TLS的服务),而不需要所有这些站点使用相同的证书

为什么需要使用SNI协议?

基于名称的虚拟主机允许多个DNS主机名由同一IP地址上的单个服务器(通常为Web服务器)托管。为了实现这一点,服务器使用客户端提供的主机名作为协议的一部分(对于HTTP,名称显示在主机头中)。但是,当使用HTTPS时,TLS握手发生在服务器看到任何HTTP头之前。因此,服务器不可能使用HTTP主机头中的信息来决定呈现哪个证书,并且因此只有由同一证书覆盖的名称才能由同一IP地址提供。

了解SNI协议可以用来做什么?

如果我们要对流量进行识别,做流量检测等,HTTPS流量是加密的,很难检测其内部的具体内容。SNI协议给出了一个切入点,在HTTPS协议建立加密连接的开始阶段检测出访问的域名信息

常规TLS/SSL握手失败

TLS/SSL版本不匹配

自从TLS 1.2版本在2008年发布以来,绝大部分HTTPS流量都跑在TLS 1.2上。服务器处于安全性考虑通常也只支持较高版本TLS,比如TLS1.0及以上。但是仍然有一些版本比较旧的操作系统和浏览器存在,如果这些客户端用低版本TLS/SSL向服务器发起握手,会因为服务器不支持而直接失败。

比如淘宝网只支持TLS 1.0及以上版本,用openssl发起SSL 3版本的握手,就会出现handshake failure。

# openssl s_client -connect www.taobao.com:443 -ssl3 -msg

140191222585232:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:s3_pkt.c:1493:SSL alert number 40

140191222585232:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

no peer certificate available

No client certificate CA names sent

TLS/SSL cipher suite不匹配

在握手的前两个ClientHello和ServerHello包中有一个重要的任务就是协商cipher。客户端在ClientHello中会带上所有支持的cipher suite, 服务器在收到ClientHello中的cipher suite后,会和自己支持的cipher suite一一匹配,如果没有可以匹配的就会握手失败。

服务器出于安全性考虑通常只会支持安全性较高的cipher,所以当客户端发过去的cipher suite安全性都比较低时会造成握手失败。

例如用openssl向淘宝网发起握手,客户端的ClientHello中只有一个安全性较低的DHE-RSA-AES128-SHA256 cipher,会出现handshake failure。

openssl s_client -connect www.taobao.com:443 -cipher DHE-RSA-AES128-SHA256 -msg

139737777813392:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:769:no peer certificate available,No client certificate CA names sent

TLS/SSL握手Warning

在握手过程中,客户端对服务器证书会做验证,验证不过时会出现Warning。浏览器可以选择忽略,用curl也可以使用-k参数来忽略。严格来说并不算Failure,这里归类成Warning,不做详细讨论。例如如下几种比较常见的情况:

访问的域名不在服务器证书的CN(Common Name)和SAN(Subject Alternative Name)中。服务器证书被吊销,导致验证不通过。

现象如下是一个例子。客户端访问阿里云的一个公网IP地址TLS/SSL握手失败。先来看下现象,在客户端的抓包如下


可以看到前面的TCP三次握手和一些数据交互(特定协议相关,正常情况在TCP三次握手后直接开始TLS/SSL握手)都没有问题。但是开始TLS/SSL握手交互过程客户端发出第一个报文,马上收到一个TCP RESET。这个和上面提到的常规握手失败很不一样, TCP RESET报文通常是设备或者主机协议栈主动发出,符合一定场景或者有一定网络管理含义。

根本原因

云盾根据访问的目的域名有没有备案做执行相关动作。云盾并没有在TCP建连时就针对源目IP做阻断,而是提取ClientHello中的SNI(Servername Indication)域名信息判断是否备案而做阻断,返回TCP RESET。

SNI是ClientHello中的一个扩展字段,带有要访问的目标域名,让同一个IP上托管多个HTTPS站点的服务器知道客户端访问的是哪个目标域名,以便使用对应的证书进行交互。在ClientHello报文的如下位置

客户端证书问题导致TLS/SSL握手失败

在双向验证的场景中,不仅仅客户端要验证服务器证书,服务器也需要验证客户端证书。在服务器验证客户端证书的过程中,由于客户端证书的安全性较低,可能会直接产生Fatal Alert,导致握手直接中断。

现象

如下是一个手机App访问服务器的例子。72号报文报出了Bad Certificate的Fatal Alert,从上下文看,这里是客户端向服务器端发送完Certificate, Client Key Exchange等消息后,服务器返回给客户端的报错。

在手机App中的报错如下:

SSL handshake aborted: ssl=0x7c1bbf6e88: Failure in SSL library, usually a protocol error

error:10000412:SSL routines:OPENSSL_internal:SSLV3_ALERT_BAD_CERTIFICATE (external/boringssl/src/ssl/http://tls_record.cc:592 0x7c6c627e48:0x00000001)


无法提取SNI导致TLS/SSL握手失败

在某些场景中,需要获取ClientHello中的SNI字段来作为一个必要条件, 比如用NGINX stream对HTTPS流量做4层代理时。客户端ClientHello中没有携带SNI,则会造成一个通过代理握手失败的局面。

现象

和上面个握手失败的现象如出一辙,在客户端发出ClientHello后,马上被代理服务器FIN掉,唯一不同的是这里的ClientHello并没有带上SNI字段。

根本原因

在利用NGINX stream做正向代理时,NGXIN服务器需要获取客户端想要访问的目的域名。利用ngx_stream_ssl_preread_module模块在不解密的情况下拿到ClientHello报文中SNI才能实现代理的正常功能。

6. iperf使用方法

Iperf是一个网络性能测试工具。Iperf可以测试TCP和UDP带宽质量。Iperf可以测量最大TCP带宽,具有多种参数和UDP特性。Iperf可以报告带宽,延迟抖动和数据包丢失。利用Iperf这一特性,可以用来测试一些网络设备如路由器,防火墙,交换机等的性能。

Iperf的主要功能如下:

TCP

测量网络带宽,报告MSS/MTU值的大小和观测值,支持TCP窗口值通过套接字缓冲

当P线程或Win32线程可用时,支持多线程。客户端与服务端支持同时多重连接

UDP

客户端可以创建指定带宽的UDP流,测量丢包,测量延迟,支持多播

当线程可用时,支持多线程。客户端与服务端支持同时多重连接(不支持Windows)

 iperf如何使用

4.1 TCP性能测试

服务器端命令:iperf3 -s

客户端命令:iperf3 -c 192.168.1.5 -b 200M

测试结果:

从图中可以看出测试的吞吐量、丢包率等参数。

服务器端:

iperf -s

客户端:

iperf -c 192.168.1.1 -t 60

在tcp模式下,客户端到服务器192.168.1.1上传带宽测试,测试时间60秒。

iperf -c 192.168.1.1 -P 30 -t 60

客户端同时向服务器端发起30个连接线程。

iperf -c 192.168.1.1 -d -t 60

进行上下行带宽测试。

4.2 UDP性能测试

带宽测试通常采用UDP模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时

step1:以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为100Mbps,先用-b 100M进行测试

step2:根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。

服务端命令:iperf3 -s

客户端命令:iperf3 -u -c 192.168.1.5 -b 200M

测试结果:

从测试结果可以看出吞吐量Bitrate、抖动jitter、丢包率

UDP模式

服务器端:

iperf -u -s

客户端:

iperf -u -c 192.168.1.1 -b 100M -t 60

在UDP模式下,以100Mbps为数据发生速率,客户端到服务器192.168.1.1上传带宽测试,测试时间为60s

iperf -u -c 192.168.1.1 -b 50M -P 30 -t 60

客户端同时向服务器端发起30个连接线程,以5Mbps为数据发生速率

iperf -u -c 192,168.1.1 -b 100M -d -t 60

以100M为数据发生速率,进行上下行带宽测试。

7. SS命令

ss是Socket Statistics的缩写。顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。但ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。

当服务器的socket连接数量变得非常大时,无论是使用netstat命令还是直接cat /proc/net/tcp,执行速度都会很慢。可能你不会有切身的感受,但请相信我,当服务器维持的连接达到上万个的时候,使用netstat等于浪费 生命,而用ss才是节省时间。

天下武功唯快不破。ss快的秘诀在于,它利用到了TCP协议栈中tcp_diag。tcp_diag是一个用于分析统计的模块,可以获得Linux 内核中第一手的信息,这就确保了ss的快捷高效。当然,如果你的系统中没有tcp_diag,ss也可以正常运行,只是效率会变得稍慢。(但仍然比 netstat要快。)

ss(Socket Statistics的缩写)命令可以用来获取 socket统计信息,此命令输出的结果类似于 netstat输出的内容,但它能显示更多更详细的 TCP连接状态的信息,且比 netstat 更快速高效。它使用了 TCP协议栈中 tcp_diag(是一个用于分析统计的模块),能直接从获得第一手内核信息,这就使得 ss命令快捷高效。在没有 tcp_diag,ss也可以正常运行。

[root@localhost ~]# ss -t -aState      Recv-Q Send-Q                                Local Address:Port                                    Peer Address:Port   

LISTEN     0      0                                         127.0.0.1:smux                                               *:*       

LISTEN     0      0                                                 *:3690                                               *:*       

LISTEN     0      0                                                 *:ssh                                                *:*       

ESTAB      0      0                                   192.168.120.204:ssh                                        10.2.0.68:49368   

8. NC命令

nc的作用

(1)实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口

(2)端口的扫描,nc可以作为client发起TCP或UDP连接

(3)机器之间传输文件

(4)机器之间网络测速  

nc的控制参数不少,常用的几个参数如下所列:

1) -l 用于指定nc将处于侦听模式。指定该参数,则意味着nc被当作server,侦听并接受连接,而非向其它地址发起连接。

2) -p 暂未用到(老版本的nc可能需要在端口号前加-p参数,下面测试环境是centos6.6,nc版本是nc-1.84,未用到-p参数)

3) -s 指定发送数据的源IP地址,适用于多网卡机 

4) -u  指定nc使用UDP协议,默认为TCP

5) -v 输出交互或出错信息,新手调试时尤为有用

6)-w 超时秒数,后面跟数字 

7)-z 表示zero,表示扫描时不发送任何数据

nc用法1,网络连通性测试和端口扫描

nc可以作为server端启动一个tcp的监听(注意,此处重点是起tcp,下面还会讲udp)

nc -l 9999

nc作为server端启动一个udp的监听(注意,此处重点是起udp,上面主要讲了tcp)

启动一个udp的端口监听

nc  -ul  9998

9. Shell 三剑客

awk:AWK一次处理是一行, 而一次中处理的最小单位是一个区域

sed: (关键字: 编辑) 以行为单位的文本编辑工具

grep: (关键字: 截取) 文本搜集工具, 结合正则表达式非常强大

grep

是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来

sed

sed 是一种在线编辑器,它一次处理一行内容 。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。

awk

相较于sed 常常作用于一整个行的处理,awk 则比较倾向于一行当中分成数个『字段』来处理。 因此,awk 相当的适合处理小型的数据数据处理

grep(文本生成器)

grep是一种强大的文本搜索工具他能使用正则表达式搜索文本,并把匹配的行统计出来

命令:grep [选项] [–color=auto] ”搜索字符串” filename

输出匹配行的前后N行(会包括匹配行)

使用-A参数输出匹配行的后一行:grep -A 1 “huangxiaoming” grep.txt

使用-B参数输出匹配行的前一行:grep -B 1 “huangxiaoming” grep.txt

使用-C参数输出匹配行的前后各一行:grep -C 1 “huangxiaoming” grep.txt

sed(流编辑器)

sed叫做流编辑器,在shell脚本和Makefile中作为过滤一使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换成为另一种格式输出。sed是一种在线编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。

sed 's/hello/hi/2' sed.txt

##  此种写法表示只替换每行的第2个hello为hi

sed 's/hello/hi/2g' sed.txt

##  此种写法表示只替换每行的第2个以后的hello为hi(包括第2个

awk(报表生成器)

Awk是一个强大的处理文本的编程语言工具,其名称得自于它的创始人Alfred Aho、Peter Weinberger和Brian Kernighan 姓氏的首个字母,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。AWK 提供了极其强大的功能:可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。简单来说awk就是扫描文件中的每一行,查找与命令行中所给定内容相匹配的模式。如果发现匹配内容,则进行下一个编程步骤。如果找不到匹配内容,则继续处理下一行

[root@localhost ~]# last -n 5 | awk '{print $1}'

root

reboot

root

root

root

awk工作流程是这样的:读入有’\n’换行符分割的一条记录,然后将记录按指定的域分隔符划分域,填充域,$0则表示所有域,1表示第一个域,1表示第一个域,1表示第一个域,n表示第n个域。默认域分隔符是"空白键" 或 “[tab]键”,所以$1表示登录用户,$3表示登录用户ip,以此类推

你可能感兴趣的:(网络命令原理自我汇总)