PrivateLinkでアクセス制御出来る箇所が多すぎる件について


<!-- 発端や概要を記載 -->
# はじめに
AWSアカウント間のデータ連携において、最もメジャーものの一つとしてPrivateLinkがあります。
特徴として通信がAWS内に留まること、またプリンシパルやセキュリティグループでのアクセス制御が容易なことなどの利点があります。

ただクライアント側とサービス提供側でそれぞれアクセス制御できる箇所が存在し、
初見の私は、`どのリソースでどの程度アクセス制御すればいいかわからない...`というのが本音でした。
本記事ではそんな迷えるPrivateLinkユーザー向けにアクセス制御方法を解説します。

:::note info
本記事の構成を作成するためのTerraformを以下リポジトリで用意しています、
実際に作成してみて設定値を確認したほうが分かりやすいので良ければご利用ください。
* [terraform-for-aws](https://github.com/Lamaglama39/terraform-for-aws/tree/main/privatelink-access-control)
:::

<!-- 各チャプター -->
<a id="#Chapter1"></a>

# 1.前提

本記事では`サービス提供側でエンドポイントサービスを用意しているPrivateLink接続`を対象としています。
構成自体はシンプルにクライアント側のEC2からPrivateLink経由で、サービス提供側のEC2へリクエストを投げる形です。

またわかりやすくするためクライアント側はEC2としていますが、
ECSやLambda(VPC内)などセキュリティーグループをアタッチできるリソースであれば同様の扱いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/6f7c2624-c20b-3b72-cd1d-1f8d1f229391.png)

PrivateLinkの主なアクセス制御として以下が存在します。
* クライアント側
  - ①クライアント側EC2のセキュリティグループ
  - ②VCPエンドポイントのセキュリティグループ

* サービス提供側
  - ③VPCエンドポイントサービスのプリンシパル/接続リクエストの承諾
  - ④NLBのセキュリティグループ
  - ⑤サービス提供側EC2のセキュリティグループ

なおAWSが提供しているサービスへ接続する場合のPrivateLinkのアクセス制御は、以下の記事をご参照ください。
* [セキュリティーグループのアウトバウンドルールでVPCエンドポイント宛の通信を許可する方法](https://qiita.com/Lamaglama39/items/511be91908820c403d75)


<a id="#Chapter2"></a>

# 2.アクセス制御
通信の順から`クライアント側`～`サービス提供側`の順で解説しますが、
リソースの作成の順は`サービス提供側`～`クライアント側`の順となります。

## 2-1.クライアント側のリソース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/2b61c3c3-d2db-3647-e315-92d112824b7c.png)

### ①.EC2
まずはクライアント側のEC2のアクセス制御です。
ここでは`EC2からVPCエンドポイント向けのアウトバウンドの通信`を制御ができます。

なお検証もかねて`VPCピアリング経由の別VPCのEC2`、`VPCエンドポイントと同じVPC内のEC2`の2パターンを確認しましたが、
どちらも同じ方式でアクセス制御ができます。

#### (1) セキュリティグループ
アウトバウンドルールで、
`VPCエンドポイント(ENI)のプライベートIPアドレス`、
または`VPCエンドポイントが利用してるセキュリティーグループ`を指定できます。
以降のアクセス制御でも同様ですが、特にこだわりがなければセキュリティーグループを指定することをお勧めします。

またインバウンドルールはPrivateLinkの通信とは直接関係ないので、
必要に応じて設定してください。

| 設定項目            | 設定値                 |
|:-------------------|:-----------------------|
|	インバウンドルール   | -                      |
|	アウトバウンドルール | VPCエンドポイントのプライベートIP or セキュリティグループ |

### ②.VPCエンドポイント
次にVPCエンドポイントのアクセス制御です。
ここではVPCエンドポイントから見てインバウンドとなる`EC2からVPCエンドポイントへの通信`を制御できます。
なおアウトバウンドについては後述の理由から制御する設定はありません。

#### (1) セキュリティグループ
インバウンドルールで`EC2のプライベートIPアドレス`、
または`EC2が利用しているセキュリティーグループ`を指定できます。
こちらも特にこだわりがなければ、セキュリティーグループを指定することをお勧めします。

アウトバウンドルールは以下ドキュメントの通り、設定は必要ありません。
* [VPCエンドポイント ナレッジセンター](https://repost.aws/ja/knowledge-center/security-network-acl-vpc-endpoint)
* [セキュリティグループのルール](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/security-group-rules.html)

具体的に設定が不要となる理由についてですが、
アウトバウンドルールの設定自体は可能ですが以下の二点から、PrivateLinkの通信ではアウトバウンドルールが適用されないためです。
```
(1).セキュリティグループはステートフルであり、
    インバウンドが許可されていればアウトバウンドは関係なく通信が流れる
(2).VPCエンドポイント自身が通信を発信しているわけではないので、
    アウトバウンドルールは適用されない
```

| 設定項目            | 設定値                 |
|:-------------------|:-----------------------|
|	インバウンドルール   | クライアント側EC2のIP or セキュリティグループ |
|	アウトバウンドルール | -                                          |

なおエンドポイントポリシーについては、
`VPCエンドポイントサービスを指定したVPCエンドポイント`はポリシーが設定項目として存在しないため考慮する必要はありません。

ドキュメントに明確な記載がないので理由は推し量るしかありませんが、
エンドポイントポリシーはS3などのAWSサービスを対象としているため、VPCエンドポイントサービスを指定したVPCエンドポイントは対象外なのではないかと思われます。

* [エンドポイントポリシー ドキュメント](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/vpc-endpoints-access.html)

**・VPCエンドポイントサービスを指定したVPCエンドポイント**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/81a8af17-21e7-28db-2de9-7af8aa1c9199.png)

**・AWSサービスを指定したVPCエンドポイント**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/9f744944-74e0-4f26-d8db-7c35a62859fe.png)


## 2-2.サービス提供側のリソース
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491064/094940e1-6085-5a50-268b-ffac5467204f.png)

### ③.VPCエンドポイントサービス
次にVPCエンドポイントサービスのアクセス制御です。
こちらの設定は一度設定するだけなので厳密にアクセス制御かと言うと微妙なラインですが、
PrivateLinkを利用する上で避けては通れない箇所なので紹介します。

#### (1) プリンシパル
`VPCエンドポイントを作成する許可`を付与する対象を指定します。
`AWSアカウント or IAMロール or IAMユーザー`を指定することで、
クライアント側のAWSアカウントでこのVPCエンドポイントサービスを指定したVPCエンドポイントが作成可能となります。

* [プリンシパル ドキュメント](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/configure-endpoint-service.html)

| 許可を付与する対象    | 設定例  |
|:--------------------|:--------|
|	すべてのAWSアカウント | *       |
|	AWSアカウント        | arn:aws:iam::`account_id`:root                    |
|	IAMロール            | arn:aws:iam::`account_id`:role/`role_name`        |
|	IAMユーザー          | arn:aws:iam::`account_id`:user/`user_name`        |


#### (2) 接続リクエストの承諾
前述のプリンシパルで許可したAWSアカウントでVPCエンドポイントが作成された後、
`VPCエンドポイントサービス側で承諾するか拒否するか`選択できます。
承諾することで、VPCエンドポイント側から通信が可能となります。

* [接続リクエストの承諾/拒否 ドキュメント](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/configure-endpoint-service.html#accept-reject-connection-requests)

### ④.NLB
NLBのアクセス制御は`セキュリティーグループ`で行います。
なおリスナー/ターゲットグループは振り分け先の設定であり本筋から外れるので割愛します。

#### (1) セキュリティグループ
インバウンドルールでは`クライアント側EC2からNLBへの通信`を許可します。
なお`PrivateLink経由の通信にセキュリティグループを適用するかどうか`は選択できるため、
セキュリティグループを適用する場合はインバウンドルールにて`クライアント側のプライベートIPを指定`、適用しない場合は`設定は不要`となります。
また別アカウントのリソースであるためか、`クライアント側EC2のセキュリティグループ`を指定することはできません。

* [NLBセキュリティグループ ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/load-balancer-security-groups.html)

アウトバウンドルールでは`NLBからサービス提供側EC2への通信`を許可します。
`EC2のプライベートIPアドレス`、
または`EC2が利用してるセキュリティーグループ`を指定できます。
こちらも特にこだわりがなければセキュリティーグループを指定することをお勧めします。

| 設定項目            | 設定値  |
|:-------------------|:-------------------------------------------|
|	インバウンドルール   | クライアント側EC2のプライベートIP                       |
|	アウトバウンドルール | サービス提供側EC2のプライベートIP or セキュリティグループ |

### ⑤.サービス提供側 EC2
最後はサービス提供側のEC2のアクセス制御です、こちらもセキュリティーグループで制御をします。

#### (1) セキュリティグループ
インバウンドルールでは`NLBからEC2への通信`を許可します。
`NLBのプライベートIPアドレス`、
または`NLBが利用してるセキュリティーグループ`を指定できます。
こちらも特にこだわりがなければセキュリティーグループを指定することをお勧めします。

アウトバウンドルールはPrivateLinkの通信とは直接関係ないので、
必要に応じて設定してください。

| 設定項目            | 設定値  |
|:-------------------|:--------|
|	インバウンドルール   | NLBのプライベートIP or セキュリティグループ |
|	アウトバウンドルール  | -                                       |


<a id="#Chapter3"></a>

# 3.最後に
長文となりましたが、PrivateLinkで設定可能なアクセス制御についての説明は以上です。
主にセキュリティグループの設定に関する内容が多く重複する部分もありましたが、皆様のPrivateLinkへの理解が少しでも深まったなら幸いです。


<a id="#Chapter4"></a>

## 参考ドキュメント
本記事の作成に際して、以下のドキュメントおよび記事を参考にさせていただきました。
この場を借りてお礼申し上げます。

* [[アップデート] 遂に Network Load Balancer でセキュリティグループがサポートされました](https://dev.classmethod.jp/articles/nlb-security-group/)
* [Network Load Balancer (NLB) がセキュリティグループをサポートして何が嬉しいのか整理してみた](https://dev.classmethod.jp/articles/benefits-of-network-load-balancer-supports-security-groups/)
* [【NLB to ALB】VPCエンドポイントからのアクセスを試してみた](https://blog.serverworks.co.jp/vpcendpoint2nlb)