Skip to content

Add Support for Customizable LUKS Encryption Parameters #1062

@clemlesne

Description

@clemlesne

TL;DR

Currently, the Hetzner CSI driver’s LUKS encryption implementation only accepts an encryption-passphrase parameter and uses hard-coded encryption settings. This feature request proposes adding support for customizable LUKS parameters to allow users to strengthen their encryption configuration based on their security requirements.

Current Behavior

As implemented in PR #279, the encryption feature only supports:

apiVersion: v1
kind: Secret
metadata:
  name: encryption-secret
  namespace: kube-system
stringData:
  encryption-passphrase: "passphrase"

The LUKS parameters are hard-coded with defaults that, while secure, cannot be modified by users who need stronger encryption settings or compliance with specific security standards.

Proposed Enhancement

Add support for optional LUKS configuration parameters in the encryption secret, similar to other CSI drivers (Longhorn, Ceph-CSI):

apiVersion: v1
kind: Secret
metadata:
  name: encryption-secret
  namespace: kube-system
stringData:
  encryption-passphrase: "passphrase"
  # Optional parameters (with secure defaults if not specified):
  encryption-cipher: "aes-xts-plain64"    # or "aes-gcm-random", "serpent-xts-plain64"
  encryption-hash: "sha256"               # or "sha512", "sha3-512"
  encryption-key-size: "256"              # or "512" for certain ciphers
  encryption-pbkdf: "argon2id"            # or "argon2i", "pbkdf2"
  encryption-iter-time: "5000"            # PBKDF iteration time in milliseconds
  encryption-memory: "1048576"            # Memory cost for Argon2 (in KB)
  encryption-parallel: "4"                # Parallelism factor for Argon2

Use Cases

1. Compliance Requirements

Organizations with strict compliance requirements (FIPS 140-2, BSI, Common Criteria) often need specific cipher configurations:

  • Some require AES-256-GCM for authenticated encryption
  • Others mandate SHA-512 or SHA3-512 for key derivation
  • Certain standards require specific PBKDF2 iteration counts

2. Enhanced Security

Users wanting maximum security might prefer:

  • serpent-xts-plain64 cipher (slower but considered more secure against certain attacks)
  • 512-bit keys where supported
  • argon2id over argon2i for better resistance against side-channel attacks
  • Higher memory costs for Argon2 to resist GPU/ASIC attacks

3. Performance Optimization

Different workloads might benefit from different configurations:

  • High-throughput workloads might prefer aes-xts-plain64 with hardware acceleration
  • Low-latency requirements might need tuned iteration times

Implementation Suggestions

1. Backward Compatibility

  • Keep current behavior as default (no breaking changes)
  • Only use custom parameters if explicitly provided in the secret
  • Validate parameters against cryptsetup capabilities on the node

2. Parameter Validation

// Pseudo-code for parameter validation
func validateCryptoParams(params map[string]string) error {
    allowedCiphers := []string{"aes-xts-plain64", "aes-gcm-random", "serpent-xts-plain64"}
    allowedHashes := []string{"sha256", "sha512", "sha3-256", "sha3-512"}
    allowedPBKDF := []string{"argon2i", "argon2id", "pbkdf2"}
    
    // Validate each parameter against allowed values
    if cipher, ok := params["encryption-cipher"]; ok {
        if !isValidCipher(cipher) {
            return fmt.Errorf("invalid cipher: %s", cipher)
        }
    }
    
    // Check compatibility (e.g., key size must match cipher requirements)
    // Return error if invalid combination
    return nil
}

3. cryptsetup Command Construction

Instead of hard-coded parameters, build the command dynamically:

cryptsetup luksFormat \
  --cipher ${encryption_cipher:-aes-xts-plain64} \
  --key-size ${encryption_key_size:-256} \
  --hash ${encryption_hash:-sha256} \
  --pbkdf ${encryption_pbkdf:-argon2i} \
  --pbkdf-memory ${encryption_memory:-1048576} \
  --pbkdf-parallel ${encryption_parallel:-4} \
  --iter-time ${encryption_iter_time:-5000} \
  /dev/device

Security Considerations

  1. Input Validation: All parameters must be strictly validated to prevent command injection
  2. Capability Detection: Check if the node’s cryptsetup version supports requested parameters
  3. Documentation: Clearly document security implications of different configurations
  4. Secure Defaults: Maintain current secure defaults when parameters are not specified

Alternative Approach

If full parameter customization is too complex, consider a simpler “security level” approach:

stringData:
  encryption-passphrase: "passphrase"
  encryption-level: "high"  # Options: "standard", "high", "maximum"

Where:

  • standard: Current defaults
  • high: AES-256-XTS with SHA-512 and increased iterations
  • maximum: Serpent-512-XTS with SHA3-512 and maximum Argon2 parameters

Testing Requirements

  • Unit tests for parameter validation
  • Integration tests with different cipher combinations
  • Performance benchmarks for different configurations
  • Compatibility tests across different Linux distributions and cryptsetup versions

Documentation Updates Needed

  • Update README.md with new parameters
  • Add examples for common security configurations
  • Include performance impact warnings
  • Document minimum cryptsetup version requirements for each parameter

Related Work

Benefits

  1. Flexibility: Users can choose encryption parameters based on their specific requirements
  2. Compliance: Easier to meet various regulatory and organizational security standards
  3. Future-proofing: As cryptographic recommendations evolve, users can adapt without waiting for CSI driver updates
  4. Feature Parity: Brings Hetzner CSI driver in line with other major CSI implementations

Risks and Mitigation

  • Risk: Increased complexity might lead to misconfigurations
    • Mitigation: Provide clear documentation and validation with helpful error messages
  • Risk: Some parameters might not work on all nodes
    • Mitigation: Runtime capability detection and clear error reporting

Questions for Maintainers

  1. Would you prefer full parameter customization or the simpler “security level” approach?
  2. Are there specific security standards you’d like to support?
  3. Should this be implemented as an experimental feature flag initially?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions