常用判断网络是否中断的方法:
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
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,以此类推