Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion nixos/frost-gate.nix
Original file line numberDiff line numberDiff line change
Expand Up@@ -742,7 +742,12 @@ in
"/dev/disk/by-partuuid/"
])
)
"keepNode.frostGate.volumeDevice (${cfg.volumeDevice}) is not a stable /dev/disk/by-id or /dev/disk/by-uuid path. On real hardware a kernel-enumeration name (or topology-based /dev/disk/by-path) can re-point at a different disk, and first-boot provisioning could format the wrong device. See the volumeDevice option docs.";
"keepNode.frostGate.volumeDevice (${cfg.volumeDevice}) is not a stable /dev/disk/by-id or /dev/disk/by-uuid path. On real hardware a kernel-enumeration name (or topology-based /dev/disk/by-path) can re-point at a different disk, and first-boot provisioning could format the wrong device. See the volumeDevice option docs."
# Production tripwire: allowInsecureWs disables the ws->wss upgrade guard on the boot OPRF
# exchange, so the unlock share/response travels in plaintext and is MITM-able by a hostile relay
# or anyone on the network path. It is test-only; surface it loudly so it can never ship enabled
# by accident.
++ lib.optional cfg.allowInsecureWs "keepNode.frostGate.allowInsecureWs is ENABLED: the boot threshold-OPRF unlock exchange runs over plaintext ws:// (KEEP_ALLOW_WS), so a hostile relay or on-path attacker can observe or tamper with the unlock. This is TEST-ONLY and must never be set on a real deployment.";

assertions = [
{
Expand Down
11 changes: 11 additions & 0 deletions nixos/ingress.nix
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,6 +106,17 @@ in

# Vaultwarden must know its public URL (links, WebAuthn, etc.) and must trust the proxy's
# forwarded client IP, so its log (and thus fail2ban) bans the real attacker, not 127.0.0.1.
#
# SECURITY ASSUMPTION: IP_HEADER trusts X-Real-IP UNCONDITIONALLY. nginx's recommendedProxySettings
# overwrites X-Real-IP with the real connection address on every proxied request, so no *remote*
# client can forge it. That reduces the trust boundary to Vaultwarden's loopback port: Vaultwarden
# binds 127.0.0.1 (vaultwarden.nix), which keeps the port off the network but does NOT structurally
# restrict it to nginx. This config therefore rests on an OPERATIONAL ASSUMPTION, not an enforced
# control: that no other local process (and no future mesh->localhost or loopback termination) can
# reach Vaultwarden's loopback port. Any local process that can connect there could forge X-Real-IP
# to make fail2ban ban an attacker-chosen victim IP or dodge its own ban. If that assumption ever
# weakens, make it structural (e.g. a unix-domain socket or dedicated netns for the nginx<->Vaultwarden
# hop) rather than relying on loopback binding alone.
services.vaultwarden.config = {
DOMAIN = "https://${cfg.hostName}";
IP_HEADER = "X-Real-IP";
Expand Down
Loading