一个Script girl的自我修养(上)——以解决搬瓦工从快照恢复后无法连接网络为例

一个Script girl的自我修养(上)——以解决搬瓦工从快照恢复后无法连接网络为例

title pic resource: deviantart.net , author: В друзья©


虽然我以前是个学前端的,但自从接触了Linux,就对基于C的shell喜欢不已,因为在我看来,coding的全部乐趣,在于使计算机系统自动化运行。让一个脚本按照我设定的规则,快速、批量、自动化地高效检测故障、运行指定任务,简直是最有意思的事!shell就是一个powerful的工具。


本篇文章主要讲述我编写shell脚本的心路历程,并不是像菜鸟教程这样的零基础指南。所以,我不会刻意从头讲述shell的概念,以及各种Linux的底层知识。就是我在编写脚本时采取的一些思维和方法,在此分享给大家,这也是人生中为数不多的几个乐子之一。


0x00 动机


是什么动机,促使我去编写一份脚本?


当然是实际中遇到的问题,无论是Linux,还是Windows OS,系统运行的时候,如果有需要进行一系列的操作(这里的操作包含且不限于安装软件、调整系统配置)才能达成的目的,就有两种方法可以帮助我们解决问题。


第一种就是手动分步骤执行,非常直接,复制现成的命令按回车执行,至于关键参数的修改,靠人肉观察判断即可,好处是入门门槛低,可实践性强。


没有第一种方法做铺垫,你不知道该用什么过程和判断,去编写脚本;那么基于脚本运行的第二种方法就是水中月、镜中花乃至空中楼阁了。


由于Windows是闭源的,虽然也可以用命令提示符达到目的,但是你很难自如地随意去修改系统内的某些参数和配置。


正所谓Windows下的Administrator管理员账户的权限,和Linux的root根账户权限范围相差甚远。后者默认当前的使用者,对系统有足够深入的理解,以及已熟练掌握所有的系统操作,故给予用户最高权限,你想怎么搞都行,就是把系统搞瘫前,也没有程序像老妈子一样去跟你念叨“你不应该/准这样/那样做”。


这种超越了世俗之上的“自由”,才让Linux里的.sh脚本比Windows下.bat脚本发挥的作用要大很多。



0x01 问题


好了,不扯闲话,脚本是用来解决问题用的,今天碰到了什么令人奶子疼的问题呢?


手上有一台搬瓦工的小鸡鸡(在群里收的19.99绝版套餐,DC8机房,详情参见:搬瓦工最近太膨胀了,以后迟早没好果子吃),透过原版系统用萌咖大佬写的脚本,重装成纯净的Ubuntu 16.04.5 LTS系统,本案例均基于此环境。


接着替换了内核、安装常用系统组件、配置魔改BBR(谷歌研发的Linux Kernel拥塞控制算法の暴力增强版,比原版发包猛一些),需要研究一下某UDP转TCP工具(抗运营商QoS加速游戏用,我自己平时不玩游戏,帮 @大枫 弄的)的服务端和客户端配置。


由于担心某些错误的服务端配置,对开发环境造成不可逆的破坏,所以我需要定期设立服务器快照,以备出现问题且调校无果后,直接还原到曾经的某个时间点,免去了错一次全部重头再来的麻烦。


首先就是对配置好的初版纯净环境做一个备份,然后我没有继续当前这份环境做配置,而是好奇试了下用快照功能恢复后,会不会出现什么异常。


理论上讲,快照即是对当前这台机器已占用硬盘的数据区块的100%无损拷贝,备份快照前的机器运行状态是什么样的(正常),从建立的快照恢复后的机器的运行状态也应该是什么样的(正常)。听起来没毛病吧,老铁?


根据“墨菲定律”第四条(如果你担心某种情况发生,那么它就更有可能发生。),不幸果然发生了:


Connection failed……



作为一个守法爱国的好公民(我只用其他的机器富强,生产环境和开发/测试环境物理隔离是一个成熟程序媛的基本准则),怎么人在家中坐,天降正义来?😂


设定用阿里云国际的HongKong proxy连接,failed依旧。



小鸡鸡被通缉了?全国ping一下:



哇,全红,惨不忍睹~~


再用IPv4检查服务确认清楚国内外连往这台机器的TCP和ICMP情况,四个红叉叉,大事不妙:




就这,全世界都访问不到它,我蹲它机房旁也连不上啊,看来得进浏览器后面板VNC控制台看看情况了。




诶,有戏,可以登进去啦!





稍有网络常识的人都会看出,出现以上情况(除去某national级过滤,现在全世界失联),大概是这台机器本身出了问题。


随手apt-get update(更新软件安装源)一下,哦豁,实锤了,别人连不上它,它也连不上别人



以本宫优良的职业素养,分析个大概,应该是本地网卡出问题了。


进入系统,先重新启动一下网络服务,下面这行命令直接翻译成中文,没人看不懂吧。


service networking restart



报错了……按错误提示,输入:


systemctl status networking.service | journalctl -xe


“|”是逻辑与,前面部分是输出系统网络服务状态的意思,后面“journalctl”用于搜集该状态产生的日志,“-xe”代表了“-x(Catalog给出问题出现时的解释)”和“-e(End直接跳转到最后部分)”两个参数的混用。



最后一行错误终止的的提示:Failed to start Raise network interfaces(无法启动唤醒的网络接口)直接指向错误的根本原因——“Error getting hardware address for 'eth0': No such device(获取“eth0”的硬件地址出错,未发现该设备)”。


看来是硬件驱动出错了?现在本来就是远程连接(相当于连接母鸡操控小鸡,小鸡出了问题不影响母鸡的正常运行,母鸡也没法直接解决小鸡上的问题)着玩单机,更谈不上从网络下载驱动,或自己手动传上去(VNC控制台只允许用户手敲键盘输入命令,连粘贴都不行,痛苦啊),难不成还要让搬瓦工客服手动从后台帮我弄?


本着伟大领袖毛主席“自己动手,丰衣足食”的号召,能自己解决的问题,绝不仰赖别人!


所以我们可以换个思路,看看当前系统正在工作的网卡有哪些:


ifconfig



只有一个,名字叫lo(不是“lo娘”的意思哈)。代表localhost,标明了127.0.0.1这个本地地址。


然而并没有看到连接到公网的网卡名称和配置。


看一看系统中总共安装的网卡(包含未被激活的)有哪些,和上面那个命令的区别是,加了一个名叫all的参数(-a),这个很好理解吧:


ifconfig -a



出现了一个叫“ens18”网卡,不出意外,这张网卡就是帮助我们连接到公网的网卡,不过它现在处于沉睡的状态!



为了确保这张网卡是可被激活的,我们来查看一下当前系统中网卡驱动是否安装正确。


lspci | grep -i "eth"



看到这个命令,懵逼了不?又是“|”又是“-i”的,这些都是啥啊?


我来慢慢给你解释,lspci命令,是Linux里查询所有硬件驱动用的,你直接按它回车,会出现下面这些:



感兴趣的,可以按照里面的关键字,如“Red Hat”、“Intel”等自己去搜,都是大厂提供的硬件或虚拟硬件驱动。网卡驱动在哪儿呢?就是上面的倒数第三条,Ethernet(以太网)开头的那一行。


如何从这些结果里,过滤出只显示某样驱动的信息呢?这个时候就需要配合grep了,而配合命令,就需要用“|”来完成,你可以把它想象成逻辑上的“与”。


然后分析这行命令的后半段,既然要用grep查询,就必须得提供一个关键字(关键字以字符串的形式存在,就是用英文引号括起来,单双引号不限)吧,根据以上经验可得,有线网卡驱动的关键字,肯定是包含“eth”(Ethernet的开头三个字母)的,但我们手输这个命令的时候,大小写切换肯定不方便,所以给grep命令加上一个“-i”参数(ignore,忽略待匹配英文字符的大小写,意思就是原文里即使有大写字母,也会全部自动转换成小写字母,与“eth”条件匹配),这样就可以过滤出我们想筛选到的结果了。


这条命令如果转换成更让人类易读的语言,可以如下表达:


列举出当前系统中安装的所有硬件设备(lspci),并以不限大小写(-i)的“eth”为关键词,去匹配(grep)安装了哪些有线以太网卡。结果就是执行lspci | grep -i "eth"命令,系统返回给我们的结果。


现在已确认,系统内是有这个设备的,下面就要看一看系统里的网卡设定是怎样的了。


cat /etc/network/interfaces


在Linux的哲学里,万物皆是文件,意思就是说不论是文件,还是目录,它们本质上都是文件,各种系统的配置,都可以通过设置这些林林总总的文件的值来完成。


上面那条命令里,cat的意思不是猫,是将某个目录里的文件的结果打印出来,也就说,“/etc/network/interfaces”这个记录了本机网卡配置的文件返回的结果,是下面这样子的:



第一行内容先不管,下面四行里,每两行代表了一张网卡的配置参数,还记得用ifconfig命令查询时,显示“lo”网卡已被激活了吗?那么就直接从第三行看起。


auto eth0
iface eth0 inet dhcp


玩过路由器的人,应该对DHCP不陌生,代表自动从网关那里获取IP地址、子网掩码等参数。按“lo”网卡的配置规律,可发现,这个参数是想尝试启动名叫“eth0”的网卡。可是,还记得我们用ifconfig -a查询的时候,系统已安装的,名叫“ens18”和“lo”的网卡吗?


这个网络配置文件,试图启动一张系统里不存在的网卡,而这张本名叫“ens18”的网卡,正是起到了负责连接互联网的作用,那我们用vim命令,把这段配置里的“eth0”,都改成“ens18”,看看效果怎么样?


vim /etc/network/interfaces



不要忘了,光是更改了文件里的内容,这个配置对于系统来说还是没有生效的,我们还要去手动重新启动一下,依赖这个配置文件的系统服务,这样才行。


/etc/init.d/networking restart


“/etc/init.d/”目录里,存放了大部分的系统服务,这些服务一般都支持“start(启动)”、“stop(停止)”、“restart(重启)”、“status(状态)”等参数,可按需配合使用。


看到“ok”两字,这事儿多半就成啦~~



赶紧用本地SSH连接工具Xshell连接一下看看:


可以了!问题得以完美解决!




手动排错的步骤讲完了,可以看出,解决以上故障的核心方法,就是先用ifconfig -a命令,获取到所有安装在本地网卡的编号,再将/etc/network/interfaces文件中,配置错误的“eth0”关键字,都修改成沉睡网卡ens18的编号,最后重新启动一下networking服务(service networking restart 与 /etc/init.d/networking restart是等价的),就可以搞定。


怎样把这个步骤,让程序去批量运行呢?自动执行的时候,需不需要考虑一些其他问题?有关这些,就放在下一篇里来讲啦。

编辑于 2018-12-22

文章被以下专栏收录