USB-triggered server shutdowns
In this guide you will learn how to set up a trigger such that your home server shuts down if any USB devices are added or removed. This is similar to USB-triggered shutdowns. The only difference is that this is server-focused and therefore has a slightly different bash script.
Note: This guide assumes that you have a homeserver setup on a configuration similar to sensitivevm.
Threat model
- This is an anti-tampering setup.
- You are running a sensitive website or service from your home server.
- You are a high-value target for LE.
- Or you just want to prevent your siblings from tampering with your systems. ;)
Setup
-
Make sure you have
lsusb
installed. Usually the package name would beusbutils
.Once you see a list of USB devices, you're good to proceed to the next step.user ~$ sudo apt install usbutils user ~$ lsusb Bus 0xx Device 0xx: ID xxxx:xxxx Logitech Wired Mouse Bus 0xx Device 0xx: ID xxxx:xxxx HP, Inc USB Flash Drive . . .
-
Make sure you have
reboot.sh
in your home directory. (This isn't mandatory. You'll see why below.)user ~$ cat reboot.sh #!/bin/bash /usr/bin/sudo /usr/sbin/reboot now
-
Copy the following bash script and give it executable permissions.
#!/bin/bash # nukeusb.sh # A script by bleak. # Variables INTERVAL=1 # <-- interval to check the devices in. TRIGGER="sh /home/user/reboot.sh" # <-- command to run if a USB device was added or removed. # Get initial list of USB devices prev_devices=$(lsusb) echo "Monitoring for any USB device changes..." echo "Press Ctrl+C to stop." while true; do current_devices=$(lsusb) if [[ "$current_devices" != "$prev_devices" ]]; then $TRIGGER exit prev_devices="$current_devices" fi sleep "$INTERVAL" done
How it works
- Once you run the script, it starts checking for any changes in the output of
lsusb
(list of connected USB devices). - If it detects a change, it runs the
$TRIGGER
, whatever you set it to. In this case, it would runexecute /home/user/reboot.sh
, rebooting the system and removing all evidence, given you have a plausibly deniable setup.
Usage
Tweak the variables present at the beginning of the script to whatever you like.
Note: Make sure you aren't running any commands that require you to enter a password. If you need to run superuser commands, either set a NOPASSWD rule for that command, or run the script as root. We want everything to be quick and automatic. You can find a guide to setting up a NOPASSWD rule in the sensitivevm guide here.
- Remember that every time you connect or disconnect a device to the server, it executes the
$TRIGGER
. This includes any mouse or keyboard you'd connect while the script is running. - Remember to run the script after you've completely set your server up. We don't want to have any false positives that might occur while you're setting things up, connecting and disconnecting devices, etc.
What exactly is this for?
In case your house was broken into and the server is being seized, LE might try to connect their own device to the server, to either exfiltrate your data, or to prevent the server from turning off. We're using exactly this against them by having the server poweroff when they connect something. It is essentially a nuke that they themselves will set off.
This reminds me a lot of the GrapheneOS Duress PIN tactic as described here. The following is the relevant text:
"It might be worthwhile to consider writing your duress PIN on a piece of paper and placing this paper in your phone case. Should anyone find your phone or compel you to give it to them, they may inadvertently enter your duress PIN thinking you were forgetful and had to write down you PIN."
*Note: Entering the duress pin causes GrapheneOS to factory-reset the phone, which is similar to our script which shuts the system down, encrypting the data (If you have FDE).
Optional setup
Manually executing the script every time you reboot server can be a hassle. If the server reboots by itself due to a power outage or kernel panics, most of the time you wouldn't even know it happened. Therefore, we are going to set up a systemd service to start the script automatically.
If you're going to set this up, you don't need to invoke sudo
in the $TRIGGER
variable or the reboot.sh
script, as nukeusb.sh
would run as root anyways.
-
Setting up the systemd service
Create
/etc/systemd/system/nukeusb.service
.Enter the following code:user ~$ sudo vim /etc/systemd/system/nukeusb.service
[Unit] Description=execute nukeusb.sh [Service] Type=oneshot ExecStart=/bin/bash /home/user/nukeusb.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target
Now we define a timer unit.
user ~$ sudo vim /etc/systemd/system/nukeusb.timer
Enter the following code; adjust wherever needed.
[Unit] Description=delay nukeusb.service on boot [Timer] # Waits 3 minutes after boot before executing nukeusb. OnBootSec=3min Unit=nukeusb.service [Install] WantedBy=timers.target
-
Enable the service
# Reload to recognize new units sudo systemctl daemon-reload # Enable & start the timer sudo systemctl enable --now nukeusb.timer
-
Check if the timer is running
systemctl list-timers --all
Note: Change the OnBootSec
value as needed. Make sure you actually restart and test if the service is working.
Conclusion
There you have it! We have now set up a script that turns off the system when a USB device is connected or disconnected. The use cases are infinite.
DISCLAIMER: This blog's stance is not to endorse sensitive activities and nothing in this article serves as legal advice. You are responsible for whatever you do, unless found not guilty.
Suggest changes
bleak 2025-07-21
43fPQSRfkorKmDrC7Toqw67yimcV8VKbxYudY1zQp6Z7XiuboXTmnAdifGrsCP5bF8A7qNDedAhEQ3TwCegudmrA1U5bgUp Donate XMR to the author: