Remotely wiping the disk(s) of a headless linux server
Seldom, the subject of how to wipe the disk(s) of a headliness linux server comes up; there are a few resources online about it. This blog summarizes all the information around into a clean, stable and generic script that can be used in order to perform this task.
As typical of this blog, the script is also used as an exercise in shell scripting and system administration, therefore, it contains (arguably) useful/interesting commands/concepts.
Contents:
Preamble/specifications
There is a variety of details that can be changed/implemented (eg. nohup, [more] secure wiping, devices ordering…). The current implementation is (relatively) basic but solid, usable with typical setups.
The script creates a chrooted minimal environment, and from there, it wipes the machine disks.
The target machine is any Debian-based one, although, with minimal changes (debootstrap
tool installation, and service stop), it will work on any distribution.
Procedure
All the commands must be run as root.
Install the program for creating a minimal environment:
apt install debootstrap
During the wipe, the filesystem will be destroyed, however, some pages may be written to disk. Therefore, we want to minimize all the potential write sources.
Check the running daemons, the stop the required ones (update the list as required):
ps ax | awk '$5 !~ /^\[/ {print $0}' # exclude system processes
for daemon in cron atd postfix ntp syslog-ng; do
service $daemon stop 2> /dev/null
done
Disable all swaps:
swapoff -a
Flush the system caches:
echo 3 > /proc/sys/vm/drop_caches
Create a minimal environment (in RAM, so that it won’t be affected by the wipe):
mount -t tmpfs tmpfs /mnt
debootstrap --variant=minbase --include=bsdmainutils xenial /mnt
mount --bind /dev /mnt/dev # mirror /dev and /sys - allows block dev operations to work
mount --bind /sys /mnt/sys #
mount --bind /proc /mnt/proc # if /proc is not mirrored, after wiping, the system will crash
The xenial
Ubuntu version is required for the status=progress
dd option; the package bsdmainutils
includes hexdump
, used later for inspection.
A reader kindly reported an error (that I can’t reproduce on my system):
# If, when running the `debootstrap` command, you get:
#
# E: Failed getting release file https://deb.debian.org/debian/dists/xenial/Release
#
# replace it with:
#
debootstrap --variant=minbase --include=bsdmainutils --arch=amd64 xenial /mnt http://archive.ubuntu.com/ubuntu/
Now, switch to the temporary environment!:
chroot /mnt
Find the disks:
# `lsblk` sample output:
#
# NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
# sda 8:0 0 953,9G 0 disk
# └─sda1 8:1 0 89,8G 0 part /media/vfio
# loop3 7:3 0 86,6M 1 loop /snap/core/4571
# sr0 11:0 1 1024M 0 rom
#
disk_devices=$(lsblk | awk '$6 == "disk" {print $1}' | sort -r)
We reverse sort the devices, with the simple assumption that the lexicographically first device (eg. sda
) is the one containing the system data.
Cycle and wipe them:
while read -r disk_device; do
disk_size=$(blockdev --getsize64 "/dev/$disk_device")
echo "Wiping /dev/$disk_device ($((disk_size / 2**30)) GiB)..."
# `conv`: sync on completion; `bs`: improve speed.
#
dd if=/dev/zero of="/dev/$disk_device" status=progress conv=fdatasync bs=64k
done <<< "$disk_devices"
(as an alternative to status=progress
, the pv
tool can be used; see comment thread at the end of the page)
With the hexdump tool, we can now inspect, for fun, what’s remaining in the disk(s):
while read -r disk_device; do
echo "/dev/$disk_device content:"
hexdump -C "/dev/$disk_device" | more
echo
done <<< "$disk_devices"
The result is lean and easy to inspect; since hexdump doesn’t show duplicate rows, the dump will be relatively short. Typically, a few pages are still written after the wipe.
Shutdown the system:
# At this stage, the `shutdown` command is not available anymore [in the host].
# Also, we don't need to exit from the guest, as the command is sent directly to the kernel.
echo 1 > /proc/sys/kernel/sysrq
echo o > /proc/sysrq-trigger