人們常常在談論託管伺服器或雲端服務器所帶來的便利,但如果這些裝置已經該壽終正寢,大家會如何處理?當然,我們可以聯絡裝置商,讓他們負責報廢工作,但這實際上很難保證其中的資料安全地被加以清除。如果不具備對裝置的物理訪問能力,他們很難將磁碟取出、覆蓋一切舊有內容,並最終用大鎚將其砸個粉碎。因此,當我們準備放棄託管(或雲)伺服器時,心中應該有所預期,即該裝置很可能得不到有效摧毀。
其實上述問題是我最近一次在與Matt Prigge的討論中無意間提及的。有一家託管服務供應商的幾台Linux伺服器已經達到三年使用上限,因此需要在不具備物理訪問能力的前提下將內容徹底清空。在這種情況下也不用考慮重啟裝置,因為你無法保證它們能夠正常重啟。儘管就這麼放著似乎也不會帶來什麼大麻煩,但任何具備解鎖許可權的傢伙還是能夠竊取到該系統上的各類資料。而且雖然Darik's Boot and Nuke也能很便捷地完成清空工作,但我們在這裡想聊聊其它方案。
大家可以在root下運行rm -rf / 指令,這可能會將裝置的內容搞得亂七八糟,但仍然無法保證一切資訊都被安全刪除。事實上,我們甚至不能肯定這種方法是否刪除了全部檔案,並使它們無法被恢複——而且一段時間之後,伺服器開始沒有響應,進入未知狀態,我們也就無法驗證資訊的清空情況了。
幸運的是,還有另外一些安全清除Linux伺服器內容的方法。
在這個例子中,我們的目標是對所有本地磁碟執行數次歸零操作,以確保MBR被徹底清空;這對於保證磁碟中資料的完全擦除是比較理想的有效方案。(遺憾的是,這一回振奮人心的大鎚沒有發揮的餘地)。另外,我還需要對磁碟內容進行確認——而且整台裝置應該在歸零操作完成後自行關閉。
如何才能做到這一點呢?事實上這相當簡單。
第一步首先要建立一個Ramdisk,並將所有相關的二進位檔案及函數庫複製進去。
接下來,停用所有可能帶來磁碟寫入動作的系統服務,例如系統日誌等。
上述內容完成後,查看掛載列表,並留心其中的全部區塊裝置,然後動態建立一個指令碼,將0(或者其它任何大家喜歡的隨機內容)向這些裝置中至少寫入一次——不過最好是五次或更多。
除此之外,還要確保我們對每個磁碟的第一個512位元組內容寫入0,這樣MBR就能得以完全清除。
一旦這套指令碼建立完成並部署到ramdisk當中,關閉所有調動指令、將根目錄更改為ramdisk,然後由此開始運行。
不要忘了給自己保留一個能夠訪問的臨時工作環境。
運行此指令碼的最終結果是以遠程方式將系統中的所有活躍分區都全面而徹底地加以清除,而這一切工作都是通過ssh完成,無需具備控制台或是物理訪問能力。如果各位擁有Linux託管伺服器,或者甚至是一些遠端站台的互連網伺服器,那麼在需要對其進行善後處理時,這套用於系統清空的指令碼將為大家提供很好的協助作用。事實上,在我們打算將一台處於任何地點的Linux伺服器扔進垃圾堆——或者即將著手處理——時,這套指令碼都能快速、便捷地為我們完成預期工作。
需要強調的是,這套指令碼還有一項任務沒有完成,即安全刪除任何由託管服務供應商所持有的備份或快照資訊。由於這屬於供應商自家的特殊規範,因此大家必須主動加以跟進;而且在雲端服務器執行個體或者託管虛擬機器領域,我們肯定要考慮到這一點。如果某台運行中的伺服器具備一大堆快照之類的後備方案,那麼對其進行歸零實際上沒有多大意義。另外,這在准虛擬化的VPS執行個體上也行不通,因為它們不允許對低級磁碟進行訪問。
如果各位有興趣,可以看看下面這個例子,功能很完整:
- #!/bin/bash
-
- #
-
- # This script will absolutely kill a RHEL/CentOS/Fedora server. Use with extreme caution.
-
- # Tested with several CentOS/RHEL versions only. Run as root user.
-
- # 10.20.11 Paul Venezia (pvenezia@pvenezia.com)
-
- #
-
- zeroscript="/var/ramdisk/zeroscript.sh"
-
- echo "*******************************************************************
-
- ** This will permanently kill this Linux system and erase every **
-
- ** local disk and filesystem. In other words, you better be **
-
- ** REALLY REALLY SURE you want to do this on this system. **
-
- *******************************************************************"
-
- echo -n "Are you absolutely sure you want to do this? [yes|no]: "; read yn
-
- if [ -z $yn ] || [ $yn != "yes" ]; then
-
- echo "Aborting"
-
- exit 1
-
- fi
-
- echo -n "How many zeroing passes? "; read zeropass
-
- if [ -z $zeropass ] || [ $zeropass -lt 1 ]; then
-
- echo "Invalid number of passes specified. Aborting."
-
- exit 1
-
- fi
-
- echo -n "Automatically shutdown? [yes|no] "; read asd
-
- echo "Okay, here we go..."
-
- echo "Making and populating ramdisk (512MB)..."
-
- mkdir -p /var/ramdisk
-
- mount -t tmpfs none /var/ramdisk -o size=512m # You may need to adjust this depending on the amount of RAM in the box
-
- mkdir -p /var/ramdisk/var/run
-
- for f in dev bin lib lib64 sbin etc; do
-
- cp -pr /$f /var/ramdisk
-
- done
-
- cp -pr /var/run /var/ramdisk/var
-
- echo "Stopping services, it's probably safe to ignore any errors..."
-
- for s in httpd acpid anacron atd auditd autofs avahi-daemon bluetooth cpuspeed crond cups firstboot gpm haldaemon hidd hplip irqbalance iscsi iscsid kudzu lm_sensors lvm2-monitor mcstrans mdmonitor messagebus microcode_ctl netfs nfslock pcscd portmap rawdevices readahead_early restorecond rpcgssd rpcidmapd sendmail smartd sshd syslog vmware-tools xfs yum-updatesd; do
-
- service $s stop
-
- done
-
- echo "Placing zeroing script..."
-
- echo "#!/bin/bash" > $zeroscript
-
- for i in `fdisk -l | grep Disk | awk '{print$2}' | sed -e s/:// | grep -v /dev/md`; do
-
- DU=$DU" "$i
-
- DSK=`basename $i`
-
- BLKS=$((`grep -w $DSK /proc/partitions | awk '{print$3}'` * 2)) # account for 512/1k blocksizes
-
- BS=512
-
- echo "echo \"Zeroing $i (dd if=/dev/zero of=$i bs=$BS count=$BLKS) ...\"" >> $zeroscript
-
- for (( c=1; c<=$zeropass; c++ )); do
-
- echo "echo \"Pass $c...\"" >> $zeroscript
-
- echo "dd if=/dev/zero of=$i bs=$BS count=$BLKS" >> $zeroscript
-
- done
-
- echo "dd if=/dev/zero of=$i bs=512 count=1" >> $zeroscript # Just to make sure
-
- done
-
- echo "echo \"Disk(s)$DU have been zeroed $zeropass times\"" >> $zeroscript
-
- if [ $asd = 'yes' ]; then
-
- echo "echo \"Shutting down...\"" >> $zeroscript
-
- echo "sleep 5 && /sbin/poweroff -n -d -f" >> $zeroscript
-
- fi
-
- chmod +x $zeroscript
-
- echo "Turning off swap..." && swapoff -a
-
- echo "Entering chroot..."
-
- chroot /var/ramdisk /`basename $zeroscript`
該指令碼中儘管存在著一些過於強橫的霸王內容,但卻確實能幫大家完成任務。它本身是專門用於RHEL(即紅帽企業版Linux)及CentOS(即社區企業作業系統)的,但只需經過簡單的調整即可奏效於任何類Unix作業系統之上。不過請大家小心,這個指令碼存在的目的是追求完全的破壞性。如果破壞不是各位的需求,或者大家不瞭解自己在做什麼,請千萬不要嘗試。