はじめに
暇を持て余しているので AWS のセキュリティグループを使って遊んでみました。
セキュリティグループとは
AWS Security Group(セキュリティグループ)は AWS の VPC 内におけるパーソナルファイアウォールのようなものです。インスタンスの NIC と関連付けることで通信を制御できます。
ステートフルファイアウォールとは
ステートフルファイアウォールとは、TCP コネクションや往復が前提の通信(ICMP や DNS、NTP など)について、行きと戻りの通信を管理し、戻りの通信も動的に許可する仕組みをもったファイアウォールのことです。
AWS セキュリティグループはステートフルなファイアウォールなので、双方向の通信制御を定義する必要はありません。片方向について制御ルールを定義してあげれば、行きの通信と戻りの通信をよしなに許可してくれます。なお、拒否の場合は行きの通信で拒否されるので、戻りの通信の考慮は不要です。
やってみたこと
ネットワークやってる人からすると当たり前に知っているのですが、ステートフルファイアウォールの挙動ってなかなか初心者には理解してもらえないので、わかりやすい実験ができないかなと考えました。
そこで
- 行きと戻りの通信が発生する
- エンジニアに馴染みの深いプロトコル
を使ってステートフルファイアウォールの挙動を確認できないか試してみようと思いました。
ステートフルファイアウォールは行きと戻りの通信の情報を管理します。その特徴の現れとして、すでにコネクションが出来上がっている通信に関してはその通信が終わるまで許可を判断した制御が継続されます。つまり、通信中にファイアウォールの設定で明示的に拒否したとしても通信ができてしまいます。これを AWS セキュリティグループで簡単に実証できないかなと思った次第です。
状態をもつプロトコルでわかりやすいのは HTTP かなとも思ったのですが、誰もが使ったことがあるであろう ping も特定条件では状態をもつプロトコルのようです。
ICMP パケットは、ステートフルとは対極に位置するものだ。というのも、 ICMP は制御に使用するだけであり、いかなるコネクションも張らないからだ。さりながら、 ICMP のうち 4つのタイプだけは、回答パケットを発生させ、これらはふたつのステートを採る可能性がある。 ICMP メッセージが採り得るステートは NEW と ESTABLISHED。これに該当する ICMP タイプが、 Echo の request と reply 、 Timestamp の request と reply 、 Information の request と reply 、そして Address mask の request と reply だ。
ping の場合はどうもシーケンスが続いている限りは状態をもつようです。
なので、今回は環境構築もいらないお手軽な ping を使って検証してみようと思います。
用意するもの
- AWS アカウント ✕ 1 個
- Amazon VPC ✕ 1 個
- サブネット ✕ 1 個
- EC2 インスタンス ✕ 2 台
- セキュリティグループ ✕ 1 個
- PC ✕ 1 台
- ターミナルソフトウェア(TeraTerm など)
2 台用意できない場合は任意の Web 上のアドレス(www.google.com とか 8.8.8.8 とか)を Ping の宛先とすることもできるので 1 台でもなんとかなります。
検証環境の構成
検証環境の概要構成図を簡単に用意しました。ネットワーク ACL は ALL Permit 状態でセキュリティグループの制御だけが効く状態です。EC2 インスタンスは 2 台用意しますが、セキュリティグループは同一のカスタムセキュリティグループを使用します。EC2 インスタンスへのアクセス用に SSH は開放、VPC 内の ping 疎通ができるように VPC に割り当てた IPv4 CIDR ブロックからの ICMP 通信を許可した状態です。
今回は自宅からアクセスしたかったので SSH をインターネットに対して開放しましたが、やりたいことは 2 つの EC2 インスタンス間の ping 疎通なので Web コンソールから EC2 インスタンスにつなぐでも問題ありません。
SSH セッションは EC2(B) に対して 2 本張ります。EC2(A) は設定変更をしたり、確認コマンドを打ったりする必要がないので SSH 接続する必要はありません。
実験と予想される結果
以下の表のとおり実験を行います。
SSH セッション①では EC2(B) から EC2(A) への ping を打ちっぱなしにします。セキュリティグループから ICMP 許可のルールを削除/追加することでどのような変化が起こるかを観察します。
SSH セッション②は実験 3 から使用し、SSH セッション①と同様に EC2(B) から EC2(A) への ping を打ちっぱなしにします。
実験 1 ではセキュリティグループで ICMP が適切に許可されているかを確認します。
実験 2 ではステートフルファイアウォールの性質通り、すでにコネクションが出来上がっている通信は許可されたままとなることを確認します。
実験 3 ではすでにコネクションが出来上がっている通信は許可されたままで、新規のコネクションは拒否されることを確認します。
実験 4 ではセキュリティグループで ICMP を許可すれば実験 3 で NG だった SSH セッション② の ping も許可されることを確認します。
結果
SSH セッション①から打った ping は、実験①~④の間で途切れることがありませんでした。この事実は、以下の ping statistics の 0% packet loss
という記載からわかります。
--- 10.255.1.197 ping statistics --- 65 packets transmitted, 65 received, 0% packet loss, time 65455ms rtt min/avg/max/mdev = 0.384/0.487/1.309/0.128 ms
SSH セッション②の ping 結果を確認すると icmp_seq=20
から表示されています。これ以前の ICMP パケットは EC2(A) に届かなかったということです。
$ ping 10.255.1.197 PING 10.255.1.197 (10.255.1.197) 56(84) bytes of data. 64 bytes from 10.255.1.197: icmp_seq=20 ttl=255 time=0.446 ms 64 bytes from 10.255.1.197: icmp_seq=21 ttl=255 time=0.483 ms 64 bytes from 10.255.1.197: icmp_seq=22 ttl=255 time=0.516 ms 以下略
そのため、以下の ping statistics では 46 packets transmitted, 27 received, 41% packet loss
という結果がでています。
--- 10.255.1.197 ping statistics --- 46 packets transmitted, 27 received, 41% packet loss, time 46009ms rtt min/avg/max/mdev = 0.422/0.495/0.910/0.100 ms
考察
この結果から次のことがわかりました。
- セキュリティグループのインバウンドルールを設定するだけで ping 通信を許可できる。(今回だと実験 1 や 2、4 で明らかです。)
- ping を打ち続けていれば セキュリティグループで ICMP を許可する用に設定しても ping 通信は止まらない。(今回だと実験 2 から明らかです)
- セキュリティグループのルールを変更した後に発生した通信は、ルール通りに制御される。(今回だと実験 3 で拒否されました。)
おわりに
今回の実験でステートフルファイアウォールの挙動が可視化できたのではないでしょうか。ブログという文字媒体ではなかなかおもしろさが伝わりにくいのですが、簡単な実験なので、みなさんもぜひ試してみてください。
反響があれば、動画でもアップしようと思いますが、今日は疲れたのでここまでとします。
以上