share facebook facebook2 twitter menu hatena pocket slack

2015.11.09 MON

VPC Flow Logs Tutorial

川原 洋平

WRITTEN BY川原 洋平

tl;dr

www.slideshare.net

上記の資料を読んでいたら VPC Flow Logs というサービスがリリースされているのを知っ
たのでどのようなものかをチュートリアルしてみた。

VPC Flow Logs とは

参考

VPC Flow Logs の詳細、制限事項等については上記の記事にお任せ。ありがとうございます。

ユースケース

想定されるユースケースとしては…(Slide Shareの記事より引用)

  • ネットワーク内のトラブルシューティング
  • ネットワークトラフィックの監視と監査
  • ネットワークトラフィックの統計情報の収集
    等。

flow log を見てみる

前後するけど flow log とはどげなもんなのかを AWS CLI で確認する。

#
# log group を確認
#
$ aws logs describe-log-groups
{
    "logGroups": [
        {
            "arn": "arn:aws:logs:ap-northeast-1:1234567890123:log-group:my-flow-log:*",
            "creationTime": 1441171757731,
            "metricFilterCount": 0,
            "logGroupName": "my-flow-log",
            "storedBytes": 295044
        }
    ]
}

#
# log stream の確認
#
$ aws logs describe-log-streams --log-group-name my-flow-log --limit 1
{
    "nextToken": "Kwfr0bfVKkYk4OrYazFRiV9H8rv4UGy1FbpS1glScpQSaNRo5QzdVDFjcfNhUHBLGZ2o2Gjxtlg9X4bBz7A4o1AZPXuMpUPe4rmZeTMdAPLFJzThySAcBa4y8klGKJgC9dwd4QyKSQ-f-VVvDFHxQ1Ir7MBofhZichsiaW_YEEaUFuvyLBWpElCBHPw1vXFlb1M8qpkQLoAgtyvr1_q9Icrbb-nio4DueZ-rV9osAPSNptfa6HktfykKubkWc-0ziWV1PZyBiA4SeXJjQ9MBY0IujbvmAgX0t2-ne58b_bXOa0LzKo6Tvl1dTqd_3HK1BGXnwwUuoxT18GqEkUGlqWPJb00xQrDjIvuDXWaZL5iluonc4Da-hp0XZpbLPGdtVTp9oC2nXlieJZSaUW380BiaQ609JGGoTofv0fhX2R8",
    "logStreams": [
        {
            "firstEventTimestamp": 1441198464000,
            "lastEventTimestamp": 1441204404000,
            "creationTime": 1441199107032,
            "uploadSequenceToken": "49545657805769367170690858206544188070413463828968768866",
            "logStreamName": "eni-75ba322d-all",
            "lastIngestionTime": 1441204508413,
            "arn": "arn:aws:logs:ap-northeast-1:1234567890123:log-group:my-flow-log:log-stream:eni-75ba322d-all",
            "storedBytes": 0
        }
    ]
}

#
# 実際の log の確認
#
$ aws logs get-log-events --log-group-name my-flow-log --log-stream-name eni-xxxxxx-all --limit 1
{
    "nextForwardToken": "f/32139928691387192232880068449704027033738899140716593658",
    "events": [
        {
            "ingestionTime": 1441204368952,
            "timestamp": 1441204247000,
            "message": "2 1234567890123 eni-xxxxxxxx xx.x.x.xxx yy.y.y.yyy 49907 80 6 4 216 1441204247 1441204306 ACCEPT OK"
        }
    ],
    "nextBackwardToken": "b/32139928691387192232880068449704027033738899140716593658"

  • nextForwardToken と nextBackwardToken が気になる(後述)

教材

今回も Terraform にて教材を用意。


github.com

terraform apply を実行すると下図のような環境が作成される。(はず!)
  
20150904170441  
尚、事前に AWS CLI にて CloudWatch Logs の log-group-name を作成しておく必要がある。  

 #
# aws cli のバージョン確認
#
$ aws --version
aws-cli/1.7.29 Python/2.7.9 Windows/8]

#
# CloudWatch Logs の log-group-name を作成
#
$ aws logs create-log-group --log-group-name my-flow-log

#
# 作成済みの log-group を確認
#
$ aws logs describe-log-groups
{
    "logGroups": [
        {
            "arn": "arn:aws:logs:ap-northeast-1:1234567890123:log-group:my-flow-log:*",
            "creationTime": 1441171757731,
            "metricFilterCount": 0,
            "logGroupName": "my-flow-log",
            "storedBytes": 295044
        }
    ]
}

 

メモ 

実際のログを見てみる

  • ログストリームの確認
$ aws logs describe-log-streams --log-group-name my-flow-log
{
    "logStreams": [
        {
            "firstEventTimestamp": 1441325286000,
            "lastEventTimestamp": 1441341377000,
            "creationTime": 1441325893365,
            "uploadSequenceToken": "49545657805903171641881967696867665731736007865060558786",
            "logStreamName": "eni-a969e3f1-all",
            "lastIngestionTime": 1441341496403,
            "arn": "arn:aws:logs:ap-northeast-1:123456789012:log-group:my-flow-log:log-stream:eni-a969e3f1-all",
            "storedBytes": 277212
        },
        {
            "firstEventTimestamp": 1441325567000,
            "lastEventTimestamp": 1441341717000,
            "creationTime": 1441326209899,
            "uploadSequenceToken": "49545657805635562699499671795513147378461817750733979906",
            "logStreamName": "eni-c26fe59a-all",
            "lastIngestionTime": 1441341812948,
            "arn": "arn:aws:logs:ap-northeast-1:123456789012:log-group:my-flow-log:log-stream:eni-c26fe59a-all",
            "storedBytes": 62674
        },
        {
            "firstEventTimestamp": 1441325390000,
            "lastEventTimestamp": 1441341480000,
            "creationTime": 1441325991488,
            "uploadSequenceToken": "49545657805724765680293733998369590602400046244230595906",
            "logStreamName": "eni-c46ee49c-all",
            "lastIngestionTime": 1441341594125,
            "arn": "arn:aws:logs:ap-northeast-1:123456789012:log-group:my-flow-log:log-stream:eni-c46ee49c-all",
            "storedBytes": 53253
        }
    ]
}

上記の通り ENI 毎にストリームが作成されていることが判る。また、プロトコルは指定していないのでストリーム名が
eni-xxxxxxx-all となっている。

  • ログの確認
$ aws logs get-log-events --log-group-name my-flow-log --log-stream-name eni-c46ee49c-all --limit 1
{
    "nextForwardToken": "f/32142989089553022185885816715984568394922307628562055307",
    "events": [
        {
            "ingestionTime": 1441341594125,
            "timestamp": 1441341480000,
            "message": "2 123456789012 eni-c46ee49c 10.0.1.218 10.0.1.63 80 54033 6 2 112 1441341480 1441341532 ACCEPT OK"
        }
    ],
    "nextBackwardToken": "b/32142989089553022185885816715984568394922307628562055307"
}

 
message のスペースで句切られた値が実際のログメッセージとなる。尚、各フィールドについては以下のとおり
ドキュメントより抜粋)。

フィールド 説明
バージョン VPC フローログバージョン。
account-id フローログの AWS アカウント ID。
interface-id ログストリームが適用されるネットワークインターフェイスの ID。
srcaddr 送信元 IP アドレス。ネットワークインターフェイスの IP アドレスは常にそのプライベート IP アドレスです。||dstaddr|送信先 IP アドレス。ネットワークインターフェイスの IP アドレスは常にそのプライベート IP アドレスです。||srcport|トラフィックの送信元ポート。
dstport トラフィックの送信先ポート。プロトコル トラフィックの IANA プロトコル番号。詳細については、「割り当てられたインターネットプロトコル番号」を参照してください。
packets キャプチャウィンドウ中に転送されたパケットの数。
bytes キャプチャウィンドウ中に転送されたバイト数。
start キャプチャウィンドウの開始時刻(Unix 時間)。
end キャプチャウィンドウの終了時刻(Unix 時間)。
action トラフィックに関連付けられたアクション: ACCEPT: 記録されたトラフィックは、セキュリティグループまたはネットワーク ACL で許可されています。REJECT: 記録されたトラフィックは、セキュリティグループまたはネットワーク ACL で許可されていません。
log-status フローログのロギングステータス。OK: データは正常に CloudWatch Logs に記録されています。NODATA: キャプチャウィンドウ中にネットワークインター フェイスとの間で行き来するネットワークトラフィックはありませんでした。SKIPDATA: 一部のフローログレコードはキャプチャウィンドウ中にスキップされました。これは、内部的なキャ パシティー制限、または内部エラーが原因である可能性があります。

なるほど、なるほど。 
 
上記の例だと…  

  • 対象のネットワークインターフェースは eni-c46ee49c
  • 送信元は 10.0.1.218
  • 宛先は 10.0.1.63
  • 送信元ポートは 80
  • 宛先ポートは 54033

で許可された通信と読み取ることが出来る。

メトリクスフィルタ

尚、CloudWatch Logs にはフィルタを定義した上で、設定したフィルタにマッチした
ログをモニタリングすることが出来る。

  • メトリクスフィルタのテスト

フィルタ定義のテストをすることが出来る。

 aws logs test-metric-filter 
        --filter-pattern '[version,account_id,interface_id,srcaddr,dstaddr,srcport,dstport=80,protocol,packets,bytes,start,end,action,log_status]' 
        --log-event-messages '2 1234567890123 eni-xxxxxxxx xx.x.x.xxx yy.y.y.yyy 49907 80 6 4 216 1441204247 1441204306 ACCEPT OK'

以下のように出力される。

 {
    "matches": [
        {
            "eventNumber": 1,
            "eventMessage": "2 1234567890123 eni-xxxxxxxx xx.x.x.xxx yy.y.y.yyy 49907 80 6 4 216 1441204247 1441204306 ACCEPT OK",
            "extractedValues": {
                "$dstaddr": "yy.y.y.yyy",
                "$dstport": "80",
                "$start": "1441204247",
                "$account_id": "1234567890123",
                "$action": "ACCEPT",
                "$packets": "4",
                "$protocol": "6",
                "$interface_id": "eni-xxxxxxxx",
                "$bytes": "216",
                "$version": "2",
                "$srcaddr": "xx.x.x.xxx",
                "$log_status": "OK",
                "$srcport": "49907",
                "$end": "1441204306"
            }
        }
    ]
}
  • メトリクスフィルタの定義

テストしたフィルタを定義する。

aws --region ap-northeast-1 logs put-metric-filter 
    --log-group-name "my-flow-log" 
    --filter-name "SSHAccess" 
    --filter-pattern '[version,account_id,interface_id,srcaddr,dstaddr,srcport,dstport=22,protocol,packets,bytes,start,end,action,log_status]' 
    --metric-transformations 'metricValue=1,metricNamespace=foo,metricName=bar'
 
  • メトリクスフィルタの確認
$ aws --region ap-northeast-1 logs describe-metric-filters --log-group-name my-flow-log
{
    "metricFilters": [
        {
            "filterName": "SSHAccess",
            "metricTransformations": [
                {
                    "metricValue": "1",
                    "metricNamespace": "LogMetrics",
                    "metricName": "SSHAccess"
                }
            ],
            "creationTime": 1441343985034,
            "filterPattern": "[version,account_id,interface_id,srcaddr,dstaddr,srcport,dstport=22,protocol,packets,bytes,start,end,action,log_status]"
        },
        {
            "filterName": "version-account-id-interface-id-srcaddr-dstaddr-srcport-dstport-80-protocol-packets-bytes-start-end-action-log-status",
            "metricTransformations": [
                {
                    "metricValue": "1",
                    "metricNamespace": "LogMetrics",
                    "metricName": "HTTPAccess"
                }
            ],
            "creationTime": 1441343592012,
            "filterPattern": "[version,account_id,interface_id,srcaddr,dstaddr,srcport,dstport=80,protocol,packets,bytes,start,end,action,log_status]"
        }
    ]
}

フィルタを定義するとフィルタに対するアラートを設定することが出来る。
20150904143610

暫くすると CloudWatch のメトリクスとしても確認することが出来るようになる。
20150904143703

なるほど。

ということで

ざくっと VPC Flow Logs と CloudWatch Logs を弄ってみたけどログなので  
リアルタイム処理をしてみたいのでCloudWatch Logs Subscriptions を利用して
VPC Flow Logs のログを弄ってみたいと思う。

つづく。

元記事はこちら

VPC Flow Logs Tutorial