Skip to main content

Crate waf_state_redis

Crate waf_state_redis 

Source
Expand description

Distributed state for Light WAF over Redis.

One RedisStore (one connection pool) provides:

  • cluster-wide rate limiting — an implementation of the core’s waf_core::StateStore trait, injected with Proxy::builder(&cfg).state_store(..) without forking the core;
  • IP reputation — the ReputationStore (read) and ReputationWriter (write) traits, used by waf-threatintel;
  • a shared certificate store — SharedCertStore + DistributedLock, used by waf-tls-managed so one node issues an ACME certificate and every node serves it (the private key encrypted at rest with CertCipher, AES-256-GCM).

Behavior:

  • Atomic refill-then-consume in a single server-side Lua script, so two nodes can never both allow from the same bucket. Time comes from Redis TIME; memory is bounded by per-key TTL.
  • Fail-open at runtime by default (RedisStoreOptions::fail_open): a down rate limiter must not block legitimate traffic. An unreachable Redis at boot is always an error (RedisStore::connect pings), so the store never silently degrades to single-node.
  • NOSCRIPT recovery (EVALSHA falls back to EVAL when the script cache was flushed).
  • No worker starvation: the blocking pooled call runs inside block_in_place on a multi-threaded runtime.

Structs§

CertCipher
AES-256-GCM authenticated encryption for the stored private key. The key is derived from the operator secret via HKDF-SHA256; a fresh random 96-bit nonce is generated per encryption and prepended to the ciphertext. Storing the derived key (not the passphrase) keeps the passphrase out of memory after construction.
DecryptError
Decryption failed (wrong key, or tampered / truncated ciphertext).
RedisStore
A distributed token-bucket StateStore over Redis. The same pool also backs ReputationStore and (when a CertCipher is attached) SharedCertStore.
RedisStoreOptions
Tunables for RedisStore (wired from [enterprise] in the config file). Defaults: a pool of DEFAULT_POOL_SIZE and fail-open on runtime Redis errors (a down limiter must not block legitimate traffic).
SharedCert
A managed TLS certificate as the driver sees it: the issued chain, OUR private key, and the cert’s expiry. key_pem is the PLAINTEXT key — the type deliberately does NOT derive Serialize, so it can never be persisted in the clear by accident (the on-wire StoredBlob carries the encrypted key instead).

Enums§

ConnectError
Why constructing a RedisStore failed (boot-time only; runtime errors fail-open).
Reputation
Reputation verdict for an IP. Unknown = no opinion (also the fail-safe on any error).

Traits§

DistributedLock
A minimal distributed lock (acquire / release) for cluster-wide single-writer coordination, separate from the cert issuance lock (its own feed_lock: namespace). The threat-intel feed uses it so exactly ONE node fetches + writes the reputation snapshot per cycle (avoids N× external fetches of a possibly-metered subscription). Unlike the cert lock there is no heartbeat/extend (F4): the feed cycle is short, and if the leader dies the next cycle another node simply acquires — liveness is covered by the entries’ TTL, not by holding the lock.
ReputationStore
Read-only cluster-wide IP-reputation lookup — the enterprise injection seam a premium reputation module consumes (the analogue of StateStore, but enterprise-side).
ReputationWriter
Write side of cluster-wide IP-reputation — the seam the threat-intel feed (§6) consumes to populate the same rep:<ip> keyspace the ReputationStore reads. Deliberately a separate trait from the read: the datapath never writes, and keeping it here (next to rep_key and Reputation::as_wire) means the key + value encoding live in ONE crate, shared by both sides.
SharedCertStore
Cluster-wide TLS cert storage + single-writer issuance lock — the enterprise injection seam the DNS-01 driver consumes (the cert analogue of StateStore). key is the caller’s logical identifier (the sorted-domain-set hash); the store owns the Redis keyspace derived from it.