こんにちは、キクです。
「AWS初心者だけど、何かしらの形でアウトプットしていきたい!!」
本記事は、そんな思いから「AWS学習記録」として気ままにアウトプットしていくシリーズです。
今回は『VPC Flow Logsの利用』をテーマに書いていきたいと思います!
それでは、よろしくお願いします。
はじめに
まずはじめに、今回の作業内容について簡単にご紹介します。
作業記録
本項では、実際にAWSでの操作内容を書いていこうと思います。
■事前準備編
1. VPCの作成
本項では、今回の作業環境の土台となる「VPC」を作成していきます。
■1-1. VPC管理画面にて「VPCを作成」ボタンをクリック
■1-2.「VPCを作成」画面にて、以下のパラメータを入力して「VPCを作成」をクリック
■1-3.「お使いのVPC」画面にて作成したVPCの名前を変更
■1-4. 左ペインより「仮想プライベートクラウド -> サブネット」をクリック
■1-5.「サブネット」画面にて自動作成されたサブネットの名前を変更
2. EC2インスタンスの作成
本項では、VPC Flow Logsの動作確認用のログを出力するためのEC2インスタンスをパブリックサブネットとプライベートサブネットに1台ずつ作成していきます。
■2-1. EC2管理画面より「インスタンスを起動」ボタンをクリック
■2-2.「インスタンスを起動」画面にて、以下のパラメータを設定して「インスタンスを起動」をクリック
「ネットワーク設定」の横にある「編集」をクリックして以下のパラメータを入力
※上記パラメータ①〜②以外の項目についてはデフォルト値を利用します。
■2-3. EC2インスタンス(1台目)が作成されたことを確認
■2-4. 2台目のEC2インスタンスを以下のパラメータで作成
■2-5. EC2インスタンス(2台目)が作成されたことを確認
■CloudWatch Logsへの送信編
3. IAMロールの作成
本項では、後続作業で利用するためのIAMロールを作成していきます。
■3-1. IAM管理画面の左ペインにて「アクセス管理 -> ロール」をクリック
■3-2.「ロールの作成」をクリック
■3-3.「信頼されたエンティティを選択」画面にて、以下のパラメータを設定して「次へ」をクリック
■3-4.「許可を追加」画面では、何も選択せずに「次へ」をクリック
■3-5.「名前、確認、および作成」画面にて、以下のパラメータを設定して「ロールを作成」をクリック
■3-6. IAMロールが作成されたことを確認
■3-7. 作成したIAMロール(青字)をクリック
■3-8.「許可」タブにて「許可を追加 -> インラインポリシーを作成」をクリック
■3-9.「ポリシーの作成①」画面のJSONタブにて、以下の内容をコピペして「ポリシーの確認」をクリック
なお、上記は公式サイトに記載されたJSONの内容となります。
参考:CloudWatch Logs へのフローログ発行のための IAM ロール
■3-10.「ポリシーの作成②」画面にて、以下のパラメータを設定して「ポリシーの作成」をクリック
■3-11. 作成したポリシーがアタッチされていることを確認
■3-12.「信頼関係」タブをクリック
■3-13.「信頼ポリシーを編集」をクリック
■3-14.「信頼ポリシーを編集」画面にて、以下のパラメータを修正して「ポリシーを更新」をクリック
参考:CloudWatch Logs へのフローログ発行のための IAM ロール
4. CloudWatchロググループの作成
本項では、後続作業で利用するためのCloudWatchのロググループを作成していきます。
■4-1. CloudWatch管理画面の左ペインにて「ログ -> ロググループ」をクリック
■4-2. 右ペインにて「ロググループを作成」ボタンをクリック
■4-3.「ロググループを作成」画面にて、以下のパラメータを設定して「作成」をクリック
■4-4. ロググループが作成されたことを確認
5. フローログの作成①
本項では、今回のテーマであるフローログの設定を行っていきます。
ログの送信先にはいくつかのパターンがありますが、ここでは「CloudWatch Logs」へ送信するための設定をします。
■5-1. VPC管理画面の左ペインにて「仮想プライベートクラウド -> お使いのVPC」をクリック
■5-2. 対象VPC(Test-VPC)を選択し、「フローログ」タブをクリック
■5-3.「フローログを作成」ボタンをクリック
■5-4.「フローログを作成」画面にて、以下のパラメータを設定して「フローログを作成」をクリック
■5-5. フローログが作成されたことを確認
6. 動作確認①
本項では、実際にVPC内で通信を発生させて、CloudWatch Logsにログが出力されているかを確認していきます。
■6-1. 項番2で作成したEC2インスタンス#1にSSH接続し、EC2インスタンス(2台目)にpingを実行
■6-2. CloudWatch管理画面の左ペインにて「ログ -> ロググループ」をクリック
■6-3. 右ペインにて対象ロググループ(青字)をクリック
■6-4.「ログストリーム」タブにてEC2インスタンス#2のログストリームをクリック
■6-5. 検索ボックスに「REJECT」を入力
Test-EC2#1(10.0.0.182)からの通信を「REJECT(拒絶)」しているというログが取得できていることが確認できます。
■S3への送信編
7. S3バケットの作成
本項では、後続作業で利用するためのS3バケットを作成していきます。
■7-1. S3管理画面より「バケットを作成」ボタンをクリック
■7-2.「バケットを作成」画面にて、以下のパラメータを設定して「バケットを作成」をクリック
■7-3. バケットが作成されたことを確認し、バケット名(青字)をクリック
■7-4.「プロパティ」タブをクリックし、「Amazon リソースネーム (ARN)」を控える
後ほどフローログの出力先としてS3バケットを指定する際に利用するので、S3バケットのARNの控えます。
■7-5.「アクセス許可」タブをクリックし、バケットポリシーが空であることを確認
バケット作成時点では空の状態ですが、後続手順で自動入力されるので比較として確認しておきます。
8. フローログの作成②
本項では、先ほど作成したフローログとは別の設定を行なっています。
ここではログの送信先として「S3バケット」を選択した際の流れを見ていきます。
■8-1. VPC管理画面の左ペインにて「仮想プライベートクラウド -> お使いのVPC」をクリック
■8-2. 対象VPC(Test-VPC)を選択し、「フローログ」タブをクリック
■8-3.「フローログを作成」ボタンをクリック
■8-4.「フローログを作成」画面にて、以下のパラメータを設定して「フローログを作成」をクリック
■8-5. フローログが作成されたことを確認
■8-6. 項番7で作成したバケットの「アクセス許可」タブにて、再度バケットポリシーを確認
■8-7.「オブジェクト」タブにて「AWSLogs/AWSアカウントID」が作成されていることを確認
9. Athena統合の生成
本項では、Athena統合の生成を実施していきます。
■9-1. VPC管理画面の左ペインにて「仮想プライベートクラウド -> お使いのVPC」をクリック
■9-2. 対象VPC(Test-VPC)を選択し、「フローログ」タブをクリック
■9-3. 対象フローログ(Test-VPC-FlowLogs#2)を選択し、「アクション -> Athena統合を生成」をクリック
■9-4.「Athena統合を生成」画面にて、以下のパラメータを設定して「Athena統合を生成」をクリック
■9-5. 指定したバケットにAthena統合によって作成されたCloudFormationテンプレート(YAMLファイル)が存在することを確認
■9-6. 必要に応じて以下の作業を実施する
1. CloudFormationテンプレートから以下の記述をコメントアウト
ReservedConcurrentExecutions: 1
2. 変更後のテンプレートをS3バケットに再アップロード
3. 対象バケットのブロックパブリックアクセス機能を無効化
4. 対象バケットのバケットポリシーに以下の内容を追記
{
"Effect": "Allow",
"Principal": "", "Action": "s3:",
"Resource": ["arn:aws:s3:::test-s3-vpc-flowlogs",
"arn:aws:s3:::test-s3-vpc-flowlogs/*"
]
}
10. CloudFormationスタックの作成
本項では、先ほどの「Athena統合の生成」で作成されたCloudFormationテンプレートを利用してスタックを作成していきます。
■10-1. CloudFormation管理画面より「スタックの作成」をクリック
■10-2.「スタックの作成画面」にて、以下のパラメータを設定して「次へ」をクリック
■10-3.「スタックの詳細を指定」画面にて、以下のパラメータを設定して「次へ」をクリック
■10-4.「スタックオプションの設定」画面では、すべてデフォルトのまま「次へ」をクリック
■10-5.「レビュー Test-Stack-VPC-FlowLogs」画面にて、以下の項目にチェックを入れて「送信」をクリック
■10-6. スタックが作成されて「ステータス:CREATE_COMPLETE」となっていることを確認
11. 動作確認②
本項では、再びVPC内で通信を発生させて、S3バケットに出力されたログにAthenaによるクエリ検索が実行できること確認していきます。
■11-1. 項番2で作成したEC2インスタンス#1にSSH接続
■11-2. Athena管理画面にて「クエリエディタを起動」をクリック
■11-3. 以下のパラメータを選択した状態にする
■11-4.「ワークグループを切り替えますか」と表示されたら「切り替える」をクリック
■11-5.「ワークグループ flxxxxxxxxWorkGroup の設定」画面にて「認証」をクリック
■11-6.「保存したクエリ」タブをクリック
■11-7.「説明:Monitor SSH and RDP traffic」のID(青字)をクリック
■11-8. SQL文が入力された状態になるので「実行」をクリック
■11-9.「クエリ結果」タブにて、以下のSSH接続成功ログが出力されていることを確認
■後片付け編
12. リソースの終了
作成したAWSリソースを削除して、今回の作業は終了です。
調べたこと
ここからは僕が作業中に疑問に思ったことや調べた内容について、備忘録的に書いていこうと思います。
超初歩的な内容もあるかもしれませんがご了承ください・・・。
1. VPC Flow Logs関連
本項では、VPC関連の疑問や調べたことを整理していきます。
1-1. VPC Flow Logsとは?
そもそも論ですが、今回のテーマである「VPC Flow Logs」とはどのようなものなのかについて。
VPC Flow Logsとは、VPCを流れるネットワークトラフィックのログを取得するサービスのこと。
ログの保管先としては、本記事で扱った「CloudWatch Logs」や「S3」を含めて以下のような選択肢が存在する(2022年12月時点)
・CloudWatch Logs
・Amazon S3 バケット
・同じアカウントの Kinesis Firehose
・別のアカウントの Kinesis Firehose
なお、VPC Flow Logsの設定を停止したとしても、上記ログ保管先のデータは自動削除されない。
そのため、ログデータも含めて不要になった場合にはCloudWatch LogsやS3から意図的に削除しないと、別途保管料金が発生し続けてしまうため注意が必要ですね。
AWSのフローログは、以下のようにさまざまな単位でネットワークトラフィックを取得することが可能です。
・VPC単位
・サブネット単位
・ENI単位
今回のテーマである「VPC Flow Logs」の場合は「VPC単位」に該当しています。
簡単にではありますが、「サブネット単位」や「ENI単位」についてもそれぞれの管理画面からフローログの作成ができることが確認できました。
また、VPC Flow Logsのログ取得はネットワークトラフィックのパスの外で行われるため、ネットワークパフォーマンスに影響を与えないという特徴もあるみたいです。
参考:VPC フローログを使用した IP トラフィックのログ記録
1-2. フローログ作成時の設定項目について
フローログ作成時の設定項目について整理していきます。
フィルタ
フィルタについては、以下の項目があります。
・承諾
・却下
・すべて
どのようなログを取得するのかという項目で、通信に成功したログを取得するか、失敗(拒否)したログを取得するか、すべてのログを取得するのかを選択します。
最大集約間隔
最大集約間隔については、以下の項目があります。
・10分間
・1分間
パケットのフローがキャプチャされてからフローログレコードに集約されるまでの間隔の最大時間になります。
通信が発生する度にCloudWatch LogsやS3にログが保管されているわけではなく、ある程度の間隔で溜め込んだものをフローログレコードとして保存しているというイメージを持ちました。
送信先
フローログの保管先となります。
送信先の選択肢としては触れているため割愛します。
選択した送信先に応じて、それ以降の設定項目が若干変わります。
例えば、送信先として「CloudWatch Logs」を選択した場合には、本記事でも扱いましたが次のような項目も設定していきます。
・送信先ロググループ
・IAMロール
ログレコード形式
ログレコード形式には、以下の項目があります。
・AWSのデフォルト形式
・カスタム形式
フローログにどのような情報を含めるかを設定します。
デフォルトで取得される情報では過不足がある場合には「カスタム形式」で設定していきます。
1-3. S3に保管されるフローログファイルの命名規則は?
フローログファイルにはどのようなルールで名前が付けられているのか気になったので調べてみました。
<aws_account_id>_vpcflowlogs_<region>_<flow>_<log_id>_<YYYYMMDD>T<HHmm>Z_hash.log.gz
参考:フローログを Amazon S3 に発行する
2. IAM関連
本項では、IAM関連の疑問や調べたことを整理していきます。
2-1. なぜIAMロールが必要?
VPC Flow LogsがCloudWatch Logsにアクセスしてログを保管する上で権限が必要だから。
2-2. 信頼ポリシー(Assume Role)とは?
今回、作業3-14にて「信頼ポリシー」の編集を実施しました。
しかし「そもそも信頼ポリシーって何?」という状態でした。
どうやら信頼ポリシーとは次のような意味を持つものだと分かりました。
誰がそのIAMロールを引き受けられるかを定義するもの
参考:[仕様変更] IAM ロール信頼ポリシーの挙動が変更になり IAM ロールの「暗黙的な自己信頼」がなくなりました
改めて今回の信頼ポリシーの内容を確認してみます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "vpc-flow-logs.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
そしてIAMポリシーの内容も確認してみます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams"
],
"Resource": "*"
}
]
}
これらを踏まえると、「ログストリーム作成」や「ログ情報の格納」などの権限が付与されたIAMロールをVPC Flow Logsというサービスが引き受けることができるという構図の認識で良いのではないかと思いました。
3. CloudWatch関連
本項では、CloudWatch関連の疑問や調べたことを整理していきます。
3-1. ロググループとは?
CloudWatch Logsにフローログを保管するにあたって、事前に「ロググループ」を作成しました。
ロググループとは、公式では以下のように説明されていました。
保持、モニタリング、アクセス制御について同じ設定を共有するログストリーミングのグループ
今回は「Test-LogGroup-VPC-FlowLogs」というロググループをVPC Flow Logsの保管先として設定しました。
これによりVPC Flow Logsから送信されてくるログストリームは軒並み「Test-LogGroup-VPC-FlowLogs」配下に保管されるようになりました。
つまりはVPC Flow Logsという1つのソースから送信されてくる複数のログストリームをまとめるグループと捉えることができます。
3-2. ログストリームとは?
では「ログストリーム」とは何なのかについても気になりました。
公式では以下のように説明されていました。
同じソースを共有する一連のログイベント
CloudWatch Logsでのログの各ソースで各ログストリームが構成されます
今回は「eni」から始まるログストリームがロググループに送信されていました。
各ログストリーム配下には、テスト用EC2インスタンスにアタッチされているENI(Elastic Network Interface)上で発生した通信がログとして記録されていました。
つまり、今回の場合「同じソース = ENI」と捉えることができて、各ENIで発生した通信は各ENIに紐付くログストリーム配下に記録されていくという構図になっていそうですね。
4. Athena関連
本項では、Athena関連の疑問や調べたことを整理していきます。
4-1. Athena統合の生成とは?
フローログをS3に保管してAthenaでクエリする際に、事前に「Athena統合の生成」という作業を実施しました。
しかし、Athenaに関して全く触ったことがない筆者にとっては「Athena統合ってなんですか・・・?」という状態でした。
今回のVPC Flow Logsに限らず、Athena統合はいくつかのサービスで利用できる機能のようです。
VPC Flow Logsの場合は、Athenaを利用したクエリ検索がより簡単になるというもので、S3に保管されたログをすぐにクエリ検索できるように「クエリセット」が事前に用意されている環境を自動構築可能なCloudFormationテンプレートを生成してくれました。
また、このテンプレートから作成したスタックには以下のようなリソースが含まれており、これらを手動で作成するとなると骨が折れそうなので、「Athena統合の生成って便利だな」と感じました。
Athena統合の生成で作成されたAWSリソース
・Athena
└WorkGroup
└NamedQuery
・Lambda
└Function
・Glue
└Table
└Database
・IAM
└Role
参考:Amazon VPC Flow Logs がすぐに使用できる Amazon Athena との統合を発表
参考:VPCフローログのAthena統合を試してみた
4-2. Athenaの用語について
Athenaの用語を知らなすぎたので、簡単に残しておきます。
■データベース
Athenaで作成するテーブルの論理的なグループ
データセットのメタデータおよびスキーマ情報のみを保持する
■テーブル
AWS Glueデータカタログに登録されるメタデータ(テーブル名, テーブル内の列名, 各列のデータ型などのスキーマ)
■データカタログ
メタデータを整理するためのシステム
■データセット
データソースの元になるデータストアの一部またはすべて
■データソース
データセットとそれを記述するデータカタログの組み合わせ
参考:[小ネタ] Athena のテーブル, データカタログなどの概念がわからなかったのでまとめた
4-3. Athena統合の生成で作成されたCloudFormationテンプレートからスタックの作成ができないのですが・・・
今回の作業で一番苦戦したのはこの部分でした。
自動作成されたテンプレートからスタックが作成できなかったんですね。
事象としては以下の2段階がありました。
- InitializerAsyncという項目で「CREATE_FAILED」になる
- 原因対処後のテンプレートからそもそもスタックが作成できない
1. InitializerAsyncという項目で「CREATE_FAILED」になる
自動作成されたテンプレートからスタックを作成しようとすると、以下の部分で失敗してロールバックしてしまいました。
失敗の理由に記載されている以下の部分が直接的に関係していました。
UnreservedConcurrentExecution below its minimum value of [50].
Lambdaもまだ全然触れていないので詳しくは理解できていませんが、Lambdaでは同時に実行できる数をあらかじめ予約しており、この予約数を上回ってしまうとおそらく機能しなくなる。
筆者の環境では「50」が上限として設定されていそうで、おそらくCoudFormationテンプレートではこれ以上のLambda関数を利用するのではないかと思われます。
そしてテンプレート内には以下の記述がありました。
ReservedConcurrentExecutions: 1
すべておそらくベースで申し訳ないのですが、以下のように理解しました。
- AWSアカウント毎にLambdaの同時実行数には上限がある(筆者環境:50)
- CloudFormationテンプレートから作成される環境で利用するLambda関数は50以上
- Lambda同時実行予約数として1以上残っている必要がある
筆者環境での上限「50」は超えてしまっており、上記3の内容を満たすことができていません。
それ故にスタック作成が失敗したと理解しています。
対処方法としては、CloudFormationテンプレートに以下の修正を加えました。
要するに「同時実行予約数として1以上残っている必要がある」の条件をコメントアウトして無くしてしまいました。
同時実行数の上限はAWSに申請することで引き上げることもできるみたいですが、今回は動作を確認したい程度のものだったので、このような対応を取りました。
参考:Lambda の予約済み同時実行数の管理
参考:【初心者向け】Lambdaの同時実行数を把握しよう
2. 原因対処後のテンプレートからそもそもスタックが作成できない
S3に慣れていなさすぎというのもあるのですが、上記で修正したCloudFormationテンプレートをS3バケットにアップロードし、スタック作成で利用するテンプレートの「Amazon S3 URL」を「アップロードしたテンプレートのオブジェクトURL」で指定すると以下のようなエラーで作成すら開始できませんでした。
ただ、Athena統合の生成で自動作成されてS3バケットにアップロードされたCloudFormationテンプレートに関しても、手動でオブジェクトURLを指定してスタックを作成しようとすると同じエラーで失敗するんですよね。
文字だけだと分かりづらいので、少し画像も添えてみていきます。
Athena統合の生成を利用したCloudFormationテンプレートが完了すると、以下のような表示がされます。
ここに表示されている「CloudFormationスタックの作成」をクリックすると、テンプレート指定のAmazon S3 URLは以下のように自動入力された状態になります。
一方で、同じCloudFormationテンプレートのオブジェクトURLを確認すると、上記で自動入力されたURLとは若干異なっています。
前者:https://test-s3-vpc-flowlogs.s3.ap-northeast-1.amazonaws.com/VPCFlowLogsIntegrationTemplate_fl-00421507fed98ba33_Wed%20Dec%2028%2021%3A07%3A13%20UTC%202022.yml
後者:https://test-s3-vpc-flowlogs.s3.ap-northeast-1.amazonaws.com/VPCFlowLogsIntegrationTemplate_fl-00421507fed98ba33_Wed+Dec+28+21%3A07%3A13+UTC+2022.yml
これは推測ですが、この「若干の違い」によってテンプレートに対するアクセス経路が変わっているのではないかと思いました。
前者はAWS内部でのアクセス、後者はインターネット経由でのアクセスなのではないかと仮説を立てました。
そして、今回の作業で作成したS3バケットはブロックパブリックアクセスが有効の状態だったので、インターネット経由でのアクセスは拒否されて「Access Denied」に繋がったのではないかと考えました。
そこからの対処は、作業内容にも含まれていますが「ブロックパブリックアクセスの無効化」と「バケットポリシーの調整」を実施しました。
4-4. なぜ存在するはずのクエリ検索で「結果なし」と表示される?
フローログの送信先としてS3バケットを指定し、Athena統合の生成も完了。
動作確認用にEC2インスタンス#1にSSH接続した後、Athenaにてクエリ検索を実行しました。
S3バケットにはそれらしきファイルは送信されているのですが、クエリ結果は「結果なし」。
そんな感じで苦戦してました。
これには、Athena統合を生成で指定する「パーティションの開始日/終了日」が大きく関係していました。
SSH接続をしたのがここで指定した日付に含まれていなかったため、クエリ検索対象に含まれず「結果なし」になったと認識しました。
例えば次のようなケース
クエリ検索が上手くいかなかったケース
・パーティションの開始日 :2022/12/21
・パーティションの終了日 :2022/12/22
・SSH接続実施日 :2022/12/23
この場合、クエリ検索可能なのは「2022/12/21〜2022/12/22」の期間のみ。
それ以降、あるいはそれ以前にSSH接続していたとしてもクエリ対象には含まれないということ。
「とりあえず環境は整えたから、動作確認は後日やろう」といった感じでSSH接続を後日実施したのですが、それが大苦戦への入り口でした・・・(笑)
でも、いい勉強になったので結果オーライです!
5. S3関連
本項では、S3関連の疑問や調べたことを整理していきます。
5-1. 自動適用されたバケットポリシーについて
フローログ作成時に自動適用されたバケットポリシーの書き込みアクション(PutObject)のConditionにて「 "s3:x-amz-acl": "bucket-owner-full-control"」という指定があったのですが、これが何を意味しているのか気になりました。
どうやらこの記述があることでオブジェクト格納時に「bucket-owner-full-control」の付与を強制することができる模様。
そして「bucket-owner-full-control」が付与されていることでオブジェクトの所有権をバケット所有者にすることができるというもののようです。
参考:S3でクロスアカウントアクセスする時に気をつけるポイント
おわりに
いかがだったでしょうか。
今回は「VPC Flow Logs」をテーマにした内容でした。
「CloudWatch Logs」と「S3」の2つのパターンを試してみましたが、苦戦した部分もちょくちょくありました。
僕自身、今回もいい勉強になりました。
前提知識が足りていないことが多々あるのですが、「困ったときに調べるのが一番身につく」と思うので、あまり気負わずに今後も学習を進めていきたいと思います!
本記事を最後まで読んでいただき、ありがとうございました。
ではでは!