共计 1247 个字符,预计需要花费 4 分钟才能阅读完成。
几乎每个运维在工作中都遇到过一些令你后发亮的瞬间,比如 Linux 服务器故障。本文的作者救灾工作会哦在那个遇到了这种眼中但又令人啼笑皆非的问题,且看他是如何处理的吧。
今天正要下班,旁边部门的 PM 过来问我:
『我们有个小伙子把生产系统上的 glibc 给删了,现在什么命令都跑不了了,还有救吗?』
(更正:今天又问了一下,是正在准备要上线的服务器,所以还不是生产系统)
我说,glibc 也能弄掉,莫不是 rpm –force?
回答是肯定的。
glibc 被卸载,负责加载所有.so 的 ld.so 也就没了,因此运行几乎所有外部命令时都会得到一句『找不到 ld-Linux-x-y-z.so.2』的出错提示。比如 ls,比如 cp,以及所有动态链接的命令。
这是一台放置于另外一个大洲的客户 IDC 的物理服务器。我说不行就光盘引导修复,但不知道什么原因他们又连不上服务器的 HP iLO 工具。
干着急也不是办法。万幸的是 rpm –force 的小伙子的 ssh 登录 shell 还连着。我说那不行就只能你自己一个 byte 一个 byte 先敲一个 static linked 的 binary 出来,这是可以运行的。
话说完,我就大概想到该怎么办了。
- 用 bash 的内部命令 printf ‘\xaa\xbb\xcc’ > file 可以生成任意内容的文件
- 另外找台同配置的 Linux,用 xxd 或 hexdump 配合一点点脚本,或者直接用 Python 写个小脚本,把 ld.so 文件转储成若干条 printf ‘…’ >> file 的命令(考虑到 bash 单行命令的长度限制,我没有尝试只生成一条命令)
- copy 2)中生成的命令,paste 到出事的 Linux shell 中运行
- 这样至少 ld.so 能用,接下来可以按图索骥恢复其他.so
Tada! 我感觉自己重新发明了 scp。
然而这样行不通。printf 重定向生成的文件不带可执行位,无法被执行,只是把出错信息变成了 permission denied 而已。
别忘了 chmod 也不能用哦。
所以往上面手动恢复 glibc 这条路看来是行不通了。
既然动态链接的命令都不能用,那就只能上静态链接了。到 http://www.busybox.net 下载了静态链接的 1.16.0 版(越旧的版本越好——因为越小)的 busybox,不到 900KB,用上面的办法,转存到出事的 Linux 上。
刚才不是说了没有可执行位吗?busybox 又怎样?
这次,我是把 busybox 直接写入到
printf '...' > /bin/cp
覆盖系统原有的带 x 位的 cp 文件,用旧瓶装新酒,我终于获得了一个可执行的 busybox!
别忘了,argv[0]为 cp 时,busybox 就是在做 cp 的事情!
因此接下来再
cp cp ln
ln -s cp chmod
ln -s cp ls
ln -s cp wget
ln -s cp sh
...
printf 和 busybox 拯救世界!
再传送一份静态连接的 dropbear 上去,起一个备用的 ssh server(别忘了把账号的登录 shell 改成 busybox 版 sh),总算可以松一口气,继续后面的灾难恢复了。