Consul 使用訪問控制列表 (ACL) 來保護 UI、API、CLI、服務通信和 agent 通信,本文主要介紹 Consul ACL 的基本概念及使用,文中所使用到的軟件版本:Consul 1.11.1。
1、Consul ACL 概述
ACL 的核心是將規則分組到策略中,然后將一個或多個策略與令牌相關聯。
在最高級別,ACL 系統有兩個主要組件:
ACL Policies:策略允許將一組規則分組到一個邏輯單元中,該邏輯單元可以重用並與許多令牌關聯。
ACL Tokens:訪問 Consul 需要攜帶 Token 進行認證;每個 ACL Token 對應一個 Accessor ID 和一個 Secret ID。Accessor ID 被用來命名 Token,Secret ID 被作為 Token 用於與 Consul 的通信。
在多數情況下,Policies 和 Tokens 足夠了;但其他組件可用於更高級的設置:
ACL Roles:角色允許將一組策略和服務標識分組到可應用於多個令牌的可重用的高級實體中。(1.5.0 中新增)
ACL Service Identities:服務標識是一個策略模板,表示一個策略鏈接。(1.5.0 中新增)
ACL Node Identities:節點標識是一個策略模板,表示一個策略鏈接。(1.5.0 中新增)
ACL Auth Methods and Binding Rules:身份驗證方法針對受信任的外部方執行身份驗證,以授權創建可在本地數據中心內使用的 ACL 令牌。。(1.8.1 中新增)
1.1、ACL Policies
ACL policies 包含如下屬性:
Attribute | Description | Required | Default |
---|---|---|---|
ID |
The policy's auto-generated public identifier. | N/A | N/A |
name |
Unique name for the policy. | Required | none |
description |
Human readable description of the policy. | Optional | none |
rules |
Set of rules granting or denying permissions. See the Rule Specification documentation for more details. | Optional | none |
datacenter |
Datacenter in which the policy is valid. More than one datacenter can be specified. | Optional | none |
namespace |
ENTERPRISE
Namespace in which the policy is valid. Added in Consul Enterprise 1.7.0. |
Optional | default |
partition |
ENTERPRISE
Admin partition in which the policy is valid. Added in Consul Enterprise 1.11.0 |
Optional | default |
查看已有策略:
consul acl policy list -format json -token <token>
內置策略:
Global Management:擁有超級權限,只能修改名稱,不能修改其他屬性
Namespace Management:企業版的內置策略,相當於社區版的 Global Management
策略管理:對應策略的增刪改查都可以方便的通過控制台來進行操作,當然也可以通過命令行或API,這里就不詳述了,可分別參考官網文檔:https://www.consul.io/commands/acl/policy、https://www.consul.io/api-docs/acl/policies。
1.2、ACL Service Identities
服務標識包含如下元素:
Service Name:服務名稱
Datacenters:數據中心列表 (可選)
參與服務網格的服務需要具有被發現和發現其他正常服務實例的權限。合適的策略往往看起來幾乎完全相同,因此服務標識是一個策略模板,可幫助避免創建樣板策略。在授權過程中,配置的服務標識將自動作為策略應用;服務標識的 ACL 規則如下:
# 運行注冊相應的服務 service "<Service Name>" { policy = "write" } service "<Service Name>-sidecar-proxy" { policy = "write" } # 允許訪問任何服務 service_prefix "" { policy = "read" } node_prefix "" { policy = "read" }
1.3、ACL Node Identities
節點標識包含如下元素:
Node Name:節點名稱
Datacenter:數據中心
在授權過程中,配置的節點標識將自動作為策略應用;節點標識的 ACL 規則如下:
# 允許注冊該節點到集群 node "<Node Name>" { policy = "write" } # 允許檢測和比較注冊到自身的服務 service_prefix "" { policy = "read" }
1.4、ACL Roles
角色包含如下元素:
ID:角色 id
Name:角色名稱
Description:描述(可選)
Policy Set:策略集合
Service Identity Set:服務標識符集合.
Namespace ENTERPRISE:命名空間 (企業版 1.7.0 新增)
可以通過控制來方便的創建、刪除角色。
1.5、ACL Tokens
Consul 使用 Token 來確定調用方是否有權執行操作,Token 包含如下元素:
Accessor ID:token 唯一標識
Secret ID:token
Policy Set:策略集合
Role Set:角色集合(1.5.0 新增)
Service Identity Set:服務標識集合(1.5.0 新增)
Local:是否為本中心的 token
CreateTime:token 創建時間
Expiration Time:token 過期時間(1.5.0 新增)
Namespace ENTERPRISE:命名空間(企業版 1.7.0 新增)
Partition ENTERPRISE: 分區(企業版 1.11.0 新增)
查看已有 Token:
consul acl token list -format json -token <token_id>
內置 Token:
Anonymous Token:訪問 Consul 時如果未修改 Token,則使用該 Token;Accessor ID 為 00000000-0000-0000-0000-000000000002,Secret ID 為 anonymous。
Initial Management Token:Global Management 策略對應的 Token;在 Consul 1.4 - 1.10 中,這被稱為 master token。在 Consul 1.11 中,它被重命名為 initial_management Token。
1.6、ACL Rules
ACL Rules 描述對資源的訪問權限,它資源聲明和策略組成:
<resource> ["<label>"] { policy = "<policy disposition>" }
資源 acl、keyring、mesh、operator 不包含 label,可使用下面的語法來配置規則:
<resource> = "<policy disposition>"
1.6.1、策略類型
有如下集中策略:
read:只讀
write:讀寫
deny:拒絕
1.6.1、策略匹配和前綴
匹配特定的資源:
service "web-prod" { policy = "deny" }
匹配某一類型特定前綴的資源:
service_prefix "web" { policy = "write" }
匹配某一類型的所有資源:
service_prefix "" { policy = "read" }
1.6.2、格式化規則
規則可以使用 HashiCorp Configuration Language (HCL) 或 JSON 來定義。
HCL 方式:
# These control access to the key/value store. key_prefix "" { policy = "read" } key_prefix "foo/" { policy = "write" } key_prefix "foo/private/" { policy = "deny" } # Or for exact key matches key "foo/bar/secret" { policy = "deny" } # This controls access to cluster-wide Consul operator information. operator = "read"
JSON 方式:
{ "key": [{ "foo/bar/secret": [{ "policy": "deny" }] }], "key_prefix": [{ "": [{ "policy": "read" }] },{ "foo/": [{ "policy": "write" }]
}, { "foo/private/": [{ "policy": "deny" }] }], "operator": "read" }
1.6.3、規則中的資源
Resource | Description | Labels |
---|---|---|
acl |
Controls access to ACL operations in the ACL API. See ACL Resource Rules for details. |
No |
partition partition_prefix |
ENTERPRISE
Controls access to one or more admin partitions.See Admin Partition Rules for details. |
Yes |
agent agent_prefix |
Controls access to the utility operations in the Agent API, such as join and leave .See Agent Rules for details. |
Yes |
event event_prefix |
Controls access to event operations in the Event API, such as firing and listing events. See Event Rules for details. |
Yes |
key key_prefix |
Controls access to key/value store operations in the KV API. Can also use the list access level when setting the policy disposition.Has additional value options in Consul Enterprise for integrating with Sentinel. See Key/Value Rules for details. |
Yes |
keyring |
Controls access to keyring operations in the Keyring API. See Keyring Rules for details. |
No |
mesh |
Provides operator-level permissions for resources in the admin partition, such as ingress gateways or mesh proxy defaults. See Mesh Rules for details. | No |
namespace namespace_prefix |
ENTERPRISE
Controls access to one or more namespaces.See Namespace Rules for details. |
Yes |
node node_prefix |
Controls access to node-level registration and read access to the Catalog API. See Node Rules for details. |
Yes |
operator |
Controls access to cluster-level operations available in the Operator API excluding keyring API endpoints. See Operator Rules for details. |
No |
query query_prefix |
Controls access to create, update, and delete prepared queries in the Prepared Query API. Access to the node and service must also be granted. See Prepared Query Rules for details. |
Yes |
service service_prefix |
Controls service-level registration and read access to the Catalog API, as well as service discovery with the Health API. See Service Rules for details. |
Yes |
session session_prefix |
Controls access to operations in the Session API. See Session Rules for details. |
Yes |
2、Consul ACL 啟用
假設在三台機器上安裝 Consul:
機器 | agent 類型 |
10.49.196.10 | server |
10.49.196.11 | server |
10.49.196.12 | server |
A、分別在各機器上啟動 Consul:
nohup ./consul agent -config-file=./agent.hcl &
10.49.196.10 上 agent.hcl:
server = true, ui_config = { enabled = true }, bootstrap_expect = 3, data_dir = "./data", datacenter = "dc1", primary_datacenter= "dc1", node_name = "node131", client_addr = "0.0.0.0", bind_addr = "10.49.196.10", acl = { enabled = true default_policy = "deny" down_policy = "extend-cache" enable_token_persistence = true }
10.49.196.11 上 agent.hcl:
server = true, ui_config = { enabled = true }, bootstrap_expect = 3, data_dir = "./data", datacenter = "dc1", primary_datacenter= "dc1", node_name = "node132", client_addr = "0.0.0.0", bind_addr = "10.49.196.11", start_join = ["10.49.196.10"], acl = { enabled = true default_policy = "deny" down_policy = "extend-cache" enable_token_persistence = true }
10.49.196.12 上 agent.hcl:
server = true, ui_config = { enabled = true }, bootstrap_expect = 3, data_dir = "./data", datacenter = "dc1", primary_datacenter= "dc1", node_name = "node132", client_addr = "0.0.0.0", bind_addr = "10.49.196.12", start_join = ["10.49.196.10"], acl = { enabled = true default_policy = "deny" down_policy = "extend-cache" enable_token_persistence = true }
B、創建初始 Token,在任一節點上執行:
./consul acl bootstrap
執行完成后控制會打印創建的 Token 信息,該 Token 具有超級權限,可以使用該 Token 登錄控制台以進行后續的操作。
3、Spring Cloud Consul 中使用 ACL
這里使用 ACL 來控制服務的注冊的發現;創建兩個 Token,一個用於服務的注冊,另外一個用於客戶端服務發現並調用服務。
3.1、創建策略和 Token
創建服務注冊的策略:
創建服務注冊的 Token:
創建服務發現的策略:
創建服務發現的 Token:
3.2、應用配置文件中增加配置 spring.cloud.consul.discovery.acl-token
服務一(不調用其他服務)配置:
spring: cloud: consul: host: 10.49.196.10 port: 8500 discovery: prefer-ip-address: true acl-token: 17d11099-64ee-e923-5e9b-60a7cb23aa87 health-check-critical-timeout: 10s
服務二(調用服務一,本身不這注冊為服務)配置:
spring: cloud: consul: host: 10.49.196.132 port: 8500 discovery: register: false acl-token: 9a6bc59e-73d7-7af5-a669-818a200a9ded prefer-ip-address: true
配置完成后,啟動兩個服務,服務二可以正常調用服務一。