AWS セキュリティグループのオレオレ設定ポリシー

# AWS セキュリティグループ
```
セキュリティグループは、1 つ以上のインスタンスのトラフィックを制御する仮想ファイアウォールとして機能します。インスタンスを起動するときに、1 つ以上のセキュリティグループとインスタンスを関連付けます。各セキュリティグループに対してルールを追加し、関連付けられたインスタンスに対するトラフィックを許可します。セキュリティグループルールはいつでも変更できます。新しいルールは、セキュリティグループに関連付けられているインスタンスすべてに自動的に適用されます。インスタンスに到達できるトラフィックを許可するかどうかの判断では、インスタンスに関連付けられているすべてのセキュリティグループのすべてのルールが評価されます。
```
by AWS

要するにファイアウォール。

# あるある事例

##同じ様なポリシーが乱立
AWS担当者が一人の場合にはあまり起こらないが、複数人で設定を行うと同じ様な設定が複数個作られる。特にたちが悪いのは微妙に異なるけど同じ様な役割の設定が乱立する事。
##何の設定だったか忘れる
長い事運用していると、または、担当者が変わるとこれ何の設定だっけ？と思う事がある。グループに名前をつけられるので意識高めな運用者であれば名前をしっかりつけてはくれるが、例えば一つのグループに複数のIPが登録されている場合、それぞれが何のIPだったかを覚えておくのは至難の技。
<font color=red>AWSさん、設定の一行一行にコメントが付けたいです！！！</font>
## 依存関係が複雑になっている
あちらを消すとこちらも消える状態。逆にこちらに入れるとあちらにも入る状態。
## 古い設定が置き去りになっている
誰これ？というやつがたまにいる。
## 総じて変えるのが怖い
ネットワークが問答無用で切られるので、知らなかったではすまないのがセキュリティグループ。
逆に、本来は閉じておかないといけない通信を空けてしまっていてセキュリティホールになる事もある。
変えるのが怖い！

# オレオレ設定ポリシー
それでもチームで共通のポリシーを持っていればもっとまともに運用出来るんじゃないかと思い、考えてみた。
ちなみに、不必要な穴はあけないといった初歩的な部分は当たり前の物とする。

## ポリシー① 一つのセキュリティグループに対して持たせる役割を一つにする。
例えば、apache + mysqlみたいなサーバーにこんな設定をしがち。

<b>セキュリティグループ1</b>

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|MySQL|TCP|3306|xxx.xxx.xxx.xxx|
|HTTP|TCP|80|xxx.xxx.xxx.xxx|

まあ、これで設定は問題ないんだけど、次にapacheだけのサーバーを立てた時に、上記セキュリティグループ1を設定するか、新しく次の様なグループを作るか、で悩む。

<b>セキュリティグループ2</b>

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|HTTP|TCP|80|xxx.xxx.xxx.xxx|

で、本ポリシーでは両方とも不正解。
一つのセキュリティグループで持たせる役割は一つとするので、以下の二つのグループをそれぞれ作って、必要な物をアサインするようにしてあげる。

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|MySQL|TCP|3306|xxx.xxx.xxx.xxx|

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|HTTP|TCP|80|xxx.xxx.xxx.xxx|

こうする事により、無駄無く重複無く、が実現する。後々の修正も楽になる。
<font color=red>セキュリティグループの数が増えていく事は大きな問題ではなく、無駄や重複が生じるのが一番大きな問題。</font>

## ポリシー ② 同じ設定に出来る物はまとめる

例えばサービスAとサービスBが同じVPC内にある場合に、それぞれのWEBサーバーがいるとして全く同じACLで、以下のように違うセキュリティグループを用意する必要は無い。

<b>サービスA用セキュリティグループ</b>

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|HTTP|TCP|80|xxx.xxx.xxx.xxx|

<b>サービスB用セキュリティグループ(Aと同じ)</b>

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|HTTP|TCP|80|xxx.xxx.xxx.xxx|

この場合には、#{vpc_name}_common_http などという名前で一つセキュリティグループを作り、これをAにもBにもアサインしておけば良い。commonという名前がついているのでこれをいじると別のサービスにも影響がある事はすぐに分かる。
大抵この運用で問題ないケースが多い。
一つのサービスだけ特別に設定を変えたい、となった時に始めて新セキュリティグループを作るようにする。

## ポリシー ③ Protocolが同じ物は設定をまとめても良い
複数のオフィスがあって、それぞれのIPからsshを許可したい場合がある。この場合には、一つのセキュリティグループに複数のIPをまとめて書いておく方がスッキリする。感覚的にはProtocolが同じ物であればまとめておいてもあまり不自由な事は起きないと思う。ただし、各行ごとにコメントが書けないのでIPが何を指しているのかは適切に保存しておく必要がある。

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|SSH|TCP|22|xxx.xxx.xxx.xxx|
|SSH|TCP|22|yyy.yyy.yyy.yyy|
|SSH|TCP|22|zzz.zzz.zzz.zzz|

## ポリシー ④ Protocolが同じでも役割が明確に異なる物は分ける

例えば以下のケース
xxx.xxx.xxxはオフィスのIP、とする。10.0.0.0/16はVPC内のIP。

|Type|Protocol|Port Range|Source|
|:-:|:-:|:-:|:-:|
|SSH|TCP|22|xxx.xxx.xxx.xxx|
|SSH|TCP|22|10.0.0.0/16|

このケースは明確に役割が異なる。おそらく前者はオフィスからアクセスされるGatewayの様な特別なサーバーにだけ設定される物で、後者はVPC内でsshされる可能性のある全サーバーに設定されるものとなる。
このセットのまま運用をすると、意図せずオフィスからアクセス出来てしまうサーバーが増えてしまう事になりかねない。

このように明確に役割や適用範囲が異なる場合にはProtocolが同じでも別ポリシーにする方が良い。

## ポリシー ⑤ なるべく名前を詳細につける
<font color=red>特にしっかり名前をつけておいた方が良いのは一時的に設定をしておくもの。</font>

temporary_#{vpc_name}_#{role}_#{name}_#{date} くらい付けておけばまあ大丈夫。
 
temporary_staging_access-from-office_kenjiszk_20151001

な感じで。
絶対放置されるので、作った人の名前をつけておく。
日付もつけておくとどのくらい放置されているのか一目瞭然でなお良し。

## ポリシー ⑥ 定期的な棚卸し
結局これは必要。
awsのapiを使って何らかの監視をしかけておくのも効果的。気が向いたら作る。もうそんなツールあるのかも。

# まとめ
最終的にはチームでしっかり運用しようという意識付けが大事ではありますが、ある程度ベースを作る時にポリシーを持っていると発展していってもスパゲッティセキュリティグループにならないのではないかと思います。

もっと良いポリシーがあったら随時追加予定。
コメント絶賛募集中です。