BSD界隈四方山話
第88回 DTraceの使い方 その8
ネットワーク2
DTraceを使うとネットワーク通信に関するデータを簡単にモニタリングしたり集計して表示させることができます。コマンドを使っても似たようなデータは得られますが,
まず簡単なサンプルから見てみましょう。次のDTraceスクリプトはtcp:::accept-establishedをモニタリングして,
リスト tcpaccept.
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("Tracing... Hit Ctrl-C to end.\n");
}
tcp:::accept-established
{
@num[args[2]->ip_saddr, args[4]->tcp_dport] = count();
}
dtrace:::END
{
printf(" %-26s %-8s %8s\n", "HOST", "PORT", "COUNT");
printa(" %-26s %-8d %@8d\n", @num);
}
実行すると次のような結果が得られます。ファイアウォールやinetdを使って似たようなデータを取得することもできますが,
図 tcpaccept.
# ./tcpaccept.d Tracing... Hit Ctrl-C to end. ^C HOST PORT COUNT 192.168.1.101 22 1 192.168.1.39 22 1 192.168.1.101 2049 2 #
似たようスクリプトで対象をtcp:::accept-establishedではなくtcp:::connect-establishedを使っても似たようなデータを取得できます
リスト tcpconnect.
#!/usr/sbin/dtrace -s
#pragma D option quiet
dtrace:::BEGIN
{
printf("Tracing... Hit Ctrl-C to end.\n");
}
tcp:::connect-established
{
@num[args[2]->ip_daddr, args[4]->tcp_dport] = count();
}
dtrace:::END
{
printf(" %-26s %-8s %8s\n", "HOST", "PORT", "COUNT");
printa(" %-26s %-8d %@8d\n", @num);
}
図 tcpconnect.
# ./tcpconnect.d Tracing... Hit Ctrl-C to end. ^C HOST PORT COUNT 192.168.1.10 57507 1 #
tcp:::sendとtcp:::receiveをモニタリングして送信元IP,
リスト tcpio.
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option switchrate=10hz
dtrace:::BEGIN
{
printf("%-3s %15s:%-5s %15s:%-5s %6s %s\n", "CPU",
"LADDR", "LPORT", "RADDR", "RPORT", "BYTES", "FLAGS");
}
tcp:::send
{
this->length = args[2]->ip_plength - args[4]->tcp_offset;
printf("%-3d %15s:%-5d -> %15s:%-5d %6d (", cpu,
args[2]->ip_saddr, args[4]->tcp_sport,
args[2]->ip_daddr, args[4]->tcp_dport, this->length);
}
tcp:::receive
{
this->length = args[2]->ip_plength - args[4]->tcp_offset;
printf("%-3d %15s:%-5d <- %15s:%-5d %6d (", cpu,
args[2]->ip_daddr, args[4]->tcp_dport,
args[2]->ip_saddr, args[4]->tcp_sport, this->length);
}
tcp:::send,
tcp:::receive
{
printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : "");
printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : "");
printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : "");
printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : "");
printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : "");
printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : "");
printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : "");
printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
printf("\b)\n");
}
実行すると次のような感じです。
図 tcpio.
# ./tcpio.d CPU LADDR:LPORT RADDR:RPORT BYTES FLAGS 0 192.168.185.50:80 <- 192.168.185.1:60622 30 (FIN|ACK) 0 192.168.185.50:80 -> 192.168.185.1:60622 30 (ACK) 0 192.168.185.50:80 -> 192.168.185.1:60622 30 (FIN|ACK) 0 192.168.185.50:80 <- 192.168.185.1:60622 30 (ACK) 0 192.168.185.50:22 <- 192.168.185.1:52416 82 (PUSH|ACK) 0 192.168.185.50:22 -> 192.168.185.1:52416 58 (PUSH|ACK) 0 192.168.185.50:22 <- 192.168.185.1:52416 30 (ACK) 0 192.168.185.50:80 <- 192.168.185.1:60621 575 (PUSH|ACK) 0 192.168.185.50:80 -> 192.168.185.1:60621 210 (PUSH|ACK) 0 192.168.185.50:80 <- 192.168.185.1:60621 30 (ACK) ^C #
特定の通信に絞り込めばTCPハンドシェークがどのように進むのかの概要も見ることができます。ネットワーク通信の中身を感じ取る方法としてはなかなか手軽で公開的な方法ではないかと思います。
※ ここに掲載したサンプルスクリプトは"DTrace Dynamic Tracing In Oracle Solaris, Mac OS X & FreeBSD", by Brendan Gregg and Jim Mauro P.
勉強会
第61回 3月23日 (木) 19:00~FreeBSD勉強会:リキャップ・ ザ・ AsiaBSDCon 2017 ~日本語でふりかえるABC~
2017年3月9~12日まで東京でAsiaBSDCon 2017が開催される予定です。ぜひこのカンファレンスにご参加いただきたいわけなのですが,
3月のFreeBSD勉強会では,
FreeBSD勉強会 発表者募集
FreeBSD勉強会では発表者を募集しています。FreeBSDに関して発表を行いたい場合,
バックナンバー
BSD界隈四方山話
- 第142回 FreeBSD Meltdown対策機能による性能影響ベンチマーク
- 第141回 FreeBSD 11.2は6月リリース
- 第140回 AsiaBSDCon 2018
- 第139回 OpenBSD,Meltdownバイナリパッチ提供開始
- 第138回 OpenBSD,Meltdown対策機能をマージ
- 第137回 FreeBSDのMeltdown/Spectre対策,11系にマージ
- 第136回 FreeBSDのMeltdown/Spectre対策
- 第135回 NetBSDにおけるMeltdown/Spectre対策状況
- 第134回 Intelマイクロコードアップデート適用の一時中止を
- 第133回 OpenBSD on iTWire