

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# ネットワークセキュリティ
<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](https://aws-experience.com/emea/smb/events/series/get-hands-on-with-amazon-eks?trk=4a9b4147-2490-4c63-bc9f-f8a84b122c8c&sc_channel=el)ワークショップを通じてベストプラクティスをご覧ください。

ネットワークセキュリティにはいくつかのファセットがあります。1 つ目は、サービス間のネットワークトラフィックの流れを制限するルールの適用です。2 つ目は、転送中のトラフィックの暗号化です。EKS にこれらのセキュリティ対策を実装するメカニズムはさまざまですが、多くの場合、次の項目が含まれます。

## トラフィックコントロール
<a name="_traffic_control"></a>
+ ネットワークポリシー
+ セキュリティグループ

## ネットワーク暗号化
<a name="_network_encryption"></a>
+ サービスメッシュ
+ コンテナネットワークインターフェイス (CNIs)
+ Ingress Controllers と Load Balancer
+ Nitro インスタンス
+ cert-manager を使用した ACM プライベート CA

## ネットワークポリシー
<a name="iam-network-policy"></a>

Kubernetes クラスター内では、すべての Pod 間通信がデフォルトで許可されています。この柔軟性は実験の促進に役立ちますが、安全とは見なされません。Kubernetes ネットワークポリシーは、ポッド間 (多くの場合、東部/西部トラフィック) およびポッドと外部サービス間のネットワークトラフィックを制限するメカニズムを提供します。Kubernetes ネットワークポリシーは、OSI モデルのレイヤー 3 と 4 で動作します。ネットワークポリシーは、ポッド、名前空間セレクタ、ラベルを使用して送信元ポッドと送信先ポッドを識別しますが、IP アドレス、ポート番号、プロトコル、またはこれらの組み合わせを含めることもできます。ネットワークポリシーは、多くの場合、イングレスルールとエグレスルールと呼ばれるポッドへのインバウンド接続とアウトバウンド接続の両方に適用できます。

Amazon VPC CNI プラグインのネイティブネットワークポリシーのサポートにより、ネットワークポリシーを実装して、kubernetes クラスター内のネットワークトラフィックを保護できます。これにより、アップストリームの Kubernetes ネットワークポリシー API と統合され、Kubernetes 標準との互換性と準拠が保証されます。アップストリーム API でサポートされているさまざまな[識別子](https://kubernetes.io/docs/concepts/services-networking/network-policies/)を使用してポリシーを定義できます。デフォルトでは、すべてのイングレストラフィックとエグレストラフィックがポッドに許可されます。policyType Ingress を持つネットワークポリシーが指定されている場合、ポッドへの許可された接続のみがポッドのノードからの接続であり、イングレスルールで許可されている接続です。出力ルールにも同じことが当てはまります。複数のルールが定義されている場合、すべてのルールの結合が決定時に考慮されます。したがって、評価の順序はポリシーの結果には影響しません。

**重要**  
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
```

 **default-deny** 

![\[default-deny\]](http://docs.aws.amazon.com/ja_jp/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>

すべてのルールをデフォルトで拒否すると、ポッドが名前解決のために 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/ja_jp/eks/latest/best-practices/images/security/allow-dns-access.jpg)


#### 名前空間/ポッド間のトラフィックフローを選択的に許可するルールを段階的に追加する
<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/ja_jp/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 エラーをモニタリングできます。
+  **ネットワークポリシーを定期的に監査する** 
  + ネットワークポリシーを定期的に監査して、現在のアプリケーション要件を満たしていることを確認します。アプリケーションが進化するにつれて、監査により冗長な進入、退出ルールを削除し、アプリケーションに過剰なアクセス許可がないことを確認する機会が得られます。
+  **Open Policy Agent (OPA) を使用してネットワークポリシーが存在することを確認する** 
  + 以下に示すような OPA ポリシーを使用して、アプリケーションポッドをオンボーディングする前にネットワークポリシーが常に存在することを確認します。このポリシーは、対応するネットワークポリシーが存在しない`k8s-app: sample-app`場合、ラベル付きの k8s ポッドのオンボーディングを拒否します。

```
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) を使用して高度なクエリを実行できます。ログから、ネットワークポリシーに解決されるポッドエンドポイントオブジェクト、ポリシーの照合ステータスを表示し、ポリシーが期待どおりに動作している場合はデバッグできます。

さらに、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 には、ノード上の eBPF プログラムとやり取りするためのインターフェイスを提供する SDK も付属しています。SDK は、 `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 フローログ](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html)は、送信元と送信先の IP アドレスやポートなど、VPC を通過するトラフィックに関するメタデータを、承諾/ドロップされたパケットとともにキャプチャします。この情報は、ポッドを含む VPC 内のリソース間の疑わしいアクティビティや異常なアクティビティを探すために分析できます。ただし、ポッドの IP アドレスは置き換えられると頻繁に変更されるため、フローログだけでは不十分である可能性があります。Calico Enterprise は、ポッドラベルやその他のメタデータを使用してフローログを拡張するため、ポッド間のトラフィックフローを簡単に解読できます。

## セキュリティグループ
<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://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html にあります。*コントロールプレーンセキュリティグループの*最小ルールでは、ワーカーノード SG からのポート 443 のインバウンドを許可します。このルールは、kubelets が Kubernetes API サーバーと通信できるようにするものです。また、ワーカーノード SG へのアウトバウンドトラフィック用のポート 10250 も含まれています。10250 は kubelets がリッスンするポートです。同様に、最小*ノードグループ*ルールでは、コントロールプレーン SG からのインバウンドポート 10250 とコントロールプレーン SG へのアウトバウンドポート 443 が許可されます。最後に、ノードグループ内のノード間の無制限の通信を許可するルールがあります。

クラスター内で実行されるサービス間の通信を制御し、RDS データベースなどのクラスター外で実行されるサービスをサービスする必要がある場合は、[ポッドのセキュリティグループを検討してください](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html)。ポッドのセキュリティグループを使用すると、**既存の**セキュリティグループをポッドのコレクションに割り当てることができます。

**警告**  
ポッドの作成前に存在しないセキュリティグループを参照すると、ポッドはスケジュールされません。

`SecurityGroupPolicy` オブジェクトを作成し、 `PodSelector`または を指定することで、セキュリティグループに割り当てられるポッドを制御できます`ServiceAccountSelector`。セレクターを に設定する`{}`と、 で参照される SGs が`SecurityGroupPolicy`、名前空間内のすべてのポッドまたは名前空間内のすべてのサービスアカウントに割り当てられます。ポッドのセキュリティグループを実装する前に、すべての[考慮事項](https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#security-groups-pods-considerations)を理解しておく必要があります。

**重要**  
ポッドSGs を使用する場合は、クラスターセキュリティグループへのポート 53 アウトバウンドを許可する SGs を作成**する必要があります**。同様に、ポッドセキュリティグループからのポート 53 インバウンドトラフィックを受け入れるようにクラスターセキュリティグループを更新**する必要があります**。

**重要**  
[セキュリティグループの制限](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-security-groups)は、ポッドのセキュリティグループを使用する場合にも適用されるため、慎重に使用してください。

**重要**  
ポッド用に設定されたすべてのプローブについて、クラスターセキュリティグループ (kubelet) からのインバウンドトラフィックのルールを作成**する必要があります**。

**重要**  
ポッドのセキュリティグループは、EC2 インスタンスの [ENI 密度を高めるために作成された ENI トランキング](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/container-instance-eni.html)と呼ばれる機能に依存しています。ポッドが SG に割り当てられると、VPC コントローラーはノードグループからのブランチ ENI をポッドに関連付けます。ポッドがスケジュールされた時点でノードグループで使用できるブランチ ENIs が不足している場合、ポッドは保留状態のままになります。インスタンスがサポートできるブランチ ENIs の数は、インスタンスタイプ/ファミリーによって異なります。詳細については、https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html\$1supported-instance-types を参照してください。

ポッドのセキュリティグループでは、ポリシーデーモンのオーバーヘッドなしでクラスター内外のネットワークトラフィックを AWS ネイティブに制御できますが、他のオプションも使用できます。たとえば、Cilium ポリシーエンジンを使用すると、ネットワークポリシーで DNS 名を参照できます。Calico Enterprise には、ネットワークポリシーを AWS セキュリティグループにマッピングするためのオプションが含まれています。Istio などのサービスメッシュを実装している場合は、Egress Gateway を使用して、ネットワーク出力を特定の完全修飾ドメインまたは IP アドレスに制限できます。このオプションの詳細については、[Istio の出力トラフィック制御](https://istio.io/blog/2019/egress-traffic-control-in-istio-part-1/)に関する 3 つのパートシリーズを参照してください。

## 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トラフィックの制御** 
  + クラスター内のポッド間のネットワークトラフィックの制御に適しています (東西トラフィック)
+  **IP アドレスまたはポートレベルでトラフィックを制御する (OSI レイヤー 3 または 4)** 

### ポッドに AWS セキュリティグループを使用するタイミング (SGP)
<a name="_when_to_use_aws_security_groups_for_pods_sgp"></a>
+  **既存の AWS 設定を活用する** 
  + AWS サービスへのアクセスを管理する複雑な EC2 セキュリティグループのセットがすでにあり、EC2 インスタンスから EKS にアプリケーションを移行する場合、SGPs はセキュリティグループのリソースを再利用してポッドに適用するために非常に適しています。
+  **AWS サービスへのアクセスを制御する** 
  + EKS クラスター内で実行されているアプリケーションは、他の AWS サービス (RDS データベース) と通信し、ポッドから AWS SGPs を使用します。
+  **ポッドとノードのトラフィックの分離** 
  + ポッドトラフィックを残りのノードトラフィックから完全に分離する場合は、 `POD_SECURITY_GROUP_ENFORCING_MODE=strict`モードで SGP を使用します。

### ポッドとネットワークポリシーのセキュリティグループを使用するベストプラクティス
<a name="_best_practices_using_security_groups_for_pods_and_network_policy"></a>
+  **レイヤードセキュリティ** 
  + レイヤードセキュリティアプローチに SGP と kubernetes ネットワークポリシーの組み合わせを使用する
  + SGPs を使用してクラスターの一部ではない AWS のサービスへのネットワークレベルのアクセスを制限し、kubernetes ネットワークポリシーはクラスター内のポッド間のネットワークトラフィックを制限できます。
+  **最小権限の原則** 
  + ポッドまたは名前空間間の必要なトラフィックのみを許可する
+  **アプリケーションをセグメント化する** 
  + 可能な限り、アプリケーションをネットワークポリシーでセグメント化して、アプリケーションが侵害された場合の爆発半径を小さくします。
+  **ポリシーをシンプルかつ明確に保つ** 
  + Kubernetes ネットワークポリシーは、非常に詳細で複雑な場合があります。設定ミスのリスクを軽減し、管理オーバーヘッドを軽減するために、できるだけシンプルに保つのが最善です。
+  **アタックサーフェスを減らす** 
  + アプリケーションの露出を制限してアタックサーフェスを最小化する

**重要**  
ポッドのセキュリティグループには、 `strict`と の 2 つの強制モードがあります`standard`。EKS クラスターのポッド機能にネットワークポリシーとセキュリティグループの両方を使用する場合は、 `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>
+ サービスメッシュへの既存の投資
+ トラフィック管理、オブザーバビリティ、セキュリティなど、より高度な機能が必要
  + トラフィック制御、負荷分散、サーキットブレーク、レート制限、タイムアウトなど。
  + サービスのパフォーマンスに関する詳細なインサイト (レイテンシー、エラー率、1 秒あたりのリクエスト数、リクエストボリュームなど)
  + mTLS などのセキュリティ機能にサービスメッシュを実装して活用したい

### よりシンプルなユースケースで Kubernetes ネットワークポリシーを選択する
<a name="_choose_kubernetes_network_policy_for_simpler_use_cases"></a>
+ 相互に通信できるポッドを制限する
+ ネットワークポリシーは、サービスメッシュよりも必要なリソースが少ないため、単純なユースケースや、サービスメッシュの実行と管理のオーバーヘッドが正当化されない可能性がある小規模なクラスターに適しています。

**注記**  
ネットワークポリシーとサービスメッシュを一緒に使用することもできます。ネットワークポリシーを使用してポッド間のベースラインレベルのセキュリティと分離を提供し、サービスメッシュを使用してトラフィック管理、オブザーバビリティ、セキュリティなどの追加機能を追加します。

## ThirdPartyのネットワークポリシーエンジン
<a name="_thirdparty_network_policy_engines"></a>

グローバルネットワークポリシー、DNS ホスト名ベースのルール、レイヤー 7 ルール、ServiceAccount ベースのルール、明示的な拒否/ログアクションなどの高度なポリシー要件がある場合は、サードパーティーのネットワークポリシーエンジンを検討してください。[Calico](https://docs.projectcalico.org/introduction/) は、EKS と連携する [Tigera](https://tigera.io) のオープンソースポリシーエンジンです。Calico は、Kubernetes ネットワークポリシー機能のフルセットの実装に加えて、Istio と統合した場合の HTTP などのレイヤー 7 ルールのサポートなど、より豊富な機能を備えた拡張ネットワークポリシーをサポートしています。Calico ポリシーの範囲は、名前空間、ポッド、サービスアカウント、またはグローバルに設定できます。ポリシーがサービスアカウントにスコープされている場合、一連の入出力ルールがそのサービスアカウントに関連付けられます。適切な RBAC ルールを設定することで、チームがこれらのルールを上書きするのを防ぐことができ、IT セキュリティプロフェッショナルは名前空間の管理を安全に委任できます。同様に、[Cilium](https://cilium.readthedocs.io/en/stable/intro/) のメンテナーもネットワークポリシーを拡張して、 HTTP などのレイヤー 7 ルールの部分的なサポートを含めました。Cilium は DNS ホスト名もサポートしており、Kubernetes サービス/ポッドと VPC 内外で実行されるリソース間のトラフィックを制限するのに役立ちます。対照的に、Calico Enterprise には、Kubernetes ネットワークポリシーを AWS セキュリティグループと DNS ホスト名にマッピングできる機能が含まれています。

一般的な Kubernetes ネットワークポリシーのリストは、https://github.com/ahmetb/kubernetes-network-policy-recipes にあります。Calico の同様のルールのセットは、https://docs.projectcalico.org/security/calico-network-policy で入手できます。

### Amazon VPC CNI ネットワークポリシーエンジンへの移行
<a name="_migration_to_amazon_vpc_cni_network_policy_engine"></a>

一貫性を維持し、予期しないポッド通信動作を回避するには、クラスターに 1 つのネットワークポリシーエンジンのみをデプロイすることをお勧めします。3P から VPC CNI ネットワークポリシーエンジンに移行する場合は、VPC CNI ネットワークポリシーのサポートを有効にする前に、既存の 3P NetworkPolicy CRDs を Kubernetes NetworkPolicy リソースに変換することをお勧めします。また、移行されたポリシーを本番環境に適用する前に、別のテストクラスターでテストします。これにより、ポッド通信動作の潜在的な問題や不整合を特定して対処できます。

#### 移行ツール
<a name="_migration_tool"></a>

移行プロセスを支援するために、既存の Calico/Cilium [ネットワークポリシー CRD を Kubernetes ネイティブネットワークポリシーに変換する K8s Network Policy Migrator](https://github.com/awslabs/k8s-network-policy-migrator) と呼ばれるツールを開発しました。 CRDs 変換後、VPC CNI ネットワークポリシーコントローラーを実行している新しいクラスターで、変換されたネットワークポリシーを直接テストできます。このツールは、移行プロセスを合理化し、スムーズに移行できるように設計されています。

**重要**  
移行ツールは、ネイティブの kubernetes ネットワークポリシー API と互換性のある 3P ポリシーのみを変換します。3P プラグインが提供する高度なネットワークポリシー機能を使用している場合、移行ツールはそれらをスキップしてレポートします。

移行ツールは、現在 AWS VPC CNI Network ポリシーエンジニアリングチームではサポートされておらず、ベストエフォートベースでお客様に提供されることに注意してください。このツールを使用して移行プロセスを容易にすることをお勧めします。ツールで問題やバグが発生した場合は、[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 Editor](https://cilium.io/blog/2021/02/10/network-policy-editor) Cilium のインタラクティブポリシーエディタ
+  [Inspektor Gadget advise network-policy 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>

 C5n, G4, I3en, M5dn, M5n, P3dn, R5dnR5n など、次の Nitro インスタンスタイプ間で交換されるトラフィックは、デフォルトで自動的に暗号化されます。トランジットゲートウェイやロードバランサーなどの中間ホップがある場合、トラフィックは暗号化されません。[転送中の暗号化の詳細と、デフォルトでネットワーク暗号化をサポートするインスタンスタイプの完全なリストについては、](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 を使用できます。

### サービスメッシュ
<a name="_service_mesh"></a>

転送中の暗号化は、App Mesh、Linkerd v2、Istio などのサービスメッシュで実装することもできます。AppMesh は、X.509 証明書または Envoy の Secret Discovery Service (SDS) による [mTLS](https://docs.aws.amazon.com/app-mesh/latest/userguide/mutual-tls.html) をサポートしています。Linkerd と Istio はどちらも mTLS をサポートしています。

[aws-app-mesh-examples](https://github.com/aws/aws-app-mesh-examples) GitHub リポジトリには、Envoy コンテナで X.509 証明書と SPIRE を SDS プロバイダーとして使用して mTLS を設定するためのチュートリアルが用意されています。
+  [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) 

### Ingress Controllers と Load Balancer
<a name="_ingress_controllers_and_load_balancers"></a>

イングレスコントローラーは、クラスター外から発せられる HTTP/S トラフィックを、クラスター内で実行されているサービスにインテリジェントにルーティングする方法です。多くの場合、これらのイングレスは Classic Load Balancer や Network Load Balancer (NLB) などのレイヤー 4 Load Balancerによって前面に配置されます。暗号化されたトラフィックは、 ロードバランサー、イングレスリソース、ポッドなど、ネットワーク内のさまざまな場所で終了できます。SSL 接続を終了する方法と場所は、最終的に組織のネットワークセキュリティポリシーによって決まります。たとえば、end-to-endの暗号化を必要とするポリシーがある場合は、Pod でトラフィックを復号化する必要があります。これにより、最初のハンドシェイクの確立にサイクルを費やす必要があるため、Pod に負担がかかります。全体的な SSL/TLS 処理は CPU を大量に消費します。したがって、柔軟性がある場合は、Ingress またはロードバランサーで SSL オフロードを実行してみてください。

#### AWS Elastic ロードバランサーで暗号化を使用する
<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 v1.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 終了の追加の例を次に示します。
+  [Contour を使用した EKS Ingress の保護と 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 コントローラーなどの一部の Ingress は、Ingress Spec の一部としてではなく、注釈を使用して SSL/TLS を実装します。

### cert-manager を使用した ACM プライベート CA
<a name="iam-cert-manager"></a>

TLS と mTLS を有効にして、進入時、ポッド上、および ACM Private Certificate Authority (CA) と証明書を配布、更新、および取り消すための一般的な Kubernetes アドオンである [cert-manager](https://cert-manager.io/) を使用するポッド間で EKS アプリケーションワークロードを保護できます。ACM Private CA は、高可用性で安全なマネージド CA であり、独自の CA を管理するための前払いとメンテナンスのコストはかかりません。デフォルトの Kubernetes 認証機関を使用している場合は、セキュリティを向上させ、ACM Private CA のコンプライアンス要件を満たす機会があります。ACM Private CA は、FIPS 140-2 Level 3 ハードウェアセキュリティモジュール (非常に安全) でプライベートキーを保護します。これに対して、メモリにエンコードされたキーを格納するデフォルトの CA (安全性が低い) と比較します。また、一元化された CA を使用すると、Kubernetes 環境内外の両方のプライベート証明書をより詳細に制御し、監査性を向上させることができます。

#### ワークロード間の相互 TLS の短縮 CA モード
<a name="iam-ca-mode"></a>

EKS で mTLS に ACM プライベート CA を使用する場合は、存続期間の短い *CA モードの存続期間の短い*証明書を使用することをお勧めします。汎用 CA モードで有効期間の短い証明書を発行することは可能ですが、有効期間の短い CA モードを使用すると、新しい証明書を頻繁に発行する必要があるユースケースで、費用対効果が向上します (一般モードよりも約 75% 安価）。これに加えて、プライベート証明書の有効期間を EKS クラスター内のポッドの有効期間に合わせて調整する必要があります。[ACM Private CA とその利点については、こちら](https://aws.amazon.com/certificate-manager/private-certificate-authority/)を参照してください。

#### ACM セットアップ手順
<a name="_acm_setup_instructions"></a>

まず、[ACM Private CA 技術ドキュメントに記載されている手順に従って Private CA ](https://docs.aws.amazon.com/acm-pca/latest/userguide/create-CA.html)を作成します。プライベート CA を作成したら、[通常のインストール手順に従って cert-manager をインストール](https://cert-manager.io/docs/installation/)します。cert-manager をインストールしたら、[GitHub のセットアップ手順に従って](https://github.com/cert-manager/aws-privateca-issuer#setup) Private CA Kubernetes cert-manager プラグインをインストールします。プラグインを使用すると、cert-manager は ACM Private CA にプライベート証明書をリクエストできます。

Private CA と cert-manager とプラグインがインストールされた EKS クラスターができたので、アクセス許可を設定し、発行者を作成します。EKS ノードロールの IAM アクセス許可を更新して、ACM Private CA へのアクセスを許可します。をプライベート CA の値`<CA_ARN>`に置き換えます。

```
{
    "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_ARN>`および `<Region>`情報をプライベート CA に置き換えます。

```
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 クラスターは、プライベート CA に証明書をリクエストするように設定されています。上で作成したプライベート CA 発行者に`issuerRef`フィールドの値を変更することで、cert-manager の`Certificate`リソースを使用して証明書を発行できるようになりました。証明書リソースを指定してリクエストする方法の詳細については、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 プライベート CA
<a name="_acm_private_ca_with_istio_and_cert_manager"></a>

EKS クラスターで Istio を実行している場合は、Istio コントロールプレーン (特に `istiod`) がルート認証局 (CA) として機能しないようにし、ワークロード間の mTLS のルート CA として ACM プライベート CA を設定できます。このアプローチを使用する場合は、ACM プライベート *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 の ID として十分かもしれませんが、Istio には独自の ID 管理システムと CA があります。ワークロードがエンボイサイドカープロキシで起動するときは、信頼できると見なされ、メッシュ内の他のサービスと通信できるようにするために、Istio から割り当てられた ID が必要です。

Istio からこの ID を取得するために、 は証明書署名リクエスト (CSR) と呼ばれるリクエストを Istio コントロールプレーン`istio-agent`に送信します。この CSR には、処理前にワークロードの ID を検証できるように、サービスアカウントトークンが含まれています。この検証プロセスは`istiod`、登録機関 (または RA) と CA の両方として機能する によって処理されます。RA は、検証済みの CSR のみが CA に渡すようにするゲートキーパーとして機能します。CSR が検証されると、CA に転送され、サービスアカウントで [SPIFFE](https://spiffe.io/) ID を含む証明書が発行されます。この証明書は、SPIFFE 検証可能な ID ドキュメント (SVID) と呼ばれます。SVID は、識別および通信サービス間の転送中のトラフィックを暗号化するために、リクエスト元のサービスに割り当てられます。

Istio 証明書署名リクエストのデフォルトフロー:

![\[Istio 証明書署名リクエストのデフォルトフロー\]](http://docs.aws.amazon.com/ja_jp/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* エージェントは、受信 CSR を検証するデフォルト設定で *istiod* が処理するのと同じサービスを公開します。 CSRs ただし、検証後、証明書マネージャーがサポートするリソース (外部 CA 発行者と の統合) にリクエストが変換されます。

ワークロードから CSR が存在するたびに、*istio-csr* に転送され、ACM Private CA に証明書がリクエストされます。*istio-csr* と ACM Private CA 間のこの通信は、[AWS Private CA 発行者プラグイン](https://github.com/cert-manager/aws-privateca-issuer)によって有効になります。Cert Manager は、このプラグインを使用して ACM Private CA に TLS 証明書をリクエストします。発行者プラグインは ACM Private CA サービスと通信して、ワークロードの署名付き証明書をリクエストします。証明書が署名されると、*istio-csr* に返されます。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 Issuer Plugin で設定された 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 をカスタム設定でインストールし、メッシュの証明書プロバイダー`cert-manager istio-csr`として `istiod` に置き換えます。このプロセスは、[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 Controller と 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)。
+  [プライベート CA Kubernetes 証明書マネージャープラグインユーザーガイド](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) 
+  [egress-operator](https://github.com/monzo/egress-operator) プロトコル検査なしでクラスターからの出力トラフィックを制御する演算子と DNS プラグイン
+  [SUSE オープンソースのゼロトラストコンテナセキュリティプラットフォームによる NeuVector ](https://www.suse.com/neuvector/) は、ポリシーネットワークルール、データ損失防止 (DLP)、ウェブアプリケーションファイアウォール (WAF)、ネットワーク脅威署名を提供します。