azureconsul

Configure TLS authentication for Consul

You can secure Consul by enabling TLS to verify the authenticity of servers and clients. This requires every key pair to be generated by a single Certificate Authority (CA). To enable TLS authentication, follow the instructions below:

Generate a private Certificate Authority (CA) certificate and key

IMPORTANT: To follow the steps below, you need to have the Go environment set up. Read the Go official documentation to learn how to install Go.

  • Install the CFSSL toolkit by running the commands below:

      $ go get -u github.com/cloudflare/cfssl/cmd/cfssl
      $ go get -u github.com/cloudflare/cfssl/cmd/cfssljson
      $ export PATH=$PATH:$HOME/go/bin
    
  • Generate a private CA certificate (consul-ca.pem) and key (consul-ca-key.pem):

      $ cfssl print-defaults csr > ca-csr.json && sed -i -e 's/256/2048/g' ca-csr.json && sed -i -e 's/ecdsa/rsa/g' ca-csr.json
      $ cfssl gencert -initca ca-csr.json | cfssljson -bare consul-ca
    

Generate certificates for your Consul servers and clients

The CA key is used to sign the certificates of each Consul node in your cluster. The CA certificate contains the public key used to validate the certificates and has to be distributed to every Consul node.

To generate and sign certificates for the Consul server and clients, follow these steps:

  • Create the cfssl.json configuration file below to increase the default certificate expiration time:

      $ sudo tee cfssl.json << 'EOF'
      {
          "signing": {
          "default": {
              "expiry": "87600h",
              "usages": [
              "signing",
              "key encipherment",
              "server auth",
              "client auth"
              ]
          }
          }
      }
      EOF
    
  • Consul certificates are signed by hostname (using the region and role) in the form ROLE.node.REGION.consul.

  • Generate a certificate for all the Consul servers in a specific region (global in this example):

      $ echo '{"key":{"algo":"rsa","size":2048}}' | cfssl gencert \
      -ca=consul-ca.pem -ca-key=consul-ca-key.pem -config=tls-ca/cfssl.json \
      -hostname="server.node.global.consul,localhost,127.0.0.1" - | \
      cfssljson -bare server
    
  • Generate a certificate for all the Consul clients in a specific region (global in this example):

      $ echo '{"key":{"algo":"rsa","size":2048}}' | cfssl gencert \
      -ca=consul-ca.pem -ca-key=consul-ca-key.pem -config=cfssl.json \
      -hostname="client.node.global.consul,localhost,127.0.0.1" - \
      | cfssljson -bare client
    
  • Generate a certificate for the CLI:

      $ echo '{"key":{"algo":"rsa","size":2048}}' | cfssl gencert \
      -ca=consul-ca.pem -ca-key=consul-ca-key.pem
      -profile=client - | cfssljson -bare cli
    

Configure your Consul servers and clients with the proper certificates

IMPORTANT: The steps below assumes you have installed the jq tool. It can be installed by running sudo apt-get install jq on Debian.

  • Each Consul node should have the following keys and certificates:

    • Appropriate key file for its region and role (e.g. server-key.pem for the server)
    • Appropriate certificate file for its region and role (e.g. server.pem for the server)
    • CA’s public certificate (consul-ca.pem)
  • Copy the following files to the /opt/bitnami/consul/certificates directory on each Consul server:

    • consul-ca.pem
    • server-key.pem
    • server.pem
    • cli-key.pem
    • cli.pem.

    Follow these instructions to upload files to the server with SFTP.

  • Copy the following files to each Consul client:

    • consul-ca.pem
    • client-key.pem
    • client.pem.

    Follow these instructions to upload files to the server with SFTP.

  • Configure your Consul server to verify incoming and outcoming connections. Connect to your server and run:

      $ tmp=$(mktemp) && jq '.verify_incoming = true' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
      $ tmp=$(mktemp) && jq '.verify_outgoing = true' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
      $ tmp=$(mktemp) && jq '.key_file = "/opt/bitnami/consul/certificates/server-key.pem"' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
      $ tmp=$(mktemp) && jq '.cert_file = "/opt/bitnami/consul/certificates/server.pem"' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
      $ tmp=$(mktemp) && jq '.ca_file = "/opt/bitnami/consul/certificates/consul-ca.pem"' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
      $ tmp=$(mktemp) && jq '.ports.https = 8443' /opt/bitnami/consul/conf/consul.json > "${tmp}" && sudo mv "${tmp}" /opt/bitnami/consul/conf/consul.json
    
  • Restart Consul and check you can connect through HTTPS using the CLI by running:

      $ sudo /opt/bitnami/ctlscript.sh restart consul
    
      $ consul members -ca-file=/opt/bitnami/consul/certificates/consul-ca.pem -client-cert=/opt/bitnami/consul/certificates/cli.pem -client-key=/opt/bitnami/consul/certificates/cli-key.pem -http-addr="https://localhost:8443"
    
Last modification December 21, 2022