【AWS】特定のIPに関するSecurity Groupのルール追加をSCPで制限できるか検証、調査してみた

AWS認定試験の練習問題を公開しているサイト[EXAMTOPICS](https://www.examtopics.com)のAWS認定SAP-C02試験、問題44について検証、調査してみました。
※EXAMTOPICSはサイト運営公式回答の他にコミュニティーの投票機能があり、正解が割れることが多々あります。
## 問題解説
問題文は[こちらの公式](https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-professional-sap-c02/view/5/)から参照。
### 問題概要
AWS Organizationsで管理しているOUに属するアカウントに対して、Security Groupに特定のIPアドレス(0.0.0.0/0)を接続元として含むインバウンドルールの作成を拒否したいがどうすればよいか。
### 回答
公式回答、コミュニティー投票が大きく割れた問題となっています。
①SCPから"aws:SourceIp"コンディションキーで条件指定して許可する(EXAMTOPICS公式回答)
②SCPから"aws:SourceIp"コンディションキーで条件指定して許可する(6割投票)
③SGにルールが追加されたタイミングでEventBrigeからLambdaをトリガーし該当のルールであれば削除(4割投票)

回答の争点はSCPで0.0.0.0/0をソースとするポリシーを追加できるか。
以下の検証調査ではその点を争点に記載していく。

## 検証、調査
### 回答①
下記イメージのようにアカウントで許可されているポリシー範囲にセキュリティグループのインバウンドルール追加権限が含まれる。
ポリシーで記載できるかどうかに関わらず、インバウンドルールとして追加できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/0f05ed1e-96f7-c1be-eead-7e4f89aa0b8c.png)
※0.0.0.0/0をソースとしないポリシーを許可とした場合には実質②と同様の回答となる。しかしこの場合既存で入っている許可ポリシーの書き換えとなるため管理が面倒。

**不正解**


### 回答②
0.0.0.0/0をソースとするセキュリティグループのインバウンドルール追加を拒否するポリシーをアタッチした場合にはアカウントで許可される権限のイメージは下記画像の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/a38983df-4cdd-c9d7-b858-b8289b25b6ff.png)


問題上記のポリシーを記載して、許可させることはできるか。

問題文と解答を参考にポリシー記載すると下記のようになる。
~~`"aws:SourceIp"`は送信元IPなので嫌な気がするが。。。~~
```json:Deny Policy
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "Statement1",
			"Effect": "Deny",
			"Action": [
				"ec2:AuthorizeSecurityGroupIngress"
			],
			"Resource": [
				"*"
			],
			"Condition": {
				"IpAddress": {
					"aws:SourceIp": [
						"0.0.0.0/0"
					]
				}
			}
		}
	]
}
```

まずはSCPをアタッチしていない状態で下記のようにルールを追加してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/e65e480b-8d8c-0fde-a2b1-c48b82789e2a.png)
これは当然許可される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/44928095-8cbd-8dc1-4019-a91a83a3b0bf.png)



次にOUにアタッチして、0.0.0.0/0を含むインバウンドルールを作成してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/3ab980b7-0bbc-7a73-74b5-13ca215c8454.png)

結果は権限問題で拒否される。
※アカウント番号等含まれるのでざっくり塗りつぶしてます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/394af2fe-16a3-dcbf-5e5a-1423c37ddfd3.png)

次に、0.0.0.0/0以外のソースアドレスのインバウンドルールを作成してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/d55996a3-9668-be26-447d-b8e977072a1b.png)

こちらも同様に拒否された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/82a60c44-310d-1bd0-8e87-8316a033409c.png)


何が起こっているのか。
`"aws:SourceIp"`はざっくりいうと送信元のIPアドレスを指す。
>このキーを使用して、リクエスタの IP アドレスをポリシーで指定した IP アドレスと比較します。
>aws:SourceIp 条件キーは、パブリック IP アドレス範囲にのみ使用できます。

今回の例では、**インバウンドルールを作成するAPIを叩いたIPアドレス**が評価対象となる。
0.0.0.0/0、すなわちインバウンドルールを作成しようとするすべてのIPアドレスに対して拒否していることになる。

条件キーを別の書き方で送信元IPアドレスを指定したので、[Amazon EC2 のアクション、リソース、および条件キー](https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonec2.html)で使える条件キーがない探してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3561522/17e03f83-cbbc-f455-68a8-b81f73b6d1e9.png)

残念ながらSecurity Gpoupルールの特定の値を条件キーには指定できなさそうだ。

**不正解**

### 回答③
そのままではないがクラスメソッドさんが似たような記事を書いているのでリンクを掲載する。
[https://dev.classmethod.jp/articles/update-securitygroup-for-lambda/](https://dev.classmethod.jp/articles/update-securitygroup-for-lambda/)

ルールを作成する権限を拒否している訳ではないので問題の回答として◯とは言い難いが消去法的に

**正解**

## まとめ
* `"aws:SourceIp"`は送信元のIPアドレス
* Security Groupの値に基づいたポリシーは書けない
* Lambdaを使って既存のSecurity Groupをフィルタして修正できる

## 補足
AWS Configを利用する回答は修正まで記載してくれていない。あくまでコンプライアンス違反として評価されるだけである。
[https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/vpc-sg-open-only-to-authorized-ports.html](https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/vpc-sg-open-only-to-authorized-ports.html)