0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【図解】AWSセキュリティグループとは。繋がらない原因と許可の書き方まとめ

0
Posted at

対象読者: AWSをこれから触る人。 AWS勉強シリーズの番外編で、EC2とVPCの回で駆け足だったセキュリティグループだけを1本にしました。全体の地図は索引記事にあります。

EC2を立てた人が最初に踏む、この2つの症状で書きます。

  • 「サーバーは動いているのに、ブラウザからもSSHからも繋がらない」
  • 「インバウンドとアウトバウンド、どっちに何を書けばいいのか分からない」

どちらも「警備員は通したいものだけをリストに書く。戻りは確認しない」の2点で答えが出ます。

セキュリティグループは、ドアの警備員。許可リストに無い人は全員お断り
セキュリティグループを警備員に例えた図(筆者作成)。443の人は通る、8080の人は止まる。リストに無い=お断り、が既定です。

セキュリティグループとは何か

セキュリティグループ(SG)は、EC2などのサーバー1台ずつに付ける通信の許可リストです。上の図の警備員で、ドアの前に立って「どのポートに、どこから来た通信を通すか」だけを見ています。

大事な性質が2つあります。

  1. 許可しか書けない。 「8080は拒否」という行は存在しない。書かれていないものが全部拒否される(実測: 作った直後のインバウンドは空っぽ=全部お断り)
  2. サーバー単位で付く。 部屋(サブネット)の入口ではなく、サーバーのすぐ横に立つ警備員

警備員はどこに立つか

VPCの回のマンションで言うと、こうなります。

セキュリティグループはサーバー1台ずつに付く。サブネットの入口はネットワークACL
配置の図(筆者作成)。SGは机(EC2)ごと、ネットワークACLは部屋(サブネット)の入口。入門ではSGだけ触れば足ります。

「VPCで守ってるのにSGも要るの?」の答えがこの図で、VPCの案内板(ルートテーブル)は道を決め、SGはドアを決めます。道が繋がっていてもドアが閉まっていれば入れない。冒頭の「動いているのに繋がらない」の大半は、道は合っているのにドア(SG)が閉まっているケースです。

今はこれだけ分かればOK

必須の3語 意味
インバウンドルール 入ってくる通信の許可リスト。作った直後は空(全部拒否)
アウトバウンドルール 出ていく通信の許可リスト。既定で全許可の行が1本入っている
ソース 「どこから来た通信か」。IPの範囲(CIDR)か、別のSGのIDが書ける

ネットワークACL、ステートレスの詳細は後回しで大丈夫です。

仕組みの要点。戻りは書かなくていい

初心者が一番混乱するのがここです。「443を許可したら、応答を返すためにアウトバウンドも書くの?」。書きません。

行きを許可すれば、戻りは自動で通る。戻りの通信はリストに書かなくていい
ステートフルの図(筆者作成)。行きを通した相手の戻りを、警備員はいちいち確認しません。

SGはステートフル(状態を覚える)で、「行き」を通した通信の「戻り」は自動で通します。だからWebサーバーのSGは「インバウンドに443」だけで動く。逆に、既定のアウトバウンド全許可を消して絞り込む運用は、この自動通過と混同しやすいので、入門の段階では触らないのが安全です。

このコードを動かす前提

この記事のコードはPython(boto3)です。動かす方法は2通りあります。

A. AWSアカウント無しで試す(おすすめ): motoというAWSのそっくりさんを使うと、課金もサインアップもなしでPCの中だけで動きます。

python3 -m venv venv
./venv/bin/pip install boto3 moto
from moto import mock_aws

@mock_aws            # この中のboto3呼び出しは全部ローカルの偽AWSに行く
def main() -> None:
    ...              # 以下の記事のコードをここに入れる

main()

B. 本物のAWSで動かす: 先にIAMユーザーとアクセスキーの設定が要ります。手順はIAM記事の「最初の1回だけやる手順」にあります。

使い方

「雇う→リストに足す→別の警備員を信用する→行を消す」の4手です。

import boto3
ec2 = boto3.client("ec2", region_name="ap-northeast-1")
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")["Vpc"]["VpcId"]

# ① 警備員を雇う(SGを作る)。この時点でインバウンドは空
sg = ec2.create_security_group(GroupName="web", Description="web server", VpcId=vpc)["GroupId"]

# ② 許可リストに2行足す。443は誰でも、22は自分のIPだけ
ec2.authorize_security_group_ingress(GroupId=sg, IpPermissions=[
    {"IpProtocol": "tcp", "FromPort": 443, "ToPort": 443,
     "IpRanges": [{"CidrIp": "0.0.0.0/0", "Description": "https"}]},
    {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
     "IpRanges": [{"CidrIp": "203.0.113.5/32", "Description": "my ip"}]}])

# ③ DB用のSGは「webのSGから来た通信だけ」を許可(IPでなくSGをソースに)
db = ec2.create_security_group(GroupName="db", Description="db", VpcId=vpc)["GroupId"]
ec2.authorize_security_group_ingress(GroupId=db, IpPermissions=[
    {"IpProtocol": "tcp", "FromPort": 3306, "ToPort": 3306,
     "UserIdGroupPairs": [{"GroupId": sg, "Description": "from web sg"}]}])

# ④ 使い終わった行は消す(22を閉じる)
ec2.revoke_security_group_ingress(GroupId=sg, IpPermissions=[
    {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22,
     "IpRanges": [{"CidrIp": "203.0.113.5/32"}]}])

実測の出力です。

作った直後のインバウンド: []                       ← 空=全部拒否
作った直後のアウトバウンド: [('-1', ['0.0.0.0/0'])]  ← 全許可が1本
追加後: [(443, ['0.0.0.0/0']), (22, ['203.0.113.5/32'])]
db SGのソース: sg-9af59f4c... (webのSG-ID)
22削除後: [(443, ['0.0.0.0/0'])]

③が実務の定番です。DBの警備員に「webの警備員が付いているサーバーから来た通信だけ通せ」と書く。webサーバーが増えてIPが変わっても、リストを書き換えなくていい。ソースにIPでなくSGを書くのがAWS流の設計です。

実際に叩くと止まるところ

間違えたときに何が返るか、実際に叩きました。

やったこと 返ってきたエラー 意味
同じ許可を二重に追加 InvalidPermission.Duplicate: The specified rule already exists 冪等ではない。スクリプトで流し直す時は先にdescribeで確認
無い許可を削除 InvalidPermission.NotFound 消す行の指定は追加時と完全一致が必要。ポートやCIDRが1文字違うとこれ
同名SGを再作成 InvalidGroup.Duplicate SG名は同じVPC内で一意
defaultのSGを削除 motoでは通ってしまった 本物のAWSでは削除できない(CannotDelete)。motoの再現漏れなので、ローカルで消せても本番で同じことはできません

似た概念との使い分け

迷うところ 答え
SGとネットワークACL SGはサーバー単位・許可のみ・戻り自動。ACLはサブネット単位・許可と拒否・戻りも書く。入門はSGだけでいい
SGとIAM IAMは「誰がAWSの操作をしていいか」、SGは「どの通信がサーバーに届いていいか」。EC2記事の権限3方向の話
22を0.0.0.0/0で開けたい 開けない。SSHは自分のIP(/32)に絞る。全開放のSSHは攻撃の総当たりが即座に来る

料金の考え方

セキュリティグループは無料です。何個作っても、ルールを何行書いても課金されません。既定の上限(インバウンド・アウトバウンド各60ルール。引き上げ可)はありますが、入門で当たることはまずありません。

よくある注意点

  • 「繋がらない」の確認順は、SGの前にまずIP。 EC2記事の確認順の通り、パブリックIPの有無→SGの順で見る
  • SGの変更は即時反映。 再起動は要らない。443を追加した瞬間から通る
  • 1台に複数のSGを付けられる。 全部のリストの合算(和集合)で判定される。「どのSGで開いてるのか分からない」を避けるため、入門のうちは1台1SGが読みやすい
  • 消す時は使われていないことを確認。 EC2にアタッチされたままのSGは消せない(DependencyViolation)。VPC記事の削除順の話

まとめ

冒頭の2つの症状に戻ります。

  • 「動いているのに繋がらない」→ 作った直後のインバウンドは空です(実測の通り)。道(ルートテーブル)が合っていても、ドアの許可リストに行が無ければ届きません。使うポートを足してください
  • 「インバウンドとアウトバウンド、どっち?」→ 入門ではインバウンドだけ書けば足ります。戻りの通信はステートフルで自動、アウトバウンドは既定で全許可のままにしておく

警備員のリストは「通したい行だけを書く。書いた瞬間に効く。戻りは書かない」。この3行で、SGの日常運用はだいたい説明できます。

次回はCloudFormation(インフラのコード化)を予定しています。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?