特定セキュリティグループの使用状況を AWS CloudShellで確認する

AWS CLIを使ったセキュリティグループ使用状況の調査です
2021.04.19

セキュリティグループのルール棚卸しを行う機会は多いです。 例えば以下のようなケースです。

それらセキュリティグループは是正する必要があります。 しかし是正前に使用状況を確認して、影響範囲を把握しておきたいです。

今回はセキュリティグループ使用状況の把握を AWS CloudShell を使って行います。

特定のセキュリティグループが関連付けられている ENI/EC2インスタンス情報を取得します。

0. 前提条件

対象のリージョンで AWS Configの有効化、および EC2セキュリティグループを記録する設定にしていることが 前提条件です。

1. CloudShell起動

AWS CloudShellを起動しましょう。

デフォルトでAWS CLIが使えるので 必須の準備事項はありませんが、 以下設定を流してページャーを無効化しておくと、まとめて実行する際に便利です。

# ページャーを無効にする
aws configure set cli_pager ''

参考: AWS CloudShell で AWS CLI v2 のページャーを無効化する | DevelopersIO

2. セキュリティグループ(SG)のID取得

調べたいセキュリティグループIDを変数 sgid に格納しておきます。

# 参考: SG一覧表示
aws ec2 describe-security-groups --output table \
--query "SecurityGroups[].{NameTag:Tags[?Key=='Name']|[0].Value, GroupId: GroupId, GroupName: GroupName}"
# --------------------------------------------------------------
# |                DescribeSecurityGroups                      |
# +-----------------------+-------------------------+----------+
# |        GroupId        |       GroupName         | NameTag  |
# +-----------------------+-------------------------+----------+
# |  sg-05xxxxxxxxxxxxxxx |  xxx-ec2-instance-sg    |  XXX     |
# |  sg-0fxxxxxxxxxxxxxxx |  xxx-elb-sg             |  YYY     |
# ...

# GroupId の登録
sgid=sg-c0xxxx

# 確認
aws ec2 describe-security-groups --filters Name=group-id,Values=$sgid --output yaml \
--query "SecurityGroups[].{NameTag:Tags[?Key=='Name']|[0].Value, GroupId: GroupId, GroupName: GroupName}"

▼出力例

- GroupId: sg-c0xxxxxx
  GroupName: default
  NameTag: default

3. SGの VPC情報

所属するVPCを調べます。

# VPC ID の取得
vpcid=$(aws ec2 describe-security-groups --filters Name=group-id,Values=$sgid \
--query "SecurityGroups[].VpcId" --output text)

# VPC 情報
aws ec2 describe-vpcs --filters Name=vpc-id,Values=$vpcid --query \
"Vpcs[].{Name:Tags[?Key=='Name']|[0].Value, VpcId:VpcId, Cidr:CidrBlock}" --output yaml

▼出力例

- Cidr: 10.10.3.0/24
  Name: xxx-dev-vpc
  VpcId: vpc-82xxxxxxx

4. SGが関連付けられているENI情報

Config の AWS::EC2::SecurityGroup リソース記録から、 「どのENI or EC2インスタンスに関連付けられているか」探ることができます。

まずは ENI情報を列挙します。

aws configservice get-resource-config-history --output text \
--resource-type AWS::EC2::SecurityGroup --resource-id $sgid --max-items 1 \
--query "configurationItems[].relationships[?relationshipName=='Is associated with NetworkInterface'][].[resourceId]" \
| while read eni; do
  if [ "$eni" = "None" ]; then
    continue
  fi
  echo "### $eni"
  # ENI情報の取得
  aws ec2 describe-network-interfaces --filters Name=network-interface-id,Values=$eni --output yaml \
  --query "NetworkInterfaces[].{Attachment:Attachment, Description:Description, Id:NetworkInterfaceId, PrivateIpAddresses:PrivateIpAddresses}"
  echo ""
done

▼出力例

### eni-027xxxx
- Attachment:
    AttachmentId: ela-attach-11xxxx
    DeleteOnTermination: false
    DeviceIndex: 1
    InstanceOwnerId: amazon-aws
    Status: attached
  Description: AWS Lambda VPC ENI-dev-xxxx
  Id: eni-027xxxx
  PrivateIpAddresses:
  - Primary: true
    PrivateDnsName: ip-xxxx.ap-northeast-1.compute.internal
    PrivateIpAddress: xxxx

### eni-b0exxxx
- Attachment:
    AttachTime: '2020-01-01T01:01:01+00:00'
    AttachmentId: eni-attach-52xxxx
    DeleteOnTermination: true
    DeviceIndex: 0
    InstanceId: i-09xxxx
    InstanceOwnerId: '123456789012'
    NetworkCardIndex: 0
    Status: attached
  Description: Primary network interface
  Id: eni-b0xxxx
  PrivateIpAddresses:
  - Association:
      AllocationId: eipalloc-baxxxx
      AssociationId: eipassoc-78xxxx
      IpOwnerId: '123456789012'
      PublicDnsName: ec2-xxxx.ap-northeast-1.compute.amazonaws.com
      PublicIp: xxxx
    Primary: true
    PrivateDnsName: ip-xxxx.ap-northeast-1.compute.internal
    PrivateIpAddress: xxxx

5. SGが関連付けられているインスタンス情報

次に EC2インスタンスとの関連付けを調べます。

aws configservice get-resource-config-history --output text \
--resource-type AWS::EC2::SecurityGroup --resource-id $sgid --max-items 1 \
--query "configurationItems[].relationships[?relationshipName=='Is associated with Instance'][].[resourceId]" \
| while read instance; do
  if [ "$instance" = "None" ]; then
    continue
  fi
  echo "### $instance"
  # インスタンス情報の取得
  aws ec2 describe-instances --filters Name=instance-id,Values=$instance --output yaml \
  --query 'Reservations[*].Instances[].{Name:Tags[?Key==`Name`]|[0].Value, Id:InstanceId, State:State.Name, LaunchTime:LaunchTime}'
  echo ""
done

▼出力例

### i-09xxxx
- Id: i-09xxxx
  LaunchTime: '2021-01-01T08:09:33+00:00'
  Name: xxx-dev
  State: running

### i-20xxxx
- Id: i-20xxxx
  LaunchTime: '2021-01-02T02:18:09+00:00'
  Name: yyy-dev
  State: stopped

6. SGが関連付けられている SG情報 (2021/05/07追記)

ここでは 対象SGからのインバウンド/アウトバウンドを許可するルール を入れている 他SGを検索します。 これは AWS CLIのフィルター(--filters)機能で簡単に検索できます。

(
  echo "### inbound"
  aws ec2 describe-security-groups --output text \
  --filters Name=ip-permission.group-id,Values=$sgid \
  --query "SecurityGroups[].[GroupName, GroupId]"
   
  echo "### outbound"
  aws ec2 describe-security-groups --output text \
  --filters Name=egress.ip-permission.group-id,Values=$sgid \
  --query "SecurityGroups[].[GroupName, GroupId]"
)

▼出力例

### inbound
xxx-aurora  sg-fdxxx
xxx-redis  sg-3bxxx
### outbound

まとめ

以上、CloudShell(AWS CLI)を使った セキュリティグループ使用状況の調査でした。

もちろん AWS Configのマネジメントコンソール上からも確認できます。 以下参照ください。

参考