
ネットワークフローを識別子にハッシュ化するためのオープン標準、通称「Community IDs」。
ZeekやSuricataなどのさまざまな監視アプリケーションからのフローデータを処理する際、あるデータセットから別のデータセットへすばやくピボットできることが望ましい場合がよくあります。必要なフロータプル情報は通常データセットに含まれていますが、そのような「結合」の詳細は、特にコーナーケースでは厄介なことがあります。この仕様は「コミュニティID」フローハッシングを説明するもので、特定のネットワークフローを表す文字列識別子の生成を標準化し、ピボットを単純な文字列比較にまで簡素化します。
function community_id_v1(ipaddr saddr, ipaddr daddr, port sport, port dport, int proto, int seed=0)
{
# Get seed and all tuple parts into network byte order
seed = pack_to_nbo(seed); # 2 bytes
saddr = pack_to_nbo(saddr); # 4 or 16 bytes
daddr = pack_to_nbo(daddr); # 4 or 16 bytes
sport = pack_to_nbo(sport); # 2 bytes
dport = pack_to_nbo(dport); # 2 bytes
# Abstract away directionality: flip the endpoints as needed
# so the smaller IP:port tuple comes first.
saddr, daddr, sport, dport = order_endpoints(saddr, daddr, sport, dport);
# Produce 20-byte SHA1 digest. "." means concatenation. The
# proto value is one byte in length and followed by a 0 byte
# for padding.
sha1_digest = sha1(seed . saddr . daddr . proto . 0 . sport . dport)
# Prepend version string to base64 rendering of the digest.
# v1 is currently the only one available.
return "1:" + base64(sha1_digest)
}
function community_id_icmp(ipaddr saddr, ipaddr daddr, int type, int code, int seed=0)
{
port sport, dport;
# ICMP / ICMPv6 endpoint mapping directly inspired by Zeek
sport, dport = map_icmp_to_ports(type, code);
# ICMP is IP protocol 1, ICMPv6 would be 58
return community_id_v1(saddr, daddr, sport, dport, 1, seed);
}
コミュニティIDは追加のフロー識別子であり、モニターがすでにサポートしている既存のフロー識別メカニズムを置き換える必要はありません。ただし、必要に応じて、モニターがコミュニティIDのみをログに記録するように構成することも問題ありません。
コミュニティIDは、モニターがフローを生成するときに計算することもできますし、そのレコードが必要なフローエンドポイント情報をすべて伝えている場合には、後の段階で既存のフローレコードに追加することもできます。
コミュニティIDの衝突は望ましくありませんが、致命的とは見なされません。ユーザーはフローのタイミング情報と、場合によってはモニター固有のIDメカニズム(できればコミュニティIDよりも強力なもの)を曖昧さの解消のために引き続き保持しているはずだからです。
ハッシュメカニズムはシードを使用して、コミュニティID使用の「ドメイン」を追加で制御できるようにします。シードはデフォルトで0なので、このメカニズムは邪魔にならず、それに関心のない運用者にとっては運用に影響しません。
IDのバージョン1では、ハッシュアルゴリズムはSHA1です。将来のハッシュバージョンでは、これを切り替えたり、追加の構成を許可したりする可能性があります。
バイナリの20バイトSHA1結果はbase64エンコードされ、通常のASCIIベースのSHA1表現と比較して出力量を削減します。これは、計算時間ではなくスペースが主な関心事であることを前提としており、後のバージョンで設定可能になる可能性があります。
結果のフローIDにはバージョン番号が含まれており、基盤となるコミュニティID実装を明示します。これにより、ユーザーはアルゴリズムの将来の変更をサポートしながら、等価なもの同士を比較していることを確認できます。たとえば、あるモニターのIDバージョンがVLAN IDを組み込んでいるが、別のモニターは組み込んでいない場合、ハッシュ値の比較は確実に失敗するはずです。この機能のより複雑な形式では、実装バージョンに加えて構成設定をキャプチャできる可能性があります。
バージョニングスキームは現在、単にハッシュ値に「:」を前置するだけで、現在のバージョン1では次のようになります:
1:hO+sN4H+MG5MY/8hIrXPqc4ZQz0=
ハッシュ入力は32ビット境界にアラインされます。フロータプルコンポーネントは、ホストのハードウェアに関係なく順序を標準化するために、ネットワークバイトオーダー(ビッグエンディアン)を使用します。
ハッシュ入力は、フロータプルから方向性を除去するために順序付けられます。必要に応じてエンドポイントを入れ替え、数値的に小さいIP:portタプルが先に来るようにします。IPアドレスが等しい場合は、ポートが決定します。たとえば、次のnetflow 5タプルは、両方とも10.0.0.1、127.0.0.1、1234、80のシーケンスに順序付けられるため、同一のコミュニティIDハッシュを生成します。
このバージョンには次のプロトコルとフィールドが含まれます:
TCP / UDP / SCTP:
IP src / IP dst / IP proto / source port / dest port
ICMPv4 / ICMPv6:
IP src / IP dst / IP proto / ICMP type + "counter-type" or code
ICMPタイプとコードの正確な処理はZeekから取られています。実装はこちらを参照してください:
完全な実装はpycommunityidパッケージで利用できます。さまざまなプロトコルに対する正しい計算を検証するための一連のテストが含まれています。新規実装のガイドとして推奨します。
このリポジトリのcommunity-id.pyスクリプトでも、ハッシュ化された値のバイトレイアウトを含むより小さな実装を利用できます(packet_get_comm_id()を参照)。開始するには--helpとmake.shを参照してください:
$ ./community-id.py --help
usage: community-id.py [-h] [--seed NUM] PCAP [PCAP ...]
Community flow ID reference
positional arguments:
PCAP PCAP packet capture files
optional arguments:
-h, --help show this help message and exit
--seed NUM Seed value for hash operations
--no-base64 Don't base64-encode the SHA1 binary value
--verbose Show verbose output on stderr
トラブルシューティングのために、この実装はbase64操作を省略することに対応しており、SHA1ハッシュ計算に入るバイトの正確なシーケンスに関する追加の詳細を提供できます。
このリポジトリのbaselineディレクトリには、コミュニティID実装が正しく機能することを検証するためのデータセットが含まれています。
コミュニティIDのさまざまな側面について、GitHubで自由に議論してください: https://github.com/corelight/community-id-spec/issues
その他のIPベースのプロトコル:
IP src / IP dst / IP proto
上記は現在、ネスト(IP in IP、v6 over v4など)やVLANやMPLSなどのカプセル化の処理方法をカバーしていません。
ネットワークモニターが上記のいずれのプロトコル構成もサポートしていない場合、フローIDとして空の文字列(または別の非衝突値)を安全に報告できます。
v1はプロトタイプとお考えください。コミュニティ、特にIDの実装者や運用ユーザーからのフィードバックを_大いに_歓迎します。https://github.com/corelight/community-id-spec のGitHubプロジェクトに直接issueを作成するか、Christian Kreibich ([email protected]) までご連絡ください。
有益な議論とフィードバックを提供してくださったVictor Julien、Johanna Amann、Robin Sommer、そしてすべての実装者とサポーターに感謝します。