Your first session
This page walks through one session. It assumes the
decoy is prepared, the
hidden volume exists and NAILS is
installed on it, for example
from Tails. The examples use the hidden volume at
/mnt/data.
In short
Section titled “In short”# On the decoy, in a shell with history offset +o history# unlock and mount the hidden volume at /mnt/data, then:sudo /mnt/data/nails checksudo /mnt/data/nails activate
# Inside the hidden session, when you are donesudo /mnt/data/nails verify --deepsudo /mnt/data/nails deactivate --poweroffOn the decoy
Section titled “On the decoy”Type as little as possible on the decoy. Use NAILS there only for init once,
the steps below, and recover or reset-upper when you need them. Do not edit
the NAILS configuration there, and do not name the hidden volume, its mapping,
its mount point or the tool in any other command.
-
Turn shell history off for this terminal.
Terminal window set +o history -
Unlock and mount the hidden volume with the commands for your backend.
-
Check readiness.
checkruns the same pre-flight checks as activation and changes nothing.Terminal window sudo /mnt/data/nails checkA failing check prints a hint that names the fix. The
platformrow names the host NAILS detected. It warns on a Debian or Ubuntu release that NAILS has not been tested on, and fails on a host that activation refuses.Also review what
checkreports about the session: which decoy filesystems are overlaid, bound read-only or masked, and which inherited decoy state needs review. It lists the autostart entries and services that you or other software added, lingering, autologin, and the clients on a list of known trace writers, such as sync and messaging clients. -
Activate.
Terminal window sudo /mnt/data/nails activateActivation asks for confirmation. Without a configuration file, it says before the prompt that it uses the built-in defaults. It then writes a read-only baseline scan of the decoy to the hidden volume, runs the pre-flight checks, prepares the overlay and, on NixOS, builds the hidden system. The first NixOS activation also copies the hidden system’s whole closure onto the hidden volume: several GB for a desktop, and minutes on a slow or encrypted backend. As its last step, activation kills the decoy’s interactive shells, so none of them writes the activation command to a history file, and soft-reboots.
Ctrl+C cancels the activation at any point before the switch. It stops at the next step, removes everything it built and exits with status 130. A step that runs a program to its end, such as the activation of the hidden NixOS system, finishes first.
-
Log in again. Your terminal closes and the screen shows a text console for a few seconds. Then the hidden session starts at its own login screen. NAILS logs nobody in, but a display manager set to log an account in automatically logs it in again, as at boot. See Autologin.
Inside the hidden session
Section titled “Inside the hidden session”The hidden volume is at the same path as on the decoy. Work as usual. Changes
land in the upper layer on the hidden volume. A disk you mount yourself is the
exception, as described below. sudo /mnt/data/nails status shows the session
and the space left on the hidden volume.
Changing the hidden system
Section titled “Changing the hidden system”-
NixOS.
nixos-rebuild testapplies a change to the running session. Give it the target that activation builds:- Without a hidden flake or
nixos_flake, runsudo nixos-rebuild test. Here/etc/nixosis the hidden configuration. - With a hidden flake, run
sudo nixos-rebuild test --flake /mnt/data/nixos#<host> --impure, where<host>is the decoy’s hostname, not the hidden name that the network-identity module sets. For a flake named withnixos_flake, pass that reference instead.
On a decoy whose
/etc/nixosis a flake, a plainnixos-rebuild testbuilds that decoy flake. It fails, or it puts the decoy’s own system into the session without the hidden module, so always name the hidden flake there. Never useswitchorboot, which try to install a bootloader into the read-only ESP and fail. The next activation builds the hidden system again from/mnt/data/config/nixos/or your flake, so keep that source in step with what you test. - Without a hidden flake or
-
Debian and Ubuntu. Use
apt, edits in/etcandsystemctl enableas on any system. Every change lands in the upper layer and stays the hidden configuration from then on.
A NixOS decoy with a flake
Section titled “A NixOS decoy with a flake”Activation refuses to build a decoy’s own /etc/nixos flake, also with
--no-preflight, because that build would leave out the hidden module and the
hidden hardware configuration. Such a decoy needs a self-contained hidden flake
in /mnt/data/nixos. Write it in a hidden session:
-
On the decoy, check and enter a session with the decoy’s own system.
Terminal window sudo /mnt/data/nails check --overlay-onlysudo /mnt/data/nails activate --overlay-only -
In that session,
/etc/nixosshows the decoy’s configuration beside the hidden hardware configuration. Copy what the hidden system needs into/mnt/data/nixos. Write aflake.nixthere that builds this machine’s hostname from those copies and imports the hidden module/mnt/data/config/nixos/configuration.nixby its absolute path. -
Lock it with
nix flake lockin the same session. Activation never updatesflake.lock, so it must exist. -
Build it there before you rely on it, with the decoy’s hostname as
<host>.--impurelets the flake import the hidden module by its absolute path.Terminal window sudo nixos-rebuild build --flake /mnt/data/nixos#<host> --impure -
End the session with
deactivate. The next activation builds the hidden flake.
Never write or lock the flake on the decoy, where the editor’s files, root’s Nix
cache and the nixpkgs the lock fetches would land on the decoy disk. Keep it
self-contained. A flake that imports the decoy’s /etc/nixos/configuration.nix
reads the decoy’s own files at every activation, which updates their access
times on a relatime decoy, and the ./hardware-configuration.nix it then
imports is the decoy’s, swap included.
Space and copy-up
Section titled “Space and copy-up”The overlay copies a decoy file to the hidden volume in full the first time you change it. The first write to a large file, such as a browser profile or a VM image, can stall on a slow or encrypted backend. The upper layer only grows.
- Watch free space with
df -h /mnt/data.nails checkfails when it drops belowminimum_space_mb. - Clear caches inside the session. On NixOS, run
nix-collect-garbage -dthere. - A file copied up earlier hides later decoy updates of that file. To drop a
path’s hidden copy, run
sudo /mnt/data/nails reset-upper <PATH>on the decoy, with the hidden volume mounted. It lists what it deletes and asks first.
Accounts, sync clients and network identity
Section titled “Accounts, sync clients and network identity”- By default the hidden session runs as the decoy user, in the decoy home. The
decoy’s browser profiles, keys and signed-in accounts are live there. Sign in
to the hidden session’s own accounts for sensitive work, or use the
fresh-homepersona. - Do not start the decoy’s sync, cloud, mail or messaging clients for sensitive
work. What they send stays on the remote side, and a decoy client can pull it
back onto the decoy disk after the session. Mask them inside the hidden
session, for example with
systemctl --user mask syncthing.service. - The hidden session keeps the decoy’s machine ID, hostname, MAC addresses and
network profiles, including VPN autoconnect. NAILS ships optional snippets
that give the hidden session its own MAC addresses and hostname. The way back
does not undo them, so end a session that used them with
deactivate --powerofforemergency --poweroff.
Autologin
Section titled “Autologin”A display manager set to log an account in automatically does so after every
switch, as at boot. After activate the hidden desktop then opens without a
password, and after deactivate or emergency the decoy’s desktop does. NAILS
logs nobody in and leaves the setting alone. check lists an autologin it finds
in the decoy’s GDM, LightDM or SDDM configuration.
To keep autologin on the decoy but have the hidden session start at its login screen, turn it off in the hidden session only:
-
NixOS. Inside a hidden session, add this line to the hidden module
/mnt/data/config/nixos/configuration.nixor to your hidden flake. The next activation builds it in.services.displayManager.autoLogin.enable = lib.mkForce false; -
Debian and Ubuntu. Inside a hidden session, edit the file that sets the display manager’s autologin. For GDM, set
AutomaticLoginEnable=falsein the[daemon]section of/etc/gdm3/daemon.confon Debian or/etc/gdm3/custom.confon Ubuntu. For LightDM, emptyautologin-user=in its[Seat:*]section. For SDDM, emptyUser=under[Autologin]. The edit lands in the upper layer, so it applies from the next activation and the decoy keeps its own setting.
check keeps listing the decoy’s autologin even after the hidden session turns
it off.
Disks you mount during a session
Section titled “Disks you mount during a session”A disk you mount yourself, such as an automounted USB drive or a decoy partition, is outside every overlay. A read-write mount writes to it directly, and mounting it read-write already writes its superblock.
- The session watcher shows a desktop alert, “Disk mounted with write access”, for every read-write mount of a disk outside the hidden volume. Alerts appear on the desktop of the account logged in on the machine’s own screen. While nobody is logged in there, none can be shown.
- A disk mounted over the hidden volume, at
/mnt/dataor at a parent such as/mnt, hides it. Every file saved under that path from then on goes to that disk. The watcher shows a separate alert, “Disk mounted over a folder in use”, andnails statusnames the disk. Unmounting it, for example withsudo umount /mnt, takes it off. NAILS writes nothing there meanwhile, anddeactivaterefuses until it is gone. session_mounts.read_only = truemakes every disk the session does not use read-only for the session. Turn it on unless you need to write to an external disk. See Backend watcher and disks.nails deactivateunmounts these disks before the way back.
Do not suspend
Section titled “Do not suspend”Suspend keeps the whole hidden session and the volume’s key in RAM, behind the
hidden lock screen. Set the decoy’s lid switch to lock as described in
Prepare the decoy, and consider
a sleep policy.
Verify and return
Section titled “Verify and return”-
Look for known artifacts.
Terminal window sudo /mnt/data/nails verify --deepInside the session, what belongs to the session is not reported as residue. One note says that the session’s runtime files in
/run, the mounted hidden volume and its active state are expected, and the header counts only warnings and critical findings. With--deep, verify also searches the journal and names sudo’s records of your own commands as such.A clean result is evidence against known artifacts, not proof. To check the decoy itself, scan an image of it offline, as Check your setup describes.
-
End the session and power off.
Terminal window sudo /mnt/data/nails deactivate --poweroffdeactivateasks for confirmation. Programs then close as at a logout. Powering off is what clears RAM, so leave the machine off for a few minutes before anyone else handles it. Without--poweroff, the machine returns to the decoy’s login screen, or to its desktop if the display manager logs an account in automatically, and the hidden volume is closed on the way.The way back keeps the network links, addresses, routes and VPN tunnels that the session set up, and they stay up until power-off. If you return to the decoy without powering off, first take down the connections and tunnels you brought up and delete the links you created. Ending a session lists what else the way back leaves.
Before you rely on NAILS, rehearse a whole session on the real machine with
nails rehearse.
Full details
Section titled “Full details”- Operator guide, with the pre-activation and in-session checklists
- Operator guide: Changing the hidden configuration
- Operator guide: Inherited autostart, services and autologin
- Operator guide: Disks mounted during the session
- README: Quick start