業務でAWSのVPCフローログを扱う場面があったので,その基礎とCLIでのログ取得までを記事としました.
概要
VPCフローログは,VPCとネットワークインターフェース間を行き来するIPトラフィックに関する情報を取得できる機能です.下記に,公式ドキュメントより概要を引用します.
ログ取得対象
・VPC
・サブネット
・ネットワークインターフェース
VPCやサブネットを対象とする場合は,それぞれのVPC/サブネット内の各ネットワークインターフェースがモニタリングの対象となります.
※ネットワークインターフェース:物理的な環境におけるNIC(Network Interface Card)に相当.インスタンスに付け替えることができる.(一つのEC2インスタンスに,複数のIPアドレスを付与したりできる.)
ログ保管場所
・CloudWatch Logs
・Amazon S3
ログの形式
集約間隔
特定のフローがキャプチャされ、フローログレコードに集約される期間.デフォルトでは,600秒(10分)間隔.集約間隔内に取得されたログは,指定したサービス(CloudWatch Logs またはAmazon S3)に送信されます.送信には,それぞれ5~10分程度要するようです.
デフォルト形式
デフォルトの形式は,ドキュメントより確認できます.送信元/先のポート番号やIPアドレス,action(対象のトラフィックに対する処理 ACCEPT/REJECT)などを確認できます.
使いどころ
VPCフローログ自体は,ログを取得するサービスなので,監視という意味では他のサービスとの連携が必要となります.
・Guard DutyをONにして,異常検知時の詳細をVPCフローログで確認する.
・CloudWatch Alarmと連携し,特定の状況時に管理者に通知する. など
構成
今回は,下記の構成でVPCフローログの取得までを行います.
対象
・EC2インスタンス(ネットワークインターフェース)
ログ保管場所
・CloudWatch Logs
CLIでの環境構築
VPC~EC2インスタンスの構成までは,下記のコードで実施しました.
ここで,EC2作成時にuser-data
を指定し,Apacheを起動させています.
#!/bin/bash yum update -y yum install httpd -y sudo systemctl start httpd.service
また,セキュリティグループを下記の通り設定しています.
IPバージョン | タイプ | ポート範囲 | ソース |
---|---|---|---|
IPv4 | HTTP | 80 | ${MYIP}/32 |
IPv4 | SSH | 22 | ${MYIP}/32 |
手元の環境から,SSH接続とApacheの画面を確認出来たらフローログ作成に取り掛かります.
VPCフローログの取得
Cloud watch logs ロググループの作成
Cloud watch logs をログの送信先とするので,まずはロググループを作成します.
ログの作成後に,put-retention-polic
コマンドでログの保持期間を1日に変更しています.(デフォルトでは,保持期間が設定されない)
# Variables PREFIX="blog" # cloudwatch logs log group aws logs create-log-group \ --log-group-name "flow-logs" \ --tags "Key=Name,Value=${PREFIX}-log-group" aws logs put-retention-policy \ --log-group-name "flow-logs" \ --retention-in-days 1
VPCフローログの作成
EC2インスタンス(ネットワークインターフェース)に対するログを取得するので,そのIDを取得しcreate-flow-logs
のresource-ids
に指定します.また,VPCフローログにCloud watch logs にログを送信するために必要な権限をIAMロールのArnを指定する形で付与します.
ENI_ID=$(aws ec2 describe-instances \ --filters "Name=tag:Name,Values=${PREFIX}-instance" \ --query "Reservations[].Instances[].NetworkInterfaces[].NetworkInterfaceId" \ --output text) && echo ${ENI_ID} aws ec2 create-flow-logs \ --deliver-logs-permission-arn "arn:aws:iam::XXXXX:role/VpcFowlogsRole" \ --log-group-name "flow-logs" \ --resource-ids ${ENI_ID} \ --resource-type "NetworkInterface" \ --max-aggregation-interval 60 \ --traffic-type ALL \ --tag-specifications "ResourceType=vpc-flow-log,Tags=[{Key=Name,Value=${PREFIX}-flow-logs}]"
IAMロールは,下記の内容で作成しておきます.
CloudWatch Logs へのフローログの発行 - Amazon Virtual Private Cloud
その他の基本的なオプションは下記の通りです.
引数 | 内容 |
---|---|
deliver-logs-permission-arn | VPCフローログに設定するIAMロールのArn |
log-group-name | CloudWatch Logs logのロググループ名 |
resource-ids | フローログ作成対象のID |
resource-type | フローログ作成対象のリソースタイプ(VPC,サブネット,ネットワークインターフェース等) |
max-aggregation-interval | パケットのフローをキャプチャし、フローログのレコードに集約する時間の最大間隔(60または600秒) |
traffic-type | ログ取得対象のトラフィックタイプ(ACCEPT,REJECT,ALL) |
ログの確認
フローログを作成後,対象のEC2インスタンスに対し,SSH接続・HTTPリクエストを送り,ログを確認します.
デフォルトのログは下記のような形式です.送信先IP(dstaddr)は,プライベートIPアドレスとなります.MYIP
(srcaddr)からEC2のプライベートIPアドレスの22/80番ポート宛に通信が走っていることが確認できます.
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/flow-logs.html
ログの形式を変更する
VPCフローログ作成後に,ログ形式の変更はできず,再作成する必要があります.先のVPCフローログを削除し,下記の通りlog-format
を指定することで,今度はログの形式を指定し作成します.
aws ec2 create-flow-logs \ --deliver-logs-permission-arn "arn:aws:iam::XXXXX:role/VpcFowlogsRole" \ --log-group-name "flow-logs" \ --resource-ids ${ENI_ID} \ --resource-type "NetworkInterface" \ --max-aggregation-interval 60 \ --traffic-type ALL \ --log-format '${version} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${type} ${pkt-srcaddr} ${pkt-dstaddr} ${flow-direction} ${traffic-path} ${action}' \ --tag-specifications "ResourceType=vpc-flow-log,Tags=[{Key=Name,Value=${PREFIX}-flow-logs}]"
新しくキャプチャされたログは下記のようになります.必要な情報のみを選択できるので,ログ保管のコスト削減も期待できそうです.
アクセス内容の確認
下記のブログにも記載がある内容ですが,フローログを確認すると多数のIPアドレスから様々なポート宛てにリクエストがあることがわかります.CloudWatch Logs Insightsで,今回作成したインスタンスに対し,セキュリティグループで拒否された通信の宛先ポート番号の一部を図にしています.利用環境に応じては,セキュリティグループをしっかりと設定しておくことは必須に感じます.
filter @message like /REJECT/ |parse @message '* * * * * * * * * * * *' as version,srcaddr,dstaddr,srcport,dstport,protocol,type,pkt_srcaddr,pkt_dstaddr,flow_direction,traffic_path,action | stats count(*) as Ports by dstport | sort Ports desc | limit 15
まとめ
今回は,CLIでフローログを取得するところまでをまとめましたが,実運用ではこのログを監視し,異常があればアラートをあげる等あると思います.次回以降,簡単なイベント通知なども検証してみようと思います.今回は以上になります.