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

     1  ---
     2  layout: "docs"
     3  page_title: "Bootstrapping ACLs"
     4  sidebar_current: "docs-guides-acl"
     5  description: |-
     6    Consul provides an optional Access Control List (ACL) system which can be used to control access to data and APIs. The ACL system is a Capability-based system that relies on tokens which can have fine grained rules applied to them. It is very similar to AWS IAM in many ways.
     7  ---
     8  
     9  # Bootstrapping the ACL System
    10  
    11  Consul uses Access Control Lists (ACLs) to secure the UI, API, CLI, service communications, and agent communications. For securing gossip and RPC communication please review [this guide](/docs/guides/agent-encryption.html). When securing your cluster you should configure the ACLs first. 
    12  
    13  At the core, ACLs operate by grouping rules into policies, then associating one or more policies with a token.
    14  
    15  To complete this guide, you should have an operational Consul 1.4+ cluster. We also recommend reading the [ACL System documentation](/docs/agent/acl-system.html). For securing Consul version 1.3 and older, please read the [legacy ACL documentation](https://www.consul.io/docs/guides/acl-legacy.html).
    16  
    17  Bootstrapping the ACL system is a multi-step process, we will cover all the necessary steps in this guide. 
    18  
    19  * [Enable ACLs on all the servers](/docs/guides/acl.html#step-1-enable-acls-on-all-the-consul-servers).
    20  * [Create the initial bootstrap token](/docs/guides/acl.html#step-2-create-the-bootstrap-token).
    21  * [Create the agent policy](/docs/guides/acl.html#step-3-create-an-agent-token-policy).
    22  * [Create the agent token](/docs/guides/acl.html#step-4-create-an-agent-token).
    23  * [Apply the new token to the servers](/docs/guides/acl.html#step-5-add-the-agent-token-to-all-the-servers). 
    24  * [Enable ACLs on the clients and apply the agent token](/docs/guides/acl.html#step-6-enable-acls-on-the-consul-clients).
    25  
    26  At the end of this guide, there are also several additional and optional steps.
    27  
    28  ## Step 1: Enable ACLs on all the Consul Servers
    29  
    30  The first step for bootstrapping the ACL system is to enable ACLs on the Consul servers in the agent configuration file. In this example, we are configuring the default policy of "deny", which means we are in whitelist mode, and a down policy of "extend-cache", which means that we will ignore token TTLs during an outage.
    31  
    32  ```json
    33  {
    34    "acl" : {
    35      "enabled" : true,
    36      "default_policy" : "deny",
    37      "down_policy" : "extend-cache"
    38    }
    39  }
    40  ```
    41  
    42  The servers will need to be restarted to load the new configuration. Please take care
    43  to restart the servers one at a time and ensure each server has joined and is operating
    44  correctly before restarting another.
    45  
    46  If ACLs are enabled correctly, we will now see the following warnings and info in the leader's logs.
    47  
    48  ```sh
    49  2018/12/12 01:36:40 [INFO] acl: Created the anonymous token
    50  2018/12/12 01:36:40 [INFO] consul: ACL bootstrap enabled
    51  2018/12/12 01:36:41 [INFO] agent: Synced node info
    52  2018/12/12 01:36:58 [WARN] agent: Coordinate update blocked by ACLs
    53  2018/12/12 01:37:40 [INFO] acl: initializing acls
    54  2018/12/12 01:37:40 [INFO] consul: Created ACL 'global-management' policy
    55  ```
    56  
    57  If you do not see ACL bootstrap enabled, the anonymous token creation, and the `global-management` policy creation message in the logs, ACLs have not been properly enabled. 
    58  
    59  Note, now that we have enabled ACLs, we will need a token to complete any operation. We can't do anything else to the cluster until we bootstrap and generate the first master token. For simplicity we will use the master token created during the bootstrap for the remainder of the guide.
    60  
    61  ## Step 2: Create the Bootstrap Token
    62  
    63  Once ACLs have been enabled we can bootstrap our first token, the bootstrap token. 
    64  The bootstrap token is a management token with unrestricted privileges. It will
    65  be shared with all the servers in the quorum, since it will be added to the 
    66  state store. 
    67  
    68  ```bash
    69  $ consul acl bootstrap
    70  AccessorID: edcaacda-b6d0-1954-5939-b5aceaca7c9a
    71  SecretID: 4411f091-a4c9-48e6-0884-1fcb092da1c8
    72  Description: Bootstrap Token (Global Management)
    73  Local: false
    74  Create Time: 2018-12-06 18:03:23.742699239 +0000 UTC
    75  Policies:
    76  00000000-0000-0000-0000-000000000001 - global-management
    77  ```
    78  
    79  On the server where the `bootstrap` command was issued we should see the following log message. 
    80  
    81  ```sh
    82  2018/12/11 15:30:23 [INFO] consul.acl: ACL bootstrap completed
    83  2018/12/11 15:30:23 [DEBUG] http: Request PUT /v1/acl/bootstrap (2.347965ms) from=127.0.0.1:40566
    84  ```
    85  
    86  Since ACLs have been enabled, we will need to use it to complete any additional operations.
    87  For example, even checking the member list will require a token.  
    88  
    89  ```sh
    90  $ consul members -token "4411f091-a4c9-48e6-0884-1fcb092da1c8"
    91  Node  Address            Status  Type    Build  Protocol  DC   Segment
    92  fox   172.20.20.10:8301  alive   server  1.4.0  2         kc  <all>
    93  bear  172.20.20.11:8301  alive   server  1.4.0  2         kc  <all>
    94  wolf  172.20.20.12:8301  alive   server  1.4.0  2         kc  <all>
    95  ```
    96  
    97  Note using the token on the command line with the `-token` flag is not 
    98  recommended, instead we will set it as an environment variable once.
    99  
   100  ```sh
   101  $ export CONSUL_HTTP_TOKEN=4411f091-a4c9-48e6-0884-1fcb092da1c8
   102  ```
   103  
   104  The bootstrap token can also be used in the server configuration file as 
   105  the [`master`](https://www.consul.io/docs/agent/options.html#acl_tokens_master) token.
   106  
   107  Note, the bootstrap token can only be created once, bootstrapping will be disabled after the master token was created. Once the ACL system is bootstrapped, ACL tokens can be managed through the
   108  [ACL API](/api/acl/acl.html).
   109  
   110  ## Step 3: Create an Agent Token Policy
   111  
   112  Before we can create a token, we will need to create its associated policy. A policy is a set of rules that can be used to specify granular permissions. To learn more about rules, read the ACL rule specification [documentation](/docs/agent/acl-rules.html).
   113  
   114  ```bash
   115  # agent-policy.hcl contains the following:
   116  node_prefix "" {
   117     policy = "write"
   118  }
   119  service_prefix "" {
   120     policy = "read"
   121  }
   122  ```
   123  
   124  This policy will allow all nodes to be registered and accessed and any service to be read. 
   125  Note, this simple policy is not recommended in production.
   126  It is best practice to create separate node policies and tokens for each node in the cluster
   127  with an exact-match node rule.
   128  
   129  We only need to create one policy and can do this on any of the servers. If you have not set the 
   130  `CONSUL_HTTP_TOKEN` environment variable to the bootstrap token, please refer to the previous step. 
   131  
   132  ```
   133  $ consul acl policy create -name "agent-token" -description "Agent Token Policy" -rules @agent-policy.hcl
   134  ID:           5102b76c-6058-9fe7-82a4-315c353eb7f7
   135  Name:         agent-policy
   136  Description:  Agent Token Policy
   137  Datacenters:
   138  Rules:
   139  node_prefix "" {
   140     policy = "write"
   141  }
   142  service_prefix "" {
   143     policy = "read"
   144  }
   145  ```
   146  
   147  The returned value is the newly-created policy that we can now use when creating our agent token. 
   148  
   149  ## Step 4: Create an Agent Token
   150  
   151  Using the newly created policy, we can create an agent token. Again we can complete this process on any of the servers. For this guide, all agents will share the same token. Note, the `SecretID` is the token used to authenticate API and CLI commands. 
   152  
   153  ```sh
   154  $ consul acl token create -description "Agent Token" -policy-name "agent-token"
   155  AccessorID:   499ab022-27f2-acb8-4e05-5a01fff3b1d1
   156  SecretID:     da666809-98ca-0e94-a99c-893c4bf5f9eb
   157  Description:  Agent Token
   158  Local:        false
   159  Create Time:  2018-10-19 14:23:40.816899 -0400 EDT
   160  Policies:
   161     fcd68580-c566-2bd2-891f-336eadc02357 - agent-token
   162  ```
   163  
   164  ## Step 5: Add the Agent Token to all the Servers
   165  
   166  Our final step for configuring the servers is to assign the token to all of our
   167  Consul servers via the configuration file and reload the Consul service 
   168  on all of the servers, one last time.
   169  
   170  ```json
   171  {
   172    "primary_datacenter": "dc1",
   173    "acl" : {
   174      "enabled" : true,
   175      "default_policy" : "deny",
   176      "down_policy" : "extend-cache",
   177      "tokens" : {
   178        "agent" : "da666809-98ca-0e94-a99c-893c4bf5f9eb"
   179      }
   180    }
   181  }
   182  ```
   183  
   184  ~> Note: In Consul version 1.4.2 and older any ACL updates
   185  in the agent configuration file will require a full restart of the 
   186  Consul service. 
   187  
   188  At this point we should no longer see the coordinate warning in the servers logs, however, we should continue to see that the node information is in sync.
   189  
   190  ```sh
   191  2018/12/11 15:34:20 [DEBUG] agent: Node info in sync
   192  ```
   193  
   194  It is important to ensure the servers are configured properly, before enable ACLs 
   195  on the clients. This will reduce any duplicate work and troubleshooting, if there
   196  is a misconfiguration.  
   197  
   198  #### Ensure the ACL System is Configured Properly
   199  
   200  Before configuring the clients, we should check that the servers are healthy. To do this, let's view the catalog.
   201  
   202  ```sh
   203  curl http://127.0.0.1:8500/v1/catalog/nodes -H 'x-consul-token: 4411f091-a4c9-48e6-0884-1fcb092da1c8' 
   204  [
   205      {
   206          "Address": "172.20.20.10",
   207          "CreateIndex": 7,
   208          "Datacenter": "kc",
   209          "ID": "881cfb69-2bcd-c2a9-d87c-cb79fc454df9",
   210          "Meta": {
   211              "consul-network-segment": ""
   212          },
   213          "ModifyIndex": 10,
   214          "Node": "fox",
   215          "TaggedAddresses": {
   216              "lan": "172.20.20.10",
   217              "wan": "172.20.20.10"
   218          }
   219      }
   220  ]
   221  ``` 
   222  
   223  All the values should be as expected. Particularly, if `TaggedAddresses` is `null` it is likely we have not configured ACLs correctly. A good place to start debugging is reviewing the Consul logs on all the servers.
   224  
   225  If you encounter issues that are unresolvable, or misplace the bootstrap token, you can reset the ACL system by updating the index. First re-run the bootstrap command to get the index number.
   226  
   227  ```
   228  $ consul acl bootstrap
   229  Failed ACL bootstrapping: Unexpected response code: 403 (Permission denied: ACL bootstrap no longer allowed (reset index: 13))
   230  ```
   231  
   232  Then write the reset index into the bootstrap reset file: (here the reset index is 13)
   233  
   234  ```
   235  $ echo 13 >> <data-directory>/acl-bootstrap-reset
   236  ```
   237  
   238  After reseting the ACL system you can start again at Step 2. 
   239  
   240  ## Step 6: Enable ACLs on the Consul Clients
   241  
   242  Since ACL enforcement also occurs on the Consul clients, we need to also restart them
   243  with a configuration file that enables ACLs. We can use the same ACL agent token that we created for the servers. The same token can be used because we did not specify any node or service prefixes.
   244  
   245  ```json
   246  {
   247    "acl" : {
   248      "enabled" : true,
   249      "down_policy" : "extend-cache",
   250      "tokens" : {
   251        "agent" : "da666809-98ca-0e94-a99c-893c4bf5f9eb"
   252      }
   253    }
   254  }
   255  ```
   256  
   257  To ensure the agent's are configured correctly, we can again use the `/catalog` endpoint. 
   258  
   259  ## Additional ACL Configuration
   260  
   261  Now that the nodes have been configured to use ACLs, we can configure the CLI, UI, and nodes to use specific tokens. All of the following steps are optional examples. In your own environment you will likely need to create more fine grained policies.
   262  
   263  #### Configure the Anonymous Token (Optional)
   264  
   265  The anonymous token is created during the bootstrap process, `consul acl bootstrap`. It is implicitly used if no token is supplied. In this section we will update the existing token with a newly created policy.
   266  
   267  At this point ACLs are bootstrapped with ACL agent tokens configured, but there are no
   268  other policies set up. Even basic operations like `consul members` will be restricted
   269  by the ACL default policy of "deny":
   270  
   271  ```
   272  $ consul members
   273  ```
   274  
   275  We will not receive an error, since the ACL has filtered what we see and we are not allowed to
   276  see any nodes by default.
   277  
   278  If we supply the token we created above we will be able to see a listing of nodes because
   279  it has write privileges to an empty `node` prefix, meaning it has access to all nodes:
   280  
   281  ```bash
   282  $ CONSUL_HTTP_TOKEN=4411f091-a4c9-48e6-0884-1fcb092da1c8 consul members
   283  Node  Address            Status  Type    Build  Protocol  DC   Segment
   284  fox   172.20.20.10:8301  alive   server  1.4.0  2         kc  <all>
   285  bear  172.20.20.11:8301  alive   server  1.4.0  2         kc  <all>
   286  wolf  172.20.20.12:8301  alive   server  1.4.0  2         kc  <all>
   287  ```
   288  
   289  It is common in many environments to allow listing of all nodes, even without a
   290  token. The policies associated with the special anonymous token can be updated to
   291  configure Consul's behavior when no token is supplied. The anonymous token is managed
   292  like any other ACL token, except that `anonymous` is used for the ID. In this example
   293  we will give the anonymous token read privileges for all nodes:
   294  
   295  ```bash
   296  $ consul acl policy create -name 'list-all-nodes' -rules 'node_prefix "" { policy = "read" }'
   297  ID:           e96d0a33-28b4-d0dd-9b3f-08301700ac72
   298  Name:         list-all-nodes
   299  Description:
   300  Datacenters:
   301  Rules:
   302  node_prefix "" { policy = "read" }
   303  
   304  $ consul acl token update -id 00000000-0000-0000-0000-000000000002 -policy-name list-all-nodes -description "Anonymous Token - Can List Nodes"
   305  Token updated successfully.
   306  AccessorID:   00000000-0000-0000-0000-000000000002
   307  SecretID:     anonymous
   308  Description:  Anonymous Token - Can List Nodes
   309  Local:        false
   310  Create Time:  0001-01-01 00:00:00 +0000 UTC
   311  Hash:         ee4638968d9061647ac8c3c99e9d37bfdd2af4d1eaa07a7b5f80af0389460948
   312  Create Index: 5
   313  Modify Index: 38
   314  Policies:
   315     e96d0a33-28b4-d0dd-9b3f-08301700ac72 - list-all-nodes
   316  
   317  ```
   318  
   319  The anonymous token is implicitly used if no token is supplied, so now we can run
   320  `consul members` without supplying a token and we will be able to see the nodes:
   321  
   322  ```bash
   323  $ consul members
   324  Node  Address            Status  Type    Build  Protocol  DC   Segment
   325  fox   172.20.20.10:8301  alive   server  1.4.0  2         kc  <all>
   326  bear  172.20.20.11:8301  alive   server  1.4.0  2         kc  <all>
   327  wolf  172.20.20.12:8301  alive   server  1.4.0  2         kc  <all>
   328  ```
   329  
   330  The anonymous token is also used for DNS lookups since there is no way to pass a
   331  token as part of a DNS request. Here's an example lookup for the "consul" service:
   332  
   333  ```
   334  $ dig @127.0.0.1 -p 8600 consul.service.consul
   335  
   336  ; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 consul.service.consul
   337  ; (1 server found)
   338  ;; global options: +cmd
   339  ;; Got answer:
   340  ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 9648
   341  ;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
   342  ;; WARNING: recursion requested but not available
   343  
   344  ;; QUESTION SECTION:
   345  ;consul.service.consul.         IN      A
   346  
   347  ;; AUTHORITY SECTION:
   348  consul.                 0       IN      SOA     ns.consul. postmaster.consul. 1499584110 3600 600 86400 0
   349  ```
   350  
   351  Now we get an `NXDOMAIN` error because the anonymous token doesn't have access to the
   352  "consul" service. Let's update the anonymous token's policy to allow for service reads of the "consul" service.
   353  
   354  ```bash
   355  $ consul acl policy create -name 'service-consul-read' -rules 'service "consul" { policy = "read" }'
   356  ID:           3c93f536-5748-2163-bb66-088d517273ba
   357  Name:         service-consul-read
   358  Description:
   359  Datacenters:
   360  Rules:
   361  service "consul" { policy = "read" }
   362  
   363  $ consul acl token update -id 00000000-0000-0000-0000-000000000002 --merge-policies -description "Anonymous Token - Can List Nodes" -policy-name service-consul-read
   364  Token updated successfully.
   365  AccessorID:   00000000-0000-0000-0000-000000000002
   366  SecretID:     anonymous
   367  Description:  Anonymous Token - Can List Nodes
   368  Local:        false
   369  Create Time:  0001-01-01 00:00:00 +0000 UTC
   370  Hash:         2c641c4f73158ef6d62f6467c68d751fccd4db9df99b235373e25934f9bbd939
   371  Create Index: 5
   372  Modify Index: 43
   373  Policies:
   374     e96d0a33-28b4-d0dd-9b3f-08301700ac72 - list-all-nodes
   375     3c93f536-5748-2163-bb66-088d517273ba - service-consul-read
   376  ```
   377  
   378  With that new policy in place, the DNS lookup will succeed:
   379  
   380  ```
   381  $ dig @127.0.0.1 -p 8600 consul.service.consul
   382  
   383  ; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 consul.service.consul
   384  ; (1 server found)
   385  ;; global options: +cmd
   386  ;; Got answer:
   387  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46006
   388  ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
   389  ;; WARNING: recursion requested but not available
   390  
   391  ;; QUESTION SECTION:
   392  ;consul.service.consul.         IN      A
   393  
   394  ;; ANSWER SECTION:
   395  consul.service.consul.  0       IN      A       127.0.0.1
   396  ```
   397  
   398  The next section shows an alternative to the anonymous token.
   399  
   400  #### Set Agent-Specific Default Tokens (Optional)
   401  
   402  An alternative to the anonymous token is the [`acl.tokens.default`](/docs/agent/options.html#acl_tokens_default)
   403  configuration item. When a request is made to a particular Consul agent and no token is
   404  supplied, the [`acl.tokens.default`](/docs/agent/options.html#acl_tokens_default) will be used for the token, instead of being left empty which would normally invoke the anonymous token.
   405  
   406  This behaves very similarly to the anonymous token, but can be configured differently on each
   407  agent, if desired. For example, this allows more fine grained control of what DNS requests a
   408  given agent can service or can give the agent read access to some key-value store prefixes by
   409  default.
   410  
   411  If using [`acl.tokens.default`](/docs/agent/options.html#acl_tokens_default), then it's likely the anonymous token will have a more restrictive policy than shown in these examples.
   412  
   413  #### Create Tokens for UI Use (Optional)
   414  
   415  If you utilize the Consul UI with a restrictive ACL policy, as above, the UI will not function fully using the anonymous ACL token. It is recommended that a UI-specific ACL token is used, which can be set in the UI during the web browser session to authenticate the interface.
   416  
   417  First create the new policy.
   418  
   419  ```bash
   420  $ consul acl policy create -name "ui-policy" \
   421                             -description "Necessary permissions for UI functionality" \
   422                             -rules 'key_prefix "" { policy = "write" } node_prefix "" { policy = "read" } service_prefix "" { policy = "read" }'
   423  ID:           9cb99b2b-3c20-81d4-a7c0-9ffdc2fbf08a
   424  Name:         ui-policy
   425  Description:  Necessary permissions for UI functionality
   426  Datacenters:
   427  Rules:
   428  key_prefix "" { policy = "write" } node_prefix "" { policy = "read" } service_prefix "" { policy = "read" }
   429  ```
   430  
   431  With the new policy, create a token.
   432  
   433  ```sh
   434  $ consul acl token create -description "UI Token" -policy-name "ui-policy"
   435  AccessorID:   56e605cf-a6f9-5f9d-5c08-a0e1323cf016
   436  SecretID:     117842b6-6208-446a-0d1e-daf93854857d
   437  Description:  UI Token
   438  Local:        false
   439  Create Time:  2018-10-19 14:55:44.254063 -0400 EDT
   440  Policies:
   441     9cb99b2b-3c20-81d4-a7c0-9ffdc2fbf08a - ui-policy
   442  ```
   443  
   444  The token can then be set on the "settings" page of the UI.
   445  
   446  Note, in this example, we have also given full write access to the KV through the UI.
   447  
   448  ## Summary
   449  
   450  The [ACL API](/api/acl/acl.html) can be used to create tokens for applications specific to their intended use and to create more specific ACL agent tokens for each agent's expected role. 
   451  Now that you have bootstrapped ACLs, learn more about [ACL rules](/docs/agent/acl-rules.html)
   452  
   453  ### Notes on Security 
   454  
   455  In this guide we configured a basic ACL environment with the ability to see all nodes
   456  by default, but with limited access to discover only the "consul" service. If your environment has stricter security requirements we would like to note the following and make some additional recommendations. 
   457  
   458  1. In this guide we added the agent token to the configuration file. This means the tokens are now saved on disk. If this is a security concern, tokens can be added to agents using the [Consul CLI](https://www.consul.io/docs/commands/acl/acl-set-agent-token.html). However, this process is more complicated and takes additional care. 
   459  
   460  2. It is recommended that each client get an ACL agent token with `node` write privileges for just its own node name, and `service` read privileges for just the service prefixes expected to be registered on that client.
   461  
   462  3. [Anti-entropy](/docs/internals/anti-entropy.html) syncing requires the ACL agent token
   463  to have `service:write` privileges for all services that may be registered with the agent.
   464  We recommend providing `service:write` for each separate service via a separate token that 
   465  is used when registering via the API, or provided along with the [registration in the 
   466  configuration file](https://www.consul.io/docs/agent/services.html). Note that `service:write`
   467  is the privilege required to assume the identity of a service and so Consul Connect's
   468  intentions are only enforceable to the extent that each service instance is unable to gain 
   469  `service:write` on any other service name. For more details see the Connect security
   470  [documentation](https://www.consul.io/docs/connect/security.html).
   471  
   472