远程擦除服务器
在很多方面,我为那些受困于专有操作系统的人们感到惋惜。当出现问题或他们需要解决问题时,解决方案要么显而易见,要么需要购买特殊软件,要么根本不可能。使用 Linux,我一直觉得我的限制仅仅是我自己的编程和解决问题的能力,无论出现什么问题。在 Linux 作为我的主要操作系统这么多年里,我遇到过不少具有挑战性和奇怪的问题,例如如何从双磁盘 RAID 1 热迁移到三磁盘 RAID 5,或者更常见的是,如何修复我严重破坏的系统。
问题最近,当我必须淘汰一台旧服务器时,我遇到了一个有趣的挑战。这台服务器上有很多敏感数据,所以我还必须安全地擦除机器上的所有内容。最后,当我完全擦除所有数据痕迹后,我必须关闭机器电源。当服务器在你的桌子下时,这是一个相对简单的请求:启动救援盘,使用像 shred 这样的工具擦除所有硬盘驱动器上的数据,然后按下电源按钮。当服务器在远程数据中心时,这有点更具挑战性:使用远程控制台重启到救援盘,擦除服务器,然后使用某种网络 PDU 远程拔掉电源。当像我一样,你必须擦除一台远在千里之外的服务器,没有远程控制台,没有远程电源,没有远程帮助,只有 SSH 连接时,你开始挠头了。
为什么要这样做?在这一点上,你们中的一些人可能会问:“你为什么需要这样做?” 事实证明,有一些不同的原因,既有合法的,也有不正当的。
-
您有硬件损坏。这可能是一台视频卡坏了的服务器、一个故障的 KVM 或远程串行控制台,或者一些其他的硬件访问不起作用的问题。
-
您被服务器锁定。例如,如果您将服务器托管在数据中心,但停止支付账单或以某种方式与提供商闹翻,就可能发生这种情况。他们撤销了您对服务器的物理访问权限,但您需要在机器仍然可以通过网络访问时删除所有敏感文件。
-
您有一个糟糕的咨询客户。也许您是一位负责且有才华的系统管理员,您出于善意为客户设置了一台服务器,但一旦服务器上线,客户就拒绝付款。您想安全地删除您的工作成果,客户不会回复您的电话,但您仍然拥有对该机器的 SSH 访问权限。
-
您购买了工具不足的云服务器。如今,将服务器环境托管在云端非常流行;然而,一个缺点是,许多云提供商通过限制您对云实例管理的访问权限来削减成本。当您终止服务器实例时,您真的相信它会被安全擦除吗?您是否可以访问允许您在云实例上启动救援盘的工具?在某些情况下,您对云服务器拥有的唯一远程管理可能就是您的 SSH 连接。
-
您是一个邪恶的、恶意的黑客,想要掩盖自己的踪迹。是的,这是远程擦除服务器的最不合法和最不正当的理由,但我觉得我应该为了完整性而提及它。
-
这是一个挑战。有些人爬山,有些人跑马拉松,还有些人尝试通过 SSH 远程擦除服务器。您可能只是一个喜欢挑战极限的人,这听起来像是一个有趣的挑战。
既然您已经了解了可能需要知道如何远程擦除服务器的原因,那么我们来谈谈您实际上将如何做到这一点。首先,也是最重要的,**没有重做机会**!当您将随机位写入原始磁盘设备时,尤其是在 SSH 上,您只有一次机会将其做好。在准备这个过程时,我在虚拟机上多次测试了我的程序,以确保我的步骤是可靠的。我很高兴我这样做了,因为它花了几次时间才使所有步骤正确,确认了我的假设,并使命令顺序正确。
使这个挑战棘手的是,您将随机写入您登录的同一文件系统。如果您在运行 shred 并通过 SSH 登录时覆盖了 sshd 和 shred 文件会发生什么?更重要的是,当您覆盖内核时会发生什么?使此过程起作用的主要原则是 Linux 喜欢尽可能将文件缓存到 RAM 中。只要您能确保您需要的一切都存储在 RAM 中,您就可以随意覆盖文件系统。诀窍只是识别您需要存储在 RAM 中的所有内容。
始终要有 Plan B所以,我提到这个过程没有重做机会,但这并不意味着您不能为自己设置某种安全网。虽然我知道一旦我启动 shred 命令,它将完全从 RAM 中运行,但我必须弄清楚的是在 shred 之后我需要运行哪些命令。即使像 ls
这样的命令,如果没有文件系统可读,也无法工作。为了让我有一些备用计划,我利用了所有现代 Linux 系统都提供的 /dev/shm 内存盘。这是一个系统上任何用户都可以写入的目录,所有文件都将完全存储在 RAM 中。
因为我不确定像 echo(我稍后会需要)这样的命令在我粉碎硬盘驱动器后是否还能工作,所以我将其与我认为我需要的任何其他文件一起复制到 /dev/shm。如果您有空间,为什么不尽可能复制所有 /bin、/sbin 和 /lib。最后,我知道我需要访问 /proc 文件系统才能关闭服务器。我假设即使我覆盖了根文件系统,我仍然可以访问 /proc,但我不是 100% 确定,所以为了安全起见,我成为了 root 用户(您不能假设 sudo 稍后会工作)并将 /proc 的额外副本以 root 用户身份挂载在 /dev/shm 下
$ sudo -s
# mkdir /dev/shm/proc
# mount -t proc proc /dev/shm/proc
事实证明,我最终不需要任何这些预防措施,但做好准备并没有坏处。
是时候猛击了现在是不可回头的时候了。为了安全起见,我切换到 /dev/shm 目录,以便我的当前工作目录位于内存盘上。然后,我卸载了任何不必要的挂载点(如 /home),并在系统上每个非根驱动器上运行了以下 shred 命令。在我的例子中,我使用了软件 RAID,所以我也采取了额外的步骤,从任何 RAID 阵列中热移除除一个驱动器之外的所有驱动器,并将它们单独粉碎。最后,我只剩下存储在 /dev/sda 上的根文件系统,所以我深吸一口气,输入了以下命令
# shred -n2 -z -v /dev/sda
此命令将随机位写入 /dev/sda,进行两次完整传递 (-n2
),然后使用零进行最后一次传递,以便驱动器看起来非常干净 (-z
),并带有详细输出,以便我可以看到发生了什么 (-v
)。当然,根据您的特定偏执程度调整 -n
参数——两次传递对我来说已经足够了。我不得不承认,在您仍然登录的情况下覆盖根文件系统,这既令人满足又奇怪。
一旦 shred 进程完成,我就有了一个完全空的文件系统。这很奇怪——像 ls
这样的命令给出了奇怪的错误,我知道我被隔离在我的 /dev/shm 监狱中。剩下的就是关闭服务器,但是当 /sbin/shutdown 被擦除时,你如何做到这一点呢?没问题,您可能会说,只需杀死 PID 1,因为如果您杀死 init,它将停止系统。如果,比如说,kill 程序仍然存在,这将起作用。在这种情况下,我剩下的唯一关闭系统的方法是通过 /proc 接口。/proc 目录是一个特殊的文件系统,允许您访问进程和内核信息,它完全驻留在 RAM 中,因此我的小 shred 特技并没有将其擦除。要停止机器,只需在内核中启用 sysrq 接口,然后向 sysrq 发送正确的命令
# echo 1 > /proc/sys/kernel/sysrq
# echo o > /proc/sysrq-trigger
如果 halt 命令不起作用,或者您只是想重新启动机器,您可以键入
# echo b > /proc/sysrq-trigger
现在您可能会问自己,我没有覆盖 echo 命令吗?毕竟,/bin/echo 在根文件系统上。事实证明,我甚至不必依赖我在 /dev/shm 下的命令副本——echo 是 bash shell 内置的程序之一。当您执行 echo 时,bash 执行内置于自身的版本,并且因为我已经在一个 bash shell 中,所以可执行文件从 RAM 中运行。一旦您运行最后一个 echo 命令,内核将立即停止。任何远程 ping 或其他命令都将停止,系统将断电。
作为最后的说明,我想说,即使您认为您永远不需要如此大费周章地擦除服务器,我认为这个过程非常有趣,您至少应该在一次性虚拟机中尝试一下。粉碎系统,看看哪些命令仍然有效,哪些命令无效。作为额外的挑战,看看您是否可以在 /dev/shm 中运行命令。