【AWS】セキュリティグループのソースに SG ID を指定するメリットと設定方法

AWS

最初見たとき「は?」ってなった

AWS のセキュリティグループのインバウンドルールを設定するとき、ソース(送信元)の欄には普通 IP アドレスを入れますよね。0.0.0.0/0 とか 10.0.1.0/24 とか。

でもある日、他のチームが作った設定を見ていたら、ソースの欄に IPアドレスではなくセキュリティグループのIDっぽいもの(sg-0123456789abcdef0 みたいなやつ)が入っていました。

正直、最初は意味がわかりませんでした。

「セキュリティグループのソースにセキュリティグループ……? グループがグループを参照してるってどういうこと?」と、しばらく画面を見つめていた記憶があります。

結論:セキュリティグループは「そのSGがアタッチされているインスタンス全部」を指す

調べてみると、そんなに難しい話ではありませんでした。

セキュリティグループのソースに別のセキュリティグループを指定すると、それは「そのセキュリティグループがアタッチされているすべてのリソース」を送信元として許可する、という意味になります。

つまり、IP アドレスの代わりに 「そのSGが付いているインスタンスかどうか」でフィルタしているということです。

具体的にイメージするとこうなります。

[App-SG] というセキュリティグループがアタッチされたEC2インスタンスが 3台ある
→ app-server-1 (10.0.1.10)
→ app-server-2 (10.0.1.20)
→ app-server-3 (10.0.1.30)

[DB-SG] のインバウンドルールで、ソースを [App-SG] に設定する
→ app-server-1, 2, 3 からの接続だけが許可される
→ IPアドレスは一切書いていない

app-server が増えても減っても、IPアドレスが変わっても、DB-SG のルールは一切変更する必要がないというのがポイントです。

なんでこれが「便利やん」ってなったのか

実際に使ってみて「あ、これ地味にありがたいな」と感じたポイントをまとめます。

1. オートスケーリングと相性が良すぎる

Auto Scaling グループでインスタンスが増減する環境だと、IPアドレスは常に変動します。IPベースでルールを組んでいたら、インスタンスが増えるたびにセキュリティグループを手動で更新する羽目になります。

でもソースをセキュリティグループにしておけば、新しく起動したインスタンスに同じSGがアタッチされてさえいれば、ルールは自動的に適用されます。IPアドレスの変動を一切気にしなくていい、というのはかなり大きいです。

2. IPアドレスの管理から解放される

「このサーバー、IPアドレス変わったからセキュリティグループの設定も直さなきゃ」みたいな作業が発生しません。サーバーを再作成しても、同じSGを付ける限り通信は許可されたままです。

インフラを触っていると、地味にこの「IPアドレス管理」がストレスだったりするので、これがなくなるだけで運用がだいぶ楽になります。

3. 「役割」で通信を許可する設計になる

IPベースの設定だと「このIPからの通信を許可する」という書き方になりますが、SGベースだと「Appサーバーからの通信を許可する」という書き方になります。

これは地味に大きな違いで、インフラの構成が変わってもルールの意味が崩れません。IPアドレスは環境によって変わりますが、「役割」は変わらないからです。設定を見返したときの可読性も上がります。

# IPベースの設定(読んでも何のための許可かわからない)
Source: 10.0.1.0/24

# SGベースの設定(意図が読み取れる)
Source: app-server-sg(Appサーバーからの通信を許可)

4. VPC内で完結していれば同一VPC内どこからでも参照できる

同じVPC内であれば、サブネットをまたいでいてもセキュリティグループを参照できます。「同じサブネットにいないと使えないんじゃないか」と最初思っていましたが、そんなことはありませんでした。

実際の設定例

3層構成(ALB → Appサーバー → RDS)を例に、セキュリティグループ同士の参照関係を組んでみます。

構成イメージ

[Internet]
↓
[ALB] (alb-sg)
↓
[App サーバー] (app-sg)
↓
[RDS] (db-sg)

ALB用セキュリティグループ(alb-sg)

インターネットからの HTTPS のみ許可します。ここは通常通り IP ベースです。

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

App サーバー用セキュリティグループ(app-sg)

ソースは IP ではなく、ALB のセキュリティグループを指定します。

aws ec2 authorize-security-group-ingress \
  --group-id sg-app0123456789abc \
  --protocol tcp \
  --port 8080 \
  --source-group sg-alb0123456789abc

これで「ALBにアタッチされているリソースからの通信だけ」を許可できます。ALBのIPアドレスは変動することがありますが、気にする必要は一切ありません。

RDS用セキュリティグループ(db-sg)

同様に、ソースを App サーバーのセキュリティグループ にします。

aws ec2 authorize-security-group-ingress \
  --group-id sg-db0123456789abc \
  --protocol tcp \
  --port 3306 \
  --source-group sg-app0123456789abc

これで、App サーバーが何台に増えても、IPアドレスが何であっても、「app-sg がついているインスタンスからの接続だけ」を DB が受け付ける状態になります。

確認コマンド

設定した内容は以下で確認できます。

aws ec2 describe-security-groups \
  --group-ids sg-db0123456789abc \
  --query 'SecurityGroups[0].IpPermissions'

出力の UserIdGroupPairs にソースとして指定したセキュリティグループのIDが表示されていれば設定完了です。

{
  "IpProtocol": "tcp",
  "FromPort": 3306,
  "ToPort": 3306,
  "UserIdGroupPairs": [
    {
      "GroupId": "sg-app0123456789abc",
      "Description": ""
    }
  ]
}

使うときにちょっと気をつけたいこと

便利な反面、いくつか注意点もあります。

別アカウントのSGを参照する場合はアカウントIDの指定が必要

同一アカウント内であれば単純にSG IDだけで参照できますが、別アカウントのセキュリティグループを参照する場合は –source-group に加えてオーナーのアカウントIDを指定する必要があります。

参照先のSGが削除されるとルールが機能しなくなる

参照しているセキュリティグループそのものが削除されると、そのルールは実質意味をなさなくなります。「このSGは他から参照されているから安易に消せない」という依存関係が見えにくくなりがちなので、命名規則やドキュメントで管理しておくと安心です。

ルールの意図が伝わりにくくなることもある

慣れていないメンバーが見ると、今回の自分のように「セキュリティグループがソースに入っている……?」と一瞬固まる可能性があります。チームに導入する際は、一言説明を添えておくと親切です(この記事のリンクを送りつけるのも手です)。

まとめ

セキュリティグループのソースにセキュリティグループを指定する設定は、初見だと「何をしているのか」がパッとイメージしづらいものの、実際に使ってみると

  • IPアドレスの変動を一切気にしなくていい
  • オートスケーリング環境と相性が良い
  • 「役割」ベースでルールが書けて可読性が上がる

という、地味だけど確実にありがたい機能でした。IPベースでセキュリティグループを組んでいる環境があれば、一度SG参照への置き換えを検討してみる価値は十分にあると思います。


参考リンク