github.com/outbrain/consul@v1.4.5/website/source/docs/guides/creating-certificates.html.md (about)

     1  ---
     2  layout: "docs"
     3  page_title: "Creating and Configuring TLS Certificates"
     4  sidebar_current: "docs-guides-creating-certificates"
     5  description: |-
     6    Learn how to create certificates for Consul.
     7  ---
     8  
     9  # Creating and Configuring TLS Certificates
    10  
    11  Setting you cluster up with TLS is an important step towards a secure
    12  deployment. Correct TLS configuration is a prerequisite of our [Security
    13  Model](/docs/internals/security.html). Correctly configuring TLS can be a
    14  complex process however, especially given the wide range of deployment
    15  methodologies. This guide will provide you with a production ready TLS
    16  configuration.
    17  
    18  ~> More advanced topics like key management and rotation are not covered by this
    19  guide. [Vault][vault] is the suggested solution for key generation and
    20  management.
    21  
    22  This guide has the following chapters:
    23  
    24  1. [Creating Certificates](#creating-certificates)
    25  1. [Configuring Agents](#configuring-agents)
    26  1. [Configuring the Consul CLI for HTTPS](#configuring-the-consul-cli-for-https)
    27  1. [Configuring the Consul UI for HTTPS](#configuring-the-consul-ui-for-https)
    28  
    29  This guide is structured in way that you build knowledge with every step. It is
    30  recommended to read the whole guide before starting with the actual work,
    31  because you can save time if you are aware of some of the more advanced things
    32  in Chapter [3](#configuring-the-consul-cli-for-https) and
    33  [4](#configuring-the-consul-ui-for-https).
    34  
    35  ### Reference Material
    36  
    37  - [Encryption](/docs/agent/encryption.html)
    38  - [Security Model](/docs/internals/security.html)
    39  
    40  ## Creating Certificates
    41  
    42  ### Estimated Time to Complete
    43  
    44  2 minutes
    45  
    46  ### Prerequisites
    47  
    48  This guide assumes you have Consul 1.4.1 (or newer) in your PATH.
    49  
    50  ### Introduction
    51  
    52  The first step to configuring TLS for Consul is generating certificates. In
    53  order to prevent unauthorized cluster access, Consul requires all certificates
    54  be signed by the same Certificate Authority (CA). This should be a _private_ CA
    55  and not a public one like [Let's Encrypt][letsencrypt] as any certificate
    56  signed by this CA will be allowed to communicate with the cluster.
    57  
    58  ### Step 1: Create a Certificate Authority
    59  
    60  There are a variety of tools for managing your own CA, [like the PKI secret
    61  backend in Vault][vault-pki], but for the sake of simplicity this guide will
    62  use Consul's builtin TLS helpers:
    63  
    64  ```shell
    65  $ consul tls ca create
    66  ==> Saved consul-agent-ca.pem
    67  ==> Saved consul-agent-ca-key.pem
    68  ```
    69  
    70  The CA certificate (`consul-agent-ca.pem`) contains the public key necessary to
    71  validate Consul certificates and therefore must be distributed to every node
    72  that runs a consul agent.
    73  
    74  ~> The CA key (`consul-agent-ca-key.pem`) will be used to sign certificates for Consul
    75  nodes and must be kept private. Possession of this key allows anyone to run Consul as
    76  a trusted server and access all Consul data including ACL tokens.
    77  
    78  
    79  ### Step 2: Create individual Server Certificates
    80  
    81  Create a server certificate for datacenter `dc1` and domain `consul`, if your
    82  datacenter or domain is different please use the appropriate flags:
    83  
    84  ```shell
    85  $ consul tls cert create -server
    86  ==> WARNING: Server Certificates grants authority to become a
    87      server and access all state in the cluster including root keys
    88      and all ACL tokens. Do not distribute them to production hosts
    89      that are not server nodes. Store them as securely as CA keys.
    90  ==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
    91  ==> Saved dc1-server-consul-0.pem
    92  ==> Saved dc1-server-consul-0-key.pem
    93  ```
    94  
    95  Please repeat this process until there is an *individual* certificate for each
    96  server. The command can be called over and over again, it will automatically add
    97  a suffix.
    98  
    99  In order to authenticate Consul servers, servers are provided with a special
   100  certificate - one that contains `server.dc1.consul` in the `Subject Alternative
   101  Name`. If you enable
   102  [`verify_server_hostname`](/docs/agent/options.html#verify_server_hostname),
   103  only agents that provide such certificate are allowed to boot as a server.
   104  Without `verify_server_hostname = true` an attacker could compromise a Consul
   105  client agent and restart the agent as a server in order to get access to all the
   106  data in your cluster! This is why server certificates are special, and only
   107  servers should have them provisioned.
   108  
   109  ~> Server keys, like the CA key, must be kept private - they effectively allow
   110  access to all Consul data.
   111  
   112  ### Step 3: Create Client Certificates
   113  
   114  Create a client certificate:
   115  
   116  ```shell
   117  $ consul tls cert create -client
   118  ==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
   119  ==> Saved dc1-client-consul-0.pem
   120  ==> Saved dc1-client-consul-0-key.pem
   121  ```
   122  
   123  Client certificates are also signed by your CA, but they do not have that
   124  special `Subject Alternative Name` which means that if `verify_server_hostname`
   125  is enabled, they cannot start as a server.
   126  
   127  ## Configuring Agents
   128  
   129  ### Prerequisites
   130  
   131  For this section you need access to your existing or new Consul cluster and have
   132  the certificates from the previous chapters available.
   133  
   134  ### Notes on example configurations
   135  
   136  The example configurations from this as well as the following chapters are in
   137  json. You can copy each one of the examples in its own file in a directory
   138  ([`-config-dir`](/docs/agent/options.html#_config_dir)) from where consul will
   139  load all the configuration. This is just one way to do it, you can also put them
   140  all into one file if you prefer that.
   141  
   142  ### Introduction
   143  
   144  By now you have created the certificates you need to enable TLS in your cluster.
   145  The next steps show how to configure TLS for a brand new cluster. If you already
   146  have a cluster in production without TLS please see the [encryption
   147  guide][guide] for the steps needed to introduce TLS without downtime.
   148  
   149  ### Step 1: Setup Consul servers with certificates
   150  
   151  This step describes how to setup one of your consul servers, you want to make
   152  sure to repeat the process for the other ones as well with their individual
   153  certificates.
   154  
   155  The following files need to be copied to your Consul server:
   156  
   157  * `consul-agent-ca.pem`: CA public certificate.
   158  * `dc1-server-consul-0.pem`: Consul server node public certificate for the `dc1` datacenter.
   159  * `dc1-server-consul-0-key.pem`: Consul server node private key for the `dc1` datacenter.
   160  
   161  Here is an example agent TLS configuration for Consul servers which mentions the
   162  copied files:
   163  
   164  ```json
   165  {
   166    "verify_incoming": true,
   167    "verify_outgoing": true,
   168    "verify_server_hostname": true,
   169    "ca_file": "consul-agent-ca.pem",
   170    "cert_file": "dc1-server-consul-0.pem",
   171    "key_file": "dc1-server-consul-0-key.pem",
   172    "ports": {
   173      "http": -1,
   174      "https": 8501
   175    }
   176  }
   177  ```
   178  
   179  This configuration disables the HTTP port to make sure there is only encryted
   180  communication. Existing clients that are not yet prepared to talk HTTPS won't be
   181  able to connect afterwards. This also affects builtin tooling like `consul
   182  members` and the UI. The next chapters will demonstrate how to setup secure
   183  access.
   184  
   185  After a Consul agent restart, your servers should be only talking TLS.
   186  
   187  ### Step 2: Setup Consul clients with certificates
   188  
   189  Now copy the following files to your Consul clients:
   190  
   191  * `consul-agent-ca.pem`: CA public certificate.
   192  * `dc1-client-consul-0.pem`: Consul client node public certificate.
   193  * `dc1-client-consul-0-key.pem`: Consul client node private key.
   194  
   195  Here is an example agent TLS configuration for Consul agents which mentions the
   196  copied files:
   197  
   198  ```json
   199  {
   200    "verify_incoming": true,
   201    "verify_outgoing": true,
   202    "verify_server_hostname": true,
   203    "ca_file": "consul-agent-ca.pem",
   204    "cert_file": "dc1-client-consul-0.pem",
   205    "key_file": "dc1-client-consul-0-key.pem",
   206    "ports": {
   207      "http": -1,
   208      "https": 8501
   209    }
   210  }
   211  ```
   212  
   213  This configuration disables the HTTP port to make sure there is only encryted
   214  communication. Existing clients that are not yet prepared to talk HTTPS won't be
   215  able to connect afterwards. This also affects builtin tooling like `consul
   216  members` and the UI. The next chapters will demonstrate how to setup secure
   217  access.
   218  
   219  After a Consul agent restart, your agents should be only talking TLS.
   220  
   221  ## Configuring the Consul CLI for HTTPS
   222  
   223  If your cluster is configured to only communicate via HTTPS, you will need to
   224  create additional certificates in order to be able to continue to access the API
   225  and the UI:
   226  
   227  ```shell
   228  $ consul tls cert create -cli
   229  ==> Using consul-agent-ca.pem and consul-agent-ca-key.pem
   230  ==> Saved dc1-cli-consul-0.pem
   231  ==> Saved dc1-cli-consul-0-key.pem
   232  ```
   233  
   234  If you are trying to get members of you cluster, the CLI will return an error:
   235  
   236  ```shell
   237  $ consul members
   238  Error retrieving members:
   239    Get http://127.0.0.1:8500/v1/agent/members?segment=_all:
   240    dial tcp 127.0.0.1:8500: connect: connection refused
   241  $ consul members -http-addr="https://localhost:8501"
   242  Error retrieving members:
   243    Get https://localhost:8501/v1/agent/members?segment=_all:
   244    x509: certificate signed by unknown authority
   245  ```
   246  
   247  But it will work again if you provide the certificates you provided:
   248  
   249  ```shell
   250  $ consul members -ca-file=consul-agent-ca.pem -client-cert=dc1-cli-consul-0.pem \
   251    -client-key=dc1-cli-consul-0-key.pem -http-addr="https://localhost:8501"
   252    Node     Address         Status  Type    Build     Protocol  DC   Segment
   253    ...
   254  ```
   255  
   256  This process can be cumbersome to type each time, so the Consul CLI also
   257  searches environment variables for default values. Set the following
   258  environment variables in your shell:
   259  
   260  ```shell
   261  $ export CONSUL_HTTP_ADDR=https://localhost:8501
   262  $ export CONSUL_CACERT=consul-agent-ca.pem
   263  $ export CONSUL_CLIENT_CERT=dc1-cli-consul-0.pem
   264  $ export CONSUL_CLIENT_KEY=dc1-cli-consul-0-key.pem
   265  ```
   266  
   267  * `CONSUL_HTTP_ADDR` is the URL of the Consul agent and sets the default for
   268    `-http-addr`.
   269  * `CONSUL_CACERT` is the location of your CA certificate and sets the default
   270    for `-ca-file`.
   271  * `CONSUL_CLIENT_CERT` is the location of your CLI certificate and sets the
   272    default for `-client-cert`.
   273  * `CONSUL_CLIENT_KEY` is the location of your CLI key and sets the default for
   274    `-client-key`.
   275  
   276  After these environment variables are correctly configured, the CLI will
   277  respond as expected.
   278  
   279  ### Note on SANs for Server and Client Certificates
   280  
   281  Using `localhost` and `127.0.0.1` as `Subject Alternative Names` in server
   282  and client certificates allows tools like `curl` to be able to communicate with
   283  Consul's HTTPS API when run on the same host. Other SANs may be added during
   284  server/client certificates creation with `-additional-dnsname` to allow remote
   285  HTTPS requests from other hosts.
   286  
   287  ## Configuring the Consul UI for HTTPS
   288  
   289  If your servers and clients are configured now like above, you won't be able to
   290  access the builtin UI anymore. We recommend that you pick one (or two for
   291  availability) Consul agent you want to run the UI on and follow the instructions
   292  to get the UI up and running again.
   293  
   294  ### Step 1: Which interface to bind to?
   295  
   296  Depending on your setup you might need to change to which interface you are
   297  binding because thats `127.0.0.1` by default for the UI. Either via the
   298  [`addresses.https`](/docs/agent/options.html#https) or
   299  [client_addr](/docs/agent/options.html#client_addr) option which also impacts
   300  the DNS server. The Consul UI is unproteced which means you need to put some
   301  auth in front of it if you want to make it publicly available!
   302  
   303  Binding to `0.0.0.0` should work:
   304  
   305  ```json
   306  {
   307    "ui": true,
   308    "client_addr": "0.0.0.0",
   309    "enable_script_checks": false,
   310    "disable_remote_exec": true
   311  }
   312  ```
   313  
   314  ~> Since your Consul agent is now available to the network, please make sure
   315  that [`enable_script_checks`](/docs/agent/options.html#_enable_script_checks) is
   316  set to `false` and
   317  [`disable_remote_exec`](https://www.consul.io/docs/agent/options.html#disable_remote_exec)
   318  is set to `true`.
   319  
   320  ### Step 2: verify_incoming_rpc
   321  
   322  Your Consul agent will deny the connection straight away because
   323  `verify_incoming` is enabled.
   324  
   325  > If set to true, Consul requires that all incoming connections make use of TLS
   326  > and that the client provides a certificate signed by a Certificate Authority
   327  > from the ca_file or ca_path. This applies to both server RPC and to the HTTPS
   328  > API.
   329  
   330  Since the browser doesn't present a certificate signed by our CA, you cannot
   331  access the UI. If you `curl` your HTTPS UI the following happens:
   332  
   333  ```shell
   334  $ curl https://localhost:8501/ui/ -k -I
   335  curl: (35) error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 alert bad certificate
   336  ```
   337  
   338  This is the Consul HTTPS server denying your connection because you are not
   339  presenting a client certificate signed by your Consul CA. There is a combination
   340  of options however that allows us to keep using `verify_incoming` for RPC, but
   341  not for HTTPS:
   342  
   343  ```json
   344  {
   345    "verify_incoming": false,
   346    "verify_incoming_rpc": true
   347  }
   348  ```
   349  
   350  ~> This is the only time we are changing the value of the existing option
   351  `verify_incoming` to false. Make sure to only change it on the agent running the
   352  UI!
   353  
   354  With the new configuration, it should work:
   355  
   356  ```shell
   357  $ curl https://localhost:8501/ui/ -k -I
   358  HTTP/2 200
   359  ...
   360  ```
   361  
   362  ### Step 3: Subject Alternative Name
   363  
   364  This step will take care of setting up the domain you want to use to access the
   365  Consul UI. Unless you only need to access the UI over localhost or 127.0.0.1 you
   366  will need to go complete this step.
   367  
   368  ```shell
   369  $ curl https://consul.example.com:8501/ui/ \
   370    --resolve 'consul.example.com:8501:127.0.0.1' \
   371    --cacert consul-agent-ca.pem
   372  curl: (51) SSL: no alternative certificate subject name matches target host name 'consul.example.com'
   373  ...
   374  ```
   375  
   376  The above command simulates a request a browser is making when you are trying to
   377  use the domain `consul.example.com` to access your UI. The problem this time is
   378  that your domain is not in `Subject Alternative Name` of the Certificate. We can
   379  fix that by creating a certificate that has our domain:
   380  
   381  ```shell
   382  $ consul tls cert create -server -additional-dnsname consul.example.com
   383  ...
   384  ```
   385  
   386  And if you put your new cert into the configuration of the agent you picked to
   387  serve the UI and restart Consul, it works now:
   388  
   389  ```shell
   390  $ curl https://consul.example.com:8501/ui/ \
   391    --resolve 'consul.example.com:8501:127.0.0.1' \
   392    --cacert consul-agent-ca.pem -I
   393  HTTP/2 200
   394  ...
   395  ```
   396  
   397  ### Step 4: Trust the Consul CA
   398  
   399  So far we have provided curl with our CA so that it can verify the connection,
   400  but if we stop doing that it will complain and so will our browser if you visit
   401  your UI on https://consul.example.com:
   402  
   403  ```shell
   404  $ curl https://consul.example.com:8501/ui/ \
   405    --resolve 'consul.example.com:8501:127.0.0.1'
   406  curl: (60) SSL certificate problem: unable to get local issuer certificate
   407  ...
   408  ```
   409  
   410  You can fix that by trusting your Consul CA (`consul-agent-ca.pem`) on your machine,
   411  please use Google to find out how to do that on your OS.
   412  
   413  ```shell
   414  $ curl https://consul.example.com:8501/ui/ \
   415    --resolve 'consul.example.com:8501:127.0.0.1' -I
   416  HTTP/2 200
   417  ...
   418  ```
   419  
   420  ## Summary
   421  
   422  When you have completed this guide, your Consul cluster will have TLS enabled
   423  and will encrypt all RPC and HTTP traffic (assuming you disabled the HTTP port).
   424  The other pre-requisites for a secure Consul deployment are:
   425  
   426  * [Enable gossip encryption](/docs/agent/encryption.html#gossip-encryption)
   427  * [Configure ACLs][acl] with default deny
   428  
   429  [letsencrypt]: https://letsencrypt.org/
   430  [vault]: https://www.vaultproject.io/
   431  [vault-pki]: https://www.vaultproject.io/docs/secrets/pki/index.html
   432  [guide]: /docs/agent/encryption.html#configuring-tls-on-an-existing-cluster
   433  [acl]: /docs/guides/acl.html
   434