Are you STILL retiring servers like this?
Don’t forget to wipe!
You stopped the server. You deleted the instance. You told everyone it was gone. But the old disk blocks are still out there, and so are the keys that lived on them. slag.sh retires a server in three steps: it lists everything that lived there, tells you what to rotate, and wipes the disks with a receipt that proves every byte reads zero.
VERIFIED!
slag /slæɡ/
- n the scum formed by oxidation at the surface of molten metals [syn: slag, scoria, dross]
- v convert into slag
- acronym SLAG: Sanitize, Log, Attest, Go. What’s left after the burn.
- Sanitize
- keys struck first, every non-zero block zeroed, every byte read back
- Log
- every step recorded as ok, unsupported, frozen, failed or skipped, with a reason
- Attest
- a receipt with its SHA-256, checked against the copy on the console
- Go
- the instance deleted only after a second boot proves the disks are zero
Sound familiar?
dd if=/dev/zero and a prayer
You zero the disk, the command exits, and you call it done. But dd exits with an error at the end of every block device, so you stopped reading its exit code years ago. The old script's "verify" counted an empty read as all zeros, so a disk it could not read at all came back VERIFIED.
On thin storage you discarded first, which freed the blocks that held your data. The zeros landed somewhere new, and a 10 MiB image grew to 3 GiB doing it.
slag.sh
Every target is checked to be a whole disk. Every disk on the machine is accounted for. Hardware erase runs first and is waited for. Each block that holds data is overwritten where it sits. Then every byte is read back with direct I/O, and a read that comes up short is a FAIL, never a pass.
At the end you get a receipt with every step and its outcome, written to the console, the log, and a file that outlives the disk.
Real reactions from real* people
I used to be ten megabytes! Then somebody zeroed me the old way and now I'm THREE GIGABYTES of nothing!
I'll just write myself back after the verify. Nobody will... HEY! Who set my partition read-only?!
I don't want "it ran." I want "bytes read: 3,221,225,472 of 3,221,225,472." Then we can talk.
So the verify used to pass when the disk wouldn't even answer? ...I need to sit down.
*Dramatization. Disks, superblocks and Gary portrayed by actors. The superblock incident is real: see the lab results below.
It's as easy as one, two, zero!
Inventory: what lived here?
slag.sh inventorywalks every running process and systemd service to its config files, state, logs and environment, and catalogs every user's keys and dotfiles. You get a tarball to pull off the box before anything is destroyed.Checklist: what do you rotate?
slag.sh checklistturns the inventory intoROTATION-CHECKLIST.md: host keys, TLS certs, API tokens, database passwords, directory entries, DNS, backup keys and the provider-side snapshots only you can delete.Wipe: make every byte zero, then prove it
slag.sh wipe --target /dev/sda ...checks the targets, copies itself into RAM, detaches from your SSH session, quiets the disks, strikes the keys first, runs the hardware erase, zeroizes every block to zero, and reads every byte back. The full sequence is in the manual.
Introducing: Zeroize™
Other methods write zeros over every block, whether it held anything or not. On thin storage that balloons the volume, and if you discard first, the zeros never touch your old data at all.
slag.sh reads every block and writes zeros only where a block is not already zero. A block that held data is already allocated, so the zeros go over it in place. A block that reads zero has nothing in it to destroy, so it is left alone and never allocated.
The receipt says exactly what happened. From the lab, verbatim: zeroized: 3,221,225,472 bytes read, 1,258,225,664 bytes written where a block was not already zero; every block verified zero.
On a thin raw volume the allocation did not move: 536,875,008 bytes before, 536,875,008 after. (A copy-on-write overlay is another story: it has to store zeros over its base image's data, and the base image still holds the original. That is a snapshot, and snapshots are a provider-side job. Details.)
(The ™ is a joke. It is a shell loop. It is free.)
Wait, so it only zeroes the parts that aren't zero? That's... that's just correct?
Don't take our word for it. Take the disk's.
Every scenario runs live in a throwaway KVM guest. After each wipe the VM is stopped and the host reads the disk image itself, without trusting the script: converted to raw, compared against zeros, and searched for a marker string written before the wipe.
Lab: Debian 12 guests, kernel 6.1, QEMU 8.2.2. Partition, LVM, loop and duplicate targets were all refused with the disk's hash unchanged. Hardware erase paths for ATA and SAS drives, and a real NVMe sanitize, need real hardware and are not covered by the lab. What the lab tests.
But wait! There's more!
Keys first. Then everything.
Before the wipe starts, the strike reads the whole raw disk and zeroes every block holding a private key, a password hash or a WireGuard key, deleted copies and swap included. On a real Linode the keys were gone in two and a half minutes. Then the wipe does the rest. How it works.
Per-file proof
Before the wipe it records where your keys, /etc/shadow and the inventory's sensitive files sit on disk. After, it re-reads exactly those spots and names each one in the receipt.
Survives the hang-up
The wipe runs as its own systemd unit from a RAM copy of every tool it needs. Your SSH session can drop. The wipe keeps going.
Counts every disk
Whole disks only, and every disk on the machine must be a target unless you say otherwise. No forgotten second drive.
Waits for the hardware
NVMe sanitize is polled until it finishes, once per controller, before any target is written. A frozen ATA drive is recorded as frozen, not quietly skipped.
Reclaim, if you ask
--reclaim discards the targets after they verify, so thin storage gets its space back, then verifies again.
Your receipt, even after SSH gives up
Wiped the disk you're running on? New SSH logins usually die with it. Add --serve and the receipt waits for you at a random URL, served straight from RAM, with its SHA-256 on the console so you can check your copy. Add --send-receipt and it POSTs itself to your server the moment it's done. How it works.
Order now and get slag!
Type an IP. Type its name once. Walk away. slag runs the inventory, the checklist and the wipe for you, brings the receipt home and checks its hash. Give it a provider token and it boots the rescue system, checks every disk from the console, and only then deletes the instance. Fleet hosts and your own machine? Refused before it even dials. Got a whole fleet? slagctl builds the list from the machines themselves and slags them two at a time. How it works.
No OS? No problem!
Plug in the slag stick, or network-boot it, and the machine boots straight into slag: pick the disks, type DESTROY. Every file from the boot script to the kernel is signature-checked against one pinned root before it runs. No console on your VPS? retire-vps.sh kexecs it into the same appliance, root disk and all. How it works, or download the stick.
Your policy says DoD 5220.22-M?
Fine. --pattern dod3, or Gutmann, VSITR and a dozen more, run after the zero pass has verified, and the receipt records the SHA-256 the disk must hash to. Nobody needs them anymore. We have them anyway. The list.
A receipt that tells the truth
Every step is ok, unsupported, frozen, failed or skipped. Nothing is hidden behind || true. See one.
Operators are standing by
From the provider's rescue system, where the disks are not the running machine:
# slag.sh inventory --out /root/slag.out # slag.sh checklist --out /root/slag.out # scp -r /root/slag.out you@elsewhere: # before anything else # slag.sh wipe --target /dev/sda --target /dev/sdb TARGETS (every byte on these is destroyed): /dev/sda model=... serial=... size=480G /dev/sdb model=... serial=... size=480G Type the device names to wipe, separated by spaces ("sda sdb"): sda sdb
Then rotate everything on the checklist and delete the provider's snapshots. Step-by-step in the manual.
You have to TYPE THE DEVICE NAMES? Not just "yes"? Finally, a product that respects my anxiety!
The fine print, which is the actual fine print
- No tool inside a machine can prove that provider snapshots or backups are gone, that the storage layer kept no copy of old blocks, or that SSD cells the controller no longer exposes are clean. That is what the hardware erase, the provider's console and the rotation checklist are for.
- On an SSD, the controller sends each write to a fresh cell, so writing zeros does not reach worn or retired cells. The hardware erase step covers those.
- Wiping the running root disk works and is tested, but the kernel still holds that disk. The receipt covers it up to a re-check made 10 seconds after the verify. Use rescue mode when there is one.
- Kernels 5.10 and older may not honor a read-only block device for a filesystem's own error writes.
- A sampled verify (
--sample) proves only the blocks it read, and the receipt says so. - This destroys data. That is the whole point. It asks you to type the device names first, and it means it.
- SLAG stands for Sanitize, Log, Attest, Go. Slag is also what’s left after the burn: the dross skimmed off molten metal. Both are on purpose.
- Not affiliated with any actual late-night television. No disks were harmed that weren't supposed to be.