人们常常在谈论托管服务器或云服务器所带来的便利,但如果这些设备已经该寿终正寝,大家会如何处理?当然,我们可以联系设备商,让他们负责报废工作,但这实际上很难保证其中的数据安全地被加以清除。如果不具备对设备的物理访问能力,他们很难将磁盘取出、覆盖一切旧有内容,并最终用大锤将其砸个粉碎。因此,当我们准备放弃托管(或云)服务器时,心中应该有所预期,即该设备很可能得不到有效的摧毁。
其实上述问题是我最近一次在与Matt Prigge的讨论中无意间提及的。有一家托管服务供应商的几台Linux服务器已经达到三年使用上限,因此需要在不具备物理访问能力的前提下将内容彻底清空。在这种情况下也不用考虑重启设备,因为你无法保证它们能够正常重启。尽管就这么放着似乎也不会带来什么大麻烦,但任何具备解锁权限的家伙还是能够窃取到该系统上的各类数据。而且虽然Darik's Boot and Nuke也能很便捷地完成清空工作,但我们在这里想聊聊其它方案。
大家可以在root下运行rm -rf / 指令,这可能会将设备的内容搞得乱七八糟,但仍然无法保证一切信息都被安全删除。事实上,我们甚至不能肯定这种方法是否删除了全部文件,并使它们无法被恢复——而且一段时间之后,服务器开始没有响应,进入未知状态,我们也就无法验证信息的清空情况了。
幸运的是,还有另外一些安全清除Linux服务器内容的方法。
在这个例子中,我们的目标是对所有本地磁盘执行数次归零操作,以确保MBR被彻底清空;这对于保证磁盘中数据的完全擦除是比较理想的有效方案。(遗憾的是,这一回振奋人心的大锤没有发挥的余地)。另外,我还需要对磁盘内容进行确认——而且整台设备应该在归零操作完成后自行关闭。
如何才能做到这一点呢?事实上这相当简单。
第一步首先要创建一个Ramdisk,并将所有相关的二进制文件及函数库复制进去。
接下来,停用所有可能带来磁盘写入动作的系统服务,例如系统日志等。
上述内容完成后,查看挂载列表,并留心其中的全部区块装置,然后动态创建一个脚本,将0(或者其它任何大家喜欢的随机内容)向这些装置中至少写入一次——不过最好是五次或更多。
除此之外,还要确保我们对每个磁盘的第一个512字节内容写入0,这样MBR就能得以完全清除。
一旦这套脚本创建完成并部署到ramdisk当中,关闭所有调动指令、将根目录更改为ramdisk,然后由此开始运行。
不要忘了给自己保留一个能够访问的临时工作环境。
运行此脚本的最终结果是以远程方式将系统中的所有活跃分区都全面而彻底地加以清除,而这一切工作都是通过ssh完成,无需具备控制台或是物理访问能力。如果各位拥有Linux托管服务器,或者甚至是一些远程站点的互联网服务器,那么在需要对其进行善后处理时,这套用于系统清空的脚本将为大家提供很好的帮助作用。事实上,在我们打算将一台处于任何地点的Linux服务器扔进垃圾堆——或者即将着手处理——时,这套脚本都能快速、便捷地为我们完成预期工作。
需要强调的是,这套脚本还有一项任务没有完成,即安全删除任何由托管服务供应商所持有的备份或快照信息。由于这属于供应商自家的特殊规范,因此大家必须主动加以跟进;而且在云服务器实例或者托管虚拟机领域,我们肯定要考虑到这一点。如果某台运行中的服务器具备一大堆快照之类的后备方案,那么对其进行归零实际上没有多大意义。另外,这在准虚拟化的VPS实例上也行不通,因为它们不允许对低级磁盘进行访问。
如果各位有兴趣,可以看看下面这个例子,功能很完整:
#p# #!/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操作系统之上。不过请大家小心,这个脚本存在的目的是追求完全的破坏性。如果破坏不是各位的需求,或者大家不了解自己在做什么,请千万不要尝试。