

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

# 網路安全
<a name="network-security"></a>

**提示**  
 透過 Amazon EKS 研討會[探索](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)最佳實務。

網路安全有幾個面向。第一種是套用會限制服務之間網路流量的規則。第二個涉及傳輸中流量的加密。在 EKS 上實作這些安全措施的機制不盡相同，但通常包括下列項目：

## 流量控制
<a name="_traffic_control"></a>
+ 網路政策
+ 安全群組

## 網路加密
<a name="_network_encryption"></a>
+ Service Mesh
+ 容器網路界面 (CNIs)
+ 輸入控制器和負載平衡器
+ Nitro 執行個體
+ 使用 cert-manager 的 ACM Private CA

## 網路政策
<a name="iam-network-policy"></a>

在 Kubernetes 叢集中，預設允許所有 Pod 對 Pod 通訊。雖然這種靈活性可能有助於促進實驗，但它不被視為安全。Kubernetes 網路政策為您提供一種機制，以限制 Pod 之間的網路流量 （通常稱為東部/西部流量），以及 Pod 與外部服務之間的網路流量。Kubernetes 網路政策會在 OSI 模型的第 3 層和第 4 層運作。網路政策使用 Pod、命名空間選擇器和標籤來識別來源和目的地 Pod，但也可以包含 IP 地址、連接埠號碼、通訊協定或這些項目的組合。網路政策可套用至 Pod 的傳入或傳出連線，通常稱為傳入和傳出規則。

透過 Amazon VPC CNI 外掛程式的原生網路政策支援，您可以實作網路政策來保護 kubernetes 叢集中的網路流量。這與上游 Kubernetes 網路政策 API 整合，以確保相容性和遵守 Kubernetes 標準。您可以使用上游 API 支援的不同[識別符](https://kubernetes.io/docs/concepts/services-networking/network-policies/)來定義政策。根據預設，允許所有傳入和傳出流量到 Pod。指定具有 policyType Ingress 的網路政策時，只有來自 Pod 節點的允許連線，以及輸入規則允許的連線。輸出規則也適用。如果定義了多個規則，則在做出決策時會將所有規則的聯集納入考量。因此，評估順序不會影響政策結果。

**重要**  
當您第一次佈建 EKS 叢集時，預設不會啟用 VPC CNI 網路政策功能。請確定您已部署支援的 VPC CNI 附加元件版本，並在 vpc-cni 附加元件`true`上將`ENABLE_NETWORK_POLICY`旗標設定為 以啟用此功能。如需詳細說明，請參閱 [Amazon EKS 使用者指南](https://docs.aws.amazon.com/eks/latest/userguide/managing-vpc-cni.html)。

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

### 網路政策入門 - 遵循最低權限原則
<a name="_getting_started_with_network_policies_follow_principle_of_least_privilege"></a>

#### 建立預設拒絕政策
<a name="_create_a_default_deny_policy"></a>

如同 RBAC 政策，建議使用網路政策遵循最低權限存取原則。首先建立拒絕所有限制命名空間中所有傳入和傳出流量的政策。

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
```

 **預設拒絕** 

![\[預設拒絕\]](http://docs.aws.amazon.com/zh_tw/eks/latest/best-practices/images/security/default-deny.jpg)


**注意**  
上圖是由網路政策檢視器從 [Tufin](https://orca.tufin.io/netpol/) 建立。

#### 建立規則以允許 DNS 查詢
<a name="_create_a_rule_to_allow_dns_queries"></a>

設定預設拒絕所有規則後，您就可以開始分層其他規則，例如允許 Pod 查詢 CoreDNS 以進行名稱解析的規則。

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-access
  namespace: default
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: kube-system
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
```

 **allow-dns-access** 

![\[allow-dns-access\]](http://docs.aws.amazon.com/zh_tw/eks/latest/best-practices/images/security/allow-dns-access.jpg)


#### 遞增新增規則，以選擇性地允許命名空間/Pod 之間的流量
<a name="_incrementally_add_rules_to_selectively_allow_the_flow_of_traffic_between_namespacespods"></a>

了解應用程式需求，並視需要建立精細的輸入和輸出規則。以下範例示範如何將連接埠 80 上的輸入流量`app-one`從 限制為 `client-one`。這有助於將攻擊面降至最低，並降低未經授權的存取風險。

```
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-app-one
  namespace: default
spec:
  podSelector:
    matchLabels:
      k8s-app: app-one
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          k8s-app: client-one
    ports:
    - protocol: TCP
      port: 80
```

 **allow-ingress-app-one** 

![\[allow-ingress-app-one\]](http://docs.aws.amazon.com/zh_tw/eks/latest/best-practices/images/security/allow-ingress-app-one.png)


### 監控網路政策強制執行
<a name="_monitoring_network_policy_enforcement"></a>
+  **使用網路政策編輯器** 
  +  [網路政策編輯器](https://networkpolicy.io/)可協助視覺化、安全分數、從網路流量日誌自動產生
  + 以互動方式建置網路政策
+  **稽核日誌** 
  + 定期檢閱 EKS 叢集的稽核日誌
  + 稽核日誌提供有關叢集上執行哪些動作的豐富資訊，包括網路政策的變更
  + 使用此資訊來追蹤網路政策隨著時間的變更，並偵測任何未經授權或非預期的變更
+  **自動化測試** 
  + 建立模擬生產環境的測試環境，並定期部署嘗試違反網路政策的工作負載，以實作自動化測試。
+  **監控指標** 
  + 設定可觀測性代理程式，從 VPC CNI 節點代理程式抓取 prometheus 指標，允許 監控代理程式運作狀態和 sdk 錯誤。
+  **定期稽核網路政策** 
  + 定期稽核您的網路政策，以確保它們符合您目前的應用程式需求。隨著應用程式的演進，稽核讓您有機會移除備援輸入、輸出規則，並確保您的應用程式沒有過多的許可。
+  **使用開放政策代理程式 (OPA) 確保網路政策存在** 
  + 使用如下所示的 OPA 政策，以確保網路政策在加入應用程式 Pod 之前始終存在。`k8s-app: sample-app` 如果對應的網路政策不存在，此政策會拒絕使用標籤加入 k8s Pod。

```
package kubernetes.admission
import data.kubernetes.networkpolicies

deny[msg] {
    input.request.kind.kind == "Pod"
    pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels}
    contains_label(pod_label_value, "sample-app")
    np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels}
    not contains_label(np_label_value, "sample-app")
    msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name])
}
contains_label(arr, val) {
    arr[_] == val
}
```

### 疑難排解
<a name="_troubleshooting"></a>

#### 監控 vpc-network-policy-controller、 node-agent 日誌
<a name="_monitor_the_vpc_network_policy_controller_node_agent_logs"></a>

啟用 EKS 控制平面控制器管理員日誌來診斷網路政策功能。您可以將控制平面日誌串流至 CloudWatch 日誌群組，並使用 [CloudWatch Log Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html) 來執行進階查詢。從日誌中，您可以檢視哪些 Pod 端點物件解析為網路政策、政策的調校狀態，以及政策是否如預期般運作時的偵錯。

此外，Amazon VPC CNI 可讓您從 EKS 工作者節點啟用政策強制執行日誌的收集和匯出至 [Amazon Cloudwatch](https://aws.amazon.com/cloudwatch/)。啟用後，您可以利用 [CloudWatch Container Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/ContainerInsights.html) 提供與網路政策相關的用量洞察。

Amazon VPC CNI 也提供 SDK，提供與節點上 eBPF 程式互動的界面。將 部署到節點時`aws-node`，會安裝 SDK。您可以在節點的 `/opt/cni/bin`目錄下找到安裝的 SDK 二進位檔。在啟動時，軟體開發套件支援基本功能，例如檢查 eBPF 程式和映射。

```
sudo /opt/cni/bin/aws-eks-na-cli ebpf progs
```

#### 日誌網路流量中繼資料
<a name="_log_network_traffic_metadata"></a>

 [AWS VPC Flow Logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html) 會擷取流經 VPC 之流量的中繼資料，例如來源和目的地 IP 地址、連接埠，以及接受/捨棄的封包。此資訊可以進行分析，以尋找 VPC 內資源之間的可疑或異常活動，包括 Pod。不過，由於 Pod 的 IP 地址在取代時經常變更，因此流程日誌本身可能不夠。Calico Enterprise 使用 Pod 標籤和其他中繼資料擴展流程日誌，讓您更輕鬆地解密 Pod 之間的流量流程。

## Security groups (安全群組)
<a name="_security_groups"></a>

EKS 使用 [AWS VPC 安全群組](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html) (SGs) 來控制 Kubernetes 控制平面與叢集工作者節點之間的流量。安全群組也用於控制工作者節點與其他 VPC 資源之間的流量，以及外部 IP 地址。當您佈建 EKS 叢集 （使用 Kubernetes 1.14-eks.3 版或更新版本） 時，系統會自動為您建立叢集安全群組。此安全群組允許 EKS 控制平面與受管節點群組的節點之間進行不中斷的通訊。為了簡化，建議您將叢集 SG 新增至所有節點群組，包括未受管節點群組。

在 Kubernetes 版本 1.14 和 EKS 版本 eks.3 之前，已針對 EKS 控制平面和節點群組設定個別的安全群組。您可以在 https：//https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html 找到控制平面和節點群組安全群組的最低和建議規則。*控制平面安全群組*的最低規則允許連接埠 443 從工作者節點 SG 傳入。此規則允許 kubelet 與 Kubernetes API 伺服器通訊。它還包括傳出流量到工作者節點 SG 的連接埠 10250；10250 是 kubelet 接聽的連接埠。同樣地，最小*節點群組*規則允許連接埠 10250 從控制平面 SG 傳入，以及 443 傳出至控制平面 SG。最後，有一個規則允許節點群組內的節點之間進行不中斷的通訊。

如果您需要控制叢集內執行的服務與叢集外執行的服務之間的通訊，例如 RDS 資料庫，請考慮 [Pod 的安全群組](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html)。透過 Pod 的安全群組，您可以將**現有的**安全群組指派給 Pod 集合。

**警告**  
如果您參考在建立 Pod 之前不存在的安全群組，則不會排程 Pod。

您可以透過建立`SecurityGroupPolicy`物件並指定 `PodSelector`或 來控制指派給安全群組的 Pod`ServiceAccountSelector`。將選取器設定為 `{}`會將 中參考SGs 指派給命名空間中的所有 `SecurityGroupPolicy` Pod 或命名空間中的所有服務帳戶。在實作 Pod 的安全群組之前，請確定您已熟悉所有[考量](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations)事項。

**重要**  
如果您將 SGs用於 Pod，**則必須**建立允許連接埠 53 傳出至叢集安全群組的 SGs。同樣地，**您必須**更新叢集安全群組，以接受來自 Pod 安全群組的連接埠 53 傳入流量。

**重要**  
對 Pod [使用安全群組時，安全群組的限制](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)仍然適用，因此請謹慎使用。

**重要**  
**您必須**為針對 Pod 設定的所有探查，從叢集安全群組 (kubelet) 建立傳入流量的規則。

**重要**  
Pod 的安全群組依賴於稱為 [ENI 中繼](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html)的功能，該功能已建立以增加 EC2 執行個體的 ENI 密度。當 Pod 指派給 SG 時，VPC 控制器會將來自節點群組的分支 ENI 與 Pod 建立關聯。如果在排程 Pod 時節點群組中沒有足夠的分支 ENIs，則 Pod 將保持待定狀態。執行個體可支援的分支 ENIs 數量會因執行個體類型/系列而異。如需更多詳細資訊，請參閱 https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html\$1supported-instance-types：//。

雖然 Pod 的安全群組提供 AWS 原生的方式來控制叢集內外的網路流量，而不會產生政策協助程式的額外負荷，但還有其他選項可用。例如，Cilium 政策引擎可讓您在網路政策中參考 DNS 名稱。Calico Enterprise 包含將網路政策映射至 AWS 安全群組的選項。如果您已實作類似 Istio 的服務網格，您可以使用輸出閘道，將網路輸出限制為特定、完全合格的網域或 IP 地址。如需此選項的詳細資訊，請閱讀 [Istio 中輸出流量控制的](https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/)三個部分系列。

## 何時使用網路政策與 Pod 的安全群組？
<a name="_when_to_use_network_policy_vs_security_group_for_pods"></a>

### 何時使用 Kubernetes 網路政策
<a name="_when_to_use_kubernetes_network_policy"></a>
+  **控制 pod-to-pod流量** 
  + 適用於控制叢集內 Pod 之間的網路流量 （東西流量）
+  **在 IP 地址或連接埠層級控制流量 (OSI layer 3 或 4)** 

### 何時針對 Pod 使用 AWS 安全群組 (SGP)
<a name="_when_to_use_aws_security_groups_for_pods_sgp"></a>
+  **利用現有的 AWS 組態** 
  + 如果您已經有一組複雜的 EC2 安全群組來管理對 AWS 服務的存取，而且您正在將應用程式從 EC2 執行個體遷移到 EKS，則 SGPs 可能是很好的選擇，可讓您重複使用安全群組資源並將其套用至您的 Pod。
+  **控制對 AWS 服務的存取** 
  + 您在 EKS 叢集內執行的應用程式想要與其他 AWS 服務 (RDS 資料庫） 通訊，使用 SGPs做為有效的機制來控制從 Pod 到 AWS 服務的流量。
+  **Pod 和節點流量的隔離** 
  + 如果您想要將 Pod 流量與其他節點流量完全分開，請在 `POD_SECURITY_GROUP_ENFORCING_MODE=strict` 模式中使用 SGP。

### 使用 Pod 安全群組和網路政策的最佳實務
<a name="_best_practices_using_security_groups_for_pods_and_network_policy"></a>
+  **分層安全性** 
  + 針對分層安全方法，使用 SGP 和 kubernetes 網路政策的組合
  + 使用 SGPs 限制網路層級存取不屬於叢集的 AWS 服務，而 kubernetes 網路政策可以限制叢集內 Pod 之間的網路流量
+  **最低權限原則** 
  + 僅允許 Pod 或命名空間之間的必要流量
+  **分割您的應用程式** 
  + 盡可能依網路政策分割應用程式，以便在應用程式遭到入侵時減少爆量半徑
+  **保持政策簡單明瞭** 
  + Kubernetes 網路政策可以相當精細且複雜，最好盡可能保持簡單，以降低組態錯誤的風險並減輕管理開銷
+  **減少攻擊面** 
  + 透過限制應用程式的暴露，將攻擊面降至最低

**重要**  
Pod 的安全群組提供兩種強制執行模式： `strict`和 `standard`。在 EKS 叢集中使用網路政策和 Pod 功能的安全群組時，您必須使用 `standard` 模式。

在網路安全方面，分層方法通常是最有效的解決方案。搭配使用 kubernetes 網路政策和 SGP 可為在 EKS 中執行的應用程式提供強大的defense-in-depth策略。

## Service Mesh 政策強制執行或 Kubernetes 網路政策
<a name="_service_mesh_policy_enforcement_or_kubernetes_network_policy"></a>

`service mesh` 是您可以新增至應用程式的專用基礎設施層。它可讓您透明地新增可觀測性、流量管理和安全性等功能，而無需將其新增至您自己的程式碼。

服務網格會在 OSI 模型的第 7 層 （應用程式） 強制執行政策，而 kubernetes 網路政策會在第 3 層 （網路） 和第 4 層 （傳輸） 操作。這個空間有許多方案，例如 AWS AppMesh、Istio、Linkerd 等。

### 何時使用服務網格執行政策
<a name="_when_to_use_service_mesh_for_policy_enforcement"></a>
+ 現有投資服務網格
+ 需要更進階的功能，例如流量管理、可觀測性和安全性
  + 流量控制、負載平衡、電路中斷、速率限制、逾時等。
  + 服務執行方式的詳細洞見 （延遲、錯誤率、每秒請求數、請求量等）
  + 您想要針對 mTLS 等安全功能實作和利用服務網格

### 針對更簡單的使用案例選擇 Kubernetes 網路政策
<a name="_choose_kubernetes_network_policy_for_simpler_use_cases"></a>
+ 限制哪些 Pod 可以互相通訊
+ 網路政策所需的資源少於服務網格，因此非常適合較簡單的使用案例，或是執行和管理服務網格的額外負荷可能不合理的小型叢集

**注意**  
網路政策和服務網格也可以一起使用。使用網路政策在 Pod 之間提供基準層級的安全性和隔離，然後使用服務網格來新增其他功能，例如流量管理、可觀測性和安全性。

## ThirdParty網路政策引擎
<a name="_thirdparty_network_policy_engines"></a>

當您有進階政策需求，例如全球網路政策、支援以 DNS 主機名稱為基礎的規則、第 7 層規則、以 ServiceAccount 為基礎的規則，以及明確拒絕/記錄動作等時，請考慮第三方網路政策引擎。[Calico](https://docs.projectcalico.org/introduction/) 是來自 [Tigera](https://tigera.io) 的開放原始碼政策引擎，可與 EKS 搭配使用。除了實作完整的 Kubernetes 網路政策功能，Calico 還支援具有更豐富功能的網路政策，包括支援第 7 層規則，例如 HTTP，當 與 Istio 整合時。Calico 政策的範圍可以是命名空間、Pod、服務帳戶或全域。當政策範圍限定於服務帳戶時，它會將一組輸入/輸出規則與該服務帳戶建立關聯。透過適當的 RBAC 規則，您可以防止團隊覆寫這些規則，讓 IT 安全專業人員安全地委派命名空間的管理。[Cilium](https://cilium.readthedocs.io/en/stable/intro/) 的維護者 Isovalent 也已擴展網路政策，以包含對第 7 層規則的部分支援，例如 HTTP。Cilium 也支援 DNS 主機名稱，可用於限制 Kubernetes Services/Pod 與 VPC 內外執行的資源之間的流量。相反地，Calico Enterprise 包含的功能可讓您將 Kubernetes 網路政策映射至 AWS 安全群組，以及 DNS 主機名稱。

您可以在 https://github.com/ahmetb/kubernetes-network-policy-recipes：// 找到常見的 Kubernetes 網路政策清單。如需 Calico 的類似規則集，請參閱 https：//https://docs.projectcalico.org/security/calico-network-policy。

### 遷移至 Amazon VPC CNI 網路政策引擎
<a name="_migration_to_amazon_vpc_cni_network_policy_engine"></a>

為了保持一致性並避免意外的 Pod 通訊行為，建議您在叢集中僅部署一個網路政策引擎。如果您想要從 3P 遷移至 VPC CNI 網路政策引擎，建議您先將現有的 3P NetworkPolicy CRDs 轉換為 Kubernetes NetworkPolicy 資源，再啟用 VPC CNI 網路政策支援。此外，在生產環境中套用遷移的政策之前，請在個別的測試叢集中進行測試。這可讓您識別和解決 Pod 通訊行為中的任何潛在問題或不一致。

#### 遷移工具
<a name="_migration_tool"></a>

為了協助您進行遷移程序，我們開發了一個名為 [K8s Network Policy Migrator](https://github.com/awslabs/k8s-network-policy-migrator) 的工具，可將您現有的 Calico/Cilium 網路政策 CRDs 轉換為 Kubernetes 原生網路政策。轉換後，您可以在執行 VPC CNI 網路政策控制器的新叢集上直接測試轉換的網路政策。此工具旨在協助您簡化遷移程序，並確保順利轉換。

**重要**  
遷移工具只會轉換與原生 kubernetes 網路政策 api 相容的 3P 政策。如果您使用 3P 外掛程式提供的進階網路政策功能，遷移工具會略過並報告它們。

請注意，AWS VPC CNI 網路政策工程團隊目前不支援遷移工具，該工具會盡力提供給客戶。我們建議您利用此工具來促進遷移程序。如果您在使用工具時遇到任何問題或錯誤，請建立 [GitHub 問題](https://github.com/awslabs/k8s-network-policy-migrator/issues)。您的意見回饋對我們來說非常寶貴，有助於持續改善我們的服務。

### 其他資源
<a name="_additional_resources"></a>
+  [Kubernetes & Tigera：網路政策、安全性和稽核](https://youtu.be/lEY2WnRHYpg) 
+  [Calico Enterprise](https://www.tigera.io/tigera-products/calico-enterprise/) 
+  [Cilium](https://cilium.readthedocs.io/en/stable/intro/) 
+  [NetworkPolicy 編輯器](https://cilium.io/blog/2021/02/10/network-policy-editor) Cilium 的互動式政策編輯器
+  [Inspektor Gadget 建議網路政策小工具](https://www.inspektor-gadget.io/docs/latest/gadgets/advise/network-policy/) 根據網路流量分析建議網路政策

## 傳輸中加密
<a name="_encryption_in_transit"></a>

需要符合 PCI、HIPAA 或其他法規的應用程式，可能需要在資料傳輸時加密資料。現在 TLS 是加密線路上流量的事實選擇。TLS 如同前一代 SSL，使用密碼編譯通訊協定透過網路提供安全通訊。TLS 使用對稱加密，其中加密資料的金鑰是根據工作階段開始時交涉的共用秘密產生。以下是您可以在 Kubernetes 環境中加密資料的幾種方式。

### Nitro 執行個體
<a name="_nitro_instances"></a>

根據預設，下列 Nitro 執行個體類型之間交換的流量會自動加密，例如 C5n, G4, I3en, M5dn, M5n, P3dn, R5dn和 R5n。有傳輸閘道或負載平衡器等中繼躍點時，不會加密流量。如需[傳輸中](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/data-protection.html#encryption-transit)加密的更多詳細資訊，以及預設支援網路加密的執行個體類型完整清單，請參閱傳輸中加密。

### 容器網路界面 (CNIs)
<a name="_container_network_interfaces_cnis"></a>

 您可以將 [WeaveNet](https://www.weave.works/oss/net/) 設定為使用 NaCl 加密來自動加密所有流量，並使用 IPsec ESP 來加密快速資料路徑流量。

### Service Mesh
<a name="_service_mesh"></a>

傳輸中的加密也可以使用服務網格實作，例如 App Mesh、Linkerd v2 和 Istio。AppMesh 支援 [mTLS](https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html) 搭配 X.509 憑證或 Envoy 的 Secret Discovery Service (SDS)。Linkerd 和 Istio 都支援 mTLS。

[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) GitHub 儲存庫提供逐步解說，以使用 X.509 憑證設定 mTLS，並使用 SPIRE 做為 SDS 供應商搭配您的 Envoy 容器：
+  [使用 X.509 憑證設定 mTLS](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-file-based) 
+  [使用 SPIRE (SDS) 設定 TLS](https://github.com/aws/aws-app-mesh-examples/tree/main/walkthroughs/howto-k8s-mtls-sds-based) 

App Mesh 也支援使用 [AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html) (ACM) 發行的私有憑證或存放在虛擬節點本機檔案系統的憑證進行 [TLS 加密](https://docs.aws.amazon.com/app-mesh/latest/userguide/virtual-node-tls.html)。

[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) GitHub 儲存庫提供逐步解說，以使用 ACM 發行的憑證和 Envoy 容器隨附的憑證來設定 TLS：
+  [使用檔案提供的 TLS 憑證設定 TLS](https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/howto-tls-file-provided) 
+  [使用 AWS Certificate Manager 設定 TLS](https://github.com/aws/aws-app-mesh-examples/tree/master/walkthroughs/tls-with-acm) 

### 輸入控制器和負載平衡器
<a name="_ingress_controllers_and_load_balancers"></a>

輸入控制器可讓您以智慧方式將從叢集外部發出的 HTTP/S 流量路由至叢集內執行的服務。通常，這些傳入會由第 4 層負載平衡器前置，例如 Classic Load Balancer 或 Network Load Balancer (NLB)。加密的流量可以在網路中的不同位置終止，例如 負載平衡器、傳入資源或 Pod。終止 SSL 連線的方式和位置最終將由組織的網路安全政策決定。例如，如果您的政策需要end-to-end加密，您必須解密 Pod 的流量。這會對 Pod 造成額外的負擔，因為它必須花費週期來建立初始交握。整體 SSL/TLS 處理非常耗用 CPU。因此，如果您有彈性，請嘗試在輸入或負載平衡器執行 SSL 卸載。

#### 搭配 AWS Elastic Load Balancer 使用加密
<a name="_use_encryption_with_aws_elastic_load_balancers"></a>

[AWS Application Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/introduction.html) (ALB) 和 [Network Load Balancer](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/introduction.html) (NLB) 都支援傳輸加密 (SSL 和 TLS)。ALB 的`alb.ingress.kubernetes.io/certificate-arn`註釋可讓您指定要新增至 ALB 的憑證。如果您省略註釋，控制器會嘗試透過使用主機欄位比對可用的 [AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html) 憑證，將憑證新增至需要它的接聽程式。從 EKS 1.15 版開始，您可以搭配 NLB 使用`service.beta.kubernetes.io/aws-load-balancer-ssl-cert`註釋，如以下範例所示。

```
apiVersion: v1
kind: Service
metadata:
  name: demo-app
  namespace: default
  labels:
    app: demo-app
  annotations:
     service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
     service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<certificate ARN>"
     service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
     service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
spec:
  type: LoadBalancer
  ports:
  - port: 443
    targetPort: 80
    protocol: TCP
  selector:
    app: demo-app
//---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nginx
  namespace: default
  labels:
    app: demo-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo-app
  template:
    metadata:
      labels:
        app: demo-app
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 443
              protocol: TCP
            - containerPort: 80
              protocol: TCP
```

以下是 SSL/TLS 終止的其他範例。
+  [使用輪廓保護 EKS 傳入，讓我們加密 GitOps 方法](https://aws.amazon.com/blogs/containers/securing-eks-ingress-contour-lets-encrypt-gitops/) 
+  [如何使用 ACM 終止 Amazon EKS 工作負載上的 HTTPS 流量？](https://aws.amazon.com/premiumsupport/knowledge-center/terminate-https-traffic-eks-acm/) 

**重要**  
有些輸入，例如 AWS LB 控制器，使用註釋實作 SSL/TLS，而不是作為輸入規格的一部分。

### 使用 cert-manager 的 ACM Private CA
<a name="iam-cert-manager"></a>

您可以啟用 TLS 和 mTLS，使用 ACM Private Certificate Authority (CA) 和 [cert-manager](https://cert-manager.io/) 保護輸入、Pod 以及 Pod 之間的 EKS 應用程式工作負載，這是常用的 Kubernetes 附加元件，用於分發、續約和撤銷憑證。ACM Private CA 是一種高可用性、安全、受管的 CA，無需管理您自己的 CA 的預付和維護成本。如果您使用的是預設的 Kubernetes 憑證授權單位，則有機會透過 ACM Private CA 提高安全性並滿足合規要求。ACM Private CA 會保護 FIPS 140-2 第 3 級硬體安全模組中的私有金鑰 （非常安全），而預設的 CA 會將金鑰存放在記憶體中 （較不安全）。集中式 CA 也可讓您在 Kubernetes 環境內外，更進一步控制並改善私有憑證的可稽核性。

#### 工作負載之間相互 TLS 的短期 CA 模式
<a name="iam-ca-mode"></a>

在 EKS 中使用 ACM Private CA for mTLS 時，建議您使用具有短期 *CA 模式的短期即時*憑證。雖然可以在一般用途 CA 模式中發行短期憑證，但對於需要頻繁發行新憑證的使用案例，使用短期 CA 模式可提高成本效益 （比一般模式便宜約 75%)。此外，您應該嘗試將私有憑證的有效期間與 EKS 叢集中的 Pod 生命週期保持一致。[在此處進一步了解 ACM Private CA 及其優點](https://aws.amazon.com/certificate-manager/private-certificate-authority/)。

#### ACM 設定說明
<a name="_acm_setup_instructions"></a>

首先，遵循 [ACM Private CA 技術文件中提供的程序建立私有 CA](https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html)。一旦您擁有私有 CA，請使用[一般安裝指示來安裝](https://cert-manager.io/docs/installation/) cert-manager。安裝 cert-manager 之後，請依照 [ GitHub 中的設定說明](https://github.com/cert-manager/aws-privateca-issuer#setup)安裝 Private CA Kubernetes cert-manager 外掛程式。外掛程式可讓 cert-manager 從 ACM Private CA 請求私有憑證。

現在您已擁有私有 CA 和已安裝 cert-manager 和外掛程式的 EKS 叢集，是時候設定許可並建立發行者了。更新 EKS 節點角色的 IAM 許可，以允許存取 ACM Private CA。將 取代`<CA_ARN>`為私有 CA 的值：

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "awspcaissuer",
            "Action": [
                "acm-pca:DescribeCertificateAuthority",
                "acm-pca:GetCertificate",
                "acm-pca:IssueCertificate"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:acm-pca:us-west-2:123456789012:certificate-authority/12345678-1234-1234-1234-123456789012"
        }
    ]
}
```

 也可以使用 [IAM 帳戶或 IRSA 的服務角色](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)。如需完整範例，請參閱以下的其他資源一節。

在 Amazon EKS 中建立發行者，方法是使用下列文字建立名為 cluster-issuer.yaml 的自訂資源定義檔案，以私有 CA 取代 `<CA_ARN>`和 `<Region>`資訊。

```
apiVersion: awspca.cert-manager.io/v1beta1
kind: AWSPCAClusterIssuer
metadata:
          name: demo-test-root-ca
spec:
          arn: <CA_ARN>
          region: <Region>
```

部署您建立的發行者。

```
kubectl apply -f cluster-issuer.yaml
```

EKS 叢集已設定為向 Private CA 請求憑證。您現在可以使用 cert-manager `Certificate`的資源，透過將`issuerRef`欄位的值變更為您在上面建立的私有 CA 發行者來發行憑證。如需如何指定和請求憑證資源的詳細資訊，請參閱 cert-manager 的[憑證資源指南](https://cert-manager.io/docs/usage/certificate/)。[請參閱此處的範例](https://github.com/cert-manager/aws-privateca-issuer/tree/main/config/samples/)。

### 具有 Istio 和 cert-manager 的 ACM Private CA
<a name="_acm_private_ca_with_istio_and_cert_manager"></a>

如果您在 EKS 叢集中執行 Istio，您可以停用 Istio 控制平面 （特別是 `istiod`) 做為根憑證授權單位 (CA)，並將 ACM Private CA 設定為工作負載之間 mTLS 的根 CA。如果您要使用此方法，請考慮在 ACM Private CA 中使用*短期 CA 模式*。如需詳細資訊，請參閱[上一節](#iam-ca-mode)和此[部落格文章](https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode)。

#### 憑證簽署如何在 Istio 中運作 （預設）
<a name="_how_certificate_signing_works_in_istio_default"></a>

Kubernetes 中的工作負載是使用服務帳戶來識別。如果您未指定服務帳戶，Kubernetes 會自動為您的工作負載指派一個。此外，服務帳戶會自動掛載相關聯的字符。服務帳戶會使用此權杖，讓工作負載對 Kubernetes API 進行身分驗證。服務帳戶可能足以做為 Kubernetes 的身分，但 Istio 擁有自己的身分管理系統和 CA。當工作負載以其呼叫附屬代理啟動時，它需要從 Istio 指派的身分，以便將其視為值得信任，並允許與網格中的其他 服務通訊。

若要從 Istio 取得此身分， `istio-agent`會將稱為憑證簽署請求 （或 CSR) 的請求傳送至 Istio 控制平面。此 CSR 包含服務帳戶字符，以便在處理之前驗證工作負載的身分。此驗證程序由 處理`istiod`，同時做為註冊授權單位 （或 RA) 和 CA。RA 做為gatekeeper，確保只有經過驗證的 CSR 才能將其傳遞給 CA。驗證 CSR 後，該 CSR 會轉送至 CA，然後向服務帳戶發行包含 [SPIFFE](https://spiffe.io/) 身分的憑證。此憑證稱為 SPIFFE 驗證身分文件 （或 SVID)。SVID 會指派給請求的服務，以用於識別和加密通訊服務之間的傳輸中流量。

Istio 憑證簽署請求的預設流程：

![\[Istio 憑證簽署請求的預設流程\]](http://docs.aws.amazon.com/zh_tw/eks/latest/best-practices/images/security/default-istio-csr-flow.png)


#### 憑證簽署如何搭配 ACM Private CA 在 Istio 中運作
<a name="_how_certificate_signing_works_in_istio_with_acm_private_ca"></a>

您可以使用稱為 Istio Certificate Signing Request 代理程式 ([istio-csr](https://cert-manager.io/docs/projects/istio-csr/)) 的 cert-manager 附加元件，將 Istio 與 ACM Private CA 整合。此代理程式允許使用憑證管理員發行者保護 Istio 工作負載和控制平面元件，在此情況下為 ACM Private CA。*istio-csr* 代理程式會在驗證傳入 CSRs 的預設組態中公開 *istiod* 提供的相同服務。除了驗證之後，它會將請求轉換為 cert manager 支援的資源 （即與外部 CA 發行者 整合）。

每當有來自工作負載的 CSR 時，就會轉送至 *istio-csr*，其會向 ACM Private CA 請求憑證。AWS Private CA 發行者外掛程式會啟用 *istio-csr* 與 ACM Private CA 之間的通訊。 [https://github.com/cert-manager/aws-privateca-issuer](https://github.com/cert-manager/aws-privateca-issuer)Cert Manager 使用此外掛程式向 ACM Private CA 請求 TLS 憑證。發行者外掛程式將與 ACM Private CA 服務通訊，以請求工作負載的已簽署憑證。憑證簽署完成後，將傳回給 *istio-csr*，其將讀取已簽署的請求，並將其傳回給啟動 CSR 的工作負載。

**使用 istio-csr 的 Istio 憑證簽署請求流程**  
image：：istio-csr-with-acm-private-ca.png【使用 istio-csr 簽署 Istio 憑證請求的流量】

#### Istio 搭配私有 CA 設定指示
<a name="_istio_with_private_ca_setup_instructions"></a>

1. 從遵循[本節中的相同設定說明](#iam-cert-manager)開始，完成下列操作：

1. 建立私有 CA

1. 安裝 cert-manager

1. 安裝發行者外掛程式

1. 設定許可並建立發行者。發行者代表 CA，用於簽署`istiod`和網格工作負載憑證。它將與 ACM Private CA 通訊。

1. 建立 `istio-system` 命名空間。這是將部署 `istiod certificate`和其他 Istio 資源的位置。

1. 安裝使用 AWS Private CA 發行者外掛程式設定的 Istio CSR。您可以保留工作負載的憑證簽署請求，以確認它們獲得核准和簽署 (`preserveCertificateRequests=true`)。

   ```
   helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \
   --set "app.certmanager.issuer.group=awspca.cert-manager.io" \
   --set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \
   --set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \
   --set "app.certmanager.preserveCertificateRequests=true" \
   --set "app.server.maxCertificateDuration=48h" \
   --set "app.tls.certificateDuration=24h" \
   --set "app.tls.istiodCertificateDuration=24h" \
   --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \
   --set "volumeMounts[0].name=root-ca" \
   --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \
   --set "volumes[0].name=root-ca" \
   --set "volumes[0].secret.secretName=istio-root-ca"
   ```

1. 使用自訂組態安裝 Istio，`istiod`以 取代 `cert-manager istio-csr` 作為網格的憑證提供者。您可以使用 [Istio Operator](https://tetrate.io/blog/what-is-istio-operator/) 執行此程序。

   ```
   apiVersion: install.istio.io/v1alpha1
   kind: IstioOperator
   metadata:
     name: istio
     namespace: istio-system
   spec:
     profile: "demo"
     hub: gcr.io/istio-release
     values:
     global:
       # Change certificate provider to cert-manager istio agent for istio agent
       caAddress: cert-manager-istio-csr.cert-manager.svc:443
     components:
       pilot:
         k8s:
           env:
             # Disable istiod CA Sever functionality
           - name: ENABLE_CA_SERVER
             value: "false"
           overlays:
           - apiVersion: apps/v1
             kind: Deployment
             name: istiod
             patches:
   
               # Mount istiod serving and webhook certificate from Secret mount
             - path: spec.template.spec.containers.[name:discovery].args[7]
               value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt"
             - path: spec.template.spec.containers.[name:discovery].args[8]
               value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key"
             - path: spec.template.spec.containers.[name:discovery].args[9]
               value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem"
   
             - path: spec.template.spec.containers.[name:discovery].volumeMounts[6]
               value:
                 name: cert-manager
                 mountPath: "/etc/cert-manager/tls"
                 readOnly: true
             - path: spec.template.spec.containers.[name:discovery].volumeMounts[7]
               value:
                 name: ca-root-cert
                 mountPath: "/etc/cert-manager/ca"
                 readOnly: true
   
             - path: spec.template.spec.volumes[6]
               value:
                 name: cert-manager
                 secret:
                   secretName: istiod-tls
             - path: spec.template.spec.volumes[7]
               value:
                 name: ca-root-cert
                 configMap:
                   defaultMode: 420
                   name: istio-ca-root-cert
   ```

1. 部署您建立的上述自訂資源。

   ```
   istioctl operator init
   kubectl apply -f istio-custom-config.yaml
   ```

1. 現在，您可以將工作負載部署到 EKS 叢集中的網格，並[強制執行 mTLS](https://istio.io/latest/docs/reference/config/security/peer_authentication/)。

**Istio 憑證簽署請求**  
image：：istio-csr-requests.png【Istio 憑證簽署請求】

## 工具和資源
<a name="_tools_and_resources"></a>
+  [Amazon EKS 安全浸入研討會 - 網路安全](https://catalog.workshops.aws/eks-security-immersionday/en-US/6-network-security) 
+  [如何實作 cert-manager 和 ACM Private CA 外掛程式，以在 EKS 中啟用 TLS](https://aws.amazon.com/blogs/security/tls-enabled-kubernetes-clusters-with-acm-private-ca-and-amazon-eks-2/)。
+  [使用新的 AWS Load Balancer 控制器和 ACM Private CA 在 Amazon EKS 上設定end-to-end TLS 加密](https://aws.amazon.com/blogs/containers/setting-up-end-to-end-tls-encryption-on-amazon-eks-with-the-new-aws-load-balancer-controller/)。
+  [GitHub 上的 Private CA Kubernetes cert-manager 外掛程式](https://github.com/cert-manager/aws-privateca-issuer)。
+  [Private CA Kubernetes cert-manager 外掛程式使用者指南](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaKubernetes.html)。
+  [如何使用 AWS Private Certificate Authority 短期憑證模式](https://aws.amazon.com/blogs/security/how-to-use-aws-private-certificate-authority-short-lived-certificate-mode) 
+  [輸出運算子](https://github.com/monzo/egress-operator) 運算子和 DNS 外掛程式，無需通訊協定檢查即可控制來自叢集的輸出流量
+  [NeuVector by SUSE](https://www.suse.com/neuvector/) 開放原始碼、零信任容器安全平台提供政策網路規則、資料外洩防護 (DLP)、Web 應用程式防火牆 (WAF) 和網路威脅簽章。