WEBKT

Consul 安全进阶:ACL 与 mTLS 联手打造细粒度访问控制

6 0 0 0

为什么需要细粒度的访问控制?

核心概念:ACL 与 mTLS

ACL(访问控制列表)

mTLS(双向 TLS)

准备工作:环境搭建

配置 ACL:逐步构建安全策略

1. 创建 Master 令牌

2. 创建策略

策略 1:允许读取服务配置

策略 2:允许注册和注销服务

策略 3:允许读取和写入 health check

3. 创建角色

4. 创建令牌

5. 测试 ACL

配置 mTLS:加强身份验证

1. 生成 CA 证书

2. 生成服务器证书

3. 配置 Consul 服务器

4. 生成客户端证书

5. 配置客户端

6. 测试 mTLS

ACL + mTLS:构建终极安全方案

1. 服务 A 的配置

2. 服务 B 的配置

3. 配置流程

最佳实践和注意事项

总结

你好,我是老 K。在当今的微服务架构中,服务间的安全通信至关重要。作为一名架构师或运维工程师,你一定深知这一点。今天,我们来聊聊如何利用 Consul 的 ACL(Access Control List,访问控制列表)和 mTLS(Mutual Transport Layer Security,双向 TLS)技术,为你的 Consul 集群构建强大的、细粒度的访问控制。

为什么需要细粒度的访问控制?

想象一下,你的公司正在使用 Consul 来管理服务发现和配置。随着业务的增长,越来越多的服务涌入 Consul,如果不对这些服务进行严格的访问控制,会发生什么?

  • 信息泄露风险: 恶意用户或错误配置的服务可能访问敏感的服务信息,如数据库连接字符串、API 密钥等。
  • 服务中断: 未经授权的服务可能意外或恶意地修改其他服务的配置或状态,导致服务中断。
  • 安全合规问题: 许多行业都有严格的安全合规要求。缺乏细粒度的访问控制可能导致无法满足这些要求。

ACL 和 mTLS 的组合可以帮你解决这些问题。它们就像两把锁,一把锁住“身份”,另一把锁住“权限”,共同确保只有授权的服务才能访问它们应该访问的资源。

核心概念:ACL 与 mTLS

在我们深入探讨如何配置之前,先来快速回顾一下 ACL 和 mTLS 的核心概念。

ACL(访问控制列表)

ACL 是 Consul 提供的基于角色的访问控制机制。你可以创建不同的角色,并为每个角色定义允许或拒绝访问的资源(例如服务、键值对、节点等)的权限。当客户端与 Consul 集群交互时,它必须提供一个有效的 ACL 令牌。Consul 会根据令牌关联的角色来判断客户端是否有权执行请求。

ACL 的关键组件:

  • 策略(Policy): 定义了对特定资源的访问权限。例如,允许读取服务配置,或允许注册新服务。
  • 角色(Role): 将一个或多个策略组合在一起,并可以关联一个或多个服务账号。
  • 令牌(Token): 代表一个身份,用于验证客户端的请求。令牌与一个或多个角色关联,从而赋予客户端相应的权限。
  • 服务账号(Service Account): 代表一个服务在 Consul 中的身份,用于标识服务并关联 ACL 令牌。

mTLS(双向 TLS)

mTLS 是一种增强的安全通信协议,它要求客户端和服务器都提供有效的 X.509 证书进行身份验证。这意味着不仅服务器要验证客户端的身份,客户端也要验证服务器的身份。这大大提高了通信的安全性。

mTLS 的关键优势:

  • 身份验证: 确保只有授权的客户端和服务才能与 Consul 集群通信。
  • 数据加密: 保护传输中的数据,防止窃听和篡改。
  • 端到端安全: 提供了从客户端到服务器的完整安全保障。

准备工作:环境搭建

在开始配置之前,我们需要一个 Consul 集群和一些客户端。这里我建议你使用 Docker Compose 来快速搭建一个测试环境。以下是一个简单的 docker-compose.yml 示例:

version: "3.7"
services:
consul-server:
image: consul:1.17.0
ports:
- "8500:8500"
volumes:
- consul-data:/consul/data
command: consul agent -server -bootstrap-expect=1 -client=0.0.0.0 -ui -bind=0.0.0.0 -datacenter=dc1 -encrypt=${CONSUL_ENCRYPT_KEY} -acl-default-policy=deny -acl-master-token=${CONSUL_MASTER_TOKEN}
environment:
CONSUL_ENCRYPT_KEY: "$(openssl rand -base64 32)"
CONSUL_MASTER_TOKEN: "your_master_token"
client1:
image: busybox:latest
depends_on:
- consul-server
command: sleep infinity
environment:
CONSUL_HTTP_ADDR: "http://consul-server:8500"
client2:
image: busybox:latest
depends_on:
- consul-server
command: sleep infinity
environment:
CONSUL_HTTP_ADDR: "http://consul-server:8500"
volumes:
consul-data:

注意:

  1. 请务必将 your_master_token 替换为一个安全的、随机生成的令牌。
  2. CONSUL_ENCRYPT_KEY 用于节点间通信加密,也请生成并替换为安全的值。你可以使用 openssl rand -base64 32 生成。
  3. 这个配置禁用了匿名访问,你需要通过 ACL 令牌来访问 Consul。acl-default-policy=deny 确保了这一点。
  4. client1client2 只是用来模拟不同客户端。稍后,我们将使用它们来测试 ACL 和 mTLS 的配置。

启动这个 Compose 文件,你将得到一个包含一个 Consul 服务器和两个客户端的集群。通过浏览器访问 http://localhost:8500,你可以看到 Consul 的 Web UI(如果启动成功)。

配置 ACL:逐步构建安全策略

现在,我们开始配置 ACL。首先,我们需要创建一个 master 令牌,然后基于这个令牌来创建其他令牌,并定义相应的策略和角色。

1. 创建 Master 令牌

Master 令牌拥有集群的最高权限,可以创建、管理所有策略、角色和令牌。在上面的 docker-compose.yml 中,我们已经通过 CONSUL_MASTER_TOKEN 环境变量设置了 Master 令牌。请务必妥善保管这个令牌!

2. 创建策略

策略定义了对资源的访问权限。以下是一些常见的策略示例:

策略 1:允许读取服务配置

{
"name": "service-read",
"rules": [
{
"key": {
"prefix": "service/",
"policy": "read"
}
}
]
}

这个策略允许读取以 service/ 开头的键值对。例如,服务的配置信息通常存储在 service/<service_name>/config 中。

策略 2:允许注册和注销服务

{
"name": "service-write",
"rules": [
{
"service": {
"name": "",
"policy": "write"
}
}
]
}

这个策略允许注册和注销所有服务。注意,"name": "" 表示匹配所有服务名称。

策略 3:允许读取和写入 health check

{
"name": "health-check-rw",
"rules": [
{
"health": {
"node": "",
"policy": "write"
}
}
]
}

这个策略允许读取和写入 health check 状态。"node": "" 表示匹配所有节点。

3. 创建角色

角色将一个或多个策略组合在一起。以下是一个示例:

{
"name": "service-admin",
"policies": [
"service-read",
"service-write",
"health-check-rw"
]
}

这个角色包含了 service-readservice-writehealth-check-rw 三个策略,赋予了对服务配置的读写权限、服务注册注销权限以及健康检查的读写权限。

4. 创建令牌

令牌代表一个身份,并与一个或多个角色关联。以下是使用 Master 令牌创建令牌的示例(使用 Consul CLI):

# 创建一个令牌,并关联 service-admin 角色
consul acl token create -role-names=service-admin -description="Service Admin Token" -format=json

这个命令会返回一个 JSON 对象,包含令牌的 ID 和 Secret ID。请记住 Secret ID,这是客户端用来访问 Consul 的令牌。

5. 测试 ACL

现在,我们来测试一下 ACL 是否生效。首先,我们使用刚刚创建的令牌来查询 Consul 的 API。假设我们得到了一个 Secret ID 为 your_service_admin_token 的令牌:

# 使用令牌查询服务列表
curl --header "X-Consul-Token: your_service_admin_token" http://localhost:8500/v1/agent/services

如果一切正常,你应该能够看到服务列表。如果你使用一个没有权限的令牌,或者没有提供令牌,则会收到 403 Forbidden 错误。

配置 mTLS:加强身份验证

mTLS 提供了更强的身份验证和数据加密。在 Consul 中,mTLS 的配置主要包括证书颁发机构(CA)的配置、服务器证书的生成和客户端证书的配置。

1. 生成 CA 证书

首先,我们需要一个 CA 证书来签发服务器和客户端证书。你可以使用 OpenSSL 或其他工具来生成 CA 证书。以下是一个简单的 OpenSSL 命令示例:

# 生成 CA 私钥
openssl genrsa -out ca.key 2048
# 生成 CA 证书
openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=Consul CA"

2. 生成服务器证书

接下来,我们需要为 Consul 服务器生成证书。在生成证书时,需要指定服务器的 DNS 名称和 IP 地址。以下是一个示例:

# 生成服务器私钥
openssl genrsa -out server.key 2048
# 生成服务器 CSR(证书签名请求)
openssl req -new -key server.key -out server.csr -subj "/CN=consul.service.dc1.consul"
# 签发服务器证书(使用 CA 证书)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 -sha256

注意:CN (Common Name) 必须与 Consul 服务器的 DNS 名称匹配。consul.service.dc1.consul 是 Consul 的默认服务 DNS 名称。你可能需要根据你的环境进行调整。

3. 配置 Consul 服务器

我们需要在 Consul 服务器的配置文件中启用 mTLS。这通常通过在启动 Consul 服务器时指定一些参数来实现。修改 docker-compose.yml 文件,添加以下内容到 consul-server 服务中:

volumes:
- ./ca.crt:/consul/ca.crt
- ./server.crt:/consul/server.crt
- ./server.key:/consul/server.key
command: consul agent -server -bootstrap-expect=1 -client=0.0.0.0 -ui -bind=0.0.0.0 -datacenter=dc1 -encrypt=${CONSUL_ENCRYPT_KEY} -acl-default-policy=deny -acl-master-token=${CONSUL_MASTER_TOKEN} -verify-incoming -verify-outgoing -ca-file=/consul/ca.crt -cert-file=/consul/server.crt -key-file=/consul/server.key

注意:

  • 将你的 CA 证书、服务器证书和私钥拷贝到与 docker-compose.yml 相同的目录下。
  • -verify-incoming 启用客户端证书验证。
  • -verify-outgoing 启用服务器证书验证(用于服务间通信)。
  • -ca-file 指定 CA 证书路径。
  • -cert-file 指定服务器证书路径。
  • -key-file 指定服务器私钥路径。

4. 生成客户端证书

客户端也需要自己的证书。生成过程与服务器类似:

# 生成客户端私钥
openssl genrsa -out client.key 2048
# 生成客户端 CSR
openssl req -new -key client.key -out client.csr -subj "/CN=client1"
# 签发客户端证书(使用 CA 证书)
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 365 -sha256

注意:CN (Common Name) 需要与客户端的标识匹配。这里我们使用 client1

5. 配置客户端

客户端也需要配置 mTLS。修改 docker-compose.yml 文件,将以下内容添加到 client1client2 服务中:

volumes:
- ./ca.crt:/ca.crt
- ./client.crt:/client.crt
- ./client.key:/client.key
environment:
CONSUL_HTTP_ADDR: "https://consul-server:8500"
CONSUL_HTTP_SSL: "true"
CONSUL_CACERT: "/ca.crt"
CONSUL_CLIENT_CERT: "/client.crt"
CONSUL_CLIENT_KEY: "/client.key"

注意:

  • 将客户端的 CA 证书、客户端证书和私钥拷贝到与 docker-compose.yml 相同的目录下。
  • CONSUL_HTTP_ADDR 使用 https 协议。
  • CONSUL_HTTP_SSL 设置为 true,启用 TLS。
  • CONSUL_CACERTCONSUL_CLIENT_CERTCONSUL_CLIENT_KEY 分别指定 CA 证书、客户端证书和私钥的路径。

6. 测试 mTLS

重新启动 Docker Compose。现在,客户端与 Consul 的通信将通过 mTLS 进行。你可以使用 curl 命令来测试:

# 使用客户端证书访问 Consul API
curl --cacert ca.crt --cert client.crt --key client.key https://localhost:8500/v1/agent/services --insecure

注意:

  • --cacert 指定 CA 证书。
  • --cert 指定客户端证书。
  • --key 指定客户端私钥。
  • --insecure 用于绕过证书验证(因为我们使用的是自签名证书,浏览器可能不信任)。在生产环境中,请不要使用 --insecure

如果一切配置正确,你应该能够看到服务列表。如果遇到错误,请检查证书路径、证书是否正确签发、以及服务器的配置是否正确。

ACL + mTLS:构建终极安全方案

单独使用 ACL 和 mTLS 都能够提高 Consul 集群的安全性。但将它们结合起来,可以实现更强大的细粒度访问控制。想象一下以下场景:

  1. 服务 A 需要读取服务 B 的配置:
    • 服务 A 通过 mTLS 与 Consul 集群建立安全连接,验证身份。
    • 服务 A 的 ACL 令牌被配置为允许读取服务 B 的配置。
    • Consul 根据 ACL 令牌的权限,允许服务 A 读取服务 B 的配置。
  2. 服务 C 尝试修改服务 D 的配置:
    • 服务 C 通过 mTLS 与 Consul 集群建立安全连接,验证身份。
    • 服务 C 的 ACL 令牌没有被配置为允许修改服务 D 的配置。
    • Consul 根据 ACL 令牌的权限,拒绝服务 C 修改服务 D 的配置。

为了实现这个终极安全方案,我们需要:

  1. 为每个服务生成唯一的客户端证书。 确保每个服务的证书 CN 能够唯一标识该服务。
  2. 为每个服务创建一个服务账号。 服务账号用于在 Consul 中标识服务,并与客户端证书的 CN 关联。
  3. 为每个服务创建一个 ACL 策略。 策略定义了服务可以访问的资源,例如其他服务的配置、服务注册等。
  4. 为每个服务创建一个角色。 角色将一个或多个策略组合在一起,并与服务账号关联。
  5. 为每个服务颁发一个 ACL 令牌。 令牌与服务账号关联,赋予服务相应的权限。

下面是一个示例,展示了如何为服务 A 和服务 B 配置 ACL 和 mTLS:

1. 服务 A 的配置

  • 客户端证书: client_a.crtclient_a.keyCNservice_a

  • 服务账号: service_a

  • ACL 策略(允许读取服务 B 的配置):

    {
    "name": "service-a-read-b-config",
    "rules": [
    {
    "key": {
    "prefix": "service/service_b/",
    "policy": "read"
    }
    }
    ]
    }
  • ACL 角色:

    {
    "name": "service-a-role",
    "policies": [
    "service-a-read-b-config"
    ],
    "service_identities": [
    {
    "service_account": "service_a"
    }
    ]
    }
  • ACL 令牌: 通过关联 service-a-roleservice_a 服务账号创建。此令牌将用于服务 A 访问 Consul。

2. 服务 B 的配置

  • 客户端证书: client_b.crtclient_b.keyCNservice_b

  • 服务账号: service_b

  • ACL 策略(允许读取和写入自身配置):

    {
    "name": "service-b-config",
    "rules": [
    {
    "key": {
    "prefix": "service/service_b/",
    "policy": "read"
    }
    },
    {
    "key": {
    "prefix": "service/service_b/",
    "policy": "write"
    }
    }
    ]
    }
  • ACL 角色:

    {
    "name": "service-b-role",
    "policies": [
    "service-b-config"
    ],
    "service_identities": [
    {
    "service_account": "service_b"
    }
    ]
    }
  • ACL 令牌: 通过关联 service-b-roleservice_b 服务账号创建。此令牌将用于服务 B 访问 Consul。

3. 配置流程

  1. 生成 CA 证书: 如前所述。
  2. 生成服务 A 和服务 B 的客户端证书。 确保 CN 分别为 service_aservice_b
  3. 在 Consul 中创建服务账号 service_aservice_b
    • 你可以使用 Consul 的 API 或 CLI 创建服务账号,并将客户端证书的 CN 与服务账号关联。
  4. 创建 ACL 策略和角色。 如上所示。
  5. 为服务 A 和服务 B 分别创建一个 ACL 令牌。 令牌需要与相应的服务账号关联。
  6. 将服务 A 和服务 B 的客户端证书、CA 证书、以及 ACL 令牌配置到相应的服务中。 服务 A 使用它的令牌和证书来访问 Consul,服务 B 亦然。

通过以上配置,服务 A 只能读取服务 B 的配置,而不能修改。服务 B 只能读取和修改自己的配置。这样,我们就实现了细粒度的访问控制。

最佳实践和注意事项

在实际生产环境中,以下是一些最佳实践和注意事项:

  • 证书管理:
    • 使用安全的 CA 证书,并妥善保管 CA 私钥。
    • 定期轮换证书,避免证书过期。
    • 使用自动化工具来管理证书的生成、分发和更新。
  • ACL 管理:
    • 遵循最小权限原则,只赋予服务必要的权限。
    • 定期审查 ACL 策略,确保其安全性。
    • 使用版本控制来管理 ACL 策略,方便回滚和审计。
  • 监控和日志:
    • 监控 Consul 集群的 ACL 和 mTLS 配置状态。
    • 启用 Consul 的审计日志,记录所有访问请求,方便审计和故障排查。
  • 自动化:
    • 使用自动化工具(例如 Terraform、Ansible)来部署和管理 Consul 集群、证书、ACL 策略和角色。
    • 将 ACL 策略和角色定义为代码,方便版本控制和部署。
  • 测试:
    • 在测试环境中充分测试 ACL 和 mTLS 配置,确保其正确性。
    • 进行渗透测试,模拟恶意攻击,评估安全防护效果。
  • 性能考虑:
    • mTLS 和 ACL 可能会对性能产生一定影响。在生产环境中,需要对性能进行测试和调优。
    • 选择合适的加密算法和证书长度,平衡安全性和性能。

总结

通过 ACL 和 mTLS 的结合,我们可以为 Consul 集群构建强大的、细粒度的访问控制,从而提高服务的安全性和可靠性。虽然配置过程稍微复杂,但为了保护你的基础设施,这绝对是值得投入的。记住,安全是一个持续的过程,我们需要不断学习、实践和改进,才能构建一个安全可靠的微服务架构。

希望这篇文章对你有所帮助!如果你有任何问题,欢迎随时提出。

老K ConsulACLmTLS安全微服务

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8392