硬限制虽然好用,但可不能乱用T_T
警告:本文含有大量致命的作死操作,请勿直接模仿!
序章:灾厄降临之时
公元2022年5月27日上午,正值《实测天体物理》的上课时间。坐在教室里面,听了会孔老师精彩的红外和紫外波段观测讲座,突然开始有些坐不住了,于是就当即Ctrl+Alt+T,随后一个ssh连进服务器,准备接着前一天的工作进度继续往下运行程序,link start!!!
然而,就在运行程序的时候,发现了一个前所未有的错误:无法打开数据库。不对啊,数据库不是都在吗?疑惑之下,我引入了pdb,试图在报错时进入断点调试,进而打印出此时要打开的数据库的名字。结果,奇特的现象发生了:在无法打开数据库,进入pdb调试的时候,又在pdb上报了个错:打开了太多的文件。在必应稍加搜索后,这才想起服务器在限制用户最大进程数的同时,还限制了最大文件描述符打开数。通过输入:
ulimit -n
发现自己帐号的最大文件描述符被限制在了1024,好家伙,这个数量,怪不得会炸……于是我先尝试着:
ulimit -n unlimited
结果发现1024也就变成了4096,看来服务器设置的上限就只有4096。这怎么行,看来只能用root去修改这个上限了。
进入root帐号,打开/etc/security/limits.conf
文件,将参数nofile(最大文件描述符持有数)的硬限制设置为unlimited,心想这下这破程序也报不了错了吧,然后便心花怒放地按下esc,随即一个:wq保存+关闭文件。退出后,似乎也没发生什么事,便连续两个Ctrl+D,先后退出root帐号和自己的帐号,然后就开始继续看老师的精彩讲座了。
过了一会,我继续尝试登入服务器,想重新运行一下刚才那个程序,看还会不会报这个错,结果悲剧果然发生了:无论是用什么帐号,在连接上服务器后,都会被直接kick。我瞬间就慌了神,于是便在必应搜了搜,这才知道nofile的上限应该在1048576以内,否则就会被解析为0,从而导致无法正常登入服务器……
这台服务器上面有好几个活跃用户(包括我),如果这样拖下去,必然会导致一场不大不小的灾难(总之是灾难就对了)。于是我便问了问机房的密码,下课吃完饭后就冲了过去……
第一章:短兵相接
如果不算上之前跟着师弟来参观的那一次,这算是我第一次去服务器的机房。此前几次服务器出现故障,要不就是远程就能解决,要不就是只能请公司直接出面。像这样的小问题而又不得不在机房直接处理的,还是第一次遇到。所以,这还是第一次执行A级任务。
机房所在的那栋楼正值装修时期,四周全被铁网给拦住了,而唯一一个入口也被一大片破旧的绿网笼罩着。在一片绿的笼罩之下,路盲的我凭借着上一次来这里的记忆,总算是在走错一次路的情况下,到达了机房门口。输入密码,等待数秒的延迟后,便打开了大门走了进去。
一进门,扑面而来的便是排气扇巨大的响声。这一瞬间的声波攻击,差点没让我耳朵炸裂(开个玩笑)。机房里面的场景十分壮观,每十来个服务器都堆在同一个铁柜里,而铁柜则整齐而又有序地并排着。如果将每一个铁柜比作一栋楼,那么这个机房必然是个繁华的城市。
在找到显示屏和推车后,我便将车推到了我们服务器所在的机柜前,随后将显示屏后的三条线,一条条地接在了服务器的插口上。说来可能自己都不信,这个接线过程我足足做了约10分钟:首先电源线我就找了半天,在确认这个就是电源线后,我又去找了半天的排插;电源线连上后,由于我们的服务器是在机柜的最底部,我便又透过数十上百条缠绕在一起、来自各个服务器的各种线,冒着闪腰的风险,弯下身来去寻找自己服务器上对应的键盘线和视频线接口。在这些线终于被接上后,显示屏变亮了起来,呈现在我面前的,是Centos的锁屏界面,上面浮现出的各个熟悉的用户名,向我传达着“恭喜,你找对服务器了”的信号。
一鼓作气,我便顺手点开了自己的帐号,输入密码,回车。然后,然后,,然后,,,。。。黑屏了,只有一个光标一直在闪。按Ctrl+Alt+F2进入到tty2后,再去尝试登录各种帐号,才发现根本登不上。在服务器公司人员的远程指导之下,我才通过刚学会的Ctrl+Alt+Delete组合技的方式,强制进行了重启。并准备进入到单用户模式进行维修。
第二章:阶段性胜利
这是第一次听说“单用户模式”这个词,虽然不知道是什么意思,但也只能先照做了。首先在开机进入grub界面的时候狂按e键,我大E了啊,按了太多次,结果在进入到一个黑底白字的代码块后,发现前面多了一大串的"e"……
删完一大串"e"后,便往下走,浏览到代码块中的最后几行:
... ro ... LANG=en_US.UTF-8
按照教程在最后加上init=/bin/sh
后,便通过Ctrl+X进入到了传说中的“单用户模式”。单用户模式下,乍一看就是一个不起眼的终端。但仔细试一试,却发现所有root帐号的功能都有所具备。试图使用vim将/etc/security/limits.conf
的内容改回来时,却发现是只读,这才知道在进入单用户模式前需要将ro改为rw……
于是便在重启后,重新进入了单用户模式:
... rw ... LANG=en_US.UTF-8 init=/bin/bash
随后使用vim将上午加上的那个硬限制改回正确的值,保存退出并重新启动,便发现帐号在主机上可以正常登录了。心中一片窃喜,便回到了办公室。结果发现依旧会在连接后直接掉线……在突然的悲痛(误)之下,只好重新返回战场,并带上了同行的大佬,请求支援。
第三章:重返战场
回到机房后,先是用远程登录测试了一下,确认还是出现了连接后立即掉线的情况后,使用:
journalctl -xeu sshd
查看了和登录相关的日志,发现在用户登录后,/etc/security/limits.conf
会立即出现权限错误。一开始大佬以为是文件格式的问题,便尝试着把所有加上的硬限制全部注释掉。但即便是全部注释光了,登录的时候也是会出现同样的问题。
就在焦灼了大半个小时后,大佬突然在日志的开头,看到了一条“SELinux禁止了xxxx(忘了是这个文件还是sshd了)的权限”这个用红字标出的消息,这才找到了问题的源头:原来是SELinux为了“保卫服务器”,才作出了这样的安全措施。
在简短的百度之后,大佬使用了:
restorecon -v /etc/security/limits.conf
重置了这个文件的权限。随后再次尝试远程登录,便成功登进去了。重启服务器,拔掉显示屏上的线,将推车推回原位。至此,首个A级任务便告一段落。
终章:标题实在想不出来了
离开机房,回到办公室后,已经是下午四点左右了。没想到即便是这么小的一个问题,也足足花费了约3小时的时间。回想起来在机房里的那几个小时,遇到的各种事情简直是刷新了自己的认知。
首先,此前一直不知道机房的服务器没有显示屏是怎么工作的。在亲自动手后,才知道原来主机才是核心部件,显示屏只是一个与用户交互的界面罢了。
其次,在这次的事件中,也深刻地体会到了nofile不能设置为unlimited(虽然不知道为什么这么简单的操作,会带来这么大的问题)。很多看似安全的操作,其实都暗藏着杀机。
同时,也知道了SELinux的存在,它竟然会为了保卫服务器的安全,而拒绝掉某些文件的权限。看来最大的战友,也有可能会成为最大的敌人(划去)。
此前虽然执行过多次C级任务以及部分B级任务,但在那其中所获得的经验,和这次的A级任务相比,似乎都显得不值一提……
因为这个事件实在是太难忘了,所以就特此记录了下来,在留下足迹的同时,也留个经验教训。