安全加固指南 - v2.5.0 - CIS1.6

本文讲解了如何使您的集群符合互联网安全中心发布的 Kubernetes 安全基准,保护集群中节点的安全。安装 Kubernetes 之前,请按照本指南进行操作。加固指南旨在与特定版本的 CIS Kubernetes Benchmark,Kubernetes 和 Rancher 一起使用。

加固指南旨在与特定版本的 CIS Kubernetes Benchmark,Kubernetes 和 Rancher 一起使用:

Rancher 版本CIS Benchmark 版本Kubernetes 版本
Rancher v2.5.4Benchmark 1.6Kubernetes v1.18

单击这里下载 PDF 版本的加固指南

概览

下面的安全加固指南是针对在生产环境的 Rancher v2.5.4 中使用 Kubernetes v1.15 版本的集群。它概述了如何满足互联网安全中心(CIS)提出的 Kubernetes 安全标准。

有关如果根据官方 CIS 基准评估集群的更多详细信息,请参阅CIS Benchmark Rancher 自测指南 - Rancher v2.5.4

已知问题

如果注册自定义节点时只提供了公共 IP,在 CIS 1.6 加固设置中,将无法正常在 Rancher UI 中使用执行命令行查看日志功能。

  • 如果注册自定义节点时只提供了公共 IP,在 CIS 1.6 加固设置中,将无法正常在 Rancher UI 中使用执行命令行查看日志功能。如果想要使用上述两个功能,请在注册自定义节点时提供私有 IP 地址。
  • default_pod_security_policy_template_id:restricted时,Rancher 在默认的 service account 中创建角色绑定集群角色绑定。CIS 1.6 要求默认 service account 没有绑定任何角色,不提供 service account 的 token,不分配特定的权限。

配置内核运行时参数

对于集群中的所有类型的节点,都建议使用以下的sysctl配置。在/etc/sysctl.d/90-kubelet.conf中设置以下参数:

  1. vm.overcommit_memory=1
  2. vm.panic_on_oom=0
  3. kernel.panic=10
  4. kernel.panic_on_oops=1
  5. kernel.keys.root_maxbytes=25000000

Copy

执行sysctl -p /etc/sysctl.d/90-kubelet.conf来启用配置。

配置etcd用户和组

在安装 RKE 之前,需要设置etcd服务的用户帐户和组。etcd用户的uidgid将在 RKE 的config.yml中使用,以在安装期间为文件和目录设置适当的权限。

以下命令使用52034作为uidgid的例子。任何有效的未使用的uidgid也可以用来代替52034

创建etcd用户和组

要创建etcd组,请运行以下控制台命令。

  1. addgroup --gid 52034 etcd
  2. useradd --comment "etcd service account" --uid 52034 --gid 52034 etcd

Copy

使用etcd用户的uidgid更新 RKE 的 config.yml文件:

  1. services:
  2. etcd:
  3. gid: 52034
  4. uid: 52034

Copy

default服务账号的automountServiceAccountToken设置为 false

Kubernetes 提供了一个默认服务账号(Service Account),如果集群的工作负载中没有为 Pod 分配任何特定服务账号,那么它将会使用这个default的服务账号。在需要从 Pod 访问 Kubernetes API 的情况下,应为该 Pod 创建一个特定的服务账号,并向该服务账号授予权限。这个default的服务账户应该被设置为不提供服务账号令牌(service account token)和任何权限。将automountServiceAccountToken设置为 false 之后,Kubernetes 在启动 Pod 时,将不会自动注入default服务账户。

对于标准 RKE 安装中包括defaultkube-system在内的每个命名空间,default服务账户必须包含这个值。

  1. automountServiceAccountToken: false

Copy

把下面的 yaml 另存为account_update.yaml

  1. apiVersion: v1
  2. kind: ServiceAccount
  3. metadata:
  4. name: default
  5. automountServiceAccountToken: false

Copy

创建一个名称为account_update.sh的脚本。通过运行chmod +x account_update.sh,使这个脚本有执行权限。

  1. #!/bin/bash -e
  2. for namespace in $(kubectl get namespaces -o custom-columns=NAME:.metadata.name --no-headers); do
  3. kubectl patch serviceaccount default -n ${namespace} -p "$(cat account_update.yaml)"
  4. done

Copy

确保所有命名空间均已定义网络策略

在同一个 Kubernetes 集群上运行不同的应用程序会产生一个风险,那就是应用可能受到相邻应用程序的攻击。为了确保容器只能与预期的容器进行通信,网络细分是必不可少的。通过设置网络策略(Network Policy),可以设置哪些 Pod 之间可以通信,以及是否可以和其他网络端点进行通信。

网络策略是作用于命名空间范围的。将网络策略应用于给定命名空间时,所有不被这个策略允许的流量将被拒绝。然而,如果命名空间中没有设置网络策略,那么进出这个命名空间中 Pod 的所有流量都将被允许。要使用网络策略,必须启用 CNI(容器网络接口)插件。本指南使用canal提供策略实施。您可以在这里找到有关 CNI 插件的其他信息。

在集群上启用 CN​​I 插件后,您可以设置一个默认的网络策略。下面是一个宽松的网络策略示例,仅供参考。如果您想要允许到某个命名空间内所有 Pod 的流量(即使已经添加了一些策略,使得一些 Pods 被隔离了),您可以创建一个策略,明确允许该命名空间中的所有流量。将以下yaml另存为 default-allow-all.yaml。额外关于网络策略的信息,请查看Kubernetes 官方文档

重要

这个NetworkPolicy示例不建议在生产环境中使用。

  1. ---
  2. apiVersion: networking.k8s.io/v1
  3. kind: NetworkPolicy
  4. metadata:
  5. name: default-allow-all
  6. spec:
  7. podSelector: {}
  8. ingress:
  9. - {}
  10. egress:
  11. - {}
  12. policyTypes:
  13. - Ingress
  14. - Egress

Copy

创建一个名称为apply_networkPolicy_to_all_ns.sh的脚本。通过运行chmod +x apply_networkPolicy_to_all_ns.sh,使这个脚本有执行权限

  1. #!/bin/bash -e
  2. for namespace in $(kubectl get namespaces -o custom-columns=NAME:.metadata.name --no-headers); do
  3. kubectl apply -f default-allow-all.yaml -n ${namespace}
  4. done

Copy

运行脚本,以使全部的命名空间使用这个default-allow-all.yaml文件中的宽松NetworkPolicy

加固的 RKE cluster.yml 配置参考

您可以用这个供您参考的cluster.yml,通过 RKE CLI 来创建安全加固的 Rancher Kubernetes Engine(RKE)集群。有关每个配置的详细信息,请参阅RKE 文档。这个cluster.yml问号不包括所需的nodes指令,它将根据你的环境而变化。有关如何节点配置的文档可以参考RKE 节点配置示例

  1. # If you intend to deploy Kubernetes in an air-gapped environment,
  2. # please consult the documentation on how to configure custom RKE images.
  3. # https://rancher.com/docs/rke/latest/en/installation/
  4. # the nodes directive is required and will vary depending on your environment
  5. # documentation for node configuration can be found here:
  6. # https://rancher.com/docs/rke/latest/en/config-options/nodes
  7. nodes: []
  8. services:
  9. etcd:
  10. image: ""
  11. extra_args: {}
  12. extra_binds: []
  13. extra_env: []
  14. win_extra_args: {}
  15. win_extra_binds: []
  16. win_extra_env: []
  17. external_urls: []
  18. ca_cert: ""
  19. cert: ""
  20. key: ""
  21. path: ""
  22. uid: 52034
  23. gid: 52034
  24. snapshot: false
  25. retention: ""
  26. creation: ""
  27. backup_config: null
  28. kube-api:
  29. image: ""
  30. extra_args: {}
  31. extra_binds: []
  32. extra_env: []
  33. win_extra_args: {}
  34. win_extra_binds: []
  35. win_extra_env: []
  36. service_cluster_ip_range: ""
  37. service_node_port_range: ""
  38. pod_security_policy: true
  39. always_pull_images: false
  40. secrets_encryption_config:
  41. enabled: true
  42. custom_config: null
  43. audit_log:
  44. enabled: true
  45. configuration: null
  46. admission_configuration: null
  47. event_rate_limit:
  48. enabled: true
  49. configuration: null
  50. kube-controller:
  51. image: ""
  52. extra_args:
  53. feature-gates: RotateKubeletServerCertificate=true
  54. extra_binds: []
  55. extra_env: []
  56. win_extra_args: {}
  57. win_extra_binds: []
  58. win_extra_env: []
  59. cluster_cidr: ""
  60. service_cluster_ip_range: ""
  61. scheduler:
  62. image: ""
  63. extra_args: {}
  64. extra_binds: []
  65. extra_env: []
  66. win_extra_args: {}
  67. win_extra_binds: []
  68. win_extra_env: []
  69. kubelet:
  70. image: ""
  71. extra_args:
  72. feature-gates: RotateKubeletServerCertificate=true
  73. protect-kernel-defaults: "true"
  74. tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
  75. extra_binds: []
  76. extra_env: []
  77. win_extra_args: {}
  78. win_extra_binds: []
  79. win_extra_env: []
  80. cluster_domain: cluster.local
  81. infra_container_image: ""
  82. cluster_dns_server: ""
  83. fail_swap_on: false
  84. generate_serving_certificate: true
  85. kubeproxy:
  86. image: ""
  87. extra_args: {}
  88. extra_binds: []
  89. extra_env: []
  90. win_extra_args: {}
  91. win_extra_binds: []
  92. win_extra_env: []
  93. network:
  94. plugin: ""
  95. options: {}
  96. mtu: 0
  97. node_selector: {}
  98. update_strategy: null
  99. authentication:
  100. strategy: ""
  101. sans: []
  102. webhook: null
  103. addons: |
  104. apiVersion: policy/v1beta1
  105. kind: PodSecurityPolicy
  106. metadata:
  107. name: restricted
  108. spec:
  109. requiredDropCapabilities:
  110. - NET_RAW
  111. privileged: false
  112. allowPrivilegeEscalation: false
  113. defaultAllowPrivilegeEscalation: false
  114. fsGroup:
  115. rule: RunAsAny
  116. runAsUser:
  117. rule: MustRunAsNonRoot
  118. seLinux:
  119. rule: RunAsAny
  120. supplementalGroups:
  121. rule: RunAsAny
  122. volumes:
  123. - emptyDir
  124. - secret
  125. - persistentVolumeClaim
  126. - downwardAPI
  127. - configMap
  128. - projected
  129. ---
  130. apiVersion: networking.k8s.io/v1
  131. kind: NetworkPolicy
  132. metadata:
  133. name: default-allow-all
  134. spec:
  135. podSelector: {}
  136. ingress:
  137. - {}
  138. egress:
  139. - {}
  140. policyTypes:
  141. - Ingress
  142. - Egress
  143. ---
  144. apiVersion: v1
  145. kind: ServiceAccount
  146. metadata:
  147. name: default
  148. automountServiceAccountToken: false
  149. addons_include: []
  150. system_images:
  151. etcd: ""
  152. alpine: ""
  153. nginx_proxy: ""
  154. cert_downloader: ""
  155. kubernetes_services_sidecar: ""
  156. kubedns: ""
  157. dnsmasq: ""
  158. kubedns_sidecar: ""
  159. kubedns_autoscaler: ""
  160. coredns: ""
  161. coredns_autoscaler: ""
  162. nodelocal: ""
  163. kubernetes: ""
  164. flannel: ""
  165. flannel_cni: ""
  166. calico_node: ""
  167. calico_cni: ""
  168. calico_controllers: ""
  169. calico_ctl: ""
  170. calico_flexvol: ""
  171. canal_node: ""
  172. canal_cni: ""
  173. canal_controllers: ""
  174. canal_flannel: ""
  175. canal_flexvol: ""
  176. weave_node: ""
  177. weave_cni: ""
  178. pod_infra_container: ""
  179. ingress: ""
  180. ingress_backend: ""
  181. metrics_server: ""
  182. windows_pod_infra_container: ""
  183. ssh_key_path: ""
  184. ssh_cert_path: ""
  185. ssh_agent_auth: false
  186. authorization:
  187. mode: ""
  188. options: {}
  189. ignore_docker_version: false
  190. kubernetes_version: v1.18.12-rancher1-1
  191. private_registries: []
  192. ingress:
  193. provider: ""
  194. options: {}
  195. node_selector: {}
  196. extra_args: {}
  197. dns_policy: ""
  198. extra_envs: []
  199. extra_volumes: []
  200. extra_volume_mounts: []
  201. update_strategy: null
  202. http_port: 0
  203. https_port: 0
  204. network_mode: ""
  205. cluster_name:
  206. cloud_provider:
  207. name: ""
  208. prefix_path: ""
  209. win_prefix_path: ""
  210. addon_job_timeout: 0
  211. bastion_host:
  212. address: ""
  213. port: ""
  214. user: ""
  215. ssh_key: ""
  216. ssh_key_path: ""
  217. ssh_cert: ""
  218. ssh_cert_path: ""
  219. monitoring:
  220. provider: ""
  221. options: {}
  222. node_selector: {}
  223. update_strategy: null
  224. replicas: null
  225. restore:
  226. restore: false
  227. snapshot_name: ""
  228. dns: null
  229. upgrade_strategy:
  230. max_unavailable_worker: ""
  231. max_unavailable_controlplane: ""
  232. drain: null
  233. node_drain_input: null

Copy

安全加固的 RKE 模板配置参考

这个 RKE 参考模板提供了安装安全加固的 Kubenetes 所需的配置。RKE 模板用于配置 Kubernetes 和定义 Rancher 设置。请参阅Rancher 文档获得更多安装和 RKE 模板的详细信息。

  1. #
  2. # Cluster Config
  3. #
  4. default_pod_security_policy_template_id: restricted
  5. docker_root_dir: /var/lib/docker
  6. enable_cluster_alerting: false
  7. enable_cluster_monitoring: false
  8. enable_network_policy: true
  9. #
  10. # Rancher Config
  11. #
  12. rancher_kubernetes_engine_config:
  13. addon_job_timeout: 45
  14. ignore_docker_version: true
  15. kubernetes_version: v1.18.12-rancher1-1
  16. #
  17. # If you are using calico on AWS
  18. #
  19. # network:
  20. # plugin: calico
  21. # calico_network_provider:
  22. # cloud_provider: aws
  23. #
  24. # # To specify flannel interface
  25. #
  26. # network:
  27. # plugin: flannel
  28. # flannel_network_provider:
  29. # iface: eth1
  30. #
  31. # # To specify flannel interface for canal plugin
  32. #
  33. # network:
  34. # plugin: canal
  35. # canal_network_provider:
  36. # iface: eth1
  37. #
  38. network:
  39. mtu: 0
  40. plugin: canal
  41. rotate_encryption_key: false
  42. #
  43. # services:
  44. # kube-api:
  45. # service_cluster_ip_range: 10.43.0.0/16
  46. # kube-controller:
  47. # cluster_cidr: 10.42.0.0/16
  48. # service_cluster_ip_range: 10.43.0.0/16
  49. # kubelet:
  50. # cluster_domain: cluster.local
  51. # cluster_dns_server: 10.43.0.10
  52. #
  53. services:
  54. etcd:
  55. backup_config:
  56. enabled: false
  57. interval_hours: 12
  58. retention: 6
  59. safe_timestamp: false
  60. creation: 12h
  61. extra_args:
  62. election-timeout: "5000"
  63. heartbeat-interval: "500"
  64. gid: 52034
  65. retention: 72h
  66. snapshot: false
  67. uid: 52034
  68. kube_api:
  69. always_pull_images: false
  70. audit_log:
  71. enabled: true
  72. event_rate_limit:
  73. enabled: true
  74. pod_security_policy: true
  75. secrets_encryption_config:
  76. enabled: true
  77. service_node_port_range: 30000-32767
  78. kube_controller:
  79. extra_args:
  80. feature-gates: RotateKubeletServerCertificate=true
  81. kubelet:
  82. extra_args:
  83. feature-gates: RotateKubeletServerCertificate=true
  84. protect-kernel-defaults: "true"
  85. tls-cipher-suites: >-
  86. TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256
  87. fail_swap_on: false
  88. generate_serving_certificate: true
  89. ssh_agent_auth: false
  90. upgrade_strategy:
  91. max_unavailable_controlplane: "1"
  92. max_unavailable_worker: 10%
  93. windows_prefered_cluster: false

Copy

安全加固的 Ubuntu 18.04 LTS cloud-config参考配置

这个供您参考的cloud-config通常被用于云基础架构环境中,来进行计算实例的配置管理。这个参考配置了在安装 kubernetes 之前需要的 Ubuntu 操作系统级别的设置。

  1. #cloud-config
  2. apt:
  3. sources:
  4. docker.list:
  5. source: deb [arch=amd64] http://download.docker.com/linux/ubuntu $RELEASE stable
  6. keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
  7. system_info:
  8. default_user:
  9. groups:
  10. - docker
  11. write_files:
  12. - path: "/etc/apt/preferences.d/docker"
  13. owner: root:root
  14. permissions: "0600"
  15. content: |
  16. Package: docker-ce
  17. Pin: version 5:19*
  18. Pin-Priority: 800
  19. - path: "/etc/sysctl.d/90-kubelet.conf"
  20. owner: root:root
  21. permissions: "0644"
  22. content: |
  23. vm.overcommit_memory=1
  24. vm.panic_on_oom=0
  25. kernel.panic=10
  26. kernel.panic_on_oops=1
  27. kernel.keys.root_maxbytes=25000000
  28. package_update: true
  29. packages:
  30. - docker-ce
  31. - docker-ce-cli
  32. - containerd.io
  33. runcmd:
  34. - sysctl -p /etc/sysctl.d/90-kubelet.conf
  35. - groupadd --gid 52034 etcd
  36. - useradd --comment "etcd service account" --uid 52034 --gid 52034 etcd

Copy