Skip to main content
  1. Index/

NBDE / Clevis / Tang (Network-Bound Disk Encryption)

NBDE (Network-Bound Disk Encryption) is an approach to automatic LUKS disk unlocking that binds the volume key not to hardware state (a TPM PCR measurement) but to network presence: a LUKS-encrypted volume unlocks automatically at boot if and only if the machine can reach a designated Tang server on a trusted network. Remove the machine from that network — because it was stolen, because a data centre drive was pulled, because someone exfiltrated the hardware — and the volume key becomes unrecoverable without a fallback passphrase. The threat model is therefore complementary to TPM-based unlocking: TPM sealing asks “is this the right software stack?” and locks the key to a specific platform measurement; NBDE asks “is this machine on the trusted network?” and locks the key to network presence. Neither addresses both threat classes alone, which is why the two are routinely combined — and why RHEL formalises NBDE as a subcategory of the broader Policy-Based Decryption (PBD) framework that the Clevis pin system implements.

Tang is the server component: a minimal, stateless HTTP service (typically running on port 80 or 443 behind a reverse proxy) that advertises a set of JOSE-formatted elliptic curve public keys and responds to key-derivation requests. Tang has no persistent state, no client registry, no authentication, and no TLS requirement — it is designed to be simple enough that its security properties are easy to audit and its availability is easy to ensure. The cryptographic protocol underlying the Tang exchange is the McCallum-Relyea exchange (named after Nathaniel McCallum and Robert Relyea who discovered it in 2015): a two-party protocol built on elliptic curve Diffie-Hellman and the Integrated Encryption Scheme that allows a client to derive a secret using the server’s private key without the server ever learning the secret and without the secret ever being transmitted over the network. The exchange proceeds as follows: at bind time, Clevis generates a random client key pair, computes a point on the curve using the Tang server’s advertised public key and the client’s private key, derives the LUKS unlock key from that point, and stores an encrypted JWE (JSON Web Encryption) token — containing the client’s public key and a recovery point — in the LUKS header’s metadata. The client’s private key is then discarded. At unlock time, Clevis sends the recovery point to the Tang server via an HTTP POST; Tang performs an elliptic curve scalar multiplication using its own private key and returns the result; Clevis combines this with locally stored data to reconstruct the original derived point and recover the LUKS key. Tang never sees the LUKS key, never stores any per-client state, and cannot decrypt the volume even with full access to its own key material — it can only participate in the reconstruction protocol. Tang key rotation is manual: old keys in /var/db/tang/ are hidden by prefixing them with a dot (.) and new keys are generated; existing clients bound to the old key can no longer unlock until rebound, which is the intended revocation mechanism — rotating Tang keys revokes network-bound unlock for all clients bound to the old key simultaneously.

Clevis is the client-side framework: a pluggable, pin-based secret management system that binds LUKS keyslots to arbitrary unlock policies expressed as JSON configurations. A pin is a plugin that implements a specific unlock mechanism; the built-in pins are: tang (NBDE unlock via a Tang server), tpm2 (hardware-bound unlock via TPM2 PCR policy, as covered in the LUKS entry), pkcs11 (PKCS#11 hardware token), and trustee (unlock via the Trustee KBS attested TLS exchange, available in RHEL 10 for confidential computing integration). The sss (Shamir’s Secret Sharing) pin is the composition mechanism: it splits the LUKS key into n shares, encrypts each share with a different pin, and requires at least t shares to reconstruct the key — enabling threshold policies across heterogeneous unlock methods. The two most operationally important SSS configurations are: t=1 (OR policy) — any one of the listed pins suffices to unlock; used for high-availability where multiple Tang servers are listed so that the failure of one server does not prevent boot — clevis luks bind -d /dev/sda sss '{"t":1,"pins":{"tang":[{"url":"http://tang1"},{"url":"http://tang2"}]}}'; and t=2 (AND policy) — both a Tang server and a TPM2 PCR measurement must be satisfied to unlock — clevis luks bind -d /dev/sda sss '{"t":2,"pins":{"tang":[{"url":"http://tang1"}],"tpm2":{"pcr_ids":"7","pcr_bank":"sha256"}}}'. The AND policy is the recommended production pattern for bare-metal servers: the disk only unlocks if the machine is on the trusted network and booted with a Secure-Boot-verified software stack (PCR 7), protecting against both hardware theft and software tampering simultaneously. Clevis integrates into the boot process via dracut modules (clevis-dracut on RHEL/Fedora, clevis-initramfs on Debian/Ubuntu) that embed the Clevis client and its network stack into the initramfs, enabling Tang queries and TPM2 operations before the root filesystem is mounted. clevis luks bind adds a new LUKS keyslot containing the Clevis JWE token; the existing passphrase keyslot is retained as a fallback. clevis luks list -d /dev/sda shows all Clevis bindings on a device; clevis luks unbind removes one. The RHEL nbde_client and nbde_server Ansible system roles automate fleet-wide deployment of Tang servers and Clevis client bindings at scale. In the context of ODF and bare-metal OpenShift node provisioning, NBDE with Tang is the standard mechanism for automatic OSD and root filesystem unlocking during node bootstrap — the node boots, reaches the Tang server on the cluster network, and unlocks all LUKS volumes without operator intervention, while a node that boots off-network (e.g. after physical removal) cannot access any data.

Related

LUKS (Linux Unified Key Setup)

LUKS (Linux Unified Key Setup) is the standard specification for block device encryption on Linux, created by Clemens Fruhwirth in 2004. It sits above the kernel’s dm-crypt subsystem — which performs the actual AES sector-by-sector encryption via the device mapper — and adds a structured, on-disk header that decouples key management from the encryption itself. Any block device can be a LUKS container: a partition, a logical volume, a loop device; anything that sits beneath it (filesystem, swap, LVM) is encrypted transparently, with no changes required to the software using it. The managed cryptsetup tool and the libcryptsetup library provide userspace access to LUKS volumes, and are the canonical interface for all operations on them.

RHCOS (Red Hat Enterprise Linux CoreOS)

RHCOS (Red Hat Enterprise Linux CoreOS) is the operating system that runs on every OpenShift control plane and worker node. It is not a general-purpose Linux distribution — it is a purpose-built, immutable, container-optimised OS designed to run exclusively as a managed node in an OpenShift cluster. Its security posture is architecturally different from a hardened RHEL installation: rather than hardening a mutable system through configuration management, RHCOS makes the OS layer structurally resistant to modification by design. The root filesystem’s /usr tree is read-only (enforced at mount time by rpm-ostree and, in recent versions, by composefs over the OSTree object store), /etc and /var are writable but managed exclusively by the Machine Config Operator (MCO), and no package manager is available at runtime for ad-hoc software installation. An operator who wants to change any node-level configuration — kernel arguments, sysctl settings, systemd units, certificates, kubelet configuration — creates a MachineConfig object in the OpenShift API; the MCO renders it into an Ignition config, applies it to the target MachineConfigPool (master, worker, or custom), and drains and reboots the affected nodes in a rolling fashion. Direct SSH access to nodes for configuration changes is explicitly unsupported and actively discouraged — oc debug node/<name> is the supported emergency access path, dropping into a privileged container on the node’s host namespaces under audit.

Storage Encryption

Storage encryption is not a single feature but a four-layer decision that must be made independently, because each layer addresses a different adversary and a different failure mode. Layer 1 — disk/OSD at-rest encryption protects against physical media theft: a decommissioned OSD or stolen drive is unreadable without the key. Layer 2 — cluster-internal wire encryption protects against a network-layer attacker who can observe traffic between storage nodes: OSDs, monitors, and clients on the cluster network. Layer 3 — PV/volume-level encryption protects against a storage operator or another tenant reading a workload’s data through the storage system itself — the threat model where the storage cluster is itself potentially untrusted or multi-tenant. Layer 4 — object storage server-side encryption provides per-object key management for S3-compatible workloads, enabling customer-managed keys (CMK) and per-tenant key isolation in object stores. These layers are independent and composable: enabling Layer 1 without Layer 2 protects against physical theft but not a network interceptor; enabling Layer 3 without Layer 1 protects against the storage operator but not physical media extraction. A complete encryption posture addresses all four explicitly, even if some layers are deliberately left disabled with a documented rationale.