consul配置ACL

consul配置ACL

第0步,几点说明

  1. Consul和其他系统ACL的区别
  • 通常的ACL授权例如etcd使用用户名:密码对的方式来认证用户,用户名是可能是公开的,密码是保密的用户自己知道;但是consul没有使用用户名:密码对的方式,就使用一个token值;那么既然只有一个值,就必须注意保密,不能使用约定的名字字符串,例如root, tom, jerry等,因为别人很容易猜出来,现在consul使用的字符串时UUID,既唯一又随机,不能被猜出来。
  • consul的三类权限类型
    • read: 读
    • write: 读和写
    • deny: 不能访问,既不能读也不能写了。

第一步,激活ACL

consul的ACL激活需要在所有的consul节点上,办法是,创建一个json格式的配置文件:

$ cat consul-acl.json 
{
  "acl" : {
    "enabled" : true,
    "default_policy" : "deny",
    "down_policy" : "extend-cache",
    "tokens" :{
        "master": "245d0a09-7139-bbea-aadc-ff170a0562b1"
    }
  }
}

放置到consul agent通过参数-config-dir指定的目录下面,缺省目录是:/consul/config/
注意几点:

  1. 这个相同的文件需要部署到所有的consul节点上。
  2. 关于tokens.master值,这个就是Bootstrap Token
    2.1 Bootstrap Token相当于Unix系统中的root,具有所有的权限。
    2.2. 其名字可以是任意字符串,不一定是一个UUID值。(原因如前面说,使用UUID为了安全用户无法猜测。)
    2.3. tokens.master可以不需要配置,然后在clustor启动之后通过命令产生,如下:
$ consul acl bootstrap
AccessorID:   0274a9e3-1349-78d7-fc53-3dd6f7886626
SecretID:     245d0a09-7139-bbea-aadc-ff170a0562b1
Description:  Bootstrap Token (Global Management)
Local:        false
Create Time:  2019-01-15 06:21:17.335464249 +0000 UTC
Policies:
   00000000-0000-0000-0000-000000000001 - global-management

此时产生的bookstrap就是字符串SecretID: 245d0a09-7139-bbea-aadc-ff170a0562b1。
注意这个bootstrap token的安全不能外泄,不能丢失,后面的创建其他token都需要用到它。

第二步:token的三种类型

  1. management token: 具有root权限的token,前面介绍的master token就属于这类。也可以增加新的management token。
  2. client token: 针对客户端的token,ACL的权限管理主要是针对这类token;当创建client token时需要一个management toke。
  3. anonymous token : 这是系统内置的token。

第三步:创建一个management token

$ curl \
    -H "X-Consul-Token: secret" \
    -X PUT \
    -d '{"Name": "dc1", "Type": "management"}' \
    http://localhost:8500/v1/acl/create?token=245d0a09-7139-bbea-aadc-ff170a0562b1
{"ID":"7fa04e1d-1b75-81b0-52d3-e311ad3c28f7"}

参数token就是另一个management token,在这个例子中就是bootstrap token。这样7fa04e1d-1b75-81b0-52d3-e311ad3c28f7就是另外一个management token了,具有"root"的权限。

第四步:创建client token

client token才是真正需要对其授权的token。
创建一个client token需要两步,先创建client policy,然后才能创建client token。

4.1 创建client policy

$ cat client-policy.json 
{
  "Name": "client-read-policy",
  "Description": "Grants read access to all node information",
  "Rules": "node_prefix \"\" { policy = \"read\"}",
  "Datacenters": ["dc1"]
}

$ curl --request PUT --data @client-policy.json http://127.0.0.1:8500/v1/acl/policy?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f
{
  "ID":"778192cf-5459-a6e0-99d6-74919ea61dfc",
  "Name":"client-read-policy",
  "Description":"Grants read access to all node information",
  "Rules":"key_prefix \"\" { policy = \"read\"}",
  "Datacenters":["dc1"],
  "Hash":"0lcW+0xrcZ6OxTwb3ND+7oA+FF8XhXj60J8KGFpEZI0=",
  "CreateIndex":105,
  "ModifyIndex":105
}

$ curl -X GET http://127.0.0.1:8500/v1/acl/policies?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f
[
    {
        "CreateIndex": 4,
        "Datacenters": null,
        "Description": "Builtin Policy that grants unlimited access",
        "Hash": "swIQt6up+s0cV4kePfJ2aRdKCLaQyykF4Hl1Nfdeumk=",
        "ID": "00000000-0000-0000-0000-000000000001",
        "ModifyIndex": 4,
        "Name": "global-management"
    },
    {
        "CreateIndex": 105,
        "Datacenters": ["dc1" ],
        "Description": "Grants read access to all node information",
        "Hash": "0lcW+0xrcZ6OxTwb3ND+7oA+FF8XhXj60J8KGFpEZI0=",
        "ID": "778192cf-5459-a6e0-99d6-74919ea61dfc",
        "ModifyIndex": 105,
        "Name": "client-read-policy"
    }
]

注意这里client-policy.json里面Rules可以为node_prefix, service_prefix,和key_prefix;在我这个例子中只使用了key_prefix因为我们只需要KV访问,没有service discover功能。

4.2 创建client token

$ cat client-token.json 
{
   "Description": "client read token",
   "Policies": [
      {
         "Name": "client-read-policy"
      }
   ],
   "Local": false
}

$ curl --request PUT --data @client-token.json http://127.0.0.1:8500/v1/acl/token?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f
{
    "AccessorID": "25be308f-43c0-11c8-e620-117e6b91629d",
    "CreateIndex": 115,
    "CreateTime": "2019-01-15T08:00:04.241925426Z",
    "Description": "client read token",
    "Hash": "AZ2/M3PRNDcTULjWcpC8eb6EPVoGUHnCKa0nQghKN0I=",
    "Local": false,
    "ModifyIndex": 115,
    "Policies": [
        {
            "ID": "778192cf-5459-a6e0-99d6-74919ea61dfc",
            "Name": "client-read-policy"
        }
    ],
    "SecretID": "23fe12e4-ac0e-00af-db43-887589f87823"
}

$ curl -X GET http://127.0.0.1:8500/v1/acl/tokens?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f
[
    {
        "AccessorID": "25be308f-43c0-11c8-e620-117e6b91629d",
        "CreateIndex": 115,
        "CreateTime": "2019-01-15T08:00:04.241925426Z",
        "Description": "client read token",
        "Hash": "AZ2/M3PRNDcTULjWcpC8eb6EPVoGUHnCKa0nQghKN0I=",
        "Local": false,
        "ModifyIndex": 115,
        "Policies": [
            {
                "ID": "778192cf-5459-a6e0-99d6-74919ea61dfc",
                "Name": "client-read-policy"
            }
        ]
    },
    ...
]

4.3 上述两步可以合并成一步执行

不过这个API已经被consul标记位Legacy Tokens了。

$ cat client-write-policy.json
{                      
  "Name": "client-write-policy",
  "Description": "Grants write access to foo key information",
  "Type": "client",
  "Rules": "key \"foo/test\" { policy = \"write\" }"
}

$ curl --request PUT --data @client-write-policy.json \
  http://127.0.0.1:8500/v1/acl/create?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f
{"ID":"1c7c1ca0-d5ee-9d02-f7f4-89dc8759f0c6"}

$ curl -H "X-Consul-Token: 1c7c1ca0-d5ee-9d02-f7f4-89dc8759f0c6" http://127.0.0.1:8500/v1/acl/token/self
{
    "AccessorID": "808d69bf-c4fe-0c9f-9a57-aecd85e7f24e",
    "CreateIndex": 36,
    "CreateTime": "0001-01-01T00:00:00Z",
    "Description": "client-write-policy",
    "Hash": "mpZmxlI5Zi6HeMFQR0A7U77ZD9IKPDr9Nc9Hrqxz/b8=",
    "Local": false,
    "ModifyIndex": 37,
    "Policies": null,
    "Rules": "key \"foo/test\" { policy = \"write\" }",
    "SecretID": "1c7c1ca0-d5ee-9d02-f7f4-89dc8759f0c6"
}

第五步, 客户端访问测试

验证,创建一个KV,然后使用client token访问KV:

$ curl --request PUT --data 'hello consul' http://127.0.0.1:8500/v1/kv/foo?token=753cc134-36c5-e4ea-6abd-56f8b8b8aa7f

$ curl --request GET http://127.0.0.1:8500/v1/kv/foo?token=23fe12e4-ac0e-00af-db43-887589f87823
[{"LockIndex":0,"Key":"foo","Flags":0,"Value":"aGVsbG8gY29uc3Vs","CreateIndex":14,"ModifyIndex":14}]

# suppose another token does not have priviledge
$ curl --request GET http://127.0.0.1:8500/v1/kv/foo?token=477ef15e-79b3-8481-b7db-ed7c750b3bea
rpc error making call: rpc error making call: Permission denied

猜你喜欢

转载自blog.csdn.net/weixin_34259159/article/details/86887557
今日推荐