本文为译文,原文链接:https://www.conjur.org/blog/cloud-native-iam-eks-secrets-management-for-kubernetes/
Kubernetes 是用于容器化应用程序的出色编排工具,Amazon 的 Elastic Kubernetes Service (EKS) 提供了一种在云中创建可扩展 Kubernetes 集群的简单方法。
但是,使用内置的 Kubernetes 机密管理工具保护容器的安全性可能在规模上具有挑战性。这就是 Conjur 介入以提供一种安全的方式来集中存储您的应用程序机密,以及在您的集群中设置和执行访问策略的地方。
一些最大的安全问题,尤其是在 Web应用程序安全风险中(请参阅OWASP 十大 Web 应用程序安全风险以获得更多信息),包括敏感数据暴露和安全配置错误。对于大型集群,可能会暴露您的机密或数据的代码和容器需要采用集中式方法。Conjur 通过提供身份验证器来验证应用程序(他们声称自己是谁?)和基于角色的访问控制 (RBAC)来授权对资源的访问(是否允许访问?),从而帮助降低这些风险。
为此,Conjur 提供了一个开箱即用的身份验证器,可让您将角色映射到预配置的身份。这允许您将 EKS pod 分配给特定角色(请参阅Amazon EKS 添加支持以将 IAM 权限分配给 Kubernetes 服务账户),Conjur 利用该功能自动为该 pod 提供与该角色关联的密钥。
让我们看一下如何设置 Conjur 来管理使用 EKS 并连接到 AWS Redshift 的简单容器化应用程序的机密。
设置和先决条件
在我们了解如何使用 Conjur 管理 EKS 集群的机密之前,让我们先了解一些设置先决条件。首先,我们需要从 AWS 的角度准备并设置以下内容:
- 具有一些备用资源的 AWS EKS 集群,用于运行 Java 应用程序节点。
- 提供了一些数据的 Amazon Redshift 数据仓库。
- Conjur 已安装并正在运行。我正在使用使用 Docker 安装的 Conjur 的简单快速启动安装,如Cyberark/conjur-quickstart GitHub 存储库中所述。
一旦我们建立了我们的基本构建块,我们还需要在我们的 Redshift 仓库上创建一个用户来允许我们的应用程序访问它。在我的例子中,我在一个名为“clusterusers”的组中创建了一个名为“conjuruser”的 Redshift 用户,该用户可以访问我的公共模式。
IAM 身份验证器配置
我们将设置一个 Conjur 实例来管理对 Redshift 仓库的访问,其方式与博文 AWS IAM Authenticator Tutorial For Conjur Open Source 类似。
在我们开始在 Conjur 中创建配置之前,我们需要设置一个 AWS 角色,我们可以将其分配给我们的 Kubernetes pod。Conjur 将使用此角色来确定是否允许 pod 检索数据库机密。
接下来,我们将在 Conjur 中设置 IAM 身份验证器,让我们的应用程序使用其 AWS IAM 角色使用类似于AWS IAM Authenticator文档的流程进行身份验证。
首先,添加以下环境变量以启用连接器(其中 dev 是服务 ID):
CONJUR_AUTHENTICATORS=authn-iam/dev
我们可以通过创建以下 root-policy.yml 文件来创建启用身份验证器的策略:
# policy id needs to match the convention `conjur/authn-iam/<service ID>`
- !policy
id: conjur/authn-iam/dev
body:
- !webservice
- !group clients
- !permit
role: !group clients
privilege: [ read, authenticate ]
resource: !webservice
使用 Conjur CLI,我们加载这个根策略:
conjur policy load root root-policy.yml
我们需要创建的另一个策略是允许在 EKS 中运行的 Web 应用程序访问 Redshift 的密钥。为此,我们创建了以下链接到我们之前创建的角色的策略:
- !policy
id: redshiftApp
body:
- &variables
- !variable connectionstring
- !variable databaseusername
- !variable databasepassword
# Create a group that will have permission to retrieve variables
- !group secrets-users
# Give the group permission to retrieve variables
- !permit
role: !group secrets-users
privilege: [ read, execute ]
resource: *variables
# Create a layer to hold this application's hosts
- !layer
# The host ID needs to match the AWS ARN of the role we wish to authenticate.
- !host 548836857282/EKSRedshiftClusterAccess
# Add our host into our layer
- !grant
role: !layer
member: !host 548836857282/EKSRedshiftClusterAccess
# Give the host in our layer permission to retrieve variables
- !grant
member: !layer
role: !group secrets-users
# Give the application permission to use the IAM authenticator
- !grant
role: !group conjur/authn-iam/dev/clients
member: !host 548836857282/EKSRedshiftClusterAccess
从这个配置可以看出,我使用的角色是 548836857282:EKSRedshiftClusterAccess。您将需要替换您的。将此策略保存为 yaml 文件 (redshift-app.yml) 并在 Conjur CLI 中运行以下命令:
conjur policy load conjur/authn-iam/dev redshift-app.yml
此命令与上述命令略有不同,因为它使其成为 conjur/authn-iam/dev 策略的子项。此策略允许 IAM 角色检索连接字符串、用户名和密码以连接到 Redshift,但我们尚未加载这些值。
要加载值,请使用以下命令填充变量(同样,根据需要替换您的值):
conjur variable values add \
conjur/authn-iam/dev/redshiftApp/connectionstring \
jdbc:redshift://redshift-cluster-1.aaaaaaaaaaaa.us-west-2.redshift.amazonaws.com:5439/dev
conjur variable values add \
conjur/authn-iam/dev/redshiftApp/databaseusername \
conjuruser
conjur variable values add \
conjur/authn-iam/dev/redshiftApp/databasepassword \
Password123456
Kubernetes 应用创建
现在 Conjur 已准备就绪,我们将创建一个简单的 Java Spring 应用程序,我们可以将其部署到我们的 EKS 集群。应用程序尝试连接到 Conjur 并检索秘密。如果失败,它将捕获错误并将其返回到页面,如下所示。
此设置还需要设置 CONJUR_APPLIANCE_URL 环境变量,并且需要信任 Conjur 服务器证书存储。这些值通常在部署清单中设置,如下所示。您可以在Cyberark/conjur-api-java:CyberArk Conjur API 存储库的 Java 客户端中找到有关设置的完整详细信息。
代码的下一部分尝试使用我们从 Conjur 服务器提取的数据库凭证连接到 AWS Redshift 实例。我将一个小型示例数据库加载到 Redshift 中,并使用硬编码的 SQL 语句。我使用以编程方式连接到您的集群Amazon Redshift 文档主题中显示的示例来设置连接器,以便在每次轮询 /data 页面时被调用。
现在,当我们将此应用程序打包到 Docker 中,部署到 EKS 集群并运行它时,我们将收到错误“Authorization missing”。这是因为我们没有将 IAM 角色分配给集群上运行的 Pod。
为此,我们需要首先使用 serviceAccountName 将我们的服务帐户添加到 spec:template:spec: 下的部署清单中。例如,我的部署清单如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: redshiftexample
spec:
replicas: 1
selector:
matchLabels:
app: redshiftexample
template:
metadata:
labels:
app: redshiftexample
spec:
containers:
- name: greeting
image: test/redshiftExample
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: "http"
env:
- name: CONJUR_APPLIANCE_URL
value: https://<conjur-hostname>
- name: CONJUR_SSL_CERTIFICATE
value: |
-----BEGIN CERTIFICATE-----
…
-----END CERTIFICATE-----
serviceAccountName: EKSRedshiftClusterAccess
当我们运行 kubectl apply 时,AWS EKS 准入控制器将注入 AWS_ROLE_ARN 和 AWS_WEB_IDENTITY_TOKEN_FILE 环境变量。您可以在 AWS 文档主题为服务账户介绍细粒度 IAM 角色中了解有关此过程工作方式的更多信息。然后,我们修改我们的应用程序以查找此角色 ARN,并将其用作我们调用 Conjur 的授权令牌。
当我们现在部署这个应用程序并访问端点时,我们会收到返回给我们的 SQL 语句。
下一步
Conjur通过利用 EKS pod 的细粒度 IAM 角色,可以轻松设置具有 EKS 和 Kubernetes机密管理的配置,而无需依赖 AWS 进行所有机密管理。这使得在 Kubernetes 中安全地运行应用程序变得容易,同时仍然允许您将应用程序移植到另一个平台,因为机密没有锁定到 Amazon Secrets Manager。
Conjur 还为本示例范围之外的各种应用程序、平台和语言提供 API 和机密管理。您可以在CyberArk Commons中查看所有这些Conjur功能或讨论其他 CyberArk 开源项目。