【AWS, VPC】通信エラーと戦う中で、デフォルトセキュリティグループの仕組みを学んだ話
【AWS, VPC】通信エラーと戦う中で、デフォルトセキュリティグループの仕組みを学んだ話:
先日、AWSのEC2上にアプリを構築していたのですが、アプリにリクエストが届かない通信エラーを戦っていました。
振り返ると通信エラーになる原因は当たり前過ぎて泣きたくなるのですが、 今回の取り組みを通して、デフォルトセキュリティグループの仕組みを改めて学んだ ので、その話を書きたいと思います。
今回RailsアプリをAWSのVPC内のEC2上に構築しました。前提として、今回のアプリはSSL通信を基本としています。
構成の概要は以下の通りです。
リクエストの動線としては、 「1. ロードバランサー」→「2. EC2」→「3. Railsアプリ」 の順ですね。
次に、その導線について、少しですが詳しく見ていきます。
まずアプリのURLにリクエストが行われた場合は、まず ロードバランサー で受けます。
ロードバランサーでは、配置しているSSL証明書によりリクエストのデコードを行い、次のターゲットであるEC2インスタンスの80番ポートへHTTPとしてリクエストを受け渡します。
次に EC2インスタンス では、 80番ポートでRailsアプリ が起動しています。そのため、EC2インスタンスが80番ポートで受け取ったリクエストは、そのままRailsアプリへ到達します。
また、DBはRDSを使用するため、RailsとRDSとの通信も行われます。
また、今回のアプリでは IP制限 を設けています。そのIP制限はセキュリティグループ で設定しています。 設定としては、許可するIP、ポート(443)のリクエストで指定しています。 このセキュリティグループ(便宜上publicと呼ぶ)を、図のように「ロードバランサー」「EC2」「RDS」に設定 していました。
また、EC2は外部からssh接続したいので、指定のIPアドレスから、22番ポートからsshを許可するセキュリティグループを指定しています(ssh)
ざっと、以上の様な流れで1つのリクエストがアプリへ届きます。
まぁ、ここですぐに原因に気づくべきでした(汗)
いざ構築をして見ると、リクエストがRailsアプリに届く途中でエラーが起きていました。
具体的に問題箇所を調べていくと、 「ロードバランサー」→「EC2」の途中 で何かの原因で通信が行われていないことが判明しました。
先に結論を言うと、タイトルにある様に 問題の原因はセキュリティグループの設定不備 でした。
今回設定したセキュリティグループは、指定のIPアドレス、ポート(443)の場合のみ許可する設定でした。
それを踏まえて、ロードバランサーからEC2へリクエストを送る際はHTTPの80番ポートへの通信であるため、セキュリティグループからすると許可されていないリクエストです。
そのため、 自分で設定したセキュリティグループにリクエストが遮断 されていたということです。振り返って見ると当たり前すぎて、泣けてきます(泣)
セキュリティグループが原因とわかったところで、VPC内のセキュリティグループの設定はどうすればよいのか?という話ですが、とても便利な機能として、 デフォルトセキュリティグループ があります。
デフォルトセキュリティグループは、特徴として、ソースに自身のセキュリティーグループが指定されている点 です。これが意味することは、デフォルトセキュリティグループが指定されたインスタンスからのインバウンド通信のみ許可する という意味になります。
これが分かれば話が早く、VPC内のインスタンスにデフォルトセキュリティグループが指定することで、同じデフォルトセキュリティグループが指定されたインスタンス間で双方向の通信を許可 することができます。
逆に、 同じデフォルトセキュリティグループが指定されてない場合の通信を遮断することができます
非常に簡単にVPC内のインスタンス間の通信制限を行うことができますね!
以上を踏まえて、正しい設定は以下の通りです。
まず、 ロードバランサー はVPC外からのリクエストを受け取るので、外部リクエストを制限するセキュリティグループ(public)を指定します。加えて、 ロードバランサーはVPC内のEC2インスタンスと通信したいので、VPCのデフォルトセキュリティグループを指定 します。
次に、 EC2インスタンス では 先ほど指定していた外部リクエストを制限するセキュリティグループ(public)を外し、代わりにデフォルトセキュリティグループを指定します。 これにより、VPC内のロードバランサーからのリクエストを受け取ることができます。
最後に RDS についても同様で、 デフォルトセキュリティグループを指定することで、EC2インスタンス(内のRailsアプリ)と通信することができます。
これで完成です!
Healthcheckがunhealthである絶望感と、healthyになった時の幸福感を感じて、インフラってやっぱり大事やなーと感じましたw
ネットワークやインフラは実際に自分で試行錯誤しないと身につかないなと思いました。今後とも手を動かして、インフラ構築能力を身につけていきたいです。
初めに
先日、AWSのEC2上にアプリを構築していたのですが、アプリにリクエストが届かない通信エラーを戦っていました。振り返ると通信エラーになる原因は当たり前過ぎて泣きたくなるのですが、 今回の取り組みを通して、デフォルトセキュリティグループの仕組みを改めて学んだ ので、その話を書きたいと思います。
今回のアプリの構成
今回RailsアプリをAWSのVPC内のEC2上に構築しました。前提として、今回のアプリはSSL通信を基本としています。構成の概要は以下の通りです。
リクエストの動線としては、 「1. ロードバランサー」→「2. EC2」→「3. Railsアプリ」 の順ですね。
次に、その導線について、少しですが詳しく見ていきます。
リクエストの導線
まずアプリのURLにリクエストが行われた場合は、まず ロードバランサー で受けます。ロードバランサーでは、配置しているSSL証明書によりリクエストのデコードを行い、次のターゲットであるEC2インスタンスの80番ポートへHTTPとしてリクエストを受け渡します。
次に EC2インスタンス では、 80番ポートでRailsアプリ が起動しています。そのため、EC2インスタンスが80番ポートで受け取ったリクエストは、そのままRailsアプリへ到達します。
また、DBはRDSを使用するため、RailsとRDSとの通信も行われます。
セキュリティグループでリクエストを制限
また、今回のアプリでは IP制限 を設けています。そのIP制限はセキュリティグループ で設定しています。 設定としては、許可するIP、ポート(443)のリクエストで指定しています。 このセキュリティグループ(便宜上publicと呼ぶ)を、図のように「ロードバランサー」「EC2」「RDS」に設定 していました。また、EC2は外部からssh接続したいので、指定のIPアドレスから、22番ポートからsshを許可するセキュリティグループを指定しています(ssh)
ざっと、以上の様な流れで1つのリクエストがアプリへ届きます。
まぁ、ここですぐに原因に気づくべきでした(汗)
今回の問題
いざ構築をして見ると、リクエストがRailsアプリに届く途中でエラーが起きていました。具体的に問題箇所を調べていくと、 「ロードバランサー」→「EC2」の途中 で何かの原因で通信が行われていないことが判明しました。
原因はセキュリティグループの設定
先に結論を言うと、タイトルにある様に 問題の原因はセキュリティグループの設定不備 でした。今回設定したセキュリティグループは、指定のIPアドレス、ポート(443)の場合のみ許可する設定でした。
それを踏まえて、ロードバランサーからEC2へリクエストを送る際はHTTPの80番ポートへの通信であるため、セキュリティグループからすると許可されていないリクエストです。
そのため、 自分で設定したセキュリティグループにリクエストが遮断 されていたということです。振り返って見ると当たり前すぎて、泣けてきます(泣)
VPC内でのインスタンス間の通信はどうやって制限するの???
セキュリティグループが原因とわかったところで、VPC内のセキュリティグループの設定はどうすればよいのか?という話ですが、とても便利な機能として、 デフォルトセキュリティグループ があります。
デフォルトセキュリティグループ
デフォルトセキュリティグループは、特徴として、ソースに自身のセキュリティーグループが指定されている点 です。これが意味することは、デフォルトセキュリティグループが指定されたインスタンスからのインバウンド通信のみ許可する という意味になります。これが分かれば話が早く、VPC内のインスタンスにデフォルトセキュリティグループが指定することで、同じデフォルトセキュリティグループが指定されたインスタンス間で双方向の通信を許可 することができます。
逆に、 同じデフォルトセキュリティグループが指定されてない場合の通信を遮断することができます
非常に簡単にVPC内のインスタンス間の通信制限を行うことができますね!
デフォルトセキュリティグループを踏まえた、正しい設定
以上を踏まえて、正しい設定は以下の通りです。まず、 ロードバランサー はVPC外からのリクエストを受け取るので、外部リクエストを制限するセキュリティグループ(public)を指定します。加えて、 ロードバランサーはVPC内のEC2インスタンスと通信したいので、VPCのデフォルトセキュリティグループを指定 します。
次に、 EC2インスタンス では 先ほど指定していた外部リクエストを制限するセキュリティグループ(public)を外し、代わりにデフォルトセキュリティグループを指定します。 これにより、VPC内のロードバランサーからのリクエストを受け取ることができます。
最後に RDS についても同様で、 デフォルトセキュリティグループを指定することで、EC2インスタンス(内のRailsアプリ)と通信することができます。
これで完成です!
最後に
Healthcheckがunhealthである絶望感と、healthyになった時の幸福感を感じて、インフラってやっぱり大事やなーと感じましたwネットワークやインフラは実際に自分で試行錯誤しないと身につかないなと思いました。今後とも手を動かして、インフラ構築能力を身につけていきたいです。
コメント
コメントを投稿