A technical guide for destroying sensitive high-risk virtual machines or full system when compelled to authenticate at border crossings or security checkpoints. The duress password is integrated at two authentication points: the lightdm display manager for system login, and the xscreensaver lock screen for session unlock. This ensures the duress action can be triggered both at initial boot authentication and when unlocking an existing session.
Make backups of all your VMs beforehand.
Download this repository in dvm:
git clone https://github.com/nuvious/pam-duress.git
then add it to a ZIP archive, for example pam.zip
Send it to dom0 and extract archive
qvm-run --pass-io dispXXX 'cat /home/user/pam.zip' > pam.zip
unzip pam.zip
Run these commands to build the module in dom0 and create duress-password:
sudo qubes-dom0-update gcc gcc-c++ make cmake automake pam-devel openssl-devel
cd pam-duress
make
sudo make install PAM_DIR=/usr/lib64/security
make clean
mkdir -p ~/.duress
sudo mkdir -p /etc/duress.d
Create a scripts with two scenarios:
1. Scenario: Delete some VMs and delete this script itself:
cat > ~/remove_vm.sh << 'EOF'
#!/bin/bash
if ! [ -w /run/qubesd.sock ] && [ -z "$DURESS_REEXEC" ]; then
exec sg qubes "DURESS_REEXEC=1 $0 $*"
fi
export PATH="/usr/bin:/usr/sbin:/bin:/sbin:$PATH"
# Add the names of VMs to be deleted here 'test_vm'
/usr/bin/qvm-remove --force test_vm
EOF
chmod +x remove_vm.sh
(
Add the names of VMs to be deleted here âtest_vmâ)
2. Scenario: Total system destruction:
cat > ~/remove_qubes.sh << 'EOF'
#!/bin/bash
# WARNING: This script irreversibly destroys data. Use only for duress password.
if ! [ -w /run/qubesd.sock ] && [ -z "$DURESS_REEXEC" ]; then
exec sg qubes "DURESS_REEXEC=1 $0 $*"
fi
export PATH="/usr/bin:/usr/sbin:/bin:/sbin:$PATH"
# ========== PHASE 0: REMOVE RAM-WIPE MODULE ==========
RAM_WIPE_DIR="/usr/lib/dracut/modules.d/40ram-wipe"
if [ -d "$RAM_WIPE_DIR" ]; then
echo "[*] Removing ram-wipe dracut module to prevent shutdown stall..."
rm -rf "$RAM_WIPE_DIR"
fi
# ========== PHASE 1: DESTROY LUKS HEADER ==========
LUKS_DEV=""
for dev in /dev/nvme0n1p3 /dev/sda2 /dev/vda2 /dev/mapper/luks-*; do
cryptsetup isLuks "$dev" 2>/dev/null && LUKS_DEV="$dev" && break
done
if [ -n "$LUKS_DEV" ]; then
echo "[*] Erasing LUKS header on $LUKS_DEV..."
if cryptsetup luksErase --batch-mode "$LUKS_DEV" 2>/dev/null; then
echo "[*] LUKS header destroyed. Triggering emergency reboot..."
echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger
xl debug-keys R 2>/dev/null || true
exit 0
fi
fi
# ========== PHASE 2: FALLBACK - DESTROY ALL VMs + CORRUPT LVM ==========
echo "[!] LUKS erase failed or not found. Executing fallback destruction..."
echo "[*] Removing all qubes..."
qvm-remove --all -f 2>/dev/null || true
echo "[*] Corrupting LVM metadata..."
vgremove -ff qubes_dom0 2>/dev/null || true
for pv in /dev/nvme0n1p3 /dev/sda2 /dev/vda2; do
[ -b "$pv" ] && dd if=/dev/urandom of="$pv" bs=1M count=4 conv=notrunc 2>/dev/null && break
done
# ========== PHASE 3: INSTANT REBOOT ==========
echo "[*] Triggering emergency reboot..."
echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger
xl debug-keys R 2>/dev/null || true
EOF
chmod +x ~/remove_qubes.sh
Then add scripts in duress module:
cat > ~/.duress/remove_passwd.sh << 'EOF'
#!/bin/sh
/home/user/remove_vm.sh
rm -rf /home/user/remove_vm.sh
rm -rf /var/log/qubes
EOF
cat > ~/.duress/remove_passwd2.sh << 'EOF'
#!/bin/sh
/home/user/remove_qubes.sh
EOF
then
chmod 500 ~/.duress/remove_passwd.sh
chmod 500 ~/.duress/remove_passwd2.sh
duress_sign ~/.duress/remove_passwd.sh
add alternative password for destroying VMs
duress_sign ~/.duress/remove_passwd2.sh
add alternative password for destroying system
and then:
chmod 400 ~/.duress/remove_passwd.sh.sha256
chmod 400 ~/.duress/remove_passwd2.sh.sha256
Check:
ls -la ~/.duress/
Module created.
Now we need to modify this file /etc/system-auth
sudo nano /etc/system-auth
Add this line
auth sufficient pam_duress.so
so that the first 6 auth-lines look like this:
auth required pam_env.so
auth required pam_faildelay.so delay=2000000
auth sufficient pam_fprintd.so
auth sufficient pam_unix.so nullok
auth sufficient pam_duress.so
auth required pam_deny.so
then click Ctrl + C and Ctrl + X
Done.
Now first duress password will remove some VMs.
Second duress password will destroy and forcibly shutdown the system. It should protect against forensics (disk will become unreadable).
For additional hardening, see my separate guide on system startup with forensic resistance - designed to mitigate disk and memory analysis.