feat(security): Add node allowlist validation to prevent SSRF attacks

Implements comprehensive node validation system to prevent SSRF attacks
via the temperature proxy. Addresses critical vulnerability where proxy
would SSH to any hostname/IP passing format validation.

Features:
- Configurable allowed_nodes list (hostnames, IPs, CIDR ranges)
- Automatic Proxmox cluster membership validation
- 5-minute cluster membership cache to reduce pvecm overhead
- strict_node_validation option for strict vs permissive modes
- New metric: pulse_proxy_node_validation_failures_total{node,reason}
- Logs blocked attempts at WARN level with 'potential SSRF attempt'

Configuration:
- allowed_nodes: [] (empty = auto-discover from cluster)
- strict_node_validation: true (require cluster membership)

Default behavior: Empty allowlist + Proxmox host = validate cluster
members (secure by default, backwards compatible).

Related to security audit 2025-11-07.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
rcourtman 2025-11-07 17:08:28 +00:00
parent 59a97f2e3e
commit 7062b07411
6 changed files with 745 additions and 80 deletions

View file

@ -10,9 +10,19 @@ allowed_source_subnets:
# Peer Authorization
# Specify which UIDs/GIDs are allowed to connect
# A peer is authorized when its UID OR GID matches one of these entries
# Required when running Pulse in a container (use mapped UID/GID from container)
allowed_peer_uids: [100999] # Container pulse user UID
allowed_peer_gids: [100996] # Container pulse group GID
allowed_peer_uids: [100999] # Legacy format; grants all capabilities unless overridden below
allowed_peer_gids: [100996]
# Preferred format with explicit capabilities (read, write, admin)
allowed_peers:
- uid: 0
capabilities: [read, write, admin] # Host root retains full control
- uid: 100999
capabilities: [read] # Container peer limited to read-only RPCs
require_proxmox_hostkeys: false # Enforce Proxmox-known host keys before falling back to ssh-keyscan
# ID-Mapped Root Authentication
# Allow connections from ID-mapped root users (for LXC containers)
@ -24,6 +34,9 @@ allowed_idmap_users:
# Address for Prometheus metrics endpoint
metrics_address: "127.0.0.1:9127"
# Limit SSH output size (bytes) when fetching temperatures
max_ssh_output_bytes: 1048576 # 1 MiB
# Rate Limiting (Optional)
# Control how frequently peers can make requests to prevent abuse
# Adjust these values based on your deployment size: