

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

# 為在 Amazon EKS 上執行的應用程式設定交互 TLS 身分驗證
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks"></a>

*Mahendra Revanasiddappa，Amazon Web Services*

## 摘要
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-summary"></a>

憑證型交互傳輸層安全 (TLS) 是選用的 TLS 元件，可在伺服器和用戶端之間提供雙向對等身分驗證。透過交互 TLS，用戶端必須在工作階段交涉過程中提供 X.509 憑證。伺服器使用此憑證來識別和驗證用戶端。

相互 TLS 是物聯網 (IoT) 應用程式的常見需求，可用於business-to-business應用程式或標準，例如 [Open Banking](https://docs.aws.amazon.com/wellarchitected/latest/financial-services-industry-lens/open-banking.html)。

此模式說明如何使用 NGINX 輸入控制器，為在 Amazon Elastic Kubernetes Service (Amazon EKS) 叢集上執行的應用程式設定交互 TLS。您可以為 NGINX 輸入控制器啟用內建的交互 TLS 功能，方法是註釋輸入資源。如需 NGINX 控制器上交互 TLS 註釋的詳細資訊，請參閱 Kubernetes 文件中的[用戶端憑證驗證](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#client-certificate-authentication)。

**重要**  
此模式使用自我簽署憑證。我們建議您僅將此模式與測試叢集搭配使用，而不是在生產環境中。如果您想要在生產環境中使用此模式，您可以使用 [AWS Private Certificate Authority (AWS Private CA)](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html) 或現有的公有金鑰基礎設施 (PKI) 標準來發行私有憑證。

## 先決條件和限制
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-prereqs"></a>

**先決條件**
+ 作用中的 Amazon Web Services (AWS) 帳戶。
+ 現有 Amazon EKS 叢集。
+ 在 macOS、Linux 或 Windows 上安裝和設定 AWS Command Line Interface (AWS CLI) 1.7 版或更新版本。
+ 安裝並設定為存取 Amazon EKS 叢集的 kubectl 命令列公用程式。如需詳細資訊，請參閱 Amazon EKS 文件中的[安裝 kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html)。
+ 用來測試應用程式的現有網域名稱系統 (DNS) 名稱。

**限制**
+ 此模式使用自我簽署憑證。我們建議您僅將此模式與測試叢集搭配使用，而不是在生產環境中。

## Architecture
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-architecture"></a>

![\[為在 Amazon EKS 上執行的應用程式設定交互 TLS 身分驗證\]](http://docs.aws.amazon.com/zh_tw/prescriptive-guidance/latest/patterns/images/pattern-img/ae2761e3-7ed2-4c2a-ba54-a4ddce8a1e7e/images/cefc60f9-2f29-4052-b7ae-df4eb6395e1c.png)


**技術堆疊**
+ Amazon EKS
+ Amazon Route 53
+ kubectl

## 工具
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-tools"></a>
+ [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) 可協助您在 AWS 上執行 Kubernetes，而無需安裝或維護您自己的 Kubernetes 控制平面或節點。
+ [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) 是一種可用性高、可擴展性強的 DNS Web 服務。
+ [Kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html) 是您用來與 Amazon EKS 叢集互動的命令列公用程式。

## 史詩
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-epics"></a>

### 產生自我簽署憑證
<a name="generate-the-self-signed-certificates"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
|  產生 CA 金鑰和憑證。 | 執行下列命令來產生憑證授權單位 (CA) 金鑰和憑證。<pre>openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=Test Cert Authority'</pre> | DevOps 工程師 | 
| 產生伺服器金鑰和憑證，並使用 CA 憑證簽署。 | 產生伺服器金鑰和憑證，並執行下列命令以 CA 憑證簽署。<pre>openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN= <your_domain_name> ' && openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt</pre>請確定您使用現有的網域名稱`<your_domain_name>`取代 。 | DevOps 工程師 | 
|  產生用戶端金鑰和憑證，並使用 CA 憑證簽署。 | 產生用戶端金鑰和憑證，並執行下列命令以 CA 憑證簽署。<pre>openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Test' && openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt</pre> | DevOps 工程師 | 

### 部署 NGINX 輸入控制器
<a name="deploy-the-nginx-ingress-controller"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 在 Amazon EKS 叢集中部署 NGINX 輸入控制器。 | 使用下列命令部署 NGINX 輸入控制器。<pre>kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.0/deploy/static/provider/aws/deploy.yaml</pre> | DevOps 工程師 | 
|  確認 NGINX 輸入控制器服務正在執行。 | 使用以下命令，確認 NGINX 輸入控制器服務正在執行。<pre>kubectl get svc -n ingress-nginx</pre>請確定服務地址欄位包含 Network Load Balancer 的網域名稱。 | DevOps 工程師 | 

### 在 Amazon EKS 叢集中建立命名空間，以測試相互 TLS
<a name="create-a-namespace-in-the-amazon-eks-cluster-to-test-mutual-tls"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 在 Amazon EKS 叢集中建立命名空間。 | 執行下列命令，在您的 Amazon EKS 叢集`mtls`中建立名為 的命名空間。<pre>kubectl create ns mtls</pre>這會部署範例應用程式來測試交互 TLS。 | DevOps 工程師 | 

### 為範例應用程式建立部署和服務
<a name="create-the-deployment-and-service-for-the-sample-application"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 在 mtls 命名空間中建立 Kubernetes 部署和服務。 | 建立名為 `mtls.yaml` 的檔案。將以下程式碼貼到檔案。<pre>kind: Deployment<br />apiVersion: apps/v1<br />metadata:<br />  name: mtls-app<br />  labels:<br />    app: mtls<br />spec:<br />  replicas: 1<br />  selector:<br />    matchLabels:<br />      app: mtls<br />  template:<br />    metadata:<br />      labels:<br />        app: mtls<br />    spec:<br />      containers:<br />      - name: mtls-app<br />        image: hashicorp/http-echo<br />        args:<br />          - "-text=mTLS is working"<br /><br /><br />---<br /><br />kind: Service<br />apiVersion: v1<br />metadata:<br />  name: mtls-service<br />spec:<br />  selector:<br />    app: mtls<br />  ports:<br />    - port: 5678 # Default port for image</pre> 執行下列命令，在 `mtls` 命名空間中建立 Kubernetes 部署和服務。<pre>kubectl create -f mtls.yaml -n mtls</pre> | DevOps 工程師 | 
| 確認已建立 Kubernetes 部署。 | 執行下列命令，以確認已建立部署，且有一個處於可用狀態的 Pod。<pre>kubectl get deploy -n mtls</pre> | DevOps 工程師 | 
| 確認已建立 Kubernetes 服務。 | 執行下列命令，確認已建立 Kubernetes 服務。<pre>kubectl get service -n mtls</pre> | DevOps 工程師 | 

### 在 mtls 命名空間中建立秘密
<a name="create-a-secret-in-the-mtls-namespace"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立傳入資源的秘密。 | 執行 folllowing 命令，使用您先前建立的憑證，為 NGINX 輸入控制器建立秘密。<pre>kubectl create secret generic mtls-certs --from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt -n mtls </pre>您的秘密具有一個伺服器憑證供用戶端識別伺服器，以及一個 CA 憑證供伺服器驗證用戶端憑證。 | DevOps 工程師 | 

### 在 mtls 命名空間中建立輸入資源
<a name="create-the-ingress-resource-in-the-mtls-namespace"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 在 mtls 命名空間中建立輸入資源。 | 建立名為 `ingress.yaml` 的檔案。將下列程式碼貼入 檔案 (`<your_domain_name>`以您現有的網域名稱取代）。<pre>apiVersion: networking.k8s.io/v1<br />kind: Ingress<br />metadata:<br />  annotations:<br />    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"<br />    nginx.ingress.kubernetes.io/auth-tls-secret: mtls/mtls-certs<br />  name: mtls-ingress<br />spec:<br />  ingressClassName: nginx<br />  rules:<br />  - host: "*.<your_domain_name>"<br />    http:<br />      paths:<br />      - path: /<br />        pathType: Prefix<br />        backend:<br />          service:<br />            name: mtls-service<br />            port:<br />              number: 5678<br />  tls:<br />  - hosts:<br />    - "*.<your_domain_name>"<br />    secretName: mtls-certs</pre> 執行下列命令，在`mtls`命名空間中建立輸入資源。<pre>kubectl create -f ingress.yaml -n mtls</pre>這表示 NGINX 輸入控制器可以將流量路由到您的範例應用程式。 | DevOps 工程師 | 
| 確認已建立輸入資源。 | 執行下列命令，確認已建立輸入資源。<pre>kubectl get ing -n mtls</pre>請確定輸入資源的地址顯示為 NGINX 輸入控制器建立的負載平衡器。 | DevOps 工程師 | 

### 設定 DNS 將主機名稱指向負載平衡器
<a name="configure-dns-to-point-the-hostname-to-the-load-balancer"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立指向 NGINX 輸入控制器負載平衡器的 CNAME 記錄。 | 登入 AWS 管理主控台，開啟 Amazon Route 53 主控台，並建立正式名稱 (CNAME) 記錄，`mtls.<your_domain_name>`指向 NGINX 輸入控制器的負載平衡器。如需詳細資訊，請參閱 Route [ Route 53 文件中的使用 Route 53 主控台建立記錄](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html)。 Route 53  | DevOps 工程師 | 

### 測試應用程式。
<a name="test-the-application"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 在沒有憑證的情況下測試交互 TLS 設定。 | 執行下列命令。<pre>curl -k https://mtls.<your_domain_name> </pre>您應該會收到「400 未傳送必要的 SSL 憑證」錯誤回應。 | DevOps 工程師 | 
| 使用憑證測試交互 TLS 設定。 | 執行下列命令。<pre>curl -k https://mtls.<your_domain_name> --cert client.crt --key client.key</pre>您應該會收到「mTLS 正在運作」回應。 | DevOps 工程師 | 

## 相關資源
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-resources"></a>
+ [使用 Amazon Route 53 主控台建立記錄](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html)
+ [在 Amazon EKS 上使用 Network Load Balancer 搭配 NGINX 輸入控制器](https://aws.amazon.com/blogs/opensource/network-load-balancer-nginx-ingress-controller-eks/)
+ [用戶端憑證驗證](https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/)