Memcached Cache Guard (memcached)
The Memcached Cache Guard plugin inspects both ASCII text and binary protocol commands directed at Memcached instances. It protects caching layers from accidental or malicious cache wipes (flush_all), blocks unauthorized server configuration manipulation, and limits connection velocity to prevent connection table exhaustion.
Capabilities & Threat Defense
| Threat / Attack Vector | Defense Mechanism | Action Taken |
|---|---|---|
Complete Cache Purge (flush_all) | Filters commands against blocked_commands | Command dropped with synthetic CLIENT_ERROR |
| Server Crash & Probe Exploits | Blocks shutdown, version, quit tampering | Command intercepted at the proxy layer |
| Connection Starvation Attacks | Enforces connection rate limits and burst caps | Connection throttled before reaching Memcached |
| Heap Exhaustion via Oversized Objects | Validates bytes field on set/add/replace/append/prepend against max_value_size (since v3.4.0) | Storage commands with negative or oversized byte declarations rejected with CLIENT_ERROR value too large |
Installation
Install the plugin via CLI or declaratively:
# Install using short nametcp-warden plugins install memcached# Or install via Git repository URLtcp-warden plugins install https://github.com/routewarden/plugins/memcachedConfiguration Reference
Add a Memcached guard service to tcp-warden.yaml:
services: memcached_guard: listen: ":11211" upstream: "127.0.0.1:112110" protocol: "memcached" rate_limit: connections_per_minute: 120 burst: 20 plugin_config: blocked_commands: - "flush_all" - "shutdown"Configuration Options
| Field | Type | Default | Description |
|---|---|---|---|
listen | string | ":11211" | Local proxy listen address and port. |
upstream | string | "127.0.0.1:112110" | Target Memcached server address and port. |
protocol | string | "memcached" | Must be set to "memcached". |
plugin_config.blocked_commands | []string | ["flush_all"] | List of commands blocked by RouteWarden. |
plugin_config.max_value_size | int | 1048576 | Maximum permitted bytes field value (in bytes) for storage commands (set, add, replace, append, prepend). Commands declaring a larger or negative size are rejected immediately with CLIENT_ERROR value too large to prevent heap exhaustion (since v3.4.0). |
Network & Deployment Architecture
Because Memcached operates on an unprivileged port (11211), firewall redirects (nftables/iptables) are not required. Deploy RouteWarden using either direct reverse proxying or container network isolation:
Option A: Direct Port Swapping (Bare-Metal / VM)
Rebind Memcached to loopback on an alternate port and expose RouteWarden on standard port :11211:
# /etc/memcached.conf# Rebind Memcached to loopback on an alternate port-l 127.0.0.1-p 112110Option B: Docker Compose Bridge Isolation
Publish port 11211 on RouteWarden while keeping the Memcached container completely private within the container network:
services: routewarden: image: ghcr.io/routewarden/tcp-warden:latest ports: - "11211:11211" - "9091:9091" volumes: - ./tcp-warden.yaml:/etc/routewarden/tcp-warden.yaml:ro depends_on: - memcached memcached: image: memcached:alpine # Do NOT publish host ports; keep internal to bridge networkTesting & Verification
Verify cache set/get commands and verify the flush_all firewall:
# Verify legitimate cache operations through RouteWardenecho -e "set testkey 0 60 5\r\nhello\r\n" | nc 127.0.0.1 11211# Returns: STOREDecho -e "get testkey\r\n" | nc 127.0.0.1 11211# Returns: VALUE testkey 0 5 / hello / END