AMQP & RabbitMQ Guard (amqp)
The AMQP Guard plugin inspects Advanced Message Queuing Protocol (AMQP 0-9-1) connection negotiation frames. It parses client Connection.StartOk and Connection.Open requests, monitors broker Connection.Close frames for authentication errors (403 ACCESS_REFUSED, 320 CONNECTION_FORCED), and enforces virtual host (vhost) access controls to safeguard RabbitMQ brokers.
Capabilities & Threat Defense
| Threat / Attack Vector | Defense Mechanism | Action Taken |
|---|---|---|
| Credential Stuffing & Unauthorized Access | Detects broker Connection.Close with code 403 | IP banned after max_auth_failures threshold |
| Unauthorized Virtual Host Scanning | Filters vhost in Connection.Open frames; zero-length vhost normalized to "/" before allowlist check (since v3.4.0) | Connection dropped before broker processes request |
| Zero-Length VHost Allowlist Bypass | extractVHost treats an empty vhost field as the default "/" vhost (since v3.4.0) | Prevents evasion when the AMQP default vhost is included in an allowlist |
| Broker Connection Exhaustion | Enforces rate limits per minute and burst caps | Connection throttled at the proxy layer |
Installation
Install the plugin via CLI or declaratively:
# Install using short nametcp-warden plugins install amqp# Or install via Git repository URLtcp-warden plugins install https://github.com/routewarden/plugins/amqpConfiguration Reference
Add an AMQP guard service to tcp-warden.yaml:
services: rabbitmq_bastion: listen: ":5672" upstream: "127.0.0.1:56720" protocol: "amqp" rate_limit: connections_per_minute: 60 burst: 10 max_auth_failures: 3 ban_after_failures: 3 ban_duration: "2h" plugin_config: blocked_vhosts: - "internal-admin" - "production-critical"Configuration Options
| Field | Type | Default | Description |
|---|---|---|---|
listen | string | ":5672" | Local proxy listen address and port. |
upstream | string | "127.0.0.1:56720" | Target RabbitMQ server address and port. |
protocol | string | "amqp" | Must be set to "amqp" or "rabbitmq". |
max_auth_failures | int | 3 | Failed login attempts before banning. |
ban_duration | string | "2h" | Duration of the automated IP ban ("30m", "2h", "24h"). |
plugin_config.blocked_vhosts | []string | [] | List of virtual host names prohibited through this proxy interface. A zero-length vhost in the AMQP Connection.Open frame is normalized to "/" (the AMQP default vhost) before evaluation (since v3.4.0). |
Network & Deployment Architecture
Because AMQP operates on an unprivileged port (5672), packet redirection rules (nftables/iptables) are not required. Deploy RouteWarden using either direct reverse proxying or container network isolation:
Option A: Direct Reverse Proxy (Bare-Metal / VM)
Bind RouteWarden directly to :5672, with RabbitMQ listening on loopback on an alternate port or private subnet IP:
# tcp-warden.yaml — RouteWarden binds to standard AMQP port 5672services: rabbitmq_bastion: listen: ":5672" upstream: "127.0.0.1:56720" # Or private backend "10.0.0.30:5672" protocol: "amqp"Option B: Docker Compose Network Isolation
Publish port 5672 on RouteWarden while keeping the RabbitMQ container completely private:
services: routewarden: image: ghcr.io/routewarden/tcp-warden:latest ports: - "5672:5672" - "9091:9091" volumes: - ./tcp-warden.yaml:/etc/routewarden/tcp-warden.yaml:ro depends_on: - rabbitmq rabbitmq: image: rabbitmq:3-management-alpine # Do NOT publish host port 5672 directlyTesting & Verification
Verify AMQP connections, test authentication error handling, and inspect ban tables:
# Verify valid connection using amqp-declare-queueamqp-declare-queue --url=amqp://guest:guest@127.0.0.1:5672/ -q test-queue