CIS HashiCorp Consul Benchmark
Security configuration recommendations for HashiCorp Consul service mesh
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for HashiCorp Consul deployments. It covers ACL system hardening, TLS and gossip encryption, Connect service mesh with intentions, KV store access control, audit logging, snapshot backups, server cluster configuration, DNS security, and UI access restrictions.
| Section | Area | Focus |
|---|---|---|
| 1 | Access Control | ACL bootstrapping with deny-by-default policy |
| 2 | Transport Security | mTLS and gossip encryption with key rotation |
| 3 | Service Mesh | Connect CA provider and deny-default intentions |
| 4 | Service & KV Security | KV ACL policies and health check configuration |
| 5 | Audit & Backup | JSON audit logging and automated Raft snapshots |
| 6 | Server Hardening | Autopilot configuration and connection limits |
| 7 | DNS & UI | Secure DNS forwarding and authenticated UI access |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Consul deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Access Control
▶1.1 ACL Configuration
▶This recommendation verifies that ACL system is enabled with deny-by-default policy on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check if ACLs are enabled: consul info | grep -A5 consul consul acl token list 2>&1 | head -5 # Verify ACL default policy: grep -i acl /etc/consul.d/*.hcl
# Enable ACL system:
cat > /etc/consul.d/acl.hcl << 'EOF'
acl {
enabled = true
default_policy = "deny"
down_policy = "extend-cache"
enable_token_persistence = true
tokens {
initial_management = "" # Set during bootstrap
}
}
EOF
systemctl restart consul
# Bootstrap ACL system:
consul acl bootstrap
# Securely store the SecretIDThis recommendation verifies that ACL tokens use service-specific least-privilege policies on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List ACL tokens: consul acl token list # List ACL policies: consul acl policy list # Check specific token: consul acl token read -id $TOKEN_ACCESSOR
# Create service-specific policy:
cat > /tmp/web-svc.hcl << 'EOF'
service "web" {
policy = "write"
}
service_prefix "" {
policy = "read"
}
node_prefix "" {
policy = "read"
}
key_prefix "config/web/" {
policy = "read"
}
session_prefix "" {
policy = "deny"
}
EOF
consul acl policy create -name web-service -rules @/tmp/web-svc.hcl
consul acl token create -description 'Web service token' -policy-name web-service2 — Transport Security
▶2.1 Encryption
▶This recommendation verifies that TLS is enabled for all HTTP, RPC, and gRPC traffic on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check TLS configuration: consul info | grep -i tls openssl s_client -connect consul.example.com:8501 2>/dev/null | \ openssl x509 -noout -subject -dates # Verify HTTPS API: curl -s https://consul.example.com:8501/v1/status/leader
# Configure TLS for all Consul traffic:
cat > /etc/consul.d/tls.hcl << 'EOF'
tls {
defaults {
ca_file = "/etc/consul.d/certs/ca.pem"
cert_file = "/etc/consul.d/certs/server.pem"
key_file = "/etc/consul.d/certs/server-key.pem"
verify_incoming = true
verify_outgoing = true
}
https {
verify_incoming = true
}
internal_rpc {
verify_server_hostname = true
}
}
ports {
http = -1
https = 8501
grpc_tls = 8503
}
EOF
systemctl restart consulThis recommendation verifies that gossip encryption is enabled with key rotation on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check gossip encryption: consul keyring list # Verify encrypt key in config: grep -i encrypt /etc/consul.d/*.hcl
# Generate and configure gossip encryption key: consul keygen # Add to configuration: cat >> /etc/consul.d/gossip.hcl << 'EOF' encrypt = "YOUR_GENERATED_KEY_HERE" encrypt_verify_incoming = true encrypt_verify_outgoing = true EOF systemctl restart consul # Rotate gossip key: consul keyring -install $NEW_KEY consul keyring -use $NEW_KEY consul keyring -remove $OLD_KEY
3 — Service Mesh
▶3.1 Connect & Intentions
▶This recommendation verifies that Connect service mesh is enabled with a secure CA provider on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Connect (service mesh) configuration: consul connect ca get-config # List service intentions: consul intention list # Check proxy defaults: consul config read -kind proxy-defaults -name global
# Enable Connect service mesh:
cat > /etc/consul.d/connect.hcl << 'EOF'
connect {
enabled = true
ca_provider = "vault" # or "consul"
ca_config {
address = "https://vault.example.com:8200"
root_pki_path = "connect-root"
intermediate_pki_path = "connect-intermediate"
token = "" # Vault token
}
}
EOF
# Set proxy defaults:
consul config write - << 'EOF'
Kind = "proxy-defaults"
Name = "global"
Config {
protocol = "http"
}
MeshGateway {
Mode = "local"
}
TransparentProxy {
OutboundListenerPort = 15001
}
EOFThis recommendation verifies that service intentions default to deny with explicit allow rules on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List service intentions: consul intention list # Check specific intention: consul intention get web api
# Create deny-all default intention:
consul config write - << 'EOF'
Kind = "service-intentions"
Name = "*"
Sources = [
{
Name = "*"
Action = "deny"
}
]
EOF
# Allow specific service-to-service communication:
consul config write - << 'EOF'
Kind = "service-intentions"
Name = "api"
Sources = [
{
Name = "web"
Action = "allow"
},
{
Name = "monitoring"
Action = "allow"
Permissions = [
{
Action = "allow"
HTTP { PathPrefix = "/health" Methods = ["GET"] }
}
]
}
]
EOF4 — Service & KV Security
▶4.1 Data & Health
▶This setting ensures that KV store access is restricted by ACL policies on the Consul service mesh and discovery platform. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the Consul service mesh and discovery platform is essential for defense in depth.
# Check KV store access: consul kv get -recurse config/ 2>/dev/null | head # Check KV ACL policies: consul acl policy list | grep -i kv
# Secure KV store with ACL policies:
cat > /tmp/kv-policy.hcl << 'EOF'
key_prefix "config/production/" {
policy = "read"
}
key_prefix "config/production/secrets/" {
policy = "deny"
}
key_prefix "config/shared/" {
policy = "read"
}
key "config/production/app/settings" {
policy = "write"
}
EOF
consul acl policy create -name kv-prod-read -rules @/tmp/kv-policy.hcl
# Use Consul Template for secure KV access:
consul-template -template 'config.tpl:config.json' -onceThis recommendation verifies that service registrations include health checks and tokens on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check prepared queries: consul query list # Check service health: consul catalog services consul health checks $SERVICE
# Configure health checks with security:
consul services register - << 'EOF'
{
"service": {
"name": "web",
"port": 8080,
"token": "service-specific-token",
"checks": [
{
"http": "http://localhost:8080/health",
"interval": "10s",
"timeout": "3s",
"deregister_critical_service_after": "90s",
"tls_skip_verify": false
}
],
"meta": {
"version": "1.0",
"environment": "production"
}
}
}
EOF5 — Audit & Backup
▶5.1 Logging & Recovery
▶This recommendation verifies that audit logging is enabled with JSON format on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check audit logging (Enterprise): grep -r audit /etc/consul.d/ # Check general logging: consul monitor -log-level=info 2>&1 | head -20
# Enable audit logging (Enterprise):
cat > /etc/consul.d/audit.hcl << 'EOF'
audit {
enabled = true
sink "file" {
type = "file"
format = "json"
path = "/var/log/consul/audit.log"
delivery_guarantee = "best-effort"
rotate_duration = "24h"
rotate_max_files = 30
}
}
EOF
# For OSS, enable verbose logging:
cat >> /etc/consul.d/logging.hcl << 'EOF'
log_level = "INFO"
log_file = "/var/log/consul/consul.log"
log_rotate_duration = "24h"
log_rotate_max_files = 30
enable_syslog = true
EOF
systemctl restart consulThis recommendation verifies that automated Raft snapshots are configured on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Consul snapshot status: ls -la /var/consul/snapshots/ # Verify Raft peers: consul operator raft list-peers
# Configure automated snapshots: # Using consul snapshot agent (Enterprise): consul snapshot agent -config-dir=/etc/consul.d/snapshot/ # For OSS, use cron: cat > /etc/cron.d/consul-backup << 'EOF' 0 */4 * * * consul consul snapshot save \ /var/consul/snapshots/backup-$(date +\%Y\%m\%d-\%H\%M).snap find /var/consul/snapshots/ -mtime +7 -delete EOF # Test restore procedure: consul snapshot inspect /var/consul/snapshots/latest.snap
6 — Server Hardening
▶6.1 Cluster & Isolation
▶This recommendation verifies that server cluster uses autopilot and connection limits on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check server configuration: grep -r 'server' /etc/consul.d/*.hcl # Verify cluster peers: consul operator raft list-peers # Check autopilot: consul operator autopilot get-config
# Configure server cluster properly:
cat > /etc/consul.d/server.hcl << 'EOF'
server = true
bootstrap_expect = 3
retry_join = [
"consul-1.example.com",
"consul-2.example.com",
"consul-3.example.com"
]
autopilot {
cleanup_dead_servers = true
last_contact_threshold = "200ms"
max_trailing_logs = 250
server_stabilization_time = "10s"
}
limits {
http_max_conns_per_client = 200
https_handshake_timeout = "5s"
rpc_handshake_timeout = "5s"
rpc_max_conns_per_client = 100
}
EOFThis setting ensures that network segments and bind addresses are properly restricted on the Consul service mesh and discovery platform. Restricting this capability limits potential abuse and enforces the principle of least privilege across the environment.
Unrestricted access to this capability could allow unauthorized users or processes to perform actions beyond their intended scope. Applying least-privilege principles to the Consul service mesh and discovery platform is essential for defense in depth.
# Check admin partitions and namespaces (Enterprise): consul partition list 2>/dev/null consul namespace list 2>/dev/null # For OSS, check datacenter: consul members | head
# Configure network segments and isolation:
cat > /etc/consul.d/segments.hcl << 'EOF'
# For Enterprise - separate admin partitions:
partition "production" {
# Resources in production partition
}
partition "staging" {
# Resources in staging partition
}
# For all editions - restrict bind addresses:
bind_addr = "{{ GetInterfaceIP \"eth0\" }}"
client_addr = "127.0.0.1"
addresses {
http = "127.0.0.1"
https = "0.0.0.0"
grpc = "127.0.0.1"
}
EOF7 — DNS & UI
▶7.1 Interface Security
▶This recommendation verifies that DNS forwarding uses caching with only-passing mode on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check DNS configuration: dig @127.0.0.1 -p 8600 web.service.consul # Verify DNS forwarding: grep -r consul /etc/systemd/resolved.conf.d/ 2>/dev/null cat /etc/dnsmasq.d/consul 2>/dev/null
# Configure secure DNS forwarding:
# Using systemd-resolved:
mkdir -p /etc/systemd/resolved.conf.d/
cat > /etc/systemd/resolved.conf.d/consul.conf << 'EOF'
[Resolve]
DNS=127.0.0.1:8600
Domains=~consul
EOF
systemctl restart systemd-resolved
# Configure Consul DNS settings:
cat >> /etc/consul.d/dns.hcl << 'EOF'
dns_config {
allow_stale = true
max_stale = "87600h"
node_ttl = "30s"
service_ttl {
"*" = "15s"
}
enable_truncate = true
only_passing = true
use_cache = true
cache_max_age = "5m"
}
recursors = ["8.8.8.8", "8.8.4.4"]
EOFThis recommendation verifies that Consul UI is secured behind authentication proxy on the Consul service mesh and discovery platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Consul service mesh and discovery platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Consul UI configuration:
grep -r ui /etc/consul.d/*.hcl
# Verify UI access:
curl -s -o /dev/null -w '%{http_code}' https://consul.example.com:8501/ui/# Secure Consul UI access:
cat > /etc/consul.d/ui.hcl << 'EOF'
ui_config {
enabled = true
content_path = "/ui/"
metrics_provider = "prometheus"
metrics_proxy {
base_url = "http://prometheus.example.com:9090"
}
}
EOF
# Use reverse proxy with auth:
# nginx configuration:
server {
listen 443 ssl;
server_name consul.example.com;
ssl_certificate /etc/ssl/consul.crt;
ssl_certificate_key /etc/ssl/consul.key;
location /ui/ {
auth_basic "Consul UI";
auth_basic_user_file /etc/nginx/.consul_htpasswd;
proxy_pass https://127.0.0.1:8501;
}
}