CloudShell 上の DuckDB に VPC フローログを取り込んでみた
皆さんは、AWS の VPC フローログを取得していますでしょうか?
おそらく、取っている方が多いのかなと思っています。
以前、DuckDB に関する記事をいくつか書きました。
その中で以下の記事では、AWS の CloudShell に DuckDB を入れて、S3 の ALB のログを SQL ライクに参照する話を書きました。
今回はその VPC フローログ版になります。
本題の前の簡単な説明
VPC フローログとは
VPC フローログは、VPC のネットワークインターフェイスとの間で行き来する IP トラフィックに関する情報をキャプチャできるようにする機能です。
上記の通り、VPC フローログとは、AWS VPC 内の IP トラフィックのログとその取得する機能を指します。
例えば、ALB から EC2 への IP パケットの状況や、ECS のコンテナから別のコンテナへの通信などを捕捉して、正常に通信がされているかを確認することができます。
ログ自体は、CloudWatch Logs や S3、Data Firehose への発行が可能です。
今回は、S3 に発行されたログを CloudShell 上の DuckDB を使って整形します。
また、この記事では、VPC フローログの設定については割愛します。
DuckDB とは
DuckDB とは、オープンソースの組み込み型 OLAP (Online Analytical Processing) SQLデータベース管理システム(DBMS)です。
詳細は上にも挙げた過去記事にも書いたり、色んな方が詳しく説明されているので、そちらに委ねるとして、、、
個人的なオススメとしては、複雑な設定など無く、様々な環境で利用が簡単にできること です。
また、バージョン 1.2.1
から DuckDB UI という UI 機能が追加され、より便利になったと感じています。[1]
本題
実行にあたっての前提や準備
DuckDB について
使用する DuckDB のバージョンは 1.2.1
です。
なので、CloudShell で使う際のコマンドは以下になります。
curl -LO https://github.com/duckdb/duckdb/releases/download/v1.2.1/duckdb_cli-linux-amd64.zip
unzip duckdb_cli-linux-amd64.zip
./duckdb
CloudShell を立ち上げて、上記のコマンドを入れると、DuckDB が立ち上がります。
🦆上のコマンド実施した結果🦆
VPC フローログについて
今回、VPC フローログはデフォルトの形式のものを使います。
具体的には、以下のドキュメントに書かれているバージョン 2 のもので、項目としては version
から log-status
の 14 項目を出力したものを対象にしています。
また、冒頭にも挙げた通り、S3 に発行したものを使いますが、発行するログファイル形式は Text のものを使用します。
S3 への出力に関しては、Text 形式以外にも、Parquet 形式も出力可能です。
ちなみにですが、Parquet 形式であれば DuckDB でそのまま扱うことができます。
扱うログファイルのイメージは以下のとおりです。
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
2 000000000000 eni-01234567890123456 10.0.0.1 10.0.0.2 443 443 6 1 123 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.3 10.0.0.1 443 443 6 12 12345 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.1 10.0.0.5 443 443 6 2 1234 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.4 10.0.0.1 443 443 6 23 12 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.1 10.0.0.3 443 443 6 38 1234 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.6 10.0.0.1 443 443 6 2 123 1743476400 1743476700 ACCEPT OK
2 000000000000 eni-01234567890123456 10.0.0.5 10.0.0.1 443 443 6 29 1234 1743476400 1743476700 ACCEPT OK
いざ実践!
S3 からログファイルの取得
CloudShell にログファイルをダウンロードするには、AWS CLI の aws s3 cp
を使用します。
あくまでも例ですが、以下のようなコマンドになります。[2]
aws s3 cp s3://<S3_BUCKET>/AWSLogs/<ACCOUNT_ID>/vpcflowlogs/<REGION>/YYYY/MM/DD/ ./ --recursive
取得したログを CloudShell でテーブル化
CloudShell で先程導入した DuckDB を立ち上げて、以下の SQL を実行します。
CREATE TABLE vpc_flow_logs AS
SELECT
"version",
"account-id",
"interface-id",
"srcaddr",
"dstaddr",
"srcport",
"dstport",
"protocol",
"packets",
"bytes",
-- (1)start と end は UNIX 時間なので、9時間足す。
to_timestamp("start") + INTERVAL 9 HOUR AS start_jst,
to_timestamp("end") + INTERVAL 9 HOUR AS end_jst,
"action",
"log-status"
FROM read_csv(
'./*.gz', -- (2)ワイルドカードが使える
columns={
'version': 'VARCHAR',
'account-id': 'VARCHAR',
'interface-id': 'VARCHAR',
'srcaddr': 'VARCHAR',
'dstaddr': 'VARCHAR',
'srcport': 'VARCHAR', -- (3)致し方なく VARCHAR で定義
'dstport': 'VARCHAR', -- (3)致し方なく VARCHAR で定義
'protocol': 'VARCHAR', -- (3)致し方なく VARCHAR で定義
'packets': 'VARCHAR', -- (3)致し方なく VARCHAR で定義
'bytes': 'VARCHAR', -- (3)致し方なく VARCHAR で定義
'start': 'BIGINT',
'end': 'BIGINT',
'action': 'VARCHAR',
'log-status': 'VARCHAR'
},
delim=' ',
quote='"',
escape='"',
header=True,
auto_detect=False
);
細かいですが、上記の SQL に関しての補足説明です。
補足説明(1) データの整形も可能
UNIX 時間だと、人間が扱うには難しいので、to_timestamp
関数を使って変換しています。
加えて、タイムゾーンの考慮も含めて、9時間を足して、日本時間にしています。
補足説明(2) ファイルの指定でワイルドカードが使える
上記のファイルの指定でワイルドカードが使えるので、すべてのファイルパスを記載せずに S3 から取得したすべてのログファイルを1つのテーブルにすることが可能です。
(トータルで100万行ぐらいであれば、数秒でテーブル化できます。)
-
となる
補足説明(3) 数値のデータ型でもパケットが無い場合は これは、VPC フローログの仕様の話ですが、
本来はポートやバイト数などは数値なので、INTEGER
や BIGINT
にしたいところですが、該当時間間隔内にログがないと -
となるため、致し方なく VARCHAR
にしています。[3]
テーブル化した中身の確認
テーブル化すると、中身の確認ができます。
DuckDB では、FROM
-first syntax があり、以下の SQL で全件の参照ができます。(表示できる件数の上限はありますが。。。)
FROM vpc_flow_logs; -- SELECT * FROM vpc_flow_logs; と同じ。
ここまで、問題なく行けば、あとは 煮るなり、焼くなり、二宮和なり です。
IP アドレスでフィルタリングしたり、CSV に書き出したり、確認したいことに応じて SQL ライクに操作ができます!٩(๑>∀<๑)۶
まとめ
今回、DuckDB を CloudShell 上で使うことで Athena の簡易的な代替にすることができるので、運用開始当初のスモールスタートであれば、使い勝手のいい選択肢だと感じました。
また、この記事では紹介していないですが、DuckDB は Parquet 形式も扱うことができるので、今後はそのケースもどこかでやってみたいと思いました。

私たち BABY JOB は、子育てを取り巻く社会のあり方を変え、「すべての人が子育てを楽しいと思える社会」の実現を目指すスタートアップ企業です。圧倒的なぬくもりと当事者意識をもって、子どもと向き合う時間、そして心のゆとりが生まれるサービスを創出します。baby-job.co.jp/
Discussion