0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VPC Flow Logsからログを調査してと言われたときに使えるawk

0
Posted at

はじめに

あまりセキュリティを強固に保っていない社内環境でVPC Flow Logsを確認して怪しいアクセスがあったかどうかを確認してほしいと依頼があった際にすぐに確認できるawkコマンドについてまとめてみます。

最初にやること

ログファイルのダウンロード

Flow Logが出力されているS3からログをダウンロードする必要があります。
Flow Logは大量にあるため、手作業でやっていたらキリがありません。

そこで以下CloudShellを使用してS3に出力されているログをCloudShel環境に一度出力します。

たとえば5月10日~13日の分のログを出力したい場合

aws s3 sync \
s3://{S3名称}/AWSLogs/{AccountId}/vpcflowlogs/{region}/yyyy/mm/ \
./vpcflowlogs \
--exclude "*" \
--include "10/*" \
--include "11/*" \
--include "12/*" \
--include "13/*"

オプションの意味

--exlude "*"     -> 一旦すべてを除外する
--include "dd/*" -> 対象の日付配下にあるすべてのファイルおよびプレフィックスにあるもの 

--exludeで一度すべてを除外するのはaws s3 syncコマンドが全部コピーする動きになるからです。

イメージ
2026/05/
├─10/
│  └─log
├─11/
│  └─log
└─12/
   └─log

つまり、日付配下にある全てのログファイルをvpcflowlogsディレクトリにコピーする動きとなる。

ファイルの解凍

ダウンロードしたら、ファイルを解凍します。

# vpcflowlogs/配下にあるgzipファイルを解凍
gunzip ./vpcflowlogs/**/*.gz

ログの中身を調査

ここまでで事前準備は完了です。

以下でログのカラム名を出力します。

awk '{print $0}' $(find ./vpcflowlogs/10 -type f) | head -1

# 出力結果
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-stattus 

print $0はファイルの中身をそのまま全部表示する
しかしhead -1を指定しているので1行目のみを表示している。
また$0以降は以下

記号 意味
$0 行全体
$1 1列目
$2 2列目
$NF 最後の列

出力されたカラム名は以下の意味となる

version VPC    Flow Logsのフォーマットバージョン番号
account-id     AWSのアカウントID
interface-id   通信が発生したENI
srcaddr        通信元IP
dstaddr        宛先IP
srcport        送信元ポート
dstport        宛先ポート
protocol       プロトコル
packets        パケット数
bytes          バイト数
start          通信開始時間
end            通信終了時間
action         判定 (ACCEPT or REJECT)
log-stattus    ログの状態 (OK or NODATA(通信なし) or SKIPDATA)
記号 意味
$0 行全体
$1 1列目
$2 2列目
$NF 最後の列

上記表から当てはめると以下になる

$1 version VPC     Flow Logsのフォーマットバージョン番号
$2 account-id      AWSのアカウントID
$3 interface-id    通信が発生したENI
$4 srcaddr         通信元IP
$5 dstaddr         宛先IP
$6 srcport         送信元ポート
$7 dstport         宛先ポート
$8 protocol        プロトコル
$9 packets         パケット数
$10 bytes          バイト数
$11 start          通信開始時間
$12 end            通信終了時間
$13 action         判定 (ACCEPT or REJECT)
$14 log-stattus    ログの状態 (OK or NODATA(通信なし) or SKIPDATA)

この内容を念頭に置いておくと以降のawsコマンドの意味が理解できると思います。

怪しいIPを抽出

awk '{print $4}' $(find ./vpcflowlogs -type f) | sort | uniq -c | sort -nr | head -20

コマンドの意味

  • find ./vpcflowlogs -type fでvpcflowlogsディレクトリ配下にあるすべてのファイルのパス一覧を取得
  • {print $4}でそれらのファイル全て読み込んで4列目を抽出する
  • sort: 値をソートする
  • uniq -c: 同じ値の件数をカウント
  • sort -nr 件数の多い順に並べる
  • head -20
# 出力結果例
# 左がアクセス回数、右がアクセス元IP
900 100.xxx.xxx.xx
400 200.xxx.xxx.xx

インターネット向けの通信の抽出

# 送信元が10.0.x.xでかつ、プライベートIPではない通信を抽出し、送信元IP・宛先IP・宛先ポートを表示する
awk '$4 ~ /^10.\.0\./ && $5 !~ /^(10\.|172\.16\.|172\.17\.|172\.18\.|192\.168\.)/ {print $4, $5, $7}'

コマンドの意味

  • find ./vpcflowlogs -type fでvpcflowlogsディレクトリ配下にあるすべてのファイルのパス一覧を取得
  • $4 ~ /^10\.10\. で「10.0で始まる」 -> つまり送信元が10.0.x.xの通信
  • $4 ~ /^10.\.0\./ && $5 !~ /^(10\.|172\.16\.|172\.17\.|172\.18\.|192\.168\.) で送信元IPが10.0.x.x かつ 宛先IPが!~で一致しないことを示している -> つまり、「172.16.x.x」「172.17.x.x」「172.18.x.x」「192.178.x.x」に一致しないを指定しているためプライベートIPアドレス帯を除外している
  • print $4, $5, $7で送信元IP、宛先IP、ポートを指定して出力

送信元IP 宛先IP ポートを出力

上記を使用してVPC Flow Logsのログチェックは最短でできそうですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?