JSL (日本システム技研) Advent Calendar 2018 - Qiita の10日目の記事です。
モチベーション
AWSのセキュリティグループの設定を月に何回か設定し直すことがあるが、コンソール上から設定するのが面倒。インバウンドのIPアドレスの追加/削除が主な設定内容となる。これをターミナルからコマンド一発で設定したい。
最終的にやったこと
aws-cliを利用し、以下のコマンドを実行することでことでセキュリティグループの確認、設定の追加/削除が可能。
# 確認
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --query "SecurityGroups[*].{Permissions:IpPermissions}" --output table
# 追加
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --group-id sg-1234xxxx --ip-permissions IpProtocol=tcp,FromPort=3389,ToPort=3389,IpRanges='[{CidrIp=127.0.0.1/32,Description="test rule"}]'
# 削除
$ aws --profile [your-profile] ec2 revoke-security-group-ingress --group-id sg-1234xxxx --ip-permissions IpProtocol=tcp,FromPort=3389,ToPort=3389,IpRanges='[{CidrIp=127.0.0.1/32,Description="test rule"}]'
解説
上記コマンドまでの経緯及び解説。
設定する項目
ここで設定する項目は以下としておく。
タイプ | プロトコル | ポート範囲 | ソース | 説明 |
---|---|---|---|---|
SSH | TCP | 22 | 127.0.0.1 | テスト項目 |
通常、説明は英数のみしか受け付けないようになっているが、cliからだとどうなるのか?テストも兼ねる。
aws-cli
セキュリティグループはEC2に紐づくものなので、EC2に対するaws-cliのコマンドリファレンスを見る。
ec2 — AWS CLI 1.16.72 Command Reference
この辺り使えば実現できそう。
authorize-security-group-ingress — AWS CLI 1.16.72 Command Reference
revoke-security-group-ingress — AWS CLI 1.16.72 Command Reference
セキュリティグループの確認
インバウンドのルールを設定するために、設定したいセキュリティグループのグループIDが必要となるので、こちらもaws-cliで確認する。
describe-security-groups — AWS CLI 1.16.72 Command Reference
セキュリティグループの一覧を見る。
# json
$ aws --profile [your-profile] ec2 describe-security-groups --output json
# table
$ aws --profile [your-profile] ec2 describe-security-groups --output table
セキュリティグループが多い場合、上記のコマンドをそのまま叩くとかなり見づらい。そういうときは、 --query
を使うと見やすくなる。
describe-security-groups#Examples — AWS CLI 1.16.72 Command Reference
# json
$ aws --profile [your-profile] ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName,ID:GroupId}" --output json
# table
$ aws --profile [your-profile] ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName,ID:GroupId}" --output table
--------------------------------------------------------------------------------------
| DescribeSecurityGroups |
+-----------------------+------------------------------------------------------------+
| ID | Name |
+-----------------------+------------------------------------------------------------+
| sg-1234xxxx | launch-xxxxxx-x |
~~~
セキュリティグループIDはこんな感じの文字列 sg-1234xxxx
グループ詳細も見れることを確認しておく。
# json
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --output json
# table
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --output table
さらにグループのインバウンドの制限設定のみ取得してみる。
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --query "SecurityGroups[*].{Permissions:IpPermissions}" --output table
-------------------------------------------
| DescribeSecurityGroups |
|| Permissions ||
|+------------+---------------+----------+|
|| FromPort | IpProtocol | ToPort ||
|+------------+---------------+----------+|
|| 22 | tcp | 22 ||
|+------------+---------------+----------+|
||| IpRanges |||
||+---------------------+---------------+||
||| CidrIp | Description |||
||+---------------------+---------------+||
||| x.x.x.x/32 | |||
~~~
設定を追加する
グループIDが分かったので、 authorize-security-group-ingress
コマンドを使って設定を追加する。
まずはport, protocol, cidrオプションを使って設定してみる。
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --group-id sg-1234xxxx --protocol tcp --port 22 --cidr 127.0.0.1/32
確認してみる
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --query "SecurityGroups[*].{Permissions:IpPermissions}" --output table
-------------------------------------------
| DescribeSecurityGroups |
|| Permissions ||
|+------------+---------------+----------+|
|| FromPort | IpProtocol | ToPort ||
|+------------+---------------+----------+|
|| 22 | tcp | 22 ||
|+------------+---------------+----------+|
||| IpRanges |||
||+---------------------+---------------+||
||| CidrIp | Description |||
||+---------------------+---------------+||
~~~
||| 127.0.0.1/32 | |||
||+---------------------+---------------+||
追加されているのでよさそう。
消しておく。
$ aws --profile [your-profile] ec2 revoke-security-group-ingress --group-id sg-1234xxxx --protocol tcp --port 22 --cidr 127.0.0.1/32
次にdescriptionありの場合で追加してみる。
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --group-id sg-1234xxxx --protocol tcp --port 22 --cidr 127.0.0.1/32 --description 'test'
Unknown options: --description, test
--description
オプションはないっぽい。
リファレンスみると --ip-permissions
にリストを渡すことで実現できそうなので試してみる。
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --group-id sg-1234xxxx --ip-permissions IpProtocol=tcp,FromPort=22,ToPort=22,IpRanges='[{CidrIp=127.0.0.1/32,Description="test rule"}]'
確認してみる。
$ aws --profile [your-profile] ec2 describe-security-groups --group-id sg-1234xxxx --query "SecurityGroups[*].{Permissions:IpPermissions}" --output table
-------------------------------------------
| DescribeSecurityGroups |
|| Permissions ||
|+------------+---------------+----------+|
|| FromPort | IpProtocol | ToPort ||
|+------------+---------------+----------+|
|| 22 | tcp | 22 ||
|+------------+---------------+----------+|
||| IpRanges |||
||+---------------------+---------------+||
||| CidrIp | Description |||
||+---------------------+---------------+||
~~~
||| 127.0.0.1/32 | test rule |||
||+---------------------+---------------+||
さらに日本語でもうまくいくのか試してみる。
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --group-id sg-1234xxxx --ip-permissions IpProtocol=tcp,FromPort=3389,ToPort=3389,IpRanges='[{CidrIp=127.0.0.1/32,Description="テスト項目"}]'
An error occurred (InvalidParameterValue) when calling the AuthorizeSecurityGroupIngress operation: Invalid rule description. Valid descriptions are strings less than 256 characters from the following set: a-zA-Z0-9. _-:/()#,@[]+=&;{}!$*
だめだった・・
なお、 --dry-run
オプションを使うと実際にコマンドを実行することなく、コマンドが実行可能かを返してくれる。
$ aws --profile [your-profile] ec2 authorize-security-group-ingress --dry-run --group-id sg-1234xxxx
An error occurred (DryRunOperation) when calling the AuthorizeSecurityGroupIngress operation: Request would have succeeded, but DryRun flag is set.
おまけ
実際は現在のグローバルIPをインバウンドに追加するというケースが多いと思う。
以下のグローバルIPを確認するサイトを覚えておくと便利。
[グローバルIP] で検索するとトップに出てくるのは前者だが、後者のほうはAPIがあるのでプログラミング的に便利。curl等でGETリクエストを送ると、現在のグローバルIPが返ってくる。
$ curl ifconfig.io
x.x.x.x