如何保护 MinIO - 第 1 部分

How to Secure MinIO - Part 1

MinIO 作为一个对象存储系统,可以充当任何 S3 应用程序的持久化层。所有这些应用程序都依赖 MinIO 来存储和保护其数据,使其免受中断以及数据损坏或丢失的影响。

由于所有数据都将进入 MinIO,因此它成为您基础架构的关键部分,并且从信息安全角度来看,它成为一个有吸引力的目标。

威胁模型

为了保护 MinIO 部署,我们必须涵盖以下部分

  • 数据是如何进入的?传入连接是如何保护的?
  • MinIO 如何存储数据?存储的数据是如何保护的?
  • 访问控制是如何实现的?我们如何授予用户和应用程序访问权限?

除了这三个主要主题外,我们还必须注意其他方面,例如审计日志记录、内部攻击预防和合规性。但是,首先我们将专注于做好基础工作,只有在确保传入和传出连接的安全并实施访问控制后,我们才会处理更细致的方面。

保护入口

首先,让我们专注于保护传入的数据流。因此,我们必须配置 MinIO 以通过 TLS 接受和服务请求。

从概念上讲,这很容易做到。MinIO 所需的只是一个 TLS 私钥和证书,这些证书应安装在 MinIO 配置目录下的 certs/ 中。例如

ls -l ~/.minio/certs
drwx------   - minio 1 Jan 2021 CAs
.rw------- 119 minio 1 Jan 2022 private.key    ⟵ The TLS private key .rw------- 461 minio 1 Jan 2022 public.crt     ⟵ The TLS certificate 

在运行分布式 MinIO 集群时,只需将相同的 public.crtprivate.key 复制到所有 MinIO 节点,以便所有节点都具有相同的 certs/ 目录。重新启动 MinIO 集群后,传输到 MinIO 的所有数据都将通过加密连接发送。

虽然配置 MinIO 以接受 TLS 连接非常简单,但获取 TLS 证书可能会带来一些麻烦。

您可以使用 OpenSSL 或其他 TLS CLI 工具生成“自签名”证书。我们对此有一些文档。但是,您的客户端应用程序将无法验证证书的真实性,因此会拒绝连接到 MinIO。为了解决此问题,您可以通过将证书复制到所有客户端来手动建立信任链接,但这很快就会演变成维护噩梦,尤其是在由于过期而更新证书时。

因此,大多数人使用由证书颁发机构 (CA) 颁发的 TLS 证书。CA 可以是 Web PKI CA,例如Let's Encrypt。由 Web PKI CA 颁发的证书将被互联网上的大多数客户端应用程序信任。但是,如果您在内部使用 MinIO(例如,仅在您的组织内),则只需从组织的内部 CA 请求 TLS 证书即可。

除了加密数据入口外,MinIO 可能还需要与其他服务(如审计日志服务)安全地通信。因此,MinIO 必须能够验证这些服务的 TLS 证书,因此需要颁发 CA 的证书。此类 CA 证书应放置在 certs/CAs/ 目录中。例如

ls -l ~/.minio/certs/CAs 
.rw-------  765 minio 1 Jan 2022 company-ca1.crt
.rw------- 1356 minio 1 Jan 2022 company-ca2.crt

默认情况下,此 certs/CAs/ 目录将为空,并且 MinIO 仅信任系统 CA。

静态加密

在保护数据入口后,我们可以看看如何保护静态数据。MinIO 支持服务器端加密。特别是,MinIO 可以在对象上传过程中以及写入底层磁盘之前,将其作为连续数据流加密。MinIO 还可以连接到各种 KMS(如 Hashicorp Vault),为每个 S3 对象获取唯一的数据加密密钥。

但是,MinIO 集群本身与其 KMS 脱钩。相反,MinIO 集群与一个或多个KES 实例通信。KES 是一个用于高性能应用程序的无状态且分布式的密钥管理系统。KES 充当 MinIO 的 KMS API 抽象,并负责可扩展性和高可用性等操作方面。

我们为我们支持的每个 KMS 供应商提供了指南。但是,我们还在 play.min.io:7373 运行一个公共 KES 实例,每个人都可以将其用于入门。

我们可以通过在每个 MinIO 节点上设置与 KES 相关的环境变量来将 MinIO 集群连接到 KES。例如

export MINIO_KMS_KES_ENDPOINT=https://play.min.io:7373
export MINIO_KMS_KES_CERT_FILE=/tmp/root.cert
export MINIO_KMS_KES_KEY_FILE=/tmp/root.key
export MINIO_KMS_KES_KEY_NAME=my-first-key 

您可以下载以下 curl 命令的管理员凭据(root.key & root.cert
play.min.io:7373

curl -sSL --tlsv1.2 \
 -O 'https://raw.githubusercontent.com/minio/kes/master/root.key' \
 -O 'https://raw.githubusercontent.com/minio/kes/master/root.cert'

配置并重新启动 MinIO 后,我们可以使用 mc CLI 检查它是否可以到达 KMS

mc admin kms key status <minio-alias>

现在,我们可以上传在静态时加密的对象。因此,我们将存储桶配置为使用从 KMS 获取的密钥加密新传入的数据

mc encrypt set sse-kms my-first-key <minio-alias>/<my-bucket>

放置在此存储桶中的任何数据都将使用 KMS 中的密钥 my-first-key 加密。这可以通过获取对象元数据来验证。例如,通过 mc

mc stat <minio-alias>/<my-bucket>/<my-object>
Name      : <my-object>
...
Encrypted :
  X-Amz-Server-Side-Encryption               : aws:kms 
  X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id: arn:aws:kms:my-first-key

在 S3 存储桶上设置 KMS 配置只会影响新传入的对象。现有对象将保持未加密状态。因此,从一开始就实施静态加密非常重要。

访问控制

到目前为止,我们已经介绍了传输中和静态数据加密的基础知识。但是,加密本身不允许进行细粒度的访问控制。相反,MinIO 使用基于S3 预定义策略的基于角色的访问控制 (RBAC) 系统。

例如,每个 MinIO 部署默认包含一个 writeonly 策略

mc admin policy info <minio-alias> writeonly 
{
 "Version": "2012-10-17",
 "Statement": [
  {
   "Effect": "Allow",
   "Action": [
    "s3:PutObject"
   ],
   "Resource": [
    "arn:aws:s3:::*"
   ]
  }
 ]
}

每个策略都包含一个或多个语句。每个语句要么明确允许或拒绝对一组资源应用一组操作。在上面的 writeonly 示例中,我们允许对任何资源(即 *)应用 PutObject 操作。

访问策略分配给单个用户或用户组。这些用户可以是内部的或外部的。内部用户是 MinIO 特定的,可以在 MinIO 本身中创建和删除。外部用户是驻留在外部 IDP(如 OpenID Connect 提供商或 LDAP 服务器/Active Directory)上的用户帐户。目前,让我们坚持为内部用户管理策略,并在以后介绍外部 IDP。

假设我们要创建一个新用户 alice 并授予她对集群中所有资源的读取权限。我们可以先创建一个新用户

mc admin user add <minio-alias> alice 
Enter Secret Key:

系统会要求您为 alice 输入一个 S3 密钥。它至少应为 8
个字符。

添加 alice 后,我们可以为她分配策略。在这种情况下,让我们使用预定义的 readonly 策略:

mc admin policy set <minio-alias> readonly user=alice 

此时,alice 将能够读取 MinIO 集群上的任何对象,但她将无法创建或删除对象。从这里,我们可以为所有应用程序创建新的用户帐户并调整其策略权限。但是,还有一个特别有用的访问控制概念:服务帐户。

服务帐户

服务帐户是属于用户的静态帐户。对于 alice,我们可以通过以下方式创建新的服务帐户

mc admin user svcacct add <minio-alias> alice
Access Key: NLJOKS0YFVAXO9XBJ1W3
Secret Key: DZrtGnRKXu++J5IreLmD+BiHsd1sJ9fxy883xWEY

创建此服务帐户时,我们将获得新的访问密钥/密钥对。默认情况下,服务帐户继承用户的策略权限。但是,服务帐户的权限可以减少到所需的最小权限集。因此,服务帐户非常适合由 S3 用户管理的应用程序。

例如,alice 可能会运行多个想要从 MinIO 集群中提取数据的应用程序。她不应该使用自己的 S3 凭据来配置这些应用程序,而应该为每个应用程序生成/请求一个新的服务帐户。此外,她可以降低特定服务帐户的权限,例如,当应用程序只需要访问一个存储桶而不是整个集群时。

应用程序不再使用或在凭据泄露的情况下,alice 可以简单地禁用或删除服务帐户

mc admin user svcacct rm <minio-alias> <service-account-access-key>
总结:MinIO 通过应用与用户、组或服务帐户关联的策略来控制数据访问。建议将常规 S3 用户用于人类。建议将服务帐户用于应用程序。

结论

本文探讨了如何保护 MinIO 的基础知识。从概念上讲,我们必须保护数据入口、静态数据并定义数据访问规则。但是,我们没有详细介绍每个主题,而是专注于一些关键方面。如果您想深入了解,请查看我们的文档加入我们的 Slack 频道,以从我们的全球社区学习。

在本系列的下一篇文章中,我们将探讨一些更高级的主题,例如审计日志记录和外部 IDP。