michimani.net

AWS CLI でセキュリティグループを触ってみる

2020-07-14

AWS CLI を使って EC2 のセキュリティグループを操作してみます。

目次

前提

今回は default ではない VPC に対してセキュリティグループの追加や削除、ルールの追加、削除を試してみます。

内容的には、 以前に JAWS-UG CLI 専門支部で実施されていたハンズオンに含まれている内容です。

また、今回使う AWS CLI のバージョンは、現時点 (2020/07/14) で最新の 2.0.30 とします。

$ aws --version
aws-cli/2.0.30 Python/3.7.4 Darwin/19.5.0 botocore/2.0.0dev34

VPC の作成

まずは今回操作するセキュリティグループを作成する VPC を作成します。

$ aws ec2 create-vpc help
...
SYNOPSIS
            create-vpc
          --cidr-block <value>
          [--amazon-provided-ipv6-cidr-block | --no-amazon-provided-ipv6-cidr-block]
          [--ipv6-pool <value>]
          [--ipv6-cidr-block <value>]
          [--dry-run | --no-dry-run]
          [--instance-tenancy <value>]
          [--ipv6-cidr-block-network-border-group <value>]
          [--tag-specifications <value>]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...

--cidr-block で CIDR ブロックを指定して、あとのオプションはデフォルトのままとします。

$ aws ec2 create-vpc \
--cidr-block 10.0.0.0/16

{
    "Vpc": {
        "CidrBlock": "10.0.0.0/16",
        "DhcpOptionsId": "dopt-cc5618a8",
        "State": "pending",
        "VpcId": "vpc-0f55f781234567890",
        "OwnerId": "123456789012",
        "InstanceTenancy": "default",
        "Ipv6CidrBlockAssociationSet": [],
        "CidrBlockAssociationSet": [
            {
                "AssociationId": "vpc-cidr-assoc-0359f7b1234567890",
                "CidrBlock": "10.0.0.0/16",
                "CidrBlockState": {
                    "State": "associated"
                }
            }
        ],
        "IsDefault": false
    }
}

セキュリティグループの作成

続いてセキュリティグループを作成します。

ec2 create-security-group

$ aws ec2 create-security-group help
...
SYNOPSIS
            create-security-group
          --description <value>
          --group-name <value>
          [--vpc-id <value>]
          [--tag-specifications <value>]
          [--dry-run | --no-dry-run]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...

--vpc-id は必須ではありませんが、 省略すると default VPC が対象となる ので、ここでは明示的に VPC を指定します。

$ aws ec2 create-security-group \
--description "SG for michimani" \
--group-name michimani-demo-sg \
--vpc-id vpc-0f55f781234567890

{
    "GroupId": "sg-03af1891234567890"
}

ec2 describe-security-groups

作成したセキュリティグループを確認してみます。

$ aws ec2 describe-security-groups help
...
SYNOPSIS
            describe-security-groups
          [--filters <value>]
          [--group-ids <value>]
          [--group-names <value>]
          [--dry-run | --no-dry-run]
          [--cli-input-json | --cli-input-yaml]
          [--starting-token <value>]
          [--page-size <value>]
          [--max-items <value>]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...

--group-names でグループ名での取得もできますが、これは default VPC が対象となります。試しに先ほど作成したセキュリティグループの名前で実行してみると InvalidGroup.NotFound エラーとなります。

$ aws ec2 describe-security-groups \
--group-names michimani-demo-sg

An error occurred (InvalidGroup.NotFound) when calling the DescribeSecurityGroups operation: The security group 'michimani-demo-sg' does not exist in default VPC 'vpc-1234567890aaaaaaa'

なので、 --group-ids でグループ ID を指定して取得します。

$ aws ec2 describe-security-groups \
--group-ids sg-03af1891234567890

{
    "SecurityGroups": [
        {
            "Description": "SG for michimani",
            "GroupName": "michimani-demo-sg",
            "IpPermissions": [],
            "OwnerId": "123456789012",
            "GroupId": "sg-03af1891234567890",
            "IpPermissionsEgress": [
                {
                    "IpProtocol": "-1",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": []
                }
            ],
            "VpcId": "vpc-0f55f781234567890"
        }
    ]
}

アウトバウンドルール (IpPermissionsEgress) として、すべてのプロトコル (-1) に対して 全開放 (0.0.0.0/0) されています。インバウンドルールはありません。

インバウンドルールの追加・削除

続いては、作成したセキュリティグループのインバウンドルールを追加・削除してみます。

ec2 authorize-security-group-ingress

インバウンドルールを作成します。

$ aws ec2 authorize-security-group-ingress help
...
SYNOPSIS
            authorize-security-group-ingress
          [--group-id <value>]
          [--group-name <value>]
          [--ip-permissions <value>]
          [--dry-run | --no-dry-run]
          [--protocol <value>]
          [--port <value>]
          [--cidr <value>]
          [--source-group <value>]
          [--group-owner <value>]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...

ここでもセキュリティグループの指定はグループ名でも可能ですが、その場合の対象は default VPC となります。 なので、ここでもグループ ID で指定します。また、 http と https でのアクセスを許可するため、 80 と 443 ポートそれぞれにルールを作成します。

$ aws ec2 authorize-security-group-ingress \
--group-id sg-03af1891234567890 \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0

$ aws ec2 authorize-security-group-ingress \
--group-id sg-03af1891234567890 \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0

ec2 authorize-security-group-ingress コマンドは特に出力がないので、 ec2 describe-security-groups コマンドで確認してみます。

$ aws ec2 describe-security-groups \
--group-ids sg-03af1891234567890

{
    "SecurityGroups": [
        {
            "Description": "SG for michimani",
            "GroupName": "michimani-demo-sg",
            "IpPermissions": [
                {
                    "FromPort": 80,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "ToPort": 80,
                    "UserIdGroupPairs": []
                },
                {
                    "FromPort": 443,
                    "IpProtocol": "tcp",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "ToPort": 443,
                    "UserIdGroupPairs": []
                }
            ],
            "OwnerId": "123456789012",
            "GroupId": "sg-03af1891234567890",
            "IpPermissionsEgress": [
                {
                    "IpProtocol": "-1",
                    "IpRanges": [
                        {
                            "CidrIp": "0.0.0.0/0"
                        }
                    ],
                    "Ipv6Ranges": [],
                    "PrefixListIds": [],
                    "UserIdGroupPairs": []
                }
            ],
            "VpcId": "vpc-0f55f781234567890"
        }
    ]
}

インバウンドルール (IpPermissions) が追加されています。

ec2 revoke-security-group-ingress

先ほど作成したインバウンドルールを削除します。

$ aws ec2 revoke-security-group-ingress help
...
SYNOPSIS
            revoke-security-group-ingress
          [--group-id <value>]
          [--group-name <value>]
          [--ip-permissions <value>]
          [--dry-run | --no-dry-run]
          [--protocol <value>]
          [--port <value>]
          [--cidr <value>]
          [--source-group <value>]
          [--group-owner <value>]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--cli-auto-prompt <value>]
...

ここでも --group-name の扱いは同じです。

プロトコルやポート、 CIDR ブロックを指定して個別に削除することもできますが、一つ一つ削除するのは面倒です。今回は対象のセキュリグループ内のインバウンドルールをできるだけ少ないオプションで削除することを目標にしてみます。

グループ ID のみを指定

$ aws ec2 revoke-security-group-ingress \
--group-id sg-03af1891234567890

An error occurred (MissingParameter) when calling the RevokeSecurityGroupIngress operation: Missing source specification: include source security group or CIDR information

エラーになりました。どうやらグループ ID のみの指定では削除できないようです。 CIDR を含める必要があると書かれています。

グループ ID と CIDR を指定

$ aws ec2 revoke-security-group-ingress \
--group-id sg-03af1891234567890 \
--cidr 0.0.0.0/0

An error occurred (InvalidParameterValue) when calling the RevokeSecurityGroupIngress operation: Invalid value 'null' for protocol. VPC security group rules must specify protocols explicitly.

これもエラーとなりました。次は プロトコルを指定しろと書かれています。

グループ ID と CIDR とプロトコルを指定

$ aws ec2 revoke-security-group-ingress \
--group-id sg-03af1891234567890 \
--protocol tcp \
--cidr 0.0.0.0/0

An error occurred (InvalidParameterValue) when calling the RevokeSecurityGroupIngress operation: Invalid value 'Must specify both from and to ports with TCP/UDP.' for portRange.

これもエラーになりました。今度はポート (ポートレンジ) を指定する必要があるようです。…ただ、これにポートの指定を加えると、結局個別に削除するのと同じになります。

グループ ID とプロトコルとポートを指定

$ aws ec2 revoke-security-group-ingress \
--group-id sg-03af1891234567890 \
--protocol tcp \
--port 80

エラーは出ませんでしたが、確認してみるとまだインバウンドルールは残っています。

$ aws ec2 describe-security-groups \
--group-ids sg-03af1891234567890 \
--query "SecurityGroups[].IpPermissions"
[
    [
        {
            "FromPort": 80,
            "IpProtocol": "tcp",
            "IpRanges": [
                {
                    "CidrIp": "0.0.0.0/0"
                }
            ],
            "Ipv6Ranges": [],
            "PrefixListIds": [],
            "ToPort": 80,
            "UserIdGroupPairs": []
        },
        {
            "FromPort": 443,
            "IpProtocol": "tcp",
            "IpRanges": [
                {
                    "CidrIp": "0.0.0.0/0"
                }
            ],
            "Ipv6Ranges": [],
            "PrefixListIds": [],
            "ToPort": 443,
            "UserIdGroupPairs": []
        }
    ]
]

グループ ID とプロトコルとポートと CIDR を指定

$ aws ec2 revoke-security-group-ingress \
--group-id sg-03af1891234567890 \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0

$ aws ec2 describe-security-groups \
--group-ids sg-03af1891234567890 \
--query "SecurityGroups[].IpPermissions"
[
    [
        {
            "FromPort": 443,
            "IpProtocol": "tcp",
            "IpRanges": [
                {
                    "CidrIp": "0.0.0.0/0"
                }
            ],
            "Ipv6Ranges": [],
            "PrefixListIds": [],
            "ToPort": 443,
            "UserIdGroupPairs": []
        }
    ]
]

ということで、結局 グループ ID 、プロトコル、ポート、 CIDR を指定して個別に削除することになりました。

まとめ

AWS CLI を使って EC2 のセキュリティグループを操作してみた話でした。テレワーク中の問題として、自宅ネットワークの IP が頻繁に変わってしまう方もいると思います。そのたびにインバウンドルールの変更が発生してしまうと、マネジメントコンソールで作業するのは辛いので、 CLI でサクッとやってしまうのが楽ですね。

ただ、できることなら VPN 経由でアクセスするなど、頻繁にインバウンドルールを変更するのは避けたほうがいいと思いますが。


comments powered by Disqus