So here's a scenario: You are paying for a VPS or dedicated server, and now want to cancel your service. Have you ever considered what happens to the disks you were using? Well, we hope that they will get wiped before being reprovisioned/re-carved out for a new customer. Does your hosting provider wipe the disk before provisioning it? Maybe, but maybe not. How can we be sure our data is secure?

There are some solutions out there that work great at securely wiping disks. But many require us to boot into a separate media, as we obviously can't wipe the disk that the operating system is still using. What if we want to wipe a disk, while the operating system is still running? Well, we have some tricks up our sleeve that allow us to accomplish just that.

I am assuming that you might be using CentOS, but the gist of these commands should work for any Linux distribution.

Setting Up the Chroot

First, we are going to setup a chroot-like environment, but in RAM. The idea here is that we're going to install a new operating system in a ramdisk, flip over to it, and then unmount the disk from which the operating system was loaded. Here, we're going to use yum to basically install the entire operating system into a directory, but in Debian-based distributions, we could use debootstrap.

First, set up a 1GB tmpfs ramdisk, and set up an RPM database so that we can yum install the operating system.

mkdir /mnt/ramchroot
mount -t tmpfs -o size=1g tmpfs /mnt/ramchroot
mkdir -p /mnt/ramchroot/var/lib/rpm/
rpm --rebuilddb --root=/mnt/ramchroot

Next, download the centos-release RPM, which contains things like yum repository definitions and RPM macros so that yum knows from where to download the operating system. Then install the RPM into the new chroot ramdisk.

yum -y install yum-utils #Might not be necessary to install yum-utils on CentOS 7
yumdownloader centos-release
rpm -i --root=/mnt/ramchroot  --nodeps centos-release*

Next, we install yum, rpm-build, openssh-server, and lsof. These packages basically have enough dependencies to where installing them essentially installs the whole OS. openssh-server and lsof are going to be necessary later after we pivot.

You can build this chroot how ever you like. If you are bandwidth constrained, you can just rsync your operating system into RAM, though you might find yourself fighting against the memory limits of your system. This minimal install only takes about 500MB of RAM.

yum  --installroot=/mnt/ramchroot --noplugins install -y yum rpm-build openssh-server lsof util-linux-ng # util-linux-ng doesn't exist on CentOS 7, so you can ignore this one for newer distributions.

Here, we move the mounts for the kernel filesystems into our new chroot. Operating systems older then CentOS 7 don't need –make-rprivate, since I believe it is systemd that makes / a shared mount by default. It doesn't hurt anything to run it on older operating systems.

mount --make-rprivate /
mount --move /dev /mnt/ramchroot/dev
mount --move /proc /mnt/ramchroot/proc
mount --move /sys /mnt/ramchroot/sys
mount --move /run /mnt/ramchroot/run #not always necessary, ignore errors

Pivot Root into Ramdisk

Finally, we make a mount point for the old root, and then pivot our root to the ramdisk!

mkdir /mnt/ramchroot/oldroot
pivot_root /mnt/ramchroot/ /mnt/ramchroot/oldroot/

Clean Up Processes Using The Old Root Directory

So now we have changed / to point to our new ramdisk! Services are still running though, just using the /mnt/ramchroot/oldroot directory as their root. (Now, called /oldroot since we're pivoted into /mnt/ramchroot.) We need to kill or restart anything that's using the /oldroot path so we can unmount that disk and shred it. (Really, init is going to be the biggest thing, because if we shred the disk while init using the shared libraries from /oldroot, it's going to crash. That's a kernel panic.)

lsof | grep oldroot

You should see a ton of processes that are running (like udev if you're using CentOS 6, postfix, acpid, rsyslog, maybe even a dhclient.) These services aren't strictly necessary to shred the disk, so you can kill them off. You should see /sbin/init (or systemd) in that output, and it should be safe to kill (init should trap the kill signal and reload using the new root.)

You might notice that sshd is running using the old root as well. You probably want to be able to access the server while the disk is shredding, so we will take care of that service here.

If you're running a non-systemd system, you're going to need to copy the pid file from the old root so that we can restart it:

cp -a /oldroot/var/run/sshd.pid /var/run/

You can then either configure your sshd for key based or password based authentication:

echo "nameserver 8.8.8.8" > /etc/resolv.conf
yum -y install passwd
passwd #set up new root password
setenforce 0 #selinux is REALLY not going to like anything about what we're doing here
service sshd restart #or systemctl

Don't do anything dumb like setting an insecure password.

Now you are free to continue killing processes as you see fit until you don't see any more in the lsof output.

Once nothing is visibly using /oldroot, you are clear to unmount /oldroot. You might need to use umount -l or umount -f:

umount -l /oldroot

Now you can shred! Or really, do whatever you want to do (dd a new OS onto the drive, resize, fsck.)

Operating On Yourself: Manipulating the Root Block Device Without Rebooting