【AWS】デフォルトセキュリティグループのインバウンドトラフィックとアウトバウンドトラフィックを許可しないようにする対応[EC2.2]

# はじめに
[**AWS Foundational Technical Review (FTR)**](https://aws.amazon.com/jp/partners/foundational-technical-review/)の評価の一つに、

**[EC2.2] VPC のデフォルトのセキュリティグループでは、インバウンドトラフィックとアウトバウンドトラフィックを許可しないようにする必要があります**

という項目があり、その対応を行ったのでやったことをまとめてみました。

参考

https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/ec2-controls.html#ec2-2

https://dev.classmethod.jp/articles/securityhub-fsbp-remediation-ec2-2/


## 今回の記事の対象者
- 同じ対応を行いたい方
- セキュリティ強化をベストプラクティスに沿って進めたい方


# ざっくりと
ここで全体の流れを書いておきます

1. 現在のデフォルトセキュリティグループのルールを確認
2. デフォルトセキュリティグループを使っているリソースを確認
3. 同じルールもしくは必要なルールだけを持っているセキュリティグループを作成
4. セキュリティグループを置き換える
5. 置き換えたリソースの動作確認
6. 全リージョンのデフォルトセキュリティグループのルールを削除する
7. 念のため一通り動作確認を行う
    - 動かないものがあれば3.から行う

# 詳しく
## 1. 現在のデフォルトセキュリティグループのルールを確認
まずは、現在の状態を確認します。

VPCのセキュリティグループを開き、セキュリティグループ名が**default**のものがデフォルトセキュリティグループです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515830/8114e1b5-a567-e68c-9982-8d346d6783e6.png)

`セキュリティグループ名 = default`で検索すると速いです。

セキュリティグループIDをクリックするか左端のチェックボックスにチェックを入れると詳細を確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515830/e39f464b-5e44-efa0-a3cf-5ef4b11c75d6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515830/86822e7c-cac7-cae2-cd7e-6ab93a9baefb.png)

基本的なデフォルトセキュリティグループのインバウンドルールとアウトバウンドルールは上の画像のようになっています。

もしこの段階ですべてのデフォルトセキュリティグループでルールが何もなければ今回の対応はここで終わりです。

ここで上の画像と異なるルールが設定されている場合は、意図的に設定しているルールになっているので何らかのリソースで使われているセキュリティグループの可能性が大です！
次の項目で確認していきましょう！

## 2. デフォルトセキュリティグループを使っているリソースを確認
ここでは、現在デフォルトセキュリティグループを使っているリソースを確認します。

もし、デフォルトセキュリティグループを使っているものがあったまま、ルールを全て削除するとネットワークが途切れてしまうので動かなくなってしまいます。

### コード上で確認

まずは、Cloudformation等でリソースを管理している場合、コード上でデフォルトセキュリティグループを使っているかどうかを確認しましょう。

`DefaultSecurityGroup`等で調べるとデフォルトセキュリティグループを参照しているリソースが出てきます。

### マネジメントコンソール上で確認

**EC2>>ネットワークインターフェース**から`セキュリティグループ名 = default`で検索し、使われているリソースを検索できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515830/d9e21c8f-0df5-a3cd-6e70-70542ee41279.png)

インターフェースのタイプから使っているリソースが分かるのでそれぞれマネジメントコンソール上で確認しましょう。

手動で作成していて現在も使っているものは何があるかをチームの方に聞くのも1つの手ですね。

私はCodebuildでデフォルトセキュリティグループを使っていることを見落としていたので、皆さんは念入りに確認しましょう。

## 3. 同じルールもしくは必要なルールだけを持っているセキュリティグループを作成

デフォルトセキュリティグループを使っているリソースがわかったら、それらを他のセキュリティグループに置き換えていきます。

### 手動で作成する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3515830/af1ed0c7-a001-7b4b-303e-ac7304c99b47.png)

セキュリティグループの詳細画面のアクションから**新しいセキュリティグループにコピー**を選択しましょう。

これで適切な名前と同じVPCに作成し、インバウンドルールのソース部分をセキュリティグループIDに指定したら同じルールでのセキュリティグループは完成です。

もしルールを変えたい場合は、通信可能になるようにルールを慎重に追加しましょう。

### コードで作成する場合
今回は、例として通常のデフォルトセキュリティグループと同じルールである、以下のルールのセキュリティグループを**Cloudformationテンプレート**で作成します。
- **インバウンドルール**
    - タイプ : すべてのトラフィック
    - プロトコル : すべて
    - ポート範囲 : すべて
    - ソース : security groupID/セキュリティグループ名
- **アウトバウンドルール**
    - IPバージョン : IPv4
    - タイプ : すべてのトラフィック
    - プロトコル : すべて
    - ポート範囲 : すべて
    - 送信先 : 0.0.0.0/0

```
  TemplateVpcSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "security group for TemplateVpc"
      VpcId:
        Ref: TemplateVpc
      SecurityGroupEgress:
        - IpProtocol: -1
          FromPort: 0
          ToPort: 65535
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: "template-sg"
  TemplateVpcSecurityGroupIngress:
    Type: AWS::EC2::SecurityGroupIngress
    Properties:
      IpProtocol: -1
      FromPort: -1
      ToPort: -1
      GroupId: !Ref TemplateVpcSecurityGroup
      SourceSecurityGroupId: !Ref TemplateVpcSecurityGroup
```

これを参考に作成してみてください。

## 4. セキュリティグループを置き換える
3.で作成したセキュリティグループに2.で調査したリソースで1つずつ置き換えていきます。

手動であればマネジメントコンソール上で編集し、

コード上であればデフォルトセキュリティグループを指定している箇所に作成したセキュリティグループを指定しなおして、Cloudformationでスタックの更新をしてください。

## 5. 置き換えたリソースの動作確認
置き換えたリソースで動作確認を行ってください。
通信する部分で通常の動作が確認できればOKです！

## 6. 全リージョンのデフォルトセキュリティグループのルールを削除する
動作確認ができたら実際にルールを削除していきます。
1つずつ削除していくのは気が遠くなる作業ですので、スクリプトで対応していきましょう。
以下のブログを参考にしました。

https://dev.classmethod.jp/articles/delete-all-default-sg-rules-with-cli/

[以下ブログから引用](https://dev.classmethod.jp/articles/delete-all-default-sg-rules-with-cli/)
```
aws ec2 describe-regions --query "Regions[].[RegionName]" --output text \
| while read REGION; do
    echo "# deleting sg-rules in ${REGION}"
    ### default SGのIDを取得し、IDごとに処理を実行
    aws ec2 describe-security-groups --filters "Name=group-name,Values=default" --region "$REGION" --query "SecurityGroups[].GroupId" --output text | xargs -n1 echo \
    | while read ID; do
        echo "# deleting default rule in ${ID}"
        SG=$(aws ec2 describe-security-groups --group-ids ${ID} --region "$REGION" --query "SecurityGroups[]" --output json)
        INGRESS=$(echo $SG | jq -r '.[].IpPermissions[]')
        EGRESS=$(echo $SG | jq -r '.[].IpPermissionsEgress[]')
        ### ingressを削除
        if [ -n "$INGRESS" ]; then
            RESULT=$(aws ec2 revoke-security-group-ingress --group-id $ID --region "$REGION" --ip-permissions "$INGRESS" --query "Return")
            echo "# deleted ${ID} ingress"
        fi
        ### egressを削除
        if [ -n "$EGRESS" ]; then
            RESULT=$(aws ec2 revoke-security-group-egress --group-id $ID --region "$REGION" --ip-permissions "$EGRESS" --query "Return")
            echo "# deleted ${ID} egress"
        fi
    done
done
```
上記スクリプトをブログの記事内ではCloudShellで実行していますが、
私は1つのファイルにし、アカウント事に実行する**CodebuildのPostBuild部分**で実行するようにしました。

## 7. 念のため一通り動作確認を行う
2.と5.でリソースの確認と動作確認はおこないましたが、どこでデフォルトセキュリティグループが使われているか、それを見落としているかは実際に触ってみないと分からない節は少しあります。

そのため、これまでの一通りの作業が終わったら、**今回関係なさそうな個所も含めて全て動作確認を行ってみましょう**。

動作が固まったり、タイムアウトしたりした場合は通信がセキュリティグループのせいで途切れている可能性があるので原因調査を行いましょう。

その後、もう一度3.から同じ工程を問題がなくなるまで繰り返しましょう！


# おわりに
今回はデフォルトセキュリティグループのインバウンドトラフィックとアウトバウンドトラフィックを許可しないようにする対応を行いました。

デフォルトセキュリティグループなので、意識せずに使っていたなんてことはある話ですし、少し調査に時間がかかってしまうなぁというのが対応してみての印象でした。

本記事がこの対応の参考になれば幸いです！