Consul ACL

Warning: consul 1.4.0 之后启用了全新的ACL系统,所以网上很多教程都是废的….

0.1 Consul和其他系统ACL的区别

  • 通常的ACL授权例如etcd使用 用户名 + 密码对的方式来认证用户,用户名是可能是公开的,密码是保密的用户自己知道;
  • 但是consul就使用一个token值,那么既然只有一个值,就必须注意保密,不能使用约定的名字字符串,例如root, jerry,因为别人很容易猜出来,现在consul使用的字符串时UUID,既唯一又随机,不能被猜出来;

0.2 consul的三类权限类型

  • read: 读;
  • write: 读和写;
  • deny: 不能访问,既不能读也不能写;

0.3 Bootstrap Token

  • Bootstrap Token相当于Unix系统中的root,具有所有的权限, 其名字可以是任意字符串,不一定是一个UUID值;
  • 一旦ACL被启用,我们就可以创建第一个token(bootstrp token)了, 该token具有无限制的权限,且会在master token被启用后自动失效;
  • 官方不建议在命令行通过-token来使用token, 而是在系统环境变量里声明export CONSUL_HTTP_TOKEN=8260a957-679e-9b63-cdbf-535dbd79cac6
  • bootstrap token 也可用于master token;
  • 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 ACL API !

输出的SecretID即为Bootstrap Token:

[root@consul-1 ~]# consul acl bootstrap
 
AccessorID:   26a912bd-6d34-5c66-490b-5e3cc4262fb4
SecretID:     8260a957-679e-9b63-cdbf-535dbd79cac6
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2019-04-13 00:48:15.478247649 +0800 CST
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

使用刚创建的 Bootstrap Token来查看consul cluster信息:

consul members -token 8260a957-679e-9b63-cdbf-535dbd79cac6
consul catalog nodes -token 8260a957-679e-9b63-cdbf-535dbd79cac6

Note: 本文不用 “consul acl bootstrap” 命令来生成 bootstrp token,而是直接自定义一个uuid,并写入配置文件.

配置acl.json:

# 生成随机uuid
cat /proc/sys/kernel/random/uuid
8260a957-679e-9b63-cdbf-535dbd79cac6

配置uuid为master token: 1) 2)

cat > /usr/local/consul/conf/acl.json <<'EOF'
{
  "acl": {
    "enabled": true,
    "default_policy": "deny",
    "down_policy": "extend-cache",
        "tokens" :{
        "master": "8260a957-679e-9b63-cdbf-535dbd79cac6"
    }
  }
}
EOF
  • 这个相同的文件需要部署到所有的consul节点上,并重启以便consul cluster能加载此配置;
  • extend-cache: 当policy或token无法从Consul servers获取到时,使用已缓存的 ACL;

依次重启consul节点:

systemctl restart consul

输出下面的日志表明ACL启用成功:

2019/04/16 17:50:03 [WARN] agent: Coordinate update blocked by ACLs
2019/04/16 17:50:08 [INFO] agent: Synced node info

Note: 这一步主要是为了生成agent token, 如果不是特别的安全要求,使用master token也是可以的.

Token的几种类型:

  • management token: 具有root权限的token,前面介绍的master token就属于这类,也可以增加新的management token;
  • client token: 针对客户端的token,ACL的权限管理主要是针对这类token;当创建client token时需要一个management toke;
  • anonymous token: 这是系统内置的token, 像默认参数,比如consul members 这种命令就会使用到,而不用额外指定token;
  • agent token: Used for clients and servers to perform internal operations. If this isnt specified, then the default will be used.

为了集群的安全,我们需要利用最开始随机生成的bootstrap token来创建另外一个management token,后面集群几点间就要使用这个token:

curl \
    -H "X-Consul-Token: secret" \
    -X PUT \
    -d '{"Name": "dc1", "Type": "management"}' \
    http://localhost:8500/v1/acl/create?token=8260a957-679e-9b63-cdbf-535dbd79cac6
{"ID":"c6aef7d8-d13c-1eea-c329-e6e719f57f4f"}

再将得到的这个token作为agent token写入配置文件,并重启集群:

cat > /usr/local/consul/conf/acl.json <<'EOF'
{
  "acl": {
    "enabled": true,
    "default_policy": "deny",
    "down_policy": "extend-cache",
    "tokens" :{
        "master": "8260a957-679e-9b63-cdbf-535dbd79cac6",
        "agent": "c6aef7d8-d13c-1eea-c329-e6e719f57f4f"
    }
  }
}
EOF
# 重启集群全部节点
systemctl restart consul

再次检查集群状态:

consul members -token "c6aef7d8-d13c-1eea-c329-e6e719f57f4f"
Node      Address           Status  Type    Build  Protocol  DC   Segment
consul-1  172.17.2.30:8301  alive   server  1.4.4  2         dc1  <all>
consul-2  172.17.2.31:8301  alive   server  1.4.4  2         dc1  <all>
consul-3  172.17.2.32:8301  alive   server  1.4.4  2         dc1  <all>
 
consul catalog nodes -token "c6aef7d8-d13c-1eea-c329-e6e719f57f4f"
Node      ID        Address      DC
consul-1  543566c9  172.17.2.30  dc1
consul-2  6049296a  172.17.2.31  dc1
consul-3  bce6eee6  172.17.2.32  dc1

  • ACL policies: a policy is a set of rules grouped together in a logical unit that can be reused and linked with many tokens;
  • ACL tokens: a token is associated with one ACL policy and is authorized for resource access.

Note: Client token 才是真正需要对齐授权的token,创建一个Client token需要两步: 先client policy,然后才能创建client token.

3.1 创建Token Policy

Note: 在consul cluster的其中一个点来操作就可以了,这里我将创建一个token,用于HTTP API远程管理KV …

# dns-policy.hcl 
cat > dns-policy.hcl <<'EOF'
key_prefix "" {
  policy = "read"
}
key_prefix "dns/" {
  policy = "write"
}
operator = "read"
EOF
# 声明变量,方便命令行调用
export CONSUL_HTTP_TOKEN=c6aef7d8-d13c-1eea-c329-e6e719f57f4f
# 创建policy
consul acl policy create -name "api-token-dns" -description "HTTP API Token Policy for dns KV" -rules @dns-policy.hcl
# 查看policy列表
curl -X GET http://127.0.0.1:8500/v1/acl/policies?token="c6aef7d8-d13c-1eea-c329-e6e719f57f4f" | jq
consul acl policy list

3.2 创建Token

为HTTP API创建token,用于远程curl调用API使用:

consul acl token create -description "HTTP API Token for dns" -policy-name "api-token-dns"
 
AccessorID:   efdbe6d1-b771-7277-cd91-7862020e7ded
SecretID:     d0f435b0-a1e6-bc9d-fc3f-f595e2410777
Description:  HTTP API Token for dns
Local:        false
Create Time:  2019-04-15 11:49:49.705100991 +0800 CST
Policies:
   ce1810ac-f069-7a9b-5276-b115025b9348 - api-token-dns

测试HTTP API的token:

# consul 本地命令
consul kv put -token d0f435b0-a1e6-bc9d-fc3f-f595e2410777 dns/foo bar
Success! Data written to: dns/foo
 
# 远程HTTP API
curl -sXPUT -d bar http://127.0.0.1:8500/v1/kv/dns/foo -H 'x-consul-token: d0f435b0-a1e6-bc9d-fc3f-f595e2410777'
true
 
# 查看foo
curl -sXGET http://127.0.0.1:8500/v1/kv/dns/foo?raw -H 'x-consul-token: d0f435b0-a1e6-bc9d-fc3f-f595e2410777'

因为开启了ACL,所以consul members这种查询节点的命令都不会有返回,但是为了这样的一些命令可以直接输出,所以设置匿名token,方便使用:

consul acl policy create -name 'list-all-nodes' -rules 'node_prefix "" { policy = "read" }'
consul acl token update -id 00000000-0000-0000-0000-000000000002 -policy-name list-all-nodes -description "Anonymous Token - Can List Nodes"

curl -s http://127.0.0.1:8500/v1/catalog/nodes -H 'x-consul-token: 8260a957-679e-9b63-cdbf-535dbd79cac6' | jq

我在consul-1节点上“export CONSUL_HTTP_TOKEN”的, 所以目前在该节点上,可以直接:

consul kv put foo bar

但是要通过HTTP API的话还是得:

curl -sXPUT -d mrco http://127.0.0.1:8500/v1/kv/name1 -H 'x-consul-token: 8260a957-679e-9b63-cdbf-535dbd79cac6'

如果token忘记了,或者其他问题搞不定了,就可以考虑重置 bootstrap token:

# 执行命令
consul acl bootstrap
# 返回
Failed ACL bootstrapping: Unexpected response code: 403 (Permission denied: ACL bootstrap no longer allowed (reset index: 13))
 
# Then write the reset index into the bootstrap reset file: (here the reset index is 13)
$ echo 13 >> <data-directory>/acl-bootstrap-reset
# 重新生成 bootstrap token
consul acl bootstrap


1)
When a master token is present within the Consul configuration, it is created and will be linked With the builtin Global Management policy giving it unrestricted privileges. The master token is created with the Secret ID set to the value of the configuration entry.
2)
此时只能自定义master token,agent token必须在启用master token后,利用API来生成,然后再回填到acl.json里
  • linux/consul/consul_acl.txt
  • 最后更改: 2019/04/18 13:47
  • 由 mrco