在“微学堂”分享之后,大家反馈说不错,故仔细整理成像样的文章,分成“上、中、下”3篇,计划分三天发出。
这是第二篇,绝对干货:
- tcpdump
- ip
- nc
- rsync
- wget
- uptime
- free
- vmstat
- mpstatl
- top
tcpdump
tcpdump就好像一个神探,它有着夜视的绝技,在毫无光亮的环境中,仍然可以看到所有的东西。
我们可以用通俗、形象、学术的表达方式来全方位地描述tcpdump :
- 通俗地说,tcpdump是一个抓包工具,用于抓取互联网上传输的数据包。
- 形象地说,tcpdump就好比是国家海关,驻扎在出入境的咽喉要道,凡是要入境和出境的集装箱,海关人员总要打开箱子,看看里面都装了些啥。
- 学术地说,tcpdump是一种嗅探器(sniffer ),利用以太网的特性,通过将网卡适配器(NIC )置于混杂模式(promiscuous )来获取传输在网络中的信息包。
开门见山,我们开始抓人生中的第一个包:
[root@roclinux ~]# tcpdump -i eth0 -nn -X 'port 53' -c 1
我们来一起解读上面这条命令:
- -i 选项:即interface,用来指定网络接口,也就是要告诉tcpdump希望它去监听哪一块网卡,这在我们的服务器有多块网卡时是很有必要的。
- -nn选项:意思是当tcpdump遇到协议号或端口号时,不要将这些数字转换成对应的协议名称或端口名称。比如,众所周知21号端口是FTP端口,我们希望显示“ 21”,而非“ FTP”。
- -X选项:告诉tcpdump命令,需要把协议头和包内容都原原本本地显示出来。 tcpdump会同时以16进制和ASCII的形式显示,这在进行协议分析时是绝对的利器。
- port 53:这是告诉 tcpdump 要有选择地展示所抓到的包。本例中,我们只关心源端口或目的端口是53的数据包,其他的数据包就不要再显示出来了。
- -c 选项:是Count的含义,这个选项用来设置我们希望 tcpdump 帮我们抓几个包。我设置的是1,所以tcpdump只会抓一个包就收手,不会帮我再多抓哪怕一个包。
好了,大家都已经学会抓包了,而在实际运维工作中,我们需要将抓到的包保存起来,然后再对抓到的包逐一进行分析。
所以,我们就要掌握“如何保存”和“如何读取”网络数据包的技能。下面,我们就来一起学习。
做过网络流量分析的同学,或许都有一个共同的需求,那就是都要做“流量保存”和“流量回放”,这就恰好对应到了的-w选项和-r选项。
流量保存就是把抓到的网络包存储到磁盘上,保存下来,为以后使用。
流量回放就是把历史上的某一时间段的流量,重新模拟回放出来,用于流量分析。
- -w选项:将流量保存到文件中:
通过上面的例子可以看到,通过-w 选项将流量都存储在了flowdata文件中了。
如果大家用less命令查看flowdata这个文件的话,会发现全是乱码。
原来,tcpdump的-w方式是把 raw packets(原始网络包)直接存储到文件中的,也就是存储的都是结构体数据,而非我们在屏幕上所看到的文本格式的数据,因此大家是无法直接通过less命令查看的。
那怎么查看呢?大家想必也想到了,那就是用-r选项。
其实上面的命令就是在不知不觉中进行了“流量回放”,你会发现曾经被抓的网络包,都按照历史顺序进行了回放,是不是有种坐上了“时光机”的感觉:)
前面我们都是围绕tcpdump 的选项来介绍的,下面,我们会把目光转向“过滤表达式”,让大家能够在抓包过程中“去其糟粕,取其精华”。
如果你希望自己研究“过滤表达式”,没问题,我会告诉你如何“入门”,方法就是:
man pcap-filter
你会发现,过滤表达式大体可以分成三种过滤条件,“类型”、“方向”和“协议”,这三种条件的搭配组合就构成了我们的过滤表达式。
我们来看实战:
我只想抓UDP的包,不想被TCP的包打扰
[root@roclinux ~]# tcpdump -i eth0 -c 10 'ump'
举这个例子,是为了说明tcpdump具有根据网络包的协议类型来进行过滤的能力,我们还可以把udp改为ether 、ip 、ip6 、arp 、tcp 或rarp 等。
我想专门查看这个源机器和那个目的机器之间的网络包,不想被其他无关的网络包所打扰,该怎么做呢?
这个其实很简单,也很直观,只要设置src(source)和dst(destination)就好了。而且很方便的是,tcpdump还支持使用and和or来进行搭配组合呢!
[root@roclinux ~]# tcpdump -i eth0 'dst 8.8.8.8'
只想看到目的端口是53或80的网络包,其他端口的我不关注。[root@roclinux ~]# tcpdump -i eth0 -c 3 'dst port 53 or dst port 80'
看,我们这里用到了or这个关系符。
我们可以设置过滤类型,上面例子中我们使用了port这个类型,就是来指定端口的。当然,tcpdump还支持如下类型:
- host:指定主机名或 IP 地址,例如‘host roclinux.cn’或‘host 202.112.18.34’。
- net:指定网络段,例如 src net 128.3’或‘ dst net 128.3’。
- portrange:指定端口区域,例如‘ src or dst portrange 6000-6008’。
如果我们没有设置过滤类型,那么默认是host 。
好了,我们在这几分钟里,为大家介绍了tcpdump的抓包、存包、读包、过滤包的各种实战方法,相信大家已经掌握了。
而如何解读包中的内容,大家可以通过阅读我书中的相应篇章来深入学习。
ip
我们接下来讲的是ip,它既不是IP地址,也不是知识产权,而是Linux系统iproute2软件包中的ip命令,一个用来管理网络设备和路由的强大命令。
假如我想展示一台服务器的网络接口信息,那就这样:ip addr show
而为网络接口添加一个IP 地址,方法是这样的:
ip addr add 192.168.1.111/24 dev p1p2
针对一个网络接口删除其IP 地址,这样:
ip addr del 192.168.1.111/24 dev p1p2
禁止和激活网卡接口,也很简单:
ip link set p1p2 downip link set p1p2 up
查看路由表的方法是:
ip route show
我要增加一条路由规则:
ip route add 192.168.2.0/24 via 192.168.1.254
指定默认网关:
ip route add default via 192.168.1.6
可以看到,ip命令是一个纯粹的管理类命令,我回头会整理一张关于ip的速查表,分享在”Linux大棚“公众号和微博中,便于大家查阅。
nc
命令nc,全名netcat ,中文叫作“网猫” ,nc的man中提到:
The nc (or netcat) utility is used for just about anything under the sun involving TCP or UDP.
这句话翻译成中文就是:“nc工具能胜任全天下的跟TCP/UDP相关的一切操作。”
nc确实很能干,它可以打开TCP 链接、发送UDP 包、监听TCP/UDP 端口、进行端口扫描,是网络世界里的一只既可爱又靠谱的网猫。
nc最常用的用法就是端口扫描,用nc可以很方便的看到哪些端口处于监听状态.
我们来实际实施一次端口扫描:
上面命令扫描本地20-23端口,发现22端口能够连接成功,也就是22号端口此时处于开放状态。下面解释该命令涉及的几个选项:
- -z 选项:一旦建立连接后马上断开,而不发送和接收任何数据。
- -v 选项:打印详细输出信息。
- -n 选项:直接使用IP 地址,而不使用域名服务器来查询其域名。
- -w 选项:设置连接的超时时间,单位为秒。
- -u 选项:使用UDP 建立连接。上面命令无此设置,则表示使用TCP 建立连接。
其实,nc还有一个实战时的用法,那就是传输文件。 只需选择一个端口就可以在两台机器之间进行文件传输,而不需要进行任何配置,即不像ftp和scp在登录阶段还需要验证用户名、密码这样的安全信息。
我们来看一个实战例子:
在服务器端,也就是文件的发送端,我们启动监听端口,准备好文件,等待客户端来接收:
[roc@roclinux ~]$ nc -v -l 12345 < book_out.txt
在客户端,也就是文件的接收端,会使用如下命令来接收服务器端的数据,并重定向到文件中:
此时,再回到服务器端,可以看到这样的信息输出:
这说明客户端已经来取数据了。一旦数据传输完毕,连接会自动断开。
看完这个例子,我再给大家举一个逆向思维的例子。
服务器端,也就是使用-l选项进行端口监听的一端,不一定非要是文件的发送端,完全可以反过来作为文件的接收端。
[roc@roclinux ~]$ nc -v -l 12345 > book_in.txt
此时的客户端,则充当文件发送端的角色。
[root@roclinux ~]# nc -n 116.255.245.207 12345 < book_out.txt
瞬间剧情反转了,是不是很有意思呢: )
好了,nc的用法,我们就先讲到这里,其实nc还有很多可以把玩的功能,大家可以继续深入研究。
rsync
说到“同步”,不得不提的是我们的同步利器rsync,接下来就来说说我从这个工具中体会到的同步的艺术。
我们经常这样使用rsync :
[userA@machineA ~]$ rsync main.c machineB:/home/userB
下面我会介绍rsync的5条规则,大家一条一条来看:
- 只要目的端( machineB)的文件内容和源端( machineA)不一样,就会触发数据同步, rsync 会确保目的端的文件保持和源端一致。
- 但 rsync不会同步文件的“ modified time”,凡是有数据同步的文件,目的端文件的“modified time”总是会被修改为最新时刻的时间。
- rsync 不太关注目的端文件的 rwx 权限。如果目的端没有此文件,那么权限会保持与源端一致。如果目的端有此文件,则权限不会随着源端变更。
- 只要 rsync 有对源文件的读权限,且对目标路径有写权限,rsync 就能确保目的端文件同步到和源端一致。
- rsync 只能以登录目的端的账号来创建文件,它没有能力保持目的端文件的属主和属组和源端一致。(除非你使用root权限,才有资格要求属主一致、属组一致)
那,有同学会问了,如果我就是想同步修改时间,该怎么办呢?
- -t 选项让修改时间也同步。
[userA@machineA ~]$ rsync -t main.c machineB:/home/userB
- 使用-t选项后,rsync总会想着一件事,那就是将源文件的“ modified time”同步到目标机器。
- 带有-t选项的rsync,会变得更“聪明”,它会在同步前先对比两边文件的时间戳和文件大小。如果时间戳和文件大小都完全一致,那么就认定两边文件是一样的,于是,对这个文件就不会发起同步动作了。
- 因为rsync 的“聪明”,所以也会反被聪明误。如果目的端的文件的时间戳、大小和源端完全一致,但是内容恰巧不一致时,rsync 就发现不了了。这就是传说中的“坑”。
我们在第一次使用rsync时,往往会遇到这样的囧境:
[userA@machineA ~]$ rsync mydir machineB:/home/userBskipping directory mkdir
如果你不额外告诉rsync你需要它帮你同步文件夹的话,它是不会主动承担的,这也正是rsync的懒惰之处。
所以,如果你真的想同步文件夹,那么一定要加上-r选项,即recursive (递归的、循环的),像这样:
[userA@machineA ~]$ rsync -r mydir machineB:/home/userB
在运维工作中,使用软链接文件,是常有的事儿。
如果我们要同步一个软链接文件,猜猜rsync会提示什么?
眼见为实,rsync又无情地拒绝了我们。它一旦发现某个文件是软链接,就会无视它。
那么,解决方法是什么呢?
我们需要增加-l选项(字母L的小写)。
[userA@machineA ~]$ rsync -l softlink machineB:/home/userB
使用了-l选项后,rsync会完全保持软链接文件类型,原原本本地将软链接文件复制到目的端,而不会“follow link ”到指向的实体文件。
如果你偏偏就是想让rsync 采取follow link的方式,那就用-L选项就可以了。大伙可以自己试试效果。
rsync其实是一个非常复杂的命令,它有非常多的选项,也有不少“坑儿”。
曾经我的同事就出现过使用rsync把远端的数据同步丢了的情况。
所以,在用这个命令前,大伙一定要多多测试。
wget
能和rsync比复杂的,当属wget,这个命令的破坏力不如rsync,但是选项也是足够的多。
wget 用英语来描述就是 the non-interactive network downloader,中文称之为非交互的网络下载器。
wget支持HTTP、 HTTPS 和 FTP 协议的下载,其中也包括通过HTTP代理的下载。看起来好像支持的协议并不多,但其实这已经足够了,通常我们是很少使用除这些协议之外的其他协议来进行下载的。
我们还是按照惯例,把wget 的最简单用法先介绍给大家。
首先试着用wget 工具来下载一张图片:
[roc@roclinux ~]$ wget http://www.yunweibang.com/yunweibang.jpg
wget用起来看着很简单的吧!
其实不然,我们来说说wget的一个潜规则。
提到潜规则,我们先来说一下有关配置文件的潜规则吧。
当你使用wget时,请务必查看/etc/wgetrc 文件和家目录下的.wgetrc文件,先搞清楚里面都设置了什么,再来使用wget命令不迟。
因为这两个文件会配置wget的一些默认行为,这对大家使用wget可能会有比较大的影响。
举一个实际的例子,你就会有所体会啦。
wget命令有一些选项可以接受用逗号隔开的参数,比如 -X(大写的 x)选项,它用来设定“不希望下载”的目录列表。
你可以用逗号把不希望下载的目录一个一个列出来,比如“ wget -X wukong,bajie”,这样 wget 心里就有数了,它知道wukong目录和bajie目录都是不用下载的
如果这些目录是你长期不希望下载的,那么你完全可以在.wgetrc文件中设置“长期不希望下载”的目录列表,格式是这样的:exclude_directories=wukong,bajie
于是,你不必在wget命令上设置,就可以实现“不下载”wukong和bajie目录。
当然,如果某天你下载文件时,发现总有几个目录下载不下来,那么你应该想到,有可能是其他人设置了.wgetrc 造成的。当然你还要再去/etc/wgetrc 文件中确认一下你的假设。
还有一个小技巧,也可以避免这种误会(别人设置了exclude_directories ,而你却不知道),那就是在你使用wget时,这样来写:
wget -r -X '' -X wukong,bajie ftp://localhost
使用-X''的目的就是去除.wgetrc和/etc/wgetrc的作用,然后再用-X wukong ,bajie设置,就可以踏踏实实地保证不下载wukong和bajie目录,而其他目录绝不会受影响。
接下来,我们来重点介绍下wget下载目录的一些技巧,因为对于初学的同学来说,目录下载估计会是大家的噩梦: D
-r选项就是用于下载远程的文件夹的,但是情况并没有想象得那么简单,对于ftp服务来讲,假如你使用了下面的命令来下载文件夹的话:
[roc@roclinux ~]$ wget -r ftp://my.test.server:/home/roc/img
那么,实际在当前目录下会生成my.test.server/home/roc/img这样的多层级目录结构,可见直接使用-r选项,默认会创建“ 域名和绝对路径”组成的目录结构。
虽然我们将数据成功下载到本地了,但这或许并不是我们的初衷,至于更优雅的解决办法,我们需要-nH来帮忙。
-nH 选项,即 --no-host-directories
通过上例我们已经知道了在使用wget –r命令下载目录时,默认会创建以域名my.test.server命名的文件夹。而使用-nH选项后就可以避免这种默认行为。
所以,当你用如下命令下载文件时,只会在当前目录下创建home/roc/img目录结构,而原来的my.test.server文件夹已经不见了。
$ wget -r -nH ftp://my.test.server:/home/roc/img
域名去掉了,但长长的目录路径仍然还在,如果我只想下载img单个文件夹,不希望掺杂着前面的路径,该怎么做呢?
我们还需要--cut-dirs来帮忙。
这个选项很常用,它表示下载数据时,在本地创建目录时,忽略前面多少层的目录结构。
我们来看一个表格,相信大家就豁然开朗了:
从表中大家应该知道-nH和--cut-dirs两个选项互相配合的效果了吧。
好了,wget我们就先讲到这里,这个命令涉及到的选项和知识有很多,即使花一堂课的时间来讲解也不足够。
在《Linux大棚命令百篇》中,我们写了一个小的系列文章,总共4篇,来讲解wget命令,有志于深入wget的同学,可以阅读这个系列文章,来更全面的掌握wget命令。
uptime
我们的内容已经过半了,为了节省时间,后面的命令,我们更多的是介绍最基本用法和1-2个实战难点。
想必大家也有些疲惫了,我们先来介绍一个轻松简单的命令吧,那就是uptime。
uptime命令,有两大功能:一个是查看机器的开机时长,另一个是查看CPU负载情况。
下面来看看uptime命令的实际运行效果:
其含义解释,我绘制了一个表格:
这时,或许会有同学问了,什么是系统平均负载?
学术的说,系统平均负载,是指在特定时间间隔内运行队列中的平均进程数。
首先讨论单核CPU情况下的系统平均负载。我们尝试用“坐大巴”的场景,来说明这个事情。
一个单核CPU可以形象地比喻成一辆大巴车。
一般来说,大巴车的载客数是一定的,比如30人。当大巴车载客营业时,如果载客20人的话,这时乘客会感觉车内很宽松;当载客30人的话,这时刚刚好,每一个人都有座位坐,但已经让人感觉拥挤了。当继续有乘客上车的话,就会有人站在车的过道上,让人感觉车内拥挤不堪。
那如何体现车的拥挤程度呢? 这就要用到平均负载这个量化指标了。
- 0.00表示车内一个人都没有,这时车是空载。
- 1.00表示车内乘客每个人都有座位坐,这时车是满载。
如果大家理解了单核CPU的系统平均负载,那么理解多核CPU的系统平均负载就会容易得多。
多核CPU,就好像我们有多辆大巴车,承载能力和运力都成比例增加。我们设服务器具有N个CPU 核,那么负载值如果小于N,则认为服务器仍然在可承受范围内,否则,就是过载状态啦。
free
free命令,是一个看似简单,但其实有很多学问的命令。
最常用的用法,当然就是直接输入free啦,输出内容则以KB为单位:
如果想让数字更可读,大家往往会加上-m选项,让输出内容以MB为单位展示:
从free的输出内容中,可以看出,这台服务器拥有3GB内存容量,对于一台入门级服务器来说,已经不算小了。
有些同学比较喜欢使用-g选项,让输出内容以GB为单位显示。这样虽然可以增加可读性,但却存在不小的隐患:
首先,-g选项并非是官方支持的选项,你会发现在 man free 时是看不到这个选项的,所以不确认在所有的free版本中都支持。
最重要的是,-g选项会采用向下取整的方式显示内存容量,就如本文给出的例子,原本3031MB内存容量,换算后变为2.96GB,最后会显示成2GB,这会在很大程度上误导用户。
就像下面这样,本来服务器的内存总量是3GB,但是这里却显示成了2GB,是不是很坑人呢?
阅读free命令的输出,也是一门学问,我遇到过太多的小伙伴,并不理解free命令输出的指标的含义,为此,我画了一张示意图,希望能让大家对free的输出一目了然。
建议大家收藏这张图,甚至可以打印出来,放在办公桌前。
好了,后面还有8个命令要介绍,关于free命令的更细节,以后有机会再给大家细致介绍。
vmstat
vmstat这个命令真的非常实用,相信所有从事Linux相关工作的同学都使用过它。
vmstat,是一个Linux的性能监控工具,是Virtual Memory Statistics的缩写。从这个细节可以看出,这个命令最初只是被设计用来展示虚拟内存状态的,后来随着不断地迭代和扩展,现在变成了一个强大的性能监控工具。
vmstat,最初是在1994年被开发出来的,其作者是美国扬斯敦州立大学的 Henry Ware。貌似Linux的牛人都很低调,网上没有找到他更多的资料。
vmstat的最常用用法
vmstat最常用的方法是:
$ vmstat 输出间隔秒数 输出次数
从上面的例子可以看出,我们希望vmstat每隔1秒输出一次系统状态信息,共输出4次。
和free命令类似,我也为大家准备了一张速查图,让大家可以更快的掌握vmstat命令:
mpstat
mpstat,全称是 ultiprocessor statistics,正如它的名字一样,它所擅长的技能正是多处理器的统计工作。
让我们来看看它的常见用法:
[roc@roclinux splan]$ mpstat -P ALL 1
有兴趣的同学,可以自己执行以下这个命令,看看输出的内容。
发现了么,我们使用了-P ALL这样的选项和参数,其作用是展示出每一个CPU核的运行状态。
我们的这台服务器总共有4个CPU核,mpstat清晰地展示出了综合状态,以及每一个CPU核的运行状态。
而命令中最后的参数1,则表示要求mpstat每隔1秒钟,产出一组新的状态数据。如果你使用过vmstat的话,你会很熟悉这种用法。
如果我们只想关注第1个CPU核(编号为0)的话,应该怎么办呢?其实很简单,只需要把ALL改成0,就可以了。
top
如果说vmstat还有些同学不知道的话,那么top命令应该是大家最耳熟能详的Linux命令之一了吧。
下面我们就来和大家聊聊top这个命令。节省时间,我们直接进入正题。
top命令,是非常常用的Linux 性能监控工具,运行时,它会独占屏幕,并周期性地更新,让工程师们可以快速了解服务器的运行状态。
通过top ,我们可以了解到服务器的CPU 负载情况、内存状态、SWAP 使用状况,以及详尽的进程级运行状态,可谓应有尽有。
我们最常使用的场景,大概有以下几个:
- 找到是哪些淘气的进程在大量消耗CPU资源。
- 看看哪些进程消耗了宝贵的内存空间。
- 看看哪些进程占用的CPU时间最多。
一图胜千言,我们还是通过速查图,来介绍top吧:
这就是top命令输出后的样子,分成系统级信息和进程级信息。
老规矩,我们仍然看图说话,不同的是,我们会将其分解成五张图,以便让大家一目了然。
在书中,我们针对top有五个篇章:
- (1)top 命令庖丁解牛之一——入门
- (2)top 命令庖丁解牛之二——列管理
- (3)top 命令庖丁解牛之三——进程数据
- (4)top 命令庖丁解牛之四——排序大法
- (5)top 命令庖丁解牛之五——CPU 和内存
有兴趣的同学可以去细细探究!
本文章内容摘录自《Linux大棚命令百篇》:
《Linux大棚命令百篇 - 上》文件和文本篇,购买传送门:
《Linux大棚命令百篇 - 下》网络和系统篇,购买传送门:
未完待续,下次继续带来iostat、sar、ps、lsof、fuser等。