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