Linux服務器教程 | 如何拯救一臺glibc被干掉的Linux服務器?
幾乎每個運維在工作中都遇到過一些令你后發亮的瞬間,比如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),總算可以松一口氣,繼續后面的災難恢復了。