| pick your distro, get ZFS on root
kldload — your platform, your way, free
Source

FIPS 140-3 & Classified Compliance

This is a technical assessment of the kldload OpenZFS stack against FIPS 140-3 and broader classified/high-security deployment requirements. It is not marketing. Where the stack meets requirements, that is stated clearly. Where there are gaps, those are named, explained, and mitigated. An auditor should be able to read this page and know exactly where they stand.

FIPS 140-3 is the US federal standard for cryptographic modules. If you handle government data, process healthcare records subject to HIPAA, manage financial transactions under PCI DSS, or operate in defense or intelligence environments — you need FIPS-validated cryptography. This masterclass is an honest assessment of where the kldload OpenZFS stack stands relative to those requirements.

Where we're compliant, we'll show you. Where there are gaps, we'll name them and explain what needs to change to close them. The goal is to give you enough information to make a risk-informed decision and to write an accurate System Security Plan.

Most open source projects either ignore FIPS entirely or make vague compliance claims. This page does neither. It is a technical assessment: here is what FIPS 140-3 requires, here is what the stack provides, here are the gaps. An auditor should be able to read this page and know exactly what work remains for their specific compliance regime. If something on this page is wrong or has changed, open an issue. Accuracy matters more than appearing compliant.

1. What FIPS 140-3 Actually Requires

FIPS 140-3 (Federal Information Processing Standard Publication 140-3) is the US government standard for cryptographic module validation. It replaced FIPS 140-2 and aligns with ISO/IEC 19790. It specifies requirements for the design and implementation of a cryptographic module — the hardware, software, or firmware that performs approved cryptographic operations.

Understanding what FIPS actually requires (versus what people assume it requires) is the first step toward an honest compliance assessment.

Cryptographic Module Validation

The module itself must be tested and certified by a NIST-accredited Cryptographic and Security Testing (CST) laboratory. It is not enough to use approved algorithms — the implementation must go through the Cryptographic Module Validation Program (CMVP) process and receive a certificate.

// "Uses AES-256" ≠ FIPS validated // "CMVP certificate #4711" = FIPS validated

Approved Algorithms

FIPS-approved algorithms include: AES-128/192/256, SHA-2 (SHA-256, SHA-384, SHA-512), SHA-3, RSA 2048+, ECDSA P-256/P-384/P-521, HMAC-SHA-2, and approved DRBGs. Deprecated or prohibited: MD5, SHA-1 for signatures, DES, 3DES (after 2023), RC4, RSA below 2048 bits.

// ChaCha20-Poly1305: NOT approved (yet) // AES-256-GCM: approved // ED25519: not approved for FIPS

Security Levels 1–4

Level 1: basic security requirements, software-only implementations. Level 2: adds tamper-evident mechanisms. Level 3: adds tamper-resistance and identity-based authentication. Level 4: complete physical protection envelope. Most software implementations target Level 1 or 2.

// Linux kernel crypto: Level 1 // Hardware HSM: Level 3 or 4 // Most cloud deployments need: Level 1

The CMVP Process

The vendor submits the module to a CST lab. Testing takes 12–24 months and costs $500K–$1M+. The certificate covers a specific version of the module — any significant code change requires revalidation. NIST maintains the active validated modules list (CSRC).

// Red Hat pays for RHEL FIPS validation // OpenZFS has not gone through CMVP // The kernel crypto API (on RHEL) has
FIPS validation is about the cryptographic module, not the entire OS. The Linux kernel's crypto API can be FIPS-validated — and it is, for RHEL 9 and Ubuntu FIPS builds. OpenZFS's encryption uses the kernel's crypto API. WireGuard uses ChaCha20-Poly1305, which is not a FIPS-approved algorithm. These distinctions matter enormously. An auditor asking "is this FIPS compliant?" needs three separate answers: is the kernel crypto API validated, is the application using validated modules, and is the algorithm FIPS-approved. All three can be true independently and still fail the overall assessment if any one is false.

2. The kldload Crypto Stack — What’s Where

The kldload stack has multiple cryptographic layers. Each one needs to be evaluated independently. This section goes component by component.

Kernel Crypto (Linux Kernel Crypto API)

STATUS: FIPS-validated modules available

The Linux kernel's crypto API is the foundation everything else rests on. On RHEL 9 (and CentOS Stream 9 in FIPS mode), Red Hat maintains FIPS-validated kernel crypto modules through the CMVP. The validation covers the in-kernel implementation of AES-GCM, AES-CBC, SHA-256, SHA-512, RSA, ECDSA, and the approved DRBGs.

kldload on CentOS Stream 9 or RHEL 9 can use these validated modules. The path:

# Install crypto-policies
dnf install -y crypto-policies crypto-policies-scripts

# Enable FIPS system-wide
update-crypto-policies --set FIPS

# Enable FIPS kernel mode (requires reboot)
grubby --update-kernel=ALL --args="fips=1"
reboot

# Verify after reboot
cat /proc/sys/crypto/fips_enabled   # should print 1
sysctl crypto.fips_enabled          # should print crypto.fips_enabled = 1

After this, the kernel enforces FIPS-only algorithms system-wide. Non-FIPS algorithms are unavailable at the kernel level — applications cannot use them even if they try.

OpenZFS Encryption

STATUS: FIPS-approved algorithm, not a validated module

OpenZFS native encryption uses AES-256-GCM via the Linux kernel's crypto API. AES-256-GCM is a FIPS-approved algorithm. But — and this matters for auditors — OpenZFS itself is not a FIPS-validated cryptographic module. The implementation has not gone through CMVP.

What this means in practice: OpenZFS encryption uses the right algorithm via a validated backend (the kernel crypto API on RHEL), but the OpenZFS code that calls that backend has not been independently tested by a CST lab. For strict FIPS compliance where the data-at-rest encryption must be a validated module, this is a gap.

Mitigation: LUKS underneath ZFS. LUKS (Linux Unified Key Setup) on RHEL 9 is FIPS-validated. Placing LUKS on the block device and running the ZFS pool on top of LUKS gives you a compliant encryption layer. ZFS still provides all of its features — snapshots, compression, send/receive replication — but encryption happens at the block level, not per-dataset.

# FIPS-compliant LUKS + ZFS layout
# Block device: /dev/sda
cryptsetup luksFormat --cipher aes-xts-plain64 \
  --key-size 512 --hash sha256 /dev/sda

cryptsetup luksOpen /dev/sda zpool-crypt

zpool create tank /dev/mapper/zpool-crypt

# ZFS sees a plain block device and provides all ZFS features.
# LUKS provides the FIPS-validated encryption layer.
# No per-dataset ZFS encryption keys in this configuration.
This is the biggest gap in the stack for strict FIPS compliance. OpenZFS uses AES-256-GCM, which is a FIPS-approved algorithm. But "uses an approved algorithm" is not the same as "is a validated module." FIPS requires the implementation to be tested by an accredited lab. OpenZFS has not gone through that process, and it is unlikely to in the near term — CMVP validation is expensive and requires ongoing maintenance per version. For environments that require strict FIPS validation for data at rest, the compliant path is LUKS on the block device with ZFS on top. You lose per-dataset encryption key granularity but gain the compliance checkbox. For most regulated environments, this is the right tradeoff.

WireGuard

STATUS: ChaCha20-Poly1305 is NOT a FIPS-approved algorithm

This is the most significant gap for FIPS deployments. WireGuard uses ChaCha20-Poly1305 as its only encryption algorithm. ChaCha20 is considered cryptographically sound by the community — it is what Google uses for HTTPS on mobile, and it is specified in IETF RFC 8439. NIST has not approved it for FIPS use. Full stop.

Enabling FIPS mode on RHEL (fips=1) disables ChaCha20 at the kernel level. WireGuard stops working on a FIPS-mode system because its only algorithm becomes unavailable.

Mitigation: IPsec with IKEv2. IPsec using AES-256-GCM + SHA-384 + ECDH P-384 is fully FIPS-compliant. strongSwan and Libreswan both have FIPS modes. The backplane architecture — management plane, data plane, monitoring plane, storage plane — works identically with IPsec instead of WireGuard. Only the transport layer changes.

# strongSwan FIPS-compliant IKEv2 configuration
# /etc/strongswan.d/charon.conf
charon {
  # Force FIPS-approved algorithms only
  proposals = aes256gcm16-sha384-ecp384
  esp_proposals = aes256gcm16-sha384-ecp384
}

# /etc/ipsec.conf
conn backplane-mgmt
  keyexchange=ikev2
  ike=aes256gcm16-sha384-ecp384!
  esp=aes256gcm16-sha384-ecp384!
  left=%any
  leftcert=node-a-cert.pem
  right=192.0.2.1
  rightcert=node-b-cert.pem
  auto=start

The exclamation mark suffix in strongSwan configuration means "only this algorithm, no fallback." Without it, IKE negotiation may fall back to non-FIPS algorithms.

This is where the "WireGuard for everything" architecture hits a wall for classified environments. ChaCha20 is arguably as secure as AES — the cryptography is sound. But NIST has not blessed it, and FIPS compliance is about NIST approval, not theoretical security strength. The FIPS-compliant alternative is IPsec with IKEv2 using AES-256-GCM, SHA-384, and ECDH P-384. The backplane architecture works identically — same concept of isolated encrypted planes, same nftables zone policies, same service binding patterns. The tunnel transport is different. IPsec is more operationally complex than WireGuard (IKE negotiation, certificate management, more moving parts), but it is the FIPS-compliant path. Plan for IPsec before enabling FIPS mode. WireGuard will stop functioning the moment fips=1 activates.

TLS (OpenSSL, step-ca)

STATUS: OpenSSL FIPS provider available; Go-based tools require FIPS builds

OpenSSL 3.x ships a FIPS provider that implements a CMVP-validated cryptographic module. RHEL 9 includes a FIPS-validated OpenSSL. When FIPS mode is active, OpenSSL automatically loads the FIPS provider and restricts itself to approved algorithms.

# Verify OpenSSL FIPS provider is active
openssl list -providers
# Should show: fips (active)

# Verify FIPS-only operation
openssl speed -evp md5
# Should fail: md5 not allowed in FIPS mode

openssl speed -evp aes-256-gcm
# Should succeed

step-ca (used for internal PKI) is written in Go. Go's standard crypto library is not FIPS-validated by default. For strict FIPS environments, use a FIPS-validated Go build (Red Hat ships one for RHEL) or replace step-ca with an OpenSSL-based CA such as OpenCA or Dogtag PKI, which RHEL includes.

# On RHEL, use the system Go which is FIPS-aware
dnf install golang

# The RHEL golang package links against the system OpenSSL
# which is FIPS-validated. Applications built with it
# inherit FIPS compliance when fips=1 is set.

SSH (OpenSSH)

STATUS: Auto-configured by FIPS crypto policy

OpenSSH on RHEL/CentOS in FIPS mode automatically disables non-FIPS algorithms. The update-crypto-policies --set FIPS command configures the system-wide crypto policy, which OpenSSH reads from /etc/crypto-policies/back-ends/openssh.config.

What FIPS mode removes from SSH:

  • chacha20-poly1305 cipher (ChaCha20 not FIPS-approved)
  • ED25519 host keys and user keys (not NIST-approved curves)
  • Diffie-Hellman group1 and group14 (deprecated key sizes)

What remains in FIPS SSH:

  • aes128-gcm, aes256-gcm, aes128-ctr, aes256-ctr ciphers
  • RSA and ECDSA (P-256, P-384, P-521) host and user keys
  • hmac-sha2-256, hmac-sha2-512 MACs
  • ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521 key exchange

Practical implication: if you have ED25519 SSH keys for users or automation, they need to be replaced with ECDSA P-256 or RSA-3072+ keys before enabling FIPS mode.

eBPF

STATUS: No FIPS implications — eBPF is not a cryptographic component

eBPF programs do not perform cryptographic operations in the kldload stack. They handle observability (packet counts, latency histograms, syscall tracing) and security monitoring (detecting anomalous behavior). None of these operations fall under FIPS's scope, which covers cryptographic modules specifically. eBPF is FIPS-neutral.


3. Enabling FIPS Mode on kldload (CentOS/RHEL Path)

Enabling FIPS mode on CentOS Stream 9 or RHEL 9 is a supported configuration. The steps are straightforward. What is not straightforward is the application audit that needs to happen first.

Pre-flight checklist

  • Identify all applications using non-FIPS algorithms: ChaCha20, ED25519, MD5, SHA-1 for signing
  • Replace WireGuard with IPsec (do this first — WireGuard will stop working)
  • Regenerate any ED25519 SSH keys as ECDSA P-384 or RSA-3072
  • Audit Go applications (step-ca, etc.) — use FIPS-aware Go builds or replace
  • Verify LUKS is in place if using ZFS encryption for FIPS compliance

Enable FIPS mode

# Step 1: Install crypto-policies
dnf install -y crypto-policies crypto-policies-scripts

# Step 2: Set FIPS crypto policy
update-crypto-policies --set FIPS

# Step 3: Enable FIPS kernel parameter
# (this also triggers kernel-level FIPS enforcement after reboot)
fips-mode-setup --enable

# Step 4: Reboot
reboot

# Step 5: Verify FIPS mode is active
fips-mode-setup --check
cat /proc/sys/crypto/fips_enabled   # prints: 1

# Step 6: Verify OpenSSL FIPS provider
openssl list -providers | grep -A2 fips

# Step 7: Verify SSH is using FIPS algorithms
ssh -Q cipher | grep -v chacha     # chacha20 should not appear
ssh -Q key | grep -v ed25519       # ed25519 should not appear

# Step 8: Confirm audit subsystem
systemctl status auditd
auditctl -l | head -20

What changes after enabling FIPS mode

ComponentBefore FIPSAfter FIPS
SSH ciphersAES + ChaCha20AES only
SSH keysRSA, ECDSA, ED25519RSA 3072+, ECDSA P-256/384
TLSAll ciphersuitesFIPS-approved only
WireGuardWorkingBroken (ChaCha20 unavailable)
OpenSSLFull algorithm setFIPS provider active, non-FIPS disabled
kernel cryptoFull algorithm setFIPS-only algorithms
Go stdlib cryptoFull algorithm setMust use RHEL FIPS Go build
Enabling FIPS mode on CentOS/RHEL is straightforward — it is a supported, tested configuration that Red Hat ships and maintains. The kernel enforces FIPS-only algorithms system-wide after fips=1. The challenge is the application audit before you flip the switch. WireGuard is the largest casualty. Any automation scripts that use ED25519 SSH keys will break. Any Go services built against the upstream Go crypto library (not the RHEL FIPS-aware build) will need to be rebuilt or replaced. Do the application audit first. The actual FIPS mode enablement is four commands and a reboot. The preparation to get there cleanly is the real work.

4. FIPS-Compliant Network Fabric (IPsec Replacing WireGuard)

When FIPS mode is enabled, WireGuard stops working. The replacement is IPsec with IKEv2 using FIPS-approved algorithms. The backplane architecture — isolated encrypted planes for management, data, monitoring, and storage — is transport-agnostic. The concepts are identical; only the tunnel implementation changes.

Algorithm selection for FIPS IPsec

The FIPS-compliant IKEv2 algorithm suite:

# IKE Phase 1 (key negotiation)
ike=aes256gcm16-sha384-ecp384!
# Algorithm breakdown:
#   aes256gcm16  = AES-256-GCM with 128-bit ICV (FIPS approved)
#   sha384       = SHA-384 (FIPS approved)
#   ecp384       = ECDH P-384 (FIPS approved)
#   !            = strict (no fallback to non-FIPS)

# IKE Phase 2 (ESP, the actual data encryption)
esp=aes256gcm16-sha384-ecp384!
# Same algorithms for the data channel

strongSwan FIPS configuration

# Install strongSwan
dnf install -y strongswan strongswan-libipsec

# /etc/strongswan.conf
charon {
  load_modular = yes
  plugins {
    include strongswan.d/charon/*.conf
  }
  # Enable FIPS mode in strongSwan
  crypto_test {
    required = yes
    on_add = yes
  }
}

# /etc/ipsec.conf — management plane (equivalent to wg1)
conn mgmt-plane
  keyexchange=ikev2
  ike=aes256gcm16-sha384-ecp384!
  esp=aes256gcm16-sha384-ecp384!
  left=192.0.2.1        # this node's public IP
  leftsubnet=10.201.0.0/24  # management plane subnet
  leftcert=node-a.pem
  leftid=node-a.mgmt.internal
  right=192.0.2.2       # peer's public IP
  rightsubnet=10.201.0.0/24
  rightcert=node-b.pem
  rightid=node-b.mgmt.internal
  auto=start

# Repeat conn blocks for:
#   data-plane    (10.200.0.0/24, equivalent to wg0)
#   monitor-plane (10.202.0.0/24, equivalent to wg2)
#   storage-plane (10.203.0.0/24, equivalent to wg3)

nftables for IPsec (same zone isolation concept)

# nftables — same architectural approach as WireGuard backplane
# Physical interface: allow only IKE (UDP 500) and ESP (protocol 50)
table inet backplane {
  chain input {
    type filter hook input priority 0; policy drop;

    # IKEv2 key exchange
    iifname "eth0" udp dport 500 accept
    iifname "eth0" udp dport 4500 accept   # NAT traversal

    # ESP (encrypted IPsec data, protocol 50)
    iifname "eth0" meta l4proto esp accept

    # Established IPsec traffic decrypted by kernel
    # arrives on the xfrm policy, not a WireGuard interface.
    # Match by source subnet instead of interface.
    ip saddr 10.201.0.0/24 accept    # mgmt plane
    ip saddr 10.202.0.0/24 accept    # monitor plane
    ip saddr 10.203.0.0/24 accept    # storage plane

    ct state established,related accept
    loopback accept
    drop
  }
}

Performance comparison

MetricWireGuardIPsec (IKEv2 + AES-GCM)
Throughput (10G NIC)~9 Gbps~6–8 Gbps (AES-NI accelerated)
Latency overhead~0.1ms~0.3ms
Setup complexityLow (one config file)High (IKE, certificates, policies)
FIPS compliantNoYes
Hardware accelerationAES-NI (via kernel)AES-NI (via kernel, same path)
Certificate managementNot requiredRequired (X.509)
RekeyingAutomaticAutomatic (IKE handles it)
IPsec with IKEv2 and modern algorithms is not the operational nightmare it was in the 2000s. The old IPsec pain came from IKEv1, aggressive mode, pre-shared keys, and vendor interoperability problems. IKEv2 with certificates is clean and well-understood. strongSwan documentation is excellent. The FIPS algorithm suite is well-defined. You lose WireGuard's simplicity (one config file, minimal moving parts) and accept a small performance penalty and significantly higher operational complexity (certificate lifecycle management, IKE negotiation debugging). The backplane architecture is transport-agnostic. The services do not care whether the encrypted tunnel is WireGuard or IPsec. The nftables zone isolation, the service binding patterns, the four-plane isolation model — all identical. Only the tunnel implementation changes.

5. Data at Rest — FIPS-Compliant Encryption

Three options exist for data-at-rest encryption in a FIPS-compliant kldload deployment. Choose based on your compliance posture and operational requirements.

Option 1: LUKS + ZFS (fully FIPS-compliant)

LUKS on RHEL 9 uses dm-crypt backed by the kernel's FIPS-validated crypto API. This is the compliant path. ZFS runs on top of the LUKS volume and provides all of its features: snapshots, compression, send/receive replication, checksumming. The cost is that encryption is at the block level — all datasets share one key, and per-dataset key rotation requires re-encrypting the entire LUKS volume.

# FIPS LUKS configuration
# Use AES-XTS-plain64 (FIPS-approved, designed for disk encryption)
cryptsetup luksFormat \
  --cipher aes-xts-plain64 \
  --key-size 512 \         # 512 bits for XTS = 256-bit effective key
  --hash sha256 \          # FIPS-approved hash for PBKDF2
  --pbkdf pbkdf2 \         # FIPS-approved KDF
  --iter-time 5000 \
  /dev/sda

cryptsetup luksOpen /dev/sda data-encrypted

# Create ZFS pool on the LUKS device
zpool create -o ashift=12 \
  -O compression=zstd \
  -O acltype=posixacl \
  -O xattr=sa \
  tank /dev/mapper/data-encrypted

# ZFS datasets inherit all ZFS features
zfs create tank/data
zfs create tank/home
zfs snapshot tank/data@daily-$(date +%Y%m%d)

Note: zstd compression is FIPS-neutral (not a cryptographic algorithm, just compression). ZFS checksumming (SHA-256 is the default for datasets using encryption) is also FIPS-neutral in this context — it provides integrity, not confidentiality, and runs via the kernel crypto API.

Option 2: ZFS native encryption (defense in depth, not CMVP-validated)

ZFS native encryption uses AES-256-GCM via the kernel crypto API. The algorithm is FIPS-approved. The module (OpenZFS) is not CMVP-validated. Per-dataset encryption keys are possible. Key rotation per dataset is possible. This is the right choice if you need dataset-level granularity and can document the gap in your SSP as an accepted risk or compensating control.

# ZFS native encryption (FIPS-approved algorithm, not FIPS-validated module)
zpool create -o ashift=12 tank /dev/sda

zfs create -o encryption=aes-256-gcm \
  -o keylocation=prompt \
  -o keyformat=passphrase \
  tank/sensitive

# Per-dataset keys provide granular access control
zfs create -o encryption=aes-256-gcm \
  -o keylocation=file:///etc/zfs/keys/finance.key \
  -o keyformat=raw \
  tank/finance

Option 3: Belt and suspenders (LUKS + ZFS encryption)

Deploy both: LUKS on the block device for the compliance checkbox, ZFS native encryption on top for per-dataset key granularity. The auditor is satisfied by LUKS. The engineer is satisfied by per-dataset ZFS keys. Two separate encryption layers, two separate keys. Breaking one requires breaking both.

# Full belt-and-suspenders setup
cryptsetup luksFormat --cipher aes-xts-plain64 --key-size 512 \
  --hash sha256 --pbkdf pbkdf2 /dev/sda

cryptsetup luksOpen /dev/sda data-encrypted

zpool create tank /dev/mapper/data-encrypted

# ZFS encryption on top (per-dataset keys)
zfs create -o encryption=aes-256-gcm \
  -o keylocation=prompt -o keyformat=passphrase \
  tank/classified
The LUKS + ZFS approach is the pragmatic answer for FIPS. LUKS encrypts the block device with FIPS-validated crypto. ZFS sits on top and provides all of its features. You lose per-dataset encryption keys (all data shares the LUKS key), but you gain the FIPS compliance checkbox. For most environments, this is the right tradeoff: LUKS satisfies the auditor, ZFS satisfies the engineer. The belt-and-suspenders option (LUKS + ZFS encryption) gives you both, at the cost of two key management systems to maintain. If your compliance requirement is strict FIPS and your auditor understands the difference between "uses a FIPS-approved algorithm via a FIPS-validated backend" and "is itself a FIPS-validated module," you may be able to document the OpenZFS gap as a compensating control. That negotiation is between you and your ATO authority. This page gives you the accurate technical picture to have that conversation.

6. Classification Levels and What They Require

NIST 800-171 / CMMC (Controlled Unclassified Information)

NIST 800-171 governs Controlled Unclassified Information (CUI) for defense contractors. CMMC (Cybersecurity Maturity Model Certification) builds on it. Both require FIPS 140-2/3 for cryptography protecting CUI.

800-171 Requirementkldload CoverageStatus
FIPS cryptography (3.13.10)FIPS mode + LUKS + IPsecReady with config
Access controls (3.1.x)RBAC, nftables, Vault policiesReady
Audit & accountability (3.3.x)Vault audit, journald, auditdReady
Data integrity (3.13.8)ZFS end-to-end checksumsExceeds requirement
Incident response (3.6.x)Process — not a platform featureProcess required
Media sanitization (3.8.x)Crypto erase (LUKS key destroy)Ready

Assessment: kldload can meet NIST 800-171 with FIPS mode enabled, IPsec replacing WireGuard, LUKS for data at rest, and Vault for secrets management. The WireGuard-to-IPsec migration and LUKS deployment are the two changes required. Everything else is configuration.

FedRAMP (Cloud Deployments for Federal Agencies)

FedRAMP is the federal authorization framework for cloud services. It requires FIPS 140-2/3 for all cryptographic operations, continuous monitoring with evidence, and vulnerability scanning.

kldload can achieve FedRAMP compliance with:

  • FIPS mode (kernel crypto, OpenSSL FIPS provider)
  • IPsec fabric for encrypted transit
  • LUKS for data at rest
  • Prometheus + eBPF for continuous monitoring
  • OpenSCAP for automated compliance scanning and evidence generation
  • Vault for secrets management with full audit log

The gap is documentation, not technology: FedRAMP requires a System Security Plan (SSP), Plan of Action and Milestones (POA&M), and Security Assessment Report (SAR). These are process deliverables, not software features.

DoD IL4/IL5 (Impact Level 4/5)

DoD Impact Levels 4 and 5 cover sensitive government information and national security systems respectively. They add stricter requirements on top of FedRAMP: DISA STIG compliance, specific approved baselines, and more rigorous access controls.

Assessment: The kldload backplane architecture with IPsec and nftables zone isolation meets the network isolation intent of IL4/IL5. The platform architecture — encrypted transits, firewalled perimeters, checksummed storage, full audit logging, identity-based access via Vault — maps cleanly to the IL4/IL5 control families.

The gap: DISA STIGs must be applied, and a STIG for OpenZFS does not exist. See Section 8 for how to handle this.

Classified (Secret / Top Secret)

Classified environments require an Authority to Operate (ATO) from the accreditation authority. The technology stack is one input. The classification requirements go well beyond algorithm selection.

Where kldload has genuine strengths for classified deployments:

  • Air-gapped installation: darksites contain the complete package mirror — no internet required
  • No telemetry: kldload phones home to nothing
  • No external dependencies at runtime: the installed system has no cloud callbacks, no license servers, no update channels
  • ZFS integrity: end-to-end checksums detect any modification to stored data
  • Reproducible builds: the ISO is built from source in a container; the build process is auditable

Classified environments have requirements outside the technology scope of any installer:

  • Cross-domain guards (CDS) for data moving between classification levels — not in scope
  • TEMPEST shielding — hardware concern, not software
  • Personnel security clearances — administrative concern
  • Physical security controls — facilities concern
  • Formal ATO process through the appropriate accreditation body
Classified environments are less about specific FIPS algorithms and more about the overall system approval process. The technology stack is one input into the ATO. The documentation, procedures, physical security, personnel clearances, and accreditation body approval are the rest. kldload's offline install capability and ZFS integrity features are genuine technical strengths in this context. The WireGuard gap requires IPsec substitution as covered above. The air-gapped deployment story — complete package mirror in the ISO, no internet required during or after install — is a significant advantage compared to any installer that reaches out to the internet for packages or updates.

7. DISA STIGs and RHEL 9 Compliance

DISA STIGs (Security Technical Implementation Guides) are DoD-mandated security configuration baselines for specific products. Applying the relevant STIGs is required for IL4+ environments and strongly recommended for any regulated deployment.

Available STIGs

ProductSTIG StatusNotes
RHEL 9Exists, well-maintainedDISA STIG for RHEL 9 is comprehensive and regularly updated
CentOS Stream 9PartialRHEL 9 STIG applies with minor differences; not officially supported by DISA
OpenZFSDoes not existNo DISA STIG for OpenZFS. Must document as compensating controls in SSP.
WireGuardDoes not existMoot if replaced with IPsec (strongSwan has guidance documents)
strongSwanNSA guidance existsNo formal DISA STIG, but NSA IPsec configuration guidance covers it
VaultGuidance documents existNo formal STIG; CIS benchmark for Vault covers most requirements

Applying the RHEL 9 STIG with OpenSCAP

# Install OpenSCAP
dnf install -y openscap-scanner scap-security-guide

# List available RHEL 9 STIG profiles
oscap info /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml | grep stig

# Run a STIG compliance scan
oscap xccdf eval \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --results /tmp/stig-results.xml \
  --report /tmp/stig-report.html \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

# Apply STIG remediations (Ansible playbook)
oscap xccdf generate fix \
  --profile xccdf_org.ssgproject.content_profile_stig \
  --fix-type ansible \
  --output stig-remediation.yml \
  /usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml

ansible-playbook -i localhost, stig-remediation.yml

Handling the OpenZFS STIG gap

OpenZFS has no DISA STIG. The approach for auditors and SSPs is to document ZFS security properties as compensating controls:

  • Data integrity: ZFS uses SHA-256 (or SHA-512 with HMAC) end-to-end checksums on all data. Corruption or tampering is detected and logged. This exceeds what POSIX filesystems provide.
  • Encryption: AES-256-GCM at the dataset level (or LUKS at the block level for FIPS). See Section 5.
  • Access controls: ZFS datasets support POSIX ACLs and NFS ACLs; dataset permissions can be delegated granularly (zfs allow).
  • Immutability: ZFS snapshots cannot be modified after creation. This provides forensic integrity for audit data stored in ZFS datasets.
  • No SUID in datasets: individual datasets can be mounted nosuid,noexec to reduce privilege escalation risk.
The RHEL 9 STIG is one of the most comprehensive OS hardening baselines available. Applying it to a kldload CentOS or RHEL install covers 90%+ of OS-level hardening requirements. The gap is ZFS-specific hardening — no STIG exists because DISA doesn't validate components that don't have a formal DoD use case documented yet. The workaround is to document ZFS security properties in the SSP as compensating controls. An auditor who understands ZFS will accept this. An auditor who doesn't understand ZFS needs a brief technical education before the SSP review. The properties of ZFS — end-to-end checksums, copy-on-write, immutable snapshots, AES-256-GCM encryption — are strong. They are just not packaged in the specific XCCDF format that a STIG requires.

8. Air-Gapped Deployment — Where kldload Excels

kldload was designed from the start for offline installation. The darksites — complete APT and RPM package mirrors baked into the ISO — mean the installer never reaches the internet during deployment. This is a significant advantage in classified and high-security environments where internet connectivity is restricted or prohibited.

What "offline" means for kldload

  • All packages for all supported distros are in the ISO image
  • No DNS lookups to external resolvers during install
  • No certificate validation against internet CAs during install
  • No telemetry, no phone-home, no license activation
  • The installed system has no configured external package mirrors by default

Air-gapped update procedure

For air-gapped environments, the update workflow is:

  1. Build a new ISO on an internet-connected build system: ./deploy.sh build
  2. Transfer the ISO to the air-gapped network via approved media (USB, DVD, network diode)
  3. Boot the target system or a staging system from the new ISO
  4. Run the installer (or mount the darksite and update packages manually)
  5. For rolling updates without reinstall: export the darksite from the ISO and configure it as a local package mirror
# Extract darksite from ISO for use as local mirror (air-gapped update)
mkdir /mnt/iso
mount -o loop kldload-1.0.2.iso /mnt/iso

# RPM darksite is at /mnt/iso/darksite/
# Copy to local mirror server
rsync -av /mnt/iso/darksite/ /srv/mirrors/kldload/

# Configure nodes to use local mirror
cat > /etc/yum.repos.d/kldload-airgap.repo <<EOF
[kldload-airgap]
name=kldload Air-Gapped Mirror
baseurl=http://mirror.internal/kldload/centos/
gpgcheck=0
enabled=1
EOF

ZFS replication for air-gapped environments

For data movement in air-gapped networks where network ZFS replication is not possible, zfs send to portable encrypted media provides a secure transfer path:

# Send snapshot to encrypted portable media
# (media is LUKS-encrypted before use)
zfs snapshot tank/classified@transfer-$(date +%Y%m%d)

# Pipe through encryption and write to media
zfs send -R tank/classified@transfer-$(date +%Y%m%d) | \
  gpg --symmetric --cipher-algo AES256 \
  --compress-algo none > /media/usb/transfer.zfs.gpg

# On receiving system (after physically transporting the media)
gpg --decrypt /media/usb/transfer.zfs.gpg | \
  zfs receive tank/classified
Air-gapped deployment is where kldload genuinely has an advantage over every other Linux deployment tool available. Most installers require internet access for packages. Most cloud-image pipelines assume network connectivity. kldload's darksites — complete APT and RPM mirrors embedded in the ISO — mean the installer has everything it needs on the boot media. For classified environments where internet connectivity is not available or not permitted, this is not a nice-to-have. It is a requirement. Building a new ISO requires an internet-connected build machine, but the deployed system and its installer are fully self-contained. The build machine can be in a different security domain from the deployment target. The ISO is the transfer artifact.

9. Compliance Gap Analysis — Honest Summary

Two genuine gaps. Everything else is configuration.

Requirement kldload Status Gap Mitigation
FIPS kernel crypto Ready None Enable FIPS crypto policy on RHEL/CentOS
FIPS data at rest Partial OpenZFS not CMVP-validated LUKS underneath ZFS (FIPS-validated on RHEL)
FIPS data in transit Gap WireGuard uses ChaCha20 (not FIPS-approved) Replace with IPsec IKEv2 (AES-256-GCM + SHA-384 + P-384)
FIPS TLS Ready None (OpenSSL FIPS provider) Enable FIPS crypto policy; use RHEL Go build for Go services
FIPS SSH Ready None Auto-configured by FIPS crypto policy
Audit logging Ready None Vault audit + auditd + journald; configure retention per policy
Data integrity Exceeds requirement None ZFS end-to-end checksums detect any modification; document in SSP
Access control Ready None RBAC + nftables + Vault policies; configure per environment
Air-gapped install Exceeds requirement None Darksite ISO is self-contained; no internet required
Continuous monitoring Ready None Prometheus + eBPF; add OpenSCAP for compliance artifacts
STIG compliance Partial RHEL STIG exists; no OpenZFS STIG Apply RHEL STIG via OpenSCAP; document ZFS controls as compensating controls
Vulnerability management Gap No built-in vulnerability scanner Add OpenSCAP (dnf install openscap-scanner scap-security-guide) or Nessus
Media sanitization Ready None Crypto erase: destroy LUKS header (cryptsetup erase) renders data unrecoverable
Key management Ready None Vault for secrets; LUKS headers for disk keys; integrate with HSM for IL5+
Two real gaps: WireGuard (ChaCha20 is not FIPS-approved) and ZFS native encryption (not CMVP-validated as a module). Both have clear mitigations: IPsec for WireGuard, LUKS for ZFS. Everything else is either already ready or requires enabling a configuration that exists and is supported. The platform architecture — encrypted transport, firewalled perimeters, checksummed storage, audit logging, identity-based access — is exactly what compliance frameworks ask for. The gaps are in specific cryptographic module validation, not in architectural design. A system with FIPS mode enabled, IPsec fabric, and LUKS storage is a defensible FIPS deployment on this stack. The residual risk is OpenZFS's lack of CMVP validation (mitigated by LUKS) and the operational complexity of IPsec versus WireGuard.

10. Roadmap — Closing the Gaps

OpenZFS FIPS validation

OpenZFS would need to go through the CMVP process to become a FIPS-validated cryptographic module. This is technically possible but organizationally expensive:

  • Budget: $500K–$1M for initial validation (CST lab fees, documentation, testing)
  • Timeline: 12–24 months from submission to certificate
  • Maintenance: revalidation required for each significant version that touches crypto code
  • Ongoing cost: $100K–$300K per revalidation cycle

This is not something an open source project does casually. Red Hat funds RHEL's FIPS validation because enterprise customers with compliance requirements pay for RHEL subscriptions. The realistic path for FIPS + OpenZFS is: use LUKS as the compliant layer, document OpenZFS's use of kernel validated crypto in the SSP, and accept the CMVP gap as a risk with LUKS as the mitigating control.

If your organization needs FIPS-validated OpenZFS: the path is defined. Sponsor the CMVP validation. The OpenZFS project would likely cooperate — the technical groundwork (AES-256-GCM via kernel crypto API) is already correct. What is needed is the organizational and financial commitment to run the process.

WireGuard FIPS

Two scenarios where WireGuard could become FIPS-usable:

  1. NIST approves ChaCha20: NIST has been considering ChaCha20 for inclusion in SP 800-175B and related guidance. If approved, WireGuard becomes FIPS-compliant with no changes. This is not imminent but is not impossible given ChaCha20's widespread adoption and strong security properties.
  2. WireGuard variant with AES-GCM: The WireGuard protocol is deliberately simple and fixed-algorithm. A variant using AES-256-GCM exists in theory but not in production-quality implementation. This would be a significant development effort and would no longer be "WireGuard" in any meaningful sense.

Planned: kldload FIPS profile

A planned future addition is a kldload FIPS install profile that auto-configures the compliant stack:

  • strongSwan IPsec instead of WireGuard in the network configuration
  • LUKS + ZFS layout instead of ZFS-only
  • FIPS crypto policy enabled from first boot
  • ECDSA P-384 host keys instead of ED25519
  • OpenSCAP STIG profile applied post-install
  • Vault configured with audit log from first boot

This is the "do the right thing by default for FIPS environments" profile. It does not eliminate the gaps — OpenZFS is still not CMVP-validated, and the LUKS layer is still the compliance mechanism — but it makes the compliant configuration the default for users who select this profile.

FIPS validation is expensive and requires organizational commitment. It is not something an open source project does without funding. Red Hat does it for RHEL because enterprise customers pay for it. The realistic near-term path for the kldload stack is the mitigations described in this page: LUKS for data at rest, IPsec for data in transit, FIPS mode for the kernel and system crypto. These are deployable today. The gap — OpenZFS's lack of CMVP validation — is accurately documented and mitigated. An organization that genuinely needs FIPS-validated OpenZFS and can fund the CMVP process should reach out. The technical foundation is there. The process and funding are the missing pieces.

11. Practical Recommendations by Environment

Homelab / Small Business

FIPS is not required. Use the full kldload stack as-is. WireGuard backplane, ZFS native encryption, step-ca for internal PKI. The cryptography is sound even if not FIPS-validated. Compliance frameworks don't apply at this scale.

// Use everything. No restrictions. // ZFS encryption + WireGuard = excellent security posture

Healthcare (HIPAA)

FIPS encryption is required for PHI systems. Enable FIPS mode on PHI hosts. Use LUKS for data at rest. Use IPsec or TLS (FIPS mode) for PHI data in transit. WireGuard is acceptable for non-PHI management traffic if PHI never traverses it.

// PHI hosts: FIPS mode + LUKS + IPsec // Admin hosts: WireGuard fine for mgmt traffic // Segment PHI from non-PHI at the network level

Financial (PCI DSS)

FIPS mode is strongly recommended for cardholder data systems. PCI DSS v4 requires "strong cryptography" — AES-256 and SHA-256+ qualify. Enable FIPS crypto policy. WireGuard may be acceptable with documented risk acceptance; IPsec is the conservative choice.

// Enable FIPS crypto policy on all CDE hosts // LUKS for cardholder data storage // Document WireGuard risk or replace with IPsec

Government (NIST 800-171 / CUI)

FIPS required. Replace WireGuard with IPsec on all systems handling CUI. LUKS for data at rest. Vault with full audit log. Apply RHEL STIG via OpenSCAP. Document OpenZFS compensating controls in SSP.

// IPsec everywhere CUI flows // LUKS + ZFS on all CUI storage // STIG + Vault audit = compliance evidence

DoD (IL4+)

All of the above plus DISA STIG application, continuous monitoring artifacts (OpenSCAP scheduled scans), formal POA&M for OpenZFS gap, and coordination with your Authorizing Official. The kldload platform covers the technology; the AO covers the authorization.

// OpenSCAP scheduled: cron daily // POA&M: document OpenZFS CMVP gap + LUKS mitigation // ATO: platform tech is sound, authorization is human process

Classified (Secret / TS)

All of IL4+ plus air-gapped deployment (kldload's strength), formal ATO through the accreditation body, and the full documentation suite. kldload's offline ISO is designed for this. No internet dependency during install or operation. ZFS replication via encrypted sneakernet for inter-enclave data movement.

// kldload strength: offline ISO, no callbacks // ZFS send | gpg | media = classified sneakernet // ATO: technology is the easy part

Related pages