RTTを検索するSQL文
今回は3ウェイハンドシェイクのSYNとSYN+ACKパケット間のタイム差を計算することで距離を推定します。以下のSQL文を実行します。
select (synack.mintime - syn.mintime) as RTT,
syn.ip_src,syn.ip_dst,syn.src_port,syn.dst_port,syn.proto from
(select min(timestamp) as mintime, ip_src,ip_dst,src_port,dst_port,proto from packets
where tcpflags = 'S'
group by ip_src,ip_dst,src_port,dst_port,proto) syn,
(select min(timestamp) as mintime, ip_src,ip_dst,src_port,dst_port,proto from packets
where tcpflags = 'SA'
group by ip_src,ip_dst,src_port,dst_port,proto) synack
where syn.ip_src = synack.ip_dst
and syn.ip_dst = synack.ip_src
and syn.src_port = synack.dst_port
and syn.dst_port = synack.src_port
and syn.proto = synack.proto
このSQL文を解説します。2つのselect文によって仮想テーブルを作り、そのテーブル同士を結合してタイム差を計算する構造になっています。
(select min(timestamp) as mintime, ip_src,ip_dst,src_port,dst_port,proto from packets
where tcpflags = 'S'
group by ip_src,ip_dst,src_port,dst_port,proto) syn
このsynテーブルはpacketsテーブルからSYNフラグのみが立ったパケットを検索し、その中で最も小さいタイムスタンプと5タプル(IPの送信元アドレス/宛先アドレス、プロトコル番号、送信元ポート/宛先ポートの情報の5つ)の組み合わせを取得します。
(select min(timestamp) as mintime, ip_src,ip_dst,src_port,dst_port,proto from packets
where tcpflags = 'SA'
group by ip_src,ip_dst,src_port,dst_port,proto) synack
続いて、同様にSYN+ACKが立ったパケットの最小タイムスタンプと5タプルの組み合わせを取得します。このとき、3ウェイハンドシェイクの構造上、この5タプルはSYNで取得した5タプルとは、IPアドレス、ポートの送信元、宛先の値が逆になっていることに注意が必要です。
そのため、この2つの仮想テーブルを結合する際には変則的な結合条件を適用します。
where syn.ip_src = synack.ip_dst
and syn.ip_dst = synack.ip_src
and syn.src_port = synack.dst_port
and syn.dst_port = synack.src_port
and syn.proto = synack.proto
アドレスとポートを逆に結合しているところに違和感を覚えるかと思いますが、これで正しい集計結果が得られます。
結果として得られたRTTの値は「0.213」「0.208」とあります。200ミリ秒前後のRTTであることが推測されます。なお開発環境から試したpingの結果を見ると、先の数値と大きな乖離(かいり)はありません。この手法で得られた数値をpingの代替として扱っても問題ないと言えそうです。
これにより、通信相手が日本国内か外国にありそうかといった大まかな分類や、経路変更などによるRTTの変化タイミングの検知が可能になります。この手法は、SYNの再送が起こると秒単位の遅延が記録されます。そのためネットワークの品質低下によるレスポンスの悪化をトラッキングする用途にも使えます。問題があると判断した通信先はtracerouteコマンドなどを併用して詳しく調べてみるなどのきっかけにもなります。
次回はHTTPSの暗号化通信のトラフィックを分析する過程で、TLSのネゴシエーションから通信先を読み取る手法について解説します。
デベルアップジャパン代表
グリーン CTO