Consul使用ACL来保护UI, API, CLI, 以及service之间, agent之间的通信。工作原理是一个ACL policy关联一系列ACL规则, 然后把ACL token和policy关联起来。
Consul中的ACL主要有以下两个主要部分:
ACL Policies: Acl rules的逻辑分组, 使得acl规则可重用。
ACL Tokens: 每个ACL token有一个Accessor ID用来命名这个token, 一个Secret ID用来作为bearer token进行授权验证。
ACL Policy
ACL Policy是一组acl规则的集合, 可配置的属性如下:
ID
Name
Description
Rules: 一组规则, 授权或者拒绝
Datacenters: 适用的数据中心
Namespace: 命令空间(只对企业版有用)
另外有两个内置的策略:
Global Management: 包含任何权限,有个默认的名字global-management
, 以及ID00000000-0000-0000-0000-000000000001
, 只能被重命名, 其他不能修改。
Namespace Management: 没创建一个命名空间就会有一个命名空间policy被创建, 名称为namespace-management
, 可以修改。
ACL Tokens
ACL token决定调用者是否有相应的权限, 每个ACL token由以下元素组成:
Accessor ID: token的唯一公开标识码
Secret ID:用于鉴权的token
Description: 描述
Policy Set: 使用的policy列表
Service Identity Set
Locality: 是否只适用于当前数据中心, 还是所有数据中心
Expiration Time: 过期时间
Namespace
当集群启用ACL时集群会生成两个token:
Anonnymous Token: 匿名token, 当请求没有指定token时使用这个token。这个token的描述和policy可以改, 但不能删除, 新建时它的Accessor ID是00000000-0000-0000-0000-000000000002
, Secret ID是anonymous
。
Master Token: 关联Global Management Policy
, 拥有所有权限, 值在配置项中指定。
具体的配置查看https://www.consul.io/docs/acl/acl-system.html#configuring-acls
ACL Rules
一条ACL规则由资源, 部分和策略组成, 结构如下:
<resource> "<segment>" {
policy = "<policy disposition>"
}
Policy可以为:
read: 可读不可改
write: 可读可改
deny: 不可读不可改
list: 允许列表显示Consul KV中的指定键值下的内容
ACL资源规则:
通过resource可以指定限制的各种资源。
agent
和agent_prefix
限制Agent API中的操作。
event
和event_prefix
限制Event API中的操作。
key
和key_prefix
限制KV API中的操作。
list
,当开启acl.enabe_key_list_policy
时限制递归显示列表的权限。
keyring
限制Keyring API的操作。
node
和node_prefix
限制Catalog API中的节点注册及读权限等。
operator
限制集群的Operator API的操作, 除了Keyring API。
query
和query_prefix
限制对于Prepared Query API的操作。
service
和service_prefix
限制Catalog API的服务注册及读取等权限, 以及Health API。
session
和session_prefix
限制对于Session API的操作权限。
namespace
和namespace_prefix
限制对于命名空间的操作权限。
创建policy步骤详见:https://learn.hashicorp.com/consul/day-0/acl-guide
Connect
Consul Connect提供了service之间通信的连接加密(通过TLS)及授权(通过connect intention)。
在Consul中可以通过sidecar proxies
为每个service配置一个proxy, 自动处理进来和出去的连接。
如果sidecar proxies
对应用程序的性能造成了影响, 则可以使用Native proxy。所谓Native proxy即是由应用程序自己处理加密的链接(获取TLS证书, 验证证书, 验证连接等等), 目前Consul只为Go提供了库方便处理加密链接。
当然也可以把proxy配置成一个单独的服务。
如果想要所有链接都是加密的, 可以使service监听本地地址, 让Connect中的proxy来处理外部请求.
Connect的配置
如果需要启用Connect, 加入如下配置:
connect {
enabled = true
}
Connect会配置使用内置CA来创建和管理证书, 当然也可以指定其他的外部的证书管理系统。
可以通过配置项来配置全局的默认的proxy配置。
Consul可以使用内置的proxy来测试和开发https://www.consul.io/docs/connect/proxies/built-in.html
也可以和第三方proxy集成:https://www.consul.io/docs/connect/proxies/envoy.html
Intentions
Connect中的授权即是通过intention来实现的。当一个service通过connect请求建立连接时, 首先验证TLS证书是否合法, 然后调用authoriza API来验证intention配置是否允许建立连接。
默认的intention行为受默认的ACL Poliy影响, 如果ACL Policy默认允许所有链接则intention默认允许所有链接,如果policy默认拒绝所有链接, 则intention默认拒绝所有链接。
Intention可以通过API, CLI和UI来管理。
示例配置:
consul intention create -deny web db
拒绝从web service 到db service的连接。
还可以使用通配符:
consul intention create -deny web '*'
以及元数据:
consul intention create
-deny
-meta description='Hello there'
web db
元数据在Consul中没有作用, 不过可以被外部系统使用。
Intention的权限
ACL也可以保护Intention。Intention的权限是基于目标service的。授权service:read或者service:write的时候, 默认会隐式地授予intentions:read 的权限, 因为service需要知道是否需要授权给进来的连接。
以下会隐式授予读权限:
service "web" {
policy = "write"
}
也可以显示配置intention的权限, 如下:
service "web" {
policy = "read"
intentions = "deny"
}