1.はじめに
皆さん、こんにちは!
唐突ですが、AWSは使っていますでしょうか?
普段から使っている方なら、まず触らないことは無いであろうEC2。
そしてEC2から切っても切り離せないもの・・・それが『セキュリティグループ 』です。
インバウンド、そしてアウトバウンドのルールを設定することによって文字通りセキュリティ面を強化 (もしくは緩和)させるものになっています。
・・・この図解いる???(※いらない)
こんなセキュリティグループですが、一度設定した後も、状況によっては変更が必要になってきます。
しかし組織やサービスの規模が大きくなればなるほど、設定変更の手間は計り知れません。
AWSコンソールにログイン、EC2、セキュリティグループ、該当のセキュリティーグループを検索、インバウンド変更、アウトバンドを変更、そしたらまたセキュリティグループの検索に戻り・・・・・・
わーーー!!やってられるか!!!><💦
はい、とても大変ですね。
でも、そんな設定変更が一括で行える方法 があったとしたら・・・?
今回はそんな話をしたいと思います。
(※注意)
今回はあくまで方法について調べたものを共有する記事になっています。
本当は実際にAWSコンソール触ってキャプチャもバンバン貼りたかったんですが、組織の都合で権限が与えられませんでした・・・;;
そのうち触れるようになると思うので、実際に動かせたら【実践編】みたいな記事も書こうと思います!
2.作業の準備
まず、今回の作業を行うにあたって、前提条件があります。
前提条件
- AWSのアカウントがあること
- EC2を作成し、必要な権限(IAMロール)が付与されていること
- サーバーに接続するために最低限必要なインバウンド、アウトバンドのルールが設定されていること
- puttyが使用可能であり、キーペアのファイルを持っていること
ちょっと解説します。
-
EC2を作成し、必要な権限(IAMロール)が付与されていること
→既存のポリシーを利用するのであれば『AmazonEC2FullAccess』があれば大丈夫です。
ただ、これはEC2に関するすべての操作を許可するポリシーですので、最小権限で許可したい場合は
AWSコンソールから『IAM』に移動し、『ポリシー』へ移動した後『ポリシーの作成』をクリックしてください。
JSONタブを選択し、中身に以下の内容を貼り付けしてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeTags",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress"
],
"Resource": "*"
}
]
}
貼り付けが終わったら、ポリシー名を『SecurityGroupManagementPolicy』にして保存します。
そしたら、既にEC2に付与されているロールにポリシーを追加します。
何もついていない場合は『SecurityGroupManagementPolicy』を含んだIAMロールを作成し、EC2にアタッチしてみてください!
-
サーバーに接続するために最低限必要なインバウンド、アウトバンドのルールが設定されていること
→今回はputtyを使用したSSH接続をする方法でいきます。
具体的に
《インバウンドルール》
プロトコル | ポート | 送信元 |
---|---|---|
TCP | 22 (SSH) | 接続元のIPアドレス |
※接続元のIPアドレスは、『マイIP』を選ぶと、自動で今接続してるIPが入ります。
《アウトバンドルール》
プロトコル | ポート | 送信元 |
---|---|---|
TCP | 全て (または少なくとも443) | 0.0.0.0/0 (全て) |
上記の2つが設定されていれば今回の作業は可能です。
(まあ、実際のサービスで動いているEC2なら、こんなに少ないことはあり得ないと思いますが笑)
-
puttyが使用可能であり、キーペアのファイルを持っていること
→puttyを持っていない方に関しては、偉大なる先駆者様がputtyを入手する記事を作ってくださっているので、こちらを参考にインストール、設定をしましょう。
https://qiita.com/e__ri/items/7827aee9ce51a3f5236b
キーペアのファイルというのは、EC2を作成した時にダウンロードでしたであろう、EC2インスタンスに安全にSSH接続するために使用される認証ファイルのことです。
今回は .ppkの形式であることを想定しています。
・・・というか、.ppkしかやったことないから分からないにゃあ(´◕ω◕`) ←おい
3.作業スタート! - サーバーに接続してみよう!
さて、さっそく作業したいところですが、まずは今回のシナリオを仮定しましょう。
【今回のシナリオ】
今回は対象のVPC『OKAIMONO-VPC』に属している、5つのセキュリティグループの設定を一括で変更する。
対象VPC |
---|
OKAIMONO-VPC |
対象セキュリティグループ |
---|
AKUSESU-SG |
MIRU-SG |
ERABU-SG |
KAU-SG |
TANOSII-SG |
【設定変更内容】
インバウンドルールに192.0.2.0/24を追加する。
※このIPアドレスは実際に使われることのないIPアドレスです。
安心して設定にぶち込んじゃってください(*^ー゚)b グッ
事前準備ができたら、さっそくスタートしましょう!
まずはputtyを開き、以下の赤枠の部分にEC2の『パブリックIPアドレス』を入力します。
(EC2インスタンスのインスタンスIDをクリックすると詳細画面が開くので、そこに書いてあるよ~)
接続タイプは『SSH』を選択してください。
そしたら、左の『カテゴリ』から『接続』→『SSH』→『認証』→『クレデンシャル』の順に開いていきます。
すると秘密鍵を入力する欄がありますので、ここに『キーペアのファイルが置いてある場所』を入力(もしくは参照して選択)します。
ここまでできたら、下の『開く』を押せばサーバーに接続できます!
恐らく背景が黒い画面が出てきたと思います。
それでは、まず最初に以下のコマンドを入力してみましょう。
ec2-user
少し待機時間があった後、EC2ユーザーでログインができたかと思います。
ここでもう1つコマンドをぶちこんでやりましょう!
sudo su
これは、『管理者権限になる』ためのコマンドです。
一般ユーザーだと実行できない内容があったりするので、管理者権限になっています。
図解するならこんな感じでしょうか。
・・・いや、だからこの図解いr
4.作業スタート! - 対象のセキュリティーグループを探してみよう!
管理者権限で入ったら、まずは作業用フォルダ(sg-update-project)を作成します。
mkdir sg-update-project
この時、画面には何も新しい表示がされません。それで正常です。
次に移管のコードを入力して、作った作業用フォルダに移動します。
cd sg-update-project
このコードを入力すると、恐らく以下のような表示になっているはずです。
(※以下スクショは入力するコードじゃないよ!)
さて、次はOKAIMONO-VPCに属するセキュリティグループの情報を取得していきます。
以下コードを入力してください。
aws ec2 describe-vpcs --filters "Name=tag:Name,Values=OKAIMONO-VPC" --query "Vpcs[0].VpcId" --output text
このコマンドを入力すると、OKAIMONO-VPCのIDが表示されます。
(今回はvpc-0a1b2c3d4e5f67890というIDが出力されたと仮定します。)
次に、このVPC内のセキュリティグループを確認します。
以下コードを入力してください。
※VPCのIDは実際のIDと入れ替えてね!
aws ec2 describe-security-groups \
--filters "Name=vpc-id,Values=vpc-0a1b2c3d4e5f67890" \
--query "SecurityGroups[?contains(['AKUSESU-SG','MIRU-SG','ERABU-SG','KAU-SG','TANOSII-SG'], GroupName)].[GroupId,GroupName]" \
--output table
このコマンドを実行すると、以下のような表形式でセキュリティグループのIDと名前が表示されるはずです。
(※以下スクショは入力しないでね!)
ここで表示された、セキュリティグループのIDをメモで残しておいてください!
5.作業スタート! - CSVファイルを作成しよう!
次に、セキュリティグループの変更内容を記載したCSVファイルを作成します。
以下コードを入力してください。
nano sg-changes.csv
このコマンドを実行すると、nanoエディタが開き、以下のような画面が表示されます。
(※以下スクショは入力しないでね!)
ここで、以下の内容を入力します。「sg-123abc456def」などの部分は、先ほど表示されたセキュリティグループのIDに置き換えてくださいね。
SecurityGroupId,操作,ルールタイプ,IPプロトコル,ポート範囲,送信元/送信先,説明
sg-123abc456def,add,ingress,tcp,全て,192.0.2.0/24,新規アクセス許可
sg-456def789ghi,add,ingress,tcp,全て,192.0.2.0/24,新規アクセス許可
sg-789ghi012jkl,add,ingress,tcp,全て,192.0.2.0/24,新規アクセス許可
sg-012jkl345mno,add,ingress,tcp,全て,192.0.2.0/24,新規アクセス許可
sg-345mno678pqr,add,ingress,tcp,全て,192.0.2.0/24,新規アクセス許可
入力が完了したら、キーボードで「Ctrl + O」を押します。
すると画面の下部に以下のメッセージが表示されます。
(※以下スクショは入力しないでね!)
Enterキーを押して保存を確定します。
そして「Ctrl + X」を押してnanoエディタを終了します。
これでCSVファイルの作成が完了です!
6.作業スタート! - Pythonスクリプトを作成しよう!
次に、セキュリティグループを変更するPythonスクリプトを作成します。
nano update_sg.py
このコマンドを実行すると、再びnanoエディタが開きます。以下のコードを入力してください
#!/usr/bin/env python3
import boto3
import csv
import sys
def update_security_groups(csv_file):
ec2 = boto3.client('ec2')
print(f"CSVファイル {csv_file} から設定を読み込みます...")
# CSVファイルを読み込む
with open(csv_file, 'r') as file:
reader = csv.DictReader(file)
for row in reader:
sg_id = row['SecurityGroupId']
operation = row['操作']
rule_type = row['ルールタイプ']
protocol = row['IPプロトコル']
port_range = row['ポート範囲']
cidr = row['送信元/送信先']
description = row['説明']
# セキュリティグループ名を取得
response = ec2.describe_security_groups(GroupIds=[sg_id])
sg_name = response['SecurityGroups'][0]['GroupName']
print(f"セキュリティグループ {sg_name}({sg_id}) を処理中...")
# ポート範囲の処理
if port_range == '全て':
from_port = -1
to_port = -1
protocol = '-1' # すべてのプロトコル
print(f" 「全て」のポートとプロトコルを設定します")
elif '-' in port_range:
from_port, to_port = map(int, port_range.split('-'))
else:
try:
from_port = to_port = int(port_range)
except ValueError:
print(f" エラー: ポート範囲「{port_range}」は数値に変換できません。処理をスキップします。")
continue
try:
# インバウンドルールの追加
if operation == 'add' and rule_type == 'ingress':
print(f" インバウンドルールを追加: {protocol} ポート {port_range} 送信元 {cidr}")
ec2.authorize_security_group_ingress(
GroupId=sg_id,
IpPermissions=[{
'IpProtocol': protocol,
'FromPort': from_port,
'ToPort': to_port,
'IpRanges': [{'CidrIp': cidr, 'Description': description}]
}]
)
print(f" ✅ {sg_name} にルールを追加しました!")
# アウトバウンドルールの追加
elif operation == 'add' and rule_type == 'egress':
print(f" アウトバウンドルールを追加: {protocol} ポート {port_range} 送信先 {cidr}")
ec2.authorize_security_group_egress(
GroupId=sg_id,
IpPermissions=[{
'IpProtocol': protocol,
'FromPort': from_port,
'ToPort': to_port,
'IpRanges': [{'CidrIp': cidr, 'Description': description}]
}]
)
print(f" ✅ {sg_name} にルールを追加しました!")
except Exception as e:
print(f" ❌ エラー発生: {e}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("使用法: python update_sg.py <CSVファイル名>")
sys.exit(1)
update_security_groups(sys.argv[1])
print("セキュリティグループの更新が完了しました!")
すべてのコードを入力したら、「Ctrl + O」を押して保存します。
ファイル名を確認するメッセージが表示されるので、Enterキーを押して確定します。
そして「Ctrl + X」を押してエディタを終了します。
6.作業スタート! - Pythonスクリプトを実行しよう!
よし!いよいよセキュリティグループの設定を変更していきますよー!
python3 update_sg.py sg-changes.csv
このコマンドを実行すると、以下のような出力が表示されます。
(※以下スクショは入力しないでね!)
この出力は、各セキュリティグループに対するルールの追加処理が成功したよー!
と言っています。
もし「Rule already exists(ルールはすでに存在します)」という出力になった場合は、すでに同じルールが存在していることを意味しています。
・・・あれ、もう設定変更できちゃった!?
実際に変更できているか確認してみましょう✨
7.変更結果を確認しよう!
まず、OKAIMONO-VPCのIDを取得します。
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=tag:Name,Values=OKAIMONO-VPC" --query "Vpcs[0].VpcId" --output text)
echo $VPC_ID
このコマンドを実行すると、以下のようにVPC IDが表示されます。
(※以下スクショは入力しないでね!)
次に、セキュリティグループの設定を確認します。
aws ec2 describe-security-groups \
--filters "Name=vpc-id,Values=$VPC_ID" "Name=group-name,Values=AKUSESU-SG,MIRU-SG,ERABU-SG,KAU-SG,TANOSII-SG" \
--query "SecurityGroups[].[GroupName,GroupId,IpPermissions[?contains(IpRanges[].CidrIp, '192.0.2.0/24')]]" \
--output table
このコマンドを実行すると、以下のような表形式で結果が表示されます。
(※以下スクショは入力しないでね!)
はい、右の方に注目~!
[{CidrIp=192.0.2.0/24}]}]
という出力がされましたね。
これで設定が追加されたということです。
やりましたね!おめでとうございます!!
ᐠ( ᐛ )ᐟヤッタアアアアアアアアアアアア
8.最後に
皆さん、お疲れ様でした!
そして、ここまで読んでくださりありがとうございました。
今回行った手順では前準備も必要ですし、変更手順も多く大変だと感じた方もいらっしゃるかもしれません。
実際、5つのセキュリティグループの設定を変更するには割に合わない。そう感じるのは当たり前です。
しかし、変更対象が10個だったら?20個だったら??50個だったら・・・
そう考えると、この方法も知っておいて損はないかもしれません。
そして繰り返しになりますが、今回の手順はあくまで実際行ったキャプチャではないので、そのうち権限が割り振られたら自分でも実行してみたいですね。
それでは皆さん、またお会いする日まで健康にはお気をつけて(❁ᴗ͈ˬᴗ͈)ペコリ