以及为什么在治理权限时经常使用它至关关键-Kubernetes-把握-RBAC-RBAC-了解什么是 (为什么什么及什么)
译者|李睿
审校|重楼
什么是KubeesRBAC?
当组织开局走上Kubernetes之旅时,在通常状况下,他们宿愿成功最低权限角色和适当的授权来包全他们的基础设备。这就是成功KubernetesRBAC以包全Kubernete资源的中央,例如敏感数据,包含部署细节、耐久存储设置和秘密。KubernetesRBAC提供了控制谁能够以何种访问形式访问每个API资源的才干。组织可认为人类用户(团体或组)和非人类用户(服务帐户)经常使用RBAC来定义他们对各种Kubernetes资源的访问类型。
例如,有Dev、Staging和Production三个不同的环境,肯定向团队(例如开发人员、DevOps人员、SRE、运行程序一切者和产品经理)提供访问权限。
在开局之前须要强调一下,从形象的角度来看,将把用户和服务帐户视为相反的——每个恳求,无论是来自用户还是服务帐户,最终都是HTTP恳求。人们知道Kubernetes中的用户和服务帐户(针对非人类用户)实质上是不同的。
如何启用KubernetesRBAC
可以在Kubernetes中启用RBAC,这种方法是启动带有授权形式标记的API主机。用于向用户运行RBAC的Kubernetes资源有:
1.服务帐户
为了治理用户,Kubernetes提供了一种身份验证机制,但通常倡导将Kubernetes与企业用户身份治理(如ActiveDirectory或LDAP)集成在一同。当触及到Kubernetes集群中的非人类用户(或机器或服务)时,就产生了服务帐户的概念。
例如,Kubernetes资源须要由Spinnaker或Argo等继续交付(CD)运行程序访问才干部署运行程序,或许服务A的一个pod须要与服务B的另一个pod对话。在这种状况下,服务帐户用于创立非人类用户的帐户并指定所需授权(经常使用角色绑定或集群角色绑定)。
可以经过创立如下所示的yaml来创立一个服务帐户:
YAMLapiVersion:v1kind:ServiceAccountmetadata:name:-saspec:automountServiceAccountToken:false
而后运行它。
Shell$kubectlly-fnginx-sa.yamlserviceaccount/nginx-sacreated
如今,肯定为部署资源中的pod提供服务帐户。
YAMLkind:Deploymentmetadata:name:nginx1labels:app:nginx1spec:replicas:2selector:matchLabels:app:nginx1template:metadata:labels:app:nginx1spec:serviceAccountName:nginx-sacontners:-name:nginx1image:nginxports:-containerPort:80
假设没有在部署资源中指定服务帐户称号(serviceAccountName),那么pod将属于自动的服务帐户。须要留意的是,每个命名空间都有一个自动的服务帐户,集群也有一个自动的服务帐户。自动服务帐户的一切自动授权战略将运行于未提及服务帐户消息的pod。
以下可以看到如何经常使用角色绑定和集群角色绑定为服务帐户调配各种权限。
2.角色和集群角色
角色(Role)和集群角色(ClusterRole)是Kubernetes资源区分用于定义用户可以在命名空间或集群中口头的操作列表。
在Kubernetes中,介入者(如用户、组或服务帐户)被称为主题。主体的举措,如创立、读取、写入、升级和删除,称为操作。
YAMLapiVersion:rbac.authorization.k8s.io/v1kind:Rolemetadata:name:read-onlynamespace:dev-namespacerules:-apiGroups:-""resources:["*"]verbs:-get-list-watch
在上方的角色资源中,指定了只读角色仅实用于deb-ns命名空间和命名空间内的一切资源。任何绑定到只读角色的服务帐户或用户都可以口头这些操作——失掉、列出和监督。
相似地,集群角色(资源将准许创立与集群相关的角色)。上方是一个例子:
YAMLapiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:chief-rolerules:-apiGroups:-""resources:["*"]verbs:-get-list-watch-create-update-patch-delete
任何绑定到chief-role的用户/组/服务帐户都可以在集群中口头任何操作。
在下一节中,将看到如何经常使用角色绑定和集群角色绑定向主题授予角色。
另外,Kubernetes准许经常使用角色资源性能自定义角色,或许经常使用自动的面向用户的角色,如下所示:
3.角色绑定和集群角色绑定
要将角色运行于主题(用户/组/服务帐号),肯定定义角色绑定。这将经常使用角色性能中定义的权限为用户提供对命名空间内所需资源的最低权限访问。
YAMLapiVersion:rbac.authorization.k8s.io/v1beta1kind:RoleBindingmetadata:name:Role-binding-devroleRef:kind:Rolename:read-only#TherolenameyoudefinedintheRoleconfigurationapiGroup:rbac.authorization.k8s.iosubjects:-kind:Username:Roy#ThenameoftheusertogivetheroletoapiGroup:rbac.authorization.k8s.io-kind:ServiceAccountname:nginx-sa#ThenameoftheServiceAccounttogivetheroletoapiGroup:rbac.authorization.k8s.io
相似地,可以创立集群角色绑定资源来定义用户的角色。须要留意的是,经常使用了Kubernetes提供的自动超级用户集群角色援用,而不是经常使用自定义角色。这可以运行于集群治理员。
YAMLapiVersion:rbac.authorization.k8s.io/v1beta1kind:ClusterRoleBindingmetadata:name:superuser-bindingroleRef:kind:ClusterRolename:superuserapiGroup:rbac.authorization.k8s.iosubjects:-kind:Username:AditiapiGroup:rbac.authorization.k8s.io
KubernetesRBAC的好处
KubernetesRBAC的长处在于它准许原生成功对集群中各种用户和机器的最小权限。关键的好处是:
1.适当的授权
经过对各种用户和服务帐户授予Kubernetes资源的最小权限,是DevOps和架构师可以成功零信赖的关键支柱之一。组织可以缩小数据暴露和数据暴露的危险,还可以防止外部员工异常删除或操纵任何关键资源。
2.职责分别
在Kubernetes资源上运行RBAC将一直有助于组织中用户(例如开发人员、DevOps、测试人员、SRE等)的职责分别。例如,为了在开发环境中创立/删除新资源,开发人员不应该依赖于治理员。雷同,将新运行程序部署到测试主机并在测试后删除pod不应该成为DevOps或测试人员的瓶颈。将授权和权限运行到用户(如开发人员和CI/CD部署代理)各自的上班空间(如命名空间或集群)将缩小依赖并缩小懒散。
3.100%恪违法规
许多行业法规(例如HIPAA、GDPR、SOX等)都要求软件畛域有严厉的认证和授权机制。经常使用KubernetesRBAC,DevOps和架构师可以极速地将RBAC成功到他们的Kubernetes集群中,并改良他们的设置以遵守这些规范。
KubernetesRBAC的缺陷
关于中小型企业来说,经常使用KubernetesRBAC是正当的,但不倡导经常使用KubernetesRBAC,其要素如下:
原文题目:WhatIsKubernetesRBACandWhyDoYouNeedIt?,作者:DebasreePanda
使用RBAC授权
基于角色的访问控制 (RBAC) 是一种根据组织内各个用户的角色来调节对计算机或网络资源的访问的方法。
RBAC 授权使用 API 组 推动授权决策,允许您通过 Kubernetes API 动态配置策略。
要启用 RBAC,请启动 API 服务器将 --authorization-mode 标志设置为逗号分隔的列表,其中包括 RBAC ; 例如:
RBAC API 声明了四种 Kubernetes 对象: Role 、 ClusterRole 、RoleBinding 和 ClusterRoleBinding 。您可以 像任何其他 Kubernetes 对象一样使用工具来 描述 或修改对象。 kubectl,
警告: 这些对象在设计上会施加访问限制。如果您在学习过程中对集群进行更改,请参阅权限提升预防和引导以了解这些限制如何阻止您进行某些更改。
RBAC 角色 或 ClusterRole 包含表示一组权限的规则。权限纯粹是附加的(没有“拒绝”规则)。
角色总是在特定的范围内设置权限 命名空间 ; 创建角色时,必须指定它所属的命名空间。
相反,ClusterRole 是一个非命名空间资源。资源具有不同的名称(Role 和 ClusterRole),因为 Kubernetes 对象总是必须具有命名空间或不具有命名空间;不可能两者兼而有之。
ClusterRoles 有多种用途。您可以使用 ClusterRole 来:
如果要在命名空间中定义角色,请使用角色;如果要在集群范围内定义角色,请使用 ClusterRole。
这是“默认”命名空间中的示例角色,可用于授予对豆荚 :
ClusterRole 可用于授予与角色相同的权限。由于 ClusterRoles 是集群范围的,您还可以使用它们来授予对以下内容的访问权限:
下面是一个 ClusterRole 示例,可用于授予对秘密 在任何特定命名空间中,或跨所有命名空间(取决于它的 绑定 方式):
Role 或 ClusterRole 对象的名称必须是有效的路径段名称 。
角色绑定将角色中定义的权限授予一个用户或一组用户。它包含一个 主题 列表(用户、组或服务帐户),以及对被授予角色的引用。RoleBinding 授予特定命名空间内的权限,而 ClusterRoleBinding 授予访问集群范围的权限。
RoleBinding 可以引用同一命名空间中的任何角色。或者,RoleBinding 可以引用 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 的命名空间。如果要将 ClusterRole 绑定到集群中的所有命名空间,请使用 ClusterRoleBinding。
RoleBinding 或 ClusterRoleBinding 对象的名称必须是有效的路径段名称 。
下面是一个 RoleBinding 示例,它将“pod-reader”角色授予“default”命名空间中的用户“jane”。这允许“jane”读取“default”命名空间中的 pod。
RoleBinding 还可以引用 ClusterRole 以将该 ClusterRole 中定义的权限授予 RoleBinding 命名空间内的资源。这种引用允许您在集群中定义一组通用角色,然后在多个命名空间中重用它们。
例如,即使以下 RoleBinding 引用 ClusterRole,“dave”(主题,区分大小写)也只能读取“development”命名空间中的 Secret,因为 RoleBinding 的命名空间(在其元数据中)是“development” .
要在整个集群中授予权限,您可以使用 ClusterRoleBinding。以下 ClusterRoleBinding 允许组“manager”中的任何用户读取任何命名空间中的机密。
创建绑定后,您无法更改它所引用的角色或集群角色。如果您尝试更改绑定 roleRef ,则会收到验证错误。如果确实要更改 roleRef 绑定,则需要删除绑定对象并创建替换。
这种限制有两个原因:
命令行实用程序创建或更新包含 RBAC 对象的 kubectl auth reconcile 清单文件,并在需要更改绑定对象引用的角色时处理删除和重新创建绑定对象。有关详细信息,请参阅 命令用法和示例 。
在 Kubernetes API 中,大多数资源都使用其对象名称的字符串表示形式来表示和访问,例如 pods Pod。RBAC 使用与相关 API 端点的 URL 中出现的完全相同的名称来引用资源。一些 Kubernetes API 涉及子资源 ,例如 Pod 的日志。对 Pod 日志的请求如下所示:
在这种情况下, pods 是 Pod 资源的命名空间资源,并且 log 是 pods . 要在 RBAC 角色中表示这一点,请使用斜杠 (/ ) 来分隔资源和子资源。要允许主题读取 pods 并访问 log 每个 Pod 的子资源,请编写:
您还可以通过 resourceNames 列表为某些请求按名称引用资源。指定后,可以将请求限制为资源的单个实例。这是一个将其主题限制为 only get 或 update a配置映射 命名 my-configmap :
注意: 您不能通过资源名称来限制 create 或 deletecollection 请求。对于 create ,此限制是因为在授权时可能不知道新对象的名称。如果您限制 list 或 watch 通过资源名称,客户端必须在其或请求中包含与指定资源名称匹配的 字段选择器才能获得授权。例如, list``watch``kubectl get configmaps --field-selector==my-configmap
您可以将多个 ClusterRole 聚合为一个组合的 ClusterRole。 一个控制器,作为集群控制平面的一部分运行,用一个集合监视 ClusterRole 对象 aggregationRule 。定义一个 aggregationRule 标签选择器 控制器用来匹配应该组合到这个 rules字段中的其他 ClusterRole 对象。
这是一个聚合 ClusterRole 的示例:
如果您创建与现有聚合 ClusterRole 的标签选择器匹配的新 ClusterRole,则该更改会触发将新规则添加到聚合 ClusterRole 中。这是一个示例,通过创建另一个标记为 的 ClusterRole,将规则添加到“监控”/aggregate-to-monitoring: true 。
默认的 面向用户的角色 使用 ClusterRole 聚合。这使您作为集群管理员可以包含自定义资源的规则,例如由自定义资源定义或聚合 API 服务器,以扩展默认角色。
例如:以下 ClusterRoles 让“admin”和“edit”默认角色管理名为 CronTab 的自定义资源,而“view”角色只能对 CronTab 资源执行读取操作。您可以假设 CronTab 对象 crontabs 在 API 服务器看到的 URL 中命名。
以下示例是 Role 或 ClusterRole 对象的摘录,仅显示该 rules 部分。
允许 pods 在核心中读取资源API 组 :
允许在 API 组和API 组中读/写部署(在 HTTP 级别: deployments在其 URL 的资源部分中的对象) : extensions``apps
允许读取核心 API 组中的 Pod,以及读取或写入 API 组中的 Job batch 资源 extensions :
允许读取名为“my-config”的 ConfigMap(必须与 RoleBinding 绑定以限制单个命名空间中的单个 ConfigMap):
允许读取 nodes 核心组中的资源(因为节点是集群范围的,这必须在与 ClusterRoleBinding 绑定的 ClusterRole 中才能生效):
允许对非资源端点 /healthz 和所有子路径的 GET 和 POST 请求(必须在与 ClusterRoleBinding 绑定的 ClusterRole 中才能生效):
RoleBinding 或 ClusterRoleBinding 将角色绑定到主题。主题可以是组、用户或服务帐户 .
Kubernetes 将用户名表示为字符串。这些可以是: 简单的名称,例如“alice”;电子邮件样式的名称,例如“ ”;或表示为字符串的数字用户 ID。作为集群管理员,您可以配置 身份验证模块,以便身份验证以您想要的格式生成用户名。
注意: 前缀 system: 是为 Kubernetes 系统保留的,因此您应该确保您没有名称 system: 以意外开头的用户或组。除了这个特殊的前缀,RBAC 授权系统不需要任何格式的用户名。
在 Kubernetes 中,Authenticator 模块提供组信息。组,如用户,表示为字符串,并且该字符串没有格式要求,除了 system: 保留前缀。
ServiceAccounts 的名称以 为前缀 system:serviceaccount: ,并且属于名称以 为前缀的组 system:serviceaccounts: 。
笔记:
以下示例是 RoleBinding 仅显示该 subjects 部分的摘录。
对于名为 的用户 :
对于名为 的组 frontend-admins :
对于“kube-system”命名空间中的默认服务帐户:
对于任何命名空间中“qa”组中的所有服务帐户:
对于“开发”命名空间中“开发”组中的所有服务帐户:
对于任何命名空间中的所有服务帐户:
对于所有经过身份验证的用户:
对于所有未经身份验证的用户:
对于所有用户:
API 服务器创建一组默认 ClusterRole 和 ClusterRoleBinding 对象。其中很多都是带 system: 前缀的,表示资源是由集群控制平面直接管理的。所有默认的 ClusterRoles 和 ClusterRoleBindings 都标有 /bootstrapping=rbac-defaults 。
警告: 使用带有 system: 前缀的名称修改 ClusterRole 和 ClusterRoleBindings 时要小心。对这些资源的修改可能会导致集群无法正常工作。
在每次启动时,API 服务器会使用任何缺失的权限更新默认集群角色,并使用任何缺失的主题更新默认集群角色绑定。这允许集群修复意外修改,并有助于在新 Kubernetes 版本中权限和主题发生变化时保持角色和角色绑定是最新的。
要退出此协调,请将 /autoupdate默认集群角色或角色绑定上的注释设置为 false . 请注意,缺少默认权限和主题可能会导致集群无法正常工作。
如果 RBAC 授权方处于活动状态,则默认情况下会启用自动对帐。
默认角色绑定授权未经身份验证和经过身份验证的用户读取被认为安全且可公开访问的 API 信息(包括 CustomResourceDefinitions)。要禁用匿名未经身份验证的访问,请添加 --anonymous-auth=false 到 API 服务器配置。
通过 kubectl 运行查看这些角色的配置:
注意: 如果您编辑该 ClusterRole,您的更改将在 API 服务器重新启动时通过 auto-reconciliation 被覆盖。为避免覆盖,请不要手动编辑角色,或禁用自动协调。
<caption>Kubernetes RBAC API 发现角色</caption><colgroup><col><col><col></colgroup>
一些默认 ClusterRoles 没有 system: 前缀。这些旨在成为面向用户的角色。它们包括超级用户角色 (cluster-admin )、旨在使用 ClusterRoleBindings 在集群范围内授予的角色,以及旨在使用 RoleBindings (admin 、 edit 、 view ) 在特定命名空间内授予的角色。
面向用户的 ClusterRoles 使用 ClusterRole 聚合 来允许管理员在这些 ClusterRoles 上包含自定义资源的规则。要将规则添加到 admin 、 edit 或 view 角色,请创建具有以下一个或多个标签的 ClusterRole:
如果在 RoleBinding 中使用,则允许对命名空间中的大多数资源进行读/写访问,包括在命名空间中创建角色和角色绑定的能力。此角色不允许对资源配额或命名空间本身进行写访问。此角色还不允许对使用 Kubernetes v1.22+ 创建的集群中的端点进行写访问。更多信息可在“端点的写入访问”部分 中找到。
| | 编辑| 没有 | 允许对命名空间中的大多数对象进行读/写访问。
此角色不允许查看或修改角色或角色绑定。但是,该角色允许访问 Secrets 并作为命名空间中的任何 ServiceAccount 运行 Pod,因此它可以用于获取命名空间中任何 ServiceAccount 的 API 访问级别。此角色还不允许对使用 Kubernetes v1.22+ 创建的集群中的端点进行写访问。更多信息可在“端点的写入访问”部分 中找到。
| | 看法| 没有 | 允许只读访问以查看命名空间中的大多数对象。它不允许查看角色或角色绑定。
此角色不允许查看 Secret,因为读取 Secret 的内容可以访问命名空间中的 ServiceAccount 凭证,这将允许 API 访问命名空间中的任何 ServiceAccount(一种权限提升形式)。
您应该使用 Node 授权 者和 NodeRestriction 准入插件 而不是<tt>system:node</tt>角色,并允许根据计划在其上运行的 Pod 授予对 kubelet 的 API 访问权限。
<tt>system:node</tt>角色的存在只是为了兼容从 v1.8 之前的版本升级的 Kubernetes 集群。
| | 系统:节点代理| 系统:kube-proxy 用户 | 允许访问所需的资源 kube-代理 零件。 |
Kubernetes 控制器管理器 运行控制器 内置在 Kubernetes 控制平面中。当使用 调用时 --use-service-account-credentials ,kube-controller-manager 使用单独的服务帐户启动每个控制器。每个内置控制器都有对应的角色,前缀为 system:controller: . 如果控制器管理器不是以 启动的 --use-service-account-credentials ,它使用自己的凭据运行所有控制循环,必须授予所有相关角色。这些角色包括:
RBAC API 可防止用户通过编辑角色或角色绑定来提升权限。因为这是在 API 级别强制执行的,所以即使没有使用 RBAC 授权方,它也适用。
仅当以下至少一项为真时,您才能创建/更新角色:
例如,如果 user-1 无法在集群范围内列出 Secret,则无法创建包含该权限的 ClusterRole。允许用户创建/更新角色:
如果您已经拥有被引用角色中包含的所有权限(与角色绑定在同一范围内) ,或者 如果您已被授权 bind 对被引用角色执行谓词,则只能创建/更新角色绑定。例如,如果 user-1 无法在集群范围内列出 Secret,则它们无法创建 ClusterRoleBinding 到授予该权限的角色。允许用户创建/更新角色绑定:
例如,此 ClusterRole 和 RoleBinding 将允许 user-1 授予其他用户命名空间中的 admin 、 edit 和 view 角色 user-1-namespace :
在引导第一个角色和角色绑定时,初始用户有必要授予他们尚未拥有的权限。引导初始角色和角色绑定:
在单个命名空间中创建定义权限的角色对象。例子:
创建一个 ClusterRole。例子:
授予特定命名空间内的角色或集群角色。例子:
在整个集群(所有命名空间)中授予 ClusterRole。例子:
/v1 从清单文件创建或更新API 对象。
如果需要,将创建缺少的对象,并为命名空间的对象创建包含的命名空间。
现有角色已更新以包含输入对象中的权限,并在 --remove-extra-permissions 指定时删除额外权限。
更新现有绑定以将主题包括在输入对象中,如果 --remove-extra-subjects 指定,则删除额外的主题。
例子:
默认 RBAC 策略授予控制平面组件、节点和控制器的范围权限,但 不授予 命名空间之外的服务帐户 kube-system 权限(除了授予所有经过身份验证的用户的发现权限)。
这允许您根据需要将特定角色授予特定的 ServiceAccounts。细粒度的角色绑定提供了更高的安全性,但需要更多的管理工作。更广泛的授权可以为 ServiceAccounts 提供不必要的(并且可能会升级的)API 访问,但更易于管理。
按照从最安全到最不安全的顺序,这些方法是:
什么是K8S?
k8s是什么?
Kubernetes 是一个可移植的,可扩展的开源容器编排平台,用于管理容器化的工作负载和服务,方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。
为什么现在流行使用容器?
早期: 在物理服务器上面部署应用程序存在资源分配问题,因为其不能在物理服务器中的应用程序定义资源边界,导致应用程序资源利用不足而无法扩展.
后来: 为了解决该问题,引入了虚拟化技术, 虚拟化技术是指允许你在单个物理服务器的 CPU 上运行多个虚拟机,可以让多个应用程序在虚拟机之间进行隔离,具有一定的安全性, 每一个虚拟机就是一台完整的计算机, 在虚拟化硬件之上运行所有组件.
现在: 多数在物理服务器上面部署应用程序都是采kubectl用容器的方式,容器类似于虚拟机,它们都具有自己的文件系统、CPU、内存、进程空间等, 且由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。基于此特点被企业大范围使用.
为什么需要使用k8s容器?
若出现这样一个环境: 在生产环境中如果一个容器发生故障,则我们需要手动去启动另外一个容器,这样的操作是对我们的管理员来说是不太方便的, 若一个容器出现故障,另一个容器可以自动启动容器接管故障的容器,这样是最好的.
k8s就可以实现该效果,Kubernetes 提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移、部署模式等。
k8s功能: 服务发现和负载均衡, 存储编排, 自动部署和回滚, 自动完成装箱计算, 自我修复, 密钥与配置管理
名词解释
Secret有三种类型:
k8s的组成
k8s是由组件,API,对象等组成.
包含所有相互关联组件的 Kubernetes 集群图如下:
组件
Kubernetes 控制面 的核心是 API 服务器。 API 服务器负责提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信。
对象
Kubernetes对象是Kubernetes系统中的持久实体。Kubernetes使用这些实体来表示集群的状态.
具体来说,他们可以描述:
Kubernetes 架构
Kubernetes 架构由节点,控制面到节点通信, 控制器, 云控制器管理器组成.
master 流程图
节点
节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。 每个节点包含运行 Pods 所需的服务, 这些 Pods 由 控制面 负责管理.
节点上的组件包括 kubelet、 容器运行时以及 kube-proxy。
节点状态
可以使用 kubectl 来查看节点状态和其他细节信息:
kubectl describe node <�节点名称>
一个节点包含以下信息:
控制面到节点通信
控制器
在 Kubernetes 中,控制器通过监控集群 的公共状态,并致力于将当前状态转变为期望的状态。
举个例子: 当前室内温度为20度, 我们通过调节遥控器,使其温度上升至24度, 这20度到24度的变化即为让其从当前状态接近期望状态。
控制器模式分为直接控制和通过API服务器来控制.
云控制器管理器
云控制器管理器是指嵌入特定云的控制逻辑的 控制平面组件。 云控制器管理器允许您链接聚合到云提供商的应用编程接口中, 并分离出相互作用的组件与您的集群交互的组件。
云控制器管理器中的控制器包括:
Kubernetes 安全性
云原生安全
云原生安全4个C: 云(Cloud)、集群(Cluster)、容器(Container)和代码(Code)
云原生安全模型的每一层都是基于下一个最外层,代码层受益于强大的基础安全层(云、集群、容器)。我们无法通过在代码层解决安全问题来为基础层中糟糕的安全标准提供保护。
基础设施安全
Kubetnetes 基础架构关注领域
建议
通过网络访问 API 服务(控制平面)
所有对 Kubernetes 控制平面的访问不允许在 Internet 上公开,同时应由网络访问控制列表控制,该列表包含管理集群所需的 IP 地址集。
通过网络访问 Node(节点)
节点应配置为 仅能 从控制平面上通过指定端口来接受(通过网络访问控制列表)连接,以及接受 NodePort 和 LoadBalancer 类型的 Kubernetes 服务连接。如果可能的话,这些节点不应完全暴露在公共互联网上。
Kubernetes 云访问提供商的 API
每个云提供商都需要向 Kubernetes 控制平面和节点授予不同的权限集。为集群提供云提供商访问权限时,最好遵循对需要管理的资源的最小特权原则。Kops 文档提供有关 IAM 策略和角色的信息。
访问 etcd
对 etcd(Kubernetes 的数据存储)的访问应仅限于控制平面。根据配置情况,你应该尝试通过 TLS 来使用 etcd。更多信息可以在 etcd 文档中找到。
etcd 加密
在所有可能的情况下,最好对所有驱动器进行静态数据加密,但是由于 etcd 拥有整个集群的状态(包括机密信息),因此其磁盘更应该进行静态数据加密。
集群组件安全
容器安全
代码安全
Kubernetes架构常见问题
Kubernetes ATTACK 矩阵
信息泄露
云账号AK泄露
API凭证(即阿里云AccessKey)是用户访问内部资源最重要的身份凭证。用户调用API时的通信加密和身份认证会使用API凭证.
API凭证是云上用户调用云服务API、访问云上资源的唯一身份凭证。
API凭证相当于登录密码,用于程序方式调用云服务API.
k8s configfile泄露
kubeconfig文件所在的位置:
$HOME//config
Kubeconfig文件包含有关Kubernetes集群的详细信息,包括它们的位置和凭据。
云厂商会给用户提供该文件,以便于用户可以通过kubectl对集群进行管理. 如果攻击者能够访问到此文件(如办公网员工机器入侵、泄露到Github的代码等),就可以直接通过API Server接管K8s集群,带来风险隐患。
Master节点SSH登录泄露
常见的容器集群管理方式是通过登录Master节点或运维跳板机,然后再通过kubectl命令工具来控制k8s。
云服务器提供了通过ssh登陆的形式进行登陆master节点.
若Master节点SSH连接地址泄露,攻击者可对ssh登陆进行爆破,从而登陆上ssh,控制集群.
容器组件未鉴权服务
Kubernetes架构下常见的开放服务指纹如下:
注:前六个重点关注: 一旦被控制可以直接获取相应容器、相应节点、集群权限的服务
了解各个组件被攻击时所造成的影响
组件分工图:
![以及为什么在治理权限时经常使用它至关关键](https://tyye.cn/zb_users/theme/tpure/style/images/lazyload.png)
假如用户想在集群里面新建一个容器集合单元, 流程如下:
攻击apiserver
apiserver介绍:在Kubernetes中,对于未鉴权对apiserver, 能访问到 apiserver 一般情况下就能获取了集群的权限.
在攻击者眼中Kubernetes APIServer
默认情况下apiserver都有鉴权:
未鉴权配置如下:
对于这类的未鉴权的设置来说,访问到 apiserver 一般情况下就获取了集群的权限:
如何通过apiserver来进行渗透,可参考:攻击kubelet
每一个Node节点都有一个kubelet(每个节点上运行的代理)服务,kubelet监听了,,等端口。
端口,是kubelet与apiserver进行通信对主要端口, 通过该端口,kubelet可以知道当前应该处理的任务.该端口在最新版Kubernetes是有鉴权的, 但在开启了接受匿名请求的情况下,不带鉴权信息的请求也可以使用提供的能力, 在Kubernetes早期,很多挖矿木马基于该端口进行传播.
在配置文件中,若进行如下配置,则可能存在未授权访问漏洞.
/var/bin/kubulet/config/yaml
若端口存在未授权访问漏洞,我们可以直接访问/pods进行查看
根据在pods中获取的信息,我们可以在容器中执行命令
curl -Gks{namespace}/{podname}/{containername} \-d input=1 -d output=1 -d tty=1 \-d command=whoami
上述命令得到websocket地址,连接websocket得到命令结果:
使用wscat工具连接websocket
wscat -c “{websocket}” --no-check
即可得到我们执行命令的结果.
获取token
/var/run/secrets//serviceaccount
然后即可访问kube-api server,获取集群权限
curl -ks -H Authorization: Bearer \ ttps://master:6443/api/v1/namespaces/{namespace}/secrets
攻击kubelet总体步骤如下:
攻击dashboard
dashboard登陆链接如下:
界面如下:
dashboard是Kubernetes官方推出的控制Kubernetes的图形化界面.在Kubernetes配置不当导致dashboard未授权访问漏洞的情况下,通过dashboard我们可以控制整个集群。
默认情况下, dashboard是需要进行鉴权操作的,当用户开启了enable-skip-login时可以在登录界面点击Skip跳过登录进入dashboard.
通过skip登陆的dashboard默认是没有操作集群的权限,因为Kubernetes使用RBAC(Role-based access control)机制进行身份认证和权限管理,不同的serviceaccount拥有不同的集群权限。
但有些开发者为了方便或者在测试环境中会为Kubernetes-dashboard绑定cluster-admin这个ClusterRole(cluster-admin拥有管理集群的最高权限).
为Kubernetes-dashboard绑定cluster-admin 设置如下:
后通过skip登陆dashboard便有了管理集群的权限.
创建Pod控制node节点,该pod主要是将宿主机根目录挂载到容器tmp目录下。
新建一个Pod如下:
通过该容器的tmp目录管理node节点的文件
攻击etcd
Kubernetes默认使用了etcd v3来存储数据, 若能naetcd对内暴露2379端口,本地127.0.0.1可免认证访问. 其他地址要带—endpoint参数和cert进行认证。
未授权访问流程:
攻击docker remote api(Docker daemon公网暴露)
2375是docker远程操控的默认端口,通过这个端口可以直接对远程的docker 守护进程进行操作。Docker 守护进程默认监听2375端口且未鉴权.
当机器以方式启动daemon时,可以在外部机器对该机器的docker daemon进行直接操作:
docker daemon -H=0.0.0.0:2375
之后依次执行systemctl daemon-reload、systemctl restart docker
外部主机使用 即可操作暴露2375端口的主机.
因此当你有访问到目标Docker API 的网络能力或主机能力的时候,你就拥有了控制当前服务器的能力。我们可以利用Docker API在远程主机上创建一个特权容器,并且挂载主机根目录到容器.
检测目标是否存在docker api未授权访问漏洞的方式也很简单,访问路径是否含有ContainersRunning、DockerRootDir等关键字。
攻击kubectl proxy
二次开发所产生的问题
管理Kubernetes无论是使用 kubectl 或 Kubernetes dashboard 的UI功能,其实都是间接在和 APIServer 做交互.
如果有需求对k8s进行二次开发的话,大部分的开发功能请求了 APIServer 的 Rest API 从而使功能实现的。
例如:
-
DELETE类似于这样去调用apiserver, 攻击者若修改namespace、pod和容器名, 那么即可造成越权.
推荐工具
Kube-Hunter扫描漏洞
kube-hunter是一款用于寻找Kubernetes集群中的安全漏洞扫描器
下载地址:强推)
CDK是一款为容器环境定制的渗透测试工具,在已攻陷的容器内部提供零依赖的常用命令及PoC/EXP。集成Docker/K8s场景特有的 逃逸、横向移动、持久化利用方式,插件化管理。
下载地址:参考链接
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。