

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 保護基礎設施 （主機）
<a name="protecting-the-infrastructure"></a>

由於保護您的容器映像非常重要，因此保護執行它們的基礎設施也同樣重要。本節會探索不同方式，以降低直接針對主機啟動之攻擊的風險。這些準則應與[執行期安全性](runtime-security.md)一節中概述的準則搭配使用。

## 建議
<a name="_recommendations"></a>

### 使用針對執行中容器最佳化的作業系統
<a name="_use_an_os_optimized_for_running_containers"></a>

請考慮使用 Flatcar Linux、Project Atomic、RancherOS 和 [Bottlerocket](https://github.com/bottlerocket-os/bottlerocket/)，這是 AWS 專為執行 Linux 容器而設計的特殊用途作業系統。它包含減少的攻擊面、開機時驗證的磁碟映像，以及使用 SELinux 強制執行許可界限。

或者，為您的 Kubernetes 工作者節點使用 [EKS 最佳化 AMI](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-amis.html)。EKS 最佳化 AMI 會定期發行，其中包含執行容器化工作負載所需的一組最少作業系統套件和二進位檔。

如需範例組態指令碼，請參閱 [Amazon EKS AMI RHEL Build Specification](https://github.com/aws-samples/amazon-eks-ami-rhel)，該指令碼可用於建置使用 Hashicorp Packer 在 Red Hat Enterprise Linux 上執行的自訂 Amazon EKS AMI。您可以進一步利用此指令碼來建置符合 STIG 規範的 EKS 自訂 AMIs。

### 讓您的工作者節點作業系統保持最新狀態
<a name="_keep_your_worker_node_os_updated"></a>

無論您使用的是 Bottlerocket 等容器最佳化主機作業系統還是更大的主機作業系統，但仍是極簡的 Amazon Machine Image，例如 EKS 最佳化 AMIs，最佳實務是將這些主機作業系統映像與最新的安全修補程式保持最新狀態。

對於 EKS 最佳化 AMIs，請定期檢查 [CHANGELOG](https://github.com/awslabs/amazon-eks-ami/blob/master/CHANGELOG.md) 和/或[版本備註管道](https://github.com/awslabs/amazon-eks-ami/releases)，並自動將更新的工作者節點映像推展到您的叢集。

### 將您的基礎設施視為不可變，並自動取代您的工作者節點
<a name="_treat_your_infrastructure_as_immutable_and_automate_the_replacement_of_your_worker_nodes"></a>

新的修補程式或更新可供使用時，請取代您的工作者，而不是執行就地升級。這可以用幾種方式進行。您可以在依序進行封鎖和耗盡節點時，使用最新的 AMI 將執行個體新增至現有的自動擴展群組，直到群組中的所有節點都被最新的 AMI 取代為止。或者，您可以將執行個體新增至新的節點群組，同時依序從舊節點群組封鎖和耗盡節點，直到取代所有節點為止。EKS [受管節點群組](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)使用第一種方法，當有新的 AMI 可用時， 會在主控台中顯示訊息來升級工作者。 `eksctl` 也有一種機制，可用來建立具有最新 AMI 的節點群組，並在執行個體終止之前從節點群組正常隔離和耗盡 Pod。如果您決定使用不同的方法來取代工作者節點，強烈建議您自動化程序，將人工監督降至最低，因為當新的更新/修補程式發佈時以及控制平面升級時，您可能需要定期取代工作者。

透過 EKS Fargate，AWS 會在更新可用時自動更新基礎基礎設施。通常可以順暢地完成此操作，但有時更新可能會導致您的 Pod 重新排程。因此，我們建議您在以 Fargate Pod 身分執行應用程式時，使用多個複本建立部署。

### 定期執行 kube-bench，以確認是否符合 [Kubernetes 的 CIS 基準](https://www.cisecurity.org/benchmark/kubernetes/)
<a name="_periodically_run_kube_bench_to_verify_compliance_with_cis_benchmarks_for_kubernetes"></a>

kube-bench 是 Aqua 的開放原始碼專案，可根據 Kubernetes 的 CIS 基準評估您的叢集。基準描述保護未受管 Kubernetes 叢集的最佳實務。CIS Kubernetes Benchmark 包含控制平面和資料平面。由於 Amazon EKS 提供全受管控制平面，因此並非所有來自 CIS Kubernetes Benchmark 的建議都適用。為了確保此範圍反映 Amazon EKS 的實作方式，AWS 建立了 *CIS Amazon EKS 基準*。EKS 基準從 CIS Kubernetes Benchmark 繼承，具有 EKS 叢集特定組態考量的其他社群輸入。

針對 EKS 叢集執行 [kube-bench](https://github.com/aquasecurity/kube-bench) 時，請遵循 Aqua Security 的[這些指示](https://github.com/aquasecurity/kube-bench/blob/main/docs/running.md#running-cis-benchmark-in-an-eks-cluster)。如需詳細資訊，請參閱[簡介 CIS Amazon EKS 基準](https://aws.amazon.com/blogs/containers/introducing-cis-amazon-eks-benchmark/)。

### 將對工作者節點的存取降到最低
<a name="_minimize_access_to_worker_nodes"></a>

當您需要遠端存取主機時，請使用 [SSM Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html)，而不是啟用 SSH 存取。與可能遺失、複製或共用的 SSH 金鑰不同，Session Manager 可讓您使用 IAM 控制對 EC2 執行個體的存取。此外，它還提供在執行個體上執行之命令的稽核線索和日誌。

自 2020 年 8 月 19 日起，受管節點群組支援自訂 AMIs 和 EC2 啟動範本。這可讓您將 SSM 代理程式嵌入 AMI，或在工作者節點啟動時安裝它。如果您不想修改最佳化 AMI 或 ASG 的啟動範本，您可以使用 DaemonSet 安裝 SSM 代理程式，如[本範例](https://github.com/aws-samples/ssm-agent-daemonset-installer)所示。

#### SSM 型 SSH 存取的最低 IAM 政策
<a name="_minimal_iam_policy_for_ssm_based_ssh_access"></a>

如果您只想避免 SSH 存取，`AmazonSSMManagedInstanceCore`AWS 受管政策包含 SSM Session Manager / SSM RunCommand 不需要的許多許可。需要特別注意`ssm:GetParameter(s)`的是允許角色存取參數存放區中所有參數的`*`許可 （包括已設定 AWS 受管 KMS 金鑰的 SecureStrings)。

下列 IAM 政策包含透過 SSM Systems Manager 啟用節點存取的最小許可集。

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "EnableAccessViaSSMSessionManager",
      "Effect": "Allow",
      "Action": [
        "ssmmessages:OpenDataChannel",
        "ssmmessages:OpenControlChannel",
        "ssmmessages:CreateDataChannel",
        "ssmmessages:CreateControlChannel",
        "ssm:UpdateInstanceInformation"
      ],
      "Resource": "*"
    },
    {
      "Sid": "EnableSSMRunCommand",
      "Effect": "Allow",
      "Action": [
        "ssm:UpdateInstanceInformation",
        "ec2messages:SendReply",
        "ec2messages:GetMessages",
        "ec2messages:GetEndpoint",
        "ec2messages:FailMessage",
        "ec2messages:DeleteMessage",
        "ec2messages:AcknowledgeMessage"
      ],
      "Resource": "*"
    }
  ]
}
```

設定此政策並安裝 [Session Manager 外掛程式](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)後，您就可以執行

```
aws ssm start-session --target [INSTANCE_ID_OF_EKS_NODE]
```

以存取節點。

**注意**  
您也可以考慮新增許可，以[啟用 Session Manager 記錄](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-create-iam-instance-profile.html#create-iam-instance-profile-ssn-logging)。

### 將工作者部署到私有子網路
<a name="_deploy_workers_onto_private_subnets"></a>

透過將工作者部署到私有子網路，您可以將他們暴露於經常引發攻擊的網際網路。從 2020 年 4 月 22 日開始，受管節點群組中節點的公有 IP 地址指派將由其部署所在的子網路控制。在此之前，受管節點群組中的節點會自動指派公有 IP。如果您選擇將工作者節點部署到公有子網路，請實作限制性 AWS 安全群組規則來限制其暴露。

### 執行 Amazon Inspector 來評估主機的暴露、漏洞和與最佳實務的偏差
<a name="_run_amazon_inspector_to_assess_hosts_for_exposure_vulnerabilities_and_deviations_from_best_practices"></a>

您可以使用 [Amazon Inspector](https://docs.aws.amazon.com/inspector/latest/user/what-is-inspector.html) 來檢查節點的意外網路存取，以及基礎 Amazon EC2 執行個體上的漏洞。

只有在安裝並啟用 Amazon EC2 Systems Manager (SSM) 代理程式時，Amazon Inspector 才能為您的 Amazon EC2 執行個體提供常見的漏洞和暴露 (CVE) 資料。 Amazon EC2 Systems Manager 此代理程式預先安裝在數個 [Amazon Machine Image AMIs)](https://docs.aws.amazon.com/systems-manager/latest/userguide/ami-preinstalled-agent.html) 上，包括 [EKS 最佳化的 Amazon Linux AMIs](https://docs.aws.amazon.com/eks/latest/userguide/eks-optimized-ami.html)。無論 SSM 代理程式狀態為何，都會掃描所有 Amazon EC2 執行個體是否有網路連線能力問題。如需設定 Amazon EC2 掃描的詳細資訊，請參閱[掃描 Amazon EC2 執行個體](https://docs.aws.amazon.com/inspector/latest/user/enable-disable-scanning-ec2.html)。

**重要**  
Inspector 無法在用來執行 Fargate Pod 的基礎設施上執行。

## 替代方案
<a name="_alternatives"></a>

### 執行 SELinux
<a name="iam-se-linux"></a>

**注意**  
適用於 Red Hat Enterprise Linux (RHEL)、CentOS、 Bottlerocket 和 Amazon Linux 2023

SELinux 提供額外的安全層，讓容器彼此和主機保持隔離。SELinux 可讓管理員針對每個使用者、應用程式、程序和檔案強制執行強制性存取控制 (MAC)。將其視為根據一組標籤，將可執行的操作限制為特定資源的後端。在 EKS 上，SELinux 可用來防止容器存取彼此的資源。

Container SELinux 政策在 [container-selinux](https://github.com/containers/container-selinux) 套件中定義。Docker CE 需要此套件 （以及其相依性），讓 Docker （或其他容器執行時間） 建立的程序和檔案在有限的系統存取下執行。容器利用 `container_t`標籤，這是 的別名`svirt_lxc_net_t`。這些政策可有效防止容器存取主機的某些功能。

當您為 Docker 設定 SELinux 時，Docker 會自動`container_t`將工作負載標記為 類型，並為每個容器提供唯一的 MCS 層級。這會將容器彼此隔離。如果您需要更寬鬆的限制，您可以在 SElinux 中建立自己的設定檔，將容器許可授予檔案系統的特定區域。這類似於 中的 PSPs，您可以為不同的容器/Pod 建立不同的設定檔。例如，您可以為具有一組限制性控制項的一般工作負載建立設定檔，並為需要特殊權限存取的物件建立設定檔。

SELinux for Containers 有一組選項，可設定為修改預設限制。您可以根據您的需求啟用或停用下列 SELinux 布林值：


| Boolean | 預設 | Description | 
| --- | --- | --- | 
|  `container_connect_any`  |  `off`  | 允許容器存取主機上的特權連接埠。例如，如果您的容器需要將連接埠映射到主機上的 443 或 80。 | 
|  `container_manage_cgroup`  |  `off`  | 允許容器管理 cgroup 組態。例如，執行 systemd 的容器將需要啟用此功能。 | 
|  `container_use_cephfs`  |  `off`  | 允許容器使用 ceph 檔案系統。 | 

根據預設，允許容器在 下讀取/執行，`/usr`並從 讀取大部分內容`/etc`。`/var/lib/docker` 和 下的檔案`/var/lib/containers`具有標籤 `container_var_lib_t`。若要檢視完整的預設清單，標籤會看到 [container.fc](https://github.com/containers/container-selinux/blob/master/container.fc) 檔案。

```
docker container run -it \
  -v /var/lib/docker/image/overlay2/repositories.json:/host/repositories.json \
  centos:7 cat /host/repositories.json
# cat: /host/repositories.json: Permission denied

docker container run -it \
  -v /etc/passwd:/host/etc/passwd \
  centos:7 cat /host/etc/passwd
# cat: /host/etc/passwd: Permission denied
```

標示`container_file_t`為 的檔案是容器可寫入的唯一檔案。如果您希望磁碟區掛載可寫入，則需要`:Z`在結尾指定 `:z`或 。
+  `:z` 會重新標記檔案，讓容器可以讀取/寫入
+  `:Z` 會重新標記檔案，以便**只有**容器可以讀取/寫入

```
ls -Z /var/lib/misc
# -rw-r--r--. root root system_u:object_r:var_lib_t:s0   postfix.aliasesdb-stamp

docker container run -it \
  -v /var/lib/misc:/host/var/lib/misc:z \
  centos:7 echo "Relabeled!"

ls -Z /var/lib/misc
#-rw-r--r--. root root system_u:object_r:container_file_t:s0 postfix.aliasesdb-stamp
```

```
docker container run -it \
  -v /var/log:/host/var/log:Z \
  fluentbit:latest
```

在 Kubernetes 中，重新標記略有不同。您可以指定自訂 MCS 標籤來執行 Pod，而不是讓 Docker 自動重新標記檔案。支援重新標記的磁碟區會自動重新標記，以便存取。具有相符 MCS 標籤的 Pod 將能夠存取磁碟區。如果您需要嚴格的隔離，請為每個 Pod 設定不同的 MCS 標籤。

```
securityContext:
  seLinuxOptions:
    # Provide a unique MCS label per container
    # You can specify user, role, and type also
    # enforcement based on type and level (svert)
    level: s0:c144:c154
```

在此範例中， `s0:c144:c154`對應至指派給允許容器存取之檔案的 MCS 標籤。

在 EKS 上，您可以建立允許執行特權容器的政策，例如 FluentD，並建立 SELinux 政策，以允許它從主機上的 /var/log 讀取，而不需要重新標記主機目錄。具有相同標籤的 Pod 將能夠存取相同的主機磁碟區。

我們已針對已在 CentOS 7 和 RHEL 7 上設定 SELinux [的 Amazon EKS 實作範例 AMIs](https://github.com/aws-samples/amazon-eks-custom-amis)。這些 AMIs的開發目的是示範符合高度管制客戶要求的範例實作。

**警告**  
SELinux 會忽略類型未受限的容器。

## 工具和資源
<a name="_tools_and_resources"></a>
+  [SELinux Kubernetes RBAC 和內部部署應用程式的運送安全政策](https://platform9.com/blog/selinux-kubernetes-rbac-and-shipping-security-policies-for-on-prem-applications/) 
+  [Kubernetes 的反覆強化](https://jayunit100.blogspot.com/2019/07/iterative-hardening-of-kubernetes-and.html) 
+  [Audit2Allow](https://linux.die.net/man/1/audit2allow) 
+  [SEAlert](https://linux.die.net/man/8/sealert) 
+  [使用 Udica 為容器產生 SELinux 政策](https://www.redhat.com/en/blog/generate-selinux-policies-containers-with-udica)說明一種工具，可查看 Linux 功能、連接埠和掛載點的容器規格檔案，並產生一組 SELinux 規則，以允許容器正常執行
+  [AMI 強化](https://github.com/aws-samples/amazon-eks-custom-amis#hardening)手冊，用於強化作業系統以符合不同的法規要求
+  [Keiko Upgrade Manager](https://github.com/keikoproj/upgrade-manager) 是來自 Intuit 的開放原始碼專案，可協調工作者節點的輪換。
+  [Sysdig 安全](https://sysdig.com/products/kubernetes-security/) 
+  [eksctl](https://eksctl.io/) 