Implement Consul ACL security and encryption for production deployments

Advanced 45 min Apr 07, 2026 11 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Consul's Access Control List (ACL) system with bootstrap tokens, implement TLS encryption for client-server communication, and enable gossip encryption to secure your Consul cluster for production environments with comprehensive authentication and authorization.

Prerequisites

  • Consul installed and basic cluster setup
  • Root or sudo access
  • Basic understanding of PKI and certificates
  • Network connectivity between Consul nodes

What this solves

Consul's default configuration lacks security controls, allowing any client to access the cluster without authentication. This tutorial implements Consul's ACL system to provide fine-grained access control, enables TLS encryption for secure client-server communication, and configures gossip encryption to protect cluster communication. You'll create ACL policies and tokens for service authentication while establishing proper certificate management for production deployments.

Prerequisites and Consul installation verification

Verify Consul installation

Confirm that Consul is installed and check the current version before proceeding with security configuration.

consul version
sudo systemctl status consul

Stop Consul service for configuration

Stop the Consul service to modify configuration files safely without conflicts.

sudo systemctl stop consul

Create backup of existing configuration

Create a backup of your current Consul configuration before making security changes.

sudo cp -r /etc/consul.d /etc/consul.d.backup
sudo cp /opt/consul/consul.hcl /opt/consul/consul.hcl.backup

Configure Consul ACL system with bootstrap token

Enable ACL system in Consul configuration

Modify the Consul configuration to enable the ACL system with default deny policy for maximum security.

datacenter = "dc1"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bind_addr = "0.0.0.0"
client_addr = "0.0.0.0"
bootstrap_expect = 3
ui_config {
  enabled = true
}

ACL Configuration

acl = { enabled = true default_policy = "deny" enable_token_persistence = true }

Performance and Connect

performance { raft_multiplier = 1 } connect { enabled = true }

Set proper permissions for Consul configuration

Ensure the Consul configuration directory has correct ownership and permissions for security.

Never use chmod 777. It gives every user on the system full access to your files. Instead, fix ownership with chown and use minimal permissions.
sudo chown -R consul:consul /etc/consul.d
sudo chmod 750 /etc/consul.d
sudo chmod 640 /etc/consul.d/*.hcl

Start Consul with ACL enabled

Start Consul service with the new ACL-enabled configuration to prepare for bootstrap token creation.

sudo systemctl start consul
sudo systemctl status consul

Bootstrap the ACL system

Create the initial bootstrap token that provides full administrative access to the Consul cluster.

consul acl bootstrap
Note: Save the bootstrap token SecretID output. This token provides full administrative access and cannot be recovered if lost.

Configure environment variable for ACL token

Set the bootstrap token as an environment variable for subsequent Consul CLI operations.

export CONSUL_HTTP_TOKEN="your-bootstrap-token-secret-id"
echo 'export CONSUL_HTTP_TOKEN="your-bootstrap-token-secret-id"' >> ~/.bashrc

Set up TLS encryption for client-server communication

Create Consul CA and certificates directory

Create a dedicated directory for Consul certificates and generate the Certificate Authority for TLS encryption.

sudo mkdir -p /opt/consul/tls
sudo chown consul:consul /opt/consul/tls
sudo chmod 750 /opt/consul/tls

Generate Consul CA certificate

Create the Certificate Authority that will sign all Consul server and client certificates.

cd /opt/consul/tls
sudo -u consul consul tls ca create

Generate server certificates

Create server certificates for each Consul server node in your cluster.

sudo -u consul consul tls cert create -server -dc dc1
sudo -u consul consul tls cert create -server -dc dc1
sudo -u consul consul tls cert create -server -dc dc1

Generate client certificate

Create client certificates for Consul agents and applications that need to communicate with the cluster.

sudo -u consul consul tls cert create -client -dc dc1

Configure TLS in Consul configuration

Update the Consul configuration to enable TLS encryption for all communications.

datacenter = "dc1"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bind_addr = "0.0.0.0"
client_addr = "0.0.0.0"
bootstrap_expect = 3
ui_config {
  enabled = true
}

ACL Configuration

acl = { enabled = true default_policy = "deny" enable_token_persistence = true }

TLS Configuration

tls { defaults { ca_file = "/opt/consul/tls/consul-agent-ca.pem" cert_file = "/opt/consul/tls/dc1-server-consul-0.pem" key_file = "/opt/consul/tls/dc1-server-consul-0-key.pem" verify_incoming = true verify_outgoing = true } internal_rpc { verify_server_hostname = true } } ports { grpc_tls = 8503 https = 8501 }

Performance and Connect

performance { raft_multiplier = 1 } connect { enabled = true }

Enable gossip encryption and secure cluster communication

Generate gossip encryption key

Create a symmetric encryption key for securing gossip protocol communications between Consul agents.

consul keygen
Note: Save this key securely. All Consul agents in the cluster must use the same gossip encryption key.

Add gossip encryption to configuration

Update the Consul configuration to include gossip encryption and disable script checks for security.

datacenter = "dc1"
data_dir = "/opt/consul"
log_level = "INFO"
server = true
bind_addr = "0.0.0.0"
client_addr = "0.0.0.0"
bootstrap_expect = 3
ui_config {
  enabled = true
}

Gossip Encryption

encrypt = "your-generated-gossip-key" encrypt_verify_incoming = true encrypt_verify_outgoing = true

Security Hardening

enable_script_checks = false enable_local_script_checks = false

ACL Configuration

acl = { enabled = true default_policy = "deny" enable_token_persistence = true }

TLS Configuration

tls { defaults { ca_file = "/opt/consul/tls/consul-agent-ca.pem" cert_file = "/opt/consul/tls/dc1-server-consul-0.pem" key_file = "/opt/consul/tls/dc1-server-consul-0-key.pem" verify_incoming = true verify_outgoing = true } internal_rpc { verify_server_hostname = true } } ports { grpc_tls = 8503 https = 8501 }

Performance and Connect

performance { raft_multiplier = 1 } connect { enabled = true }

Create ACL policies and tokens for service authentication

Create a service registration policy

Define an ACL policy that allows services to register with Consul and perform health checks.

service_prefix "" {
  policy = "write"
}

node_prefix "" {
  policy = "read"
}

key_prefix "" {
  policy = "read"
}

session_prefix "" {
  policy = "read"
}

Create the service policy in Consul

Register the service policy with Consul ACL system for use by application tokens.

consul acl policy create -name "service-policy" -description "Service registration and health checks" -rules @/tmp/service-policy.hcl

Create a read-only policy for monitoring

Define a restricted policy for monitoring tools that only need read access to Consul data.

service_prefix "" {
  policy = "read"
}

node_prefix "" {
  policy = "read"
}

key_prefix "" {
  policy = "read"
}

session_prefix "" {
  policy = "read"
}

operator = "read"

query_prefix "" {
  policy = "read"
}

Create the read-only policy

Register the read-only policy for use by monitoring and observability tools.

consul acl policy create -name "readonly-policy" -description "Read-only access for monitoring" -rules @/tmp/readonly-policy.hcl

Create service token

Generate an ACL token with service registration permissions for applications to use.

consul acl token create -description "Service registration token" -policy-name service-policy

Create monitoring token

Generate a read-only token for monitoring tools like Prometheus or Grafana to access Consul metrics.

consul acl token create -description "Monitoring read-only token" -policy-name readonly-policy

Implement certificate management and rotation

Create certificate rotation script

Prepare an automated script to handle certificate rotation before expiration.

#!/bin/bash

Consul Certificate Rotation Script

CONSUL_TLS_DIR="/opt/consul/tls" BACKUP_DIR="/opt/consul/tls-backup-$(date +%Y%m%d)"

Create backup

sudo mkdir -p "$BACKUP_DIR" sudo cp -r "$CONSUL_TLS_DIR"/*.pem "$BACKUP_DIR"/

Generate new certificates

cd "$CONSUL_TLS_DIR" sudo -u consul consul tls cert create -server -dc dc1 sudo -u consul consul tls cert create -client -dc dc1

Update configuration with new certificate paths

sudo systemctl reload consul echo "Certificate rotation completed. Backup stored in: $BACKUP_DIR"

Make rotation script executable

Set proper permissions for the certificate rotation script and create directory structure.

sudo mkdir -p /opt/consul/scripts
sudo chown consul:consul /opt/consul/scripts
sudo chmod 750 /opt/consul/scripts
sudo chmod 750 /opt/consul/scripts/rotate-certs.sh

Configure systemd environment for TLS

Create systemd environment file to ensure Consul uses TLS for all operations.

CONSUL_HTTP_SSL=true
CONSUL_HTTP_SSL_VERIFY=true
CONSUL_CACERT=/opt/consul/tls/consul-agent-ca.pem
CONSUL_CLIENT_CERT=/opt/consul/tls/dc1-client-consul-0.pem
CONSUL_CLIENT_KEY=/opt/consul/tls/dc1-client-consul-0-key.pem

Restart Consul with full security configuration

Restart Consul service to apply all security configurations including ACL, TLS, and gossip encryption.

sudo systemctl restart consul
sudo systemctl status consul

Verify your setup

# Verify Consul is running with TLS
curl -k --cert /opt/consul/tls/dc1-client-consul-0.pem \
     --key /opt/consul/tls/dc1-client-consul-0-key.pem \
     --cacert /opt/consul/tls/consul-agent-ca.pem \
     "https://localhost:8501/v1/status/leader"

Check ACL system status

consul acl auth-method list

Verify gossip encryption

consul members

Test token authentication

consul catalog services

Common issues

SymptomCauseFix
"Permission denied" ACL errorsMissing or invalid ACL tokenSet CONSUL_HTTP_TOKEN environment variable with valid token
TLS certificate verification failsCertificate path or permissions issueVerify certificate files exist and consul user can read them
Consul UI shows "ACL not found"Bootstrap token not properly setRe-run bootstrap process or verify token configuration
Gossip encryption errors in logsMismatched encryption keys across nodesEnsure all nodes use identical gossip encryption key
Service registration failsService lacks proper ACL tokenCreate service token with appropriate policy and configure application
Certificate expired errorsTLS certificates have expiredRun certificate rotation script and restart Consul

Next steps

Automated install script

Run this to automate the entire setup

#consul #acl #security #tls #encryption

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer