iptables を有効にして LOG
に設定します 着信接続用。ルールの例:
-A INPUT --state NEW -p tcp --dport 4711 -j LOG
(4711 は追跡するポートです)。
次に、結果のログを、要約を作成できる任意のスクリプトで実行します。
tcpdump を使用して、すべての SYN (ACK なし) パケットをログに記録できます:
tcpdump "dst port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn"
または、すべての SYN+ACK パケット (確立された接続) をログに記録します:
tcpdump "src port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)"
そしてそれを wc -l
と組み合わせる すべての行を数える
また、一定の期間を測定する方法も必要です (cron に定期的に SIGINT を送信させることができます。tcpdump はバイトとパケットをカウントしますが、時間のみをログに記録します)
更新:言うまでもありませんが、tcpdump の man ページを見て、次のようないくつかのオプションの使用を検討してください:-i
(1 つのインターフェースのみを聞く)、-p
(プロミスキャス モードを無効にする; 侵襲性が低い)、またはいくつかの出力オプション。 Tcpdump には root 権限が必要であり、ハッカー ツールのようなものであるため、上司は気に入らないかもしれません。一方、システムを実行するためにシステムに何も触れる必要はありません (iptables LOG
とは対照的に)。 ソリューション)
また、フィルターの src/dsk の小さな違いにも注目してください。 SYN+ACK パケットをキャッチし、 への接続をカウントしたい場合 ポート 4711 のサーバーには src が必要です。同じ結果の SYN+!ACK パケットをキャッチする場合は、dst が必要です。サーバー自体で接続をカウントする場合は、常に逆を使用する必要があります。
SystemTap ソリューション
tcp_connections.stp の例に触発されたスクリプト:
#!/usr/bin/env stap
# To monitor another TCP port run:
# stap -G port=80 tcp_connections.stp
# or
# ./tcp_connections.stp -G port=80
global port = 22
global connections
function report() {
foreach (addr in connections) {
printf("%s: %d\n", addr, @count(connections[addr]))
}
}
probe end {
printf("\n=== Summary ===\n")
report()
}
probe kernel.function("tcp_accept").return?,
kernel.function("inet_csk_accept").return? {
sock = $return
if (sock != 0) {
local_port = inet_get_local_port(sock)
if (local_port == port) {
remote_addr = inet_get_ip_source(sock)
connections[remote_addr] <<< 1
printf("%s New connection from %s\n", ctime(gettimeofday_s()), remote_addr)
}
}
}
出力:
[[email protected] ~]# ./tcp_connections.stp -G port=80
Mon Mar 17 04:13:03 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:04 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:08 2014 New connection from 192.168.122.4
^C
=== Summary ===
192.168.122.1: 2
192.168.122.4: 1
strace ソリューション
strace の下でプログラムを開始します:
strace -r -f -e trace=accept -o /tmp/strace ${PROGRAM} ${ARGS}
または、すでに実行中のプログラムをトレースします:
strace -r -f -e trace=accept -o /tmp/strace -p ${PID_OF_PROGRAM}
-r
後で追加のパフォーマンス分析が必要になった場合に備えて、各システム コールへのエントリ時に相対タイムスタンプを出力します。 -f
子プロセスをトレースするため、必要ない場合があります。
出力は次のようになります:
999 0.000000 accept(3, {sa_family=AF_INET, sin_port=htons(34702), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999 0.008079 --- SIGCHLD (Child exited) @ 0 (0) ---
999 1.029846 accept(3, {sa_family=AF_INET, sin_port=htons(34703), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999 0.008276 --- SIGCHLD (Child exited) @ 0 (0) ---
999 3.580122 accept(3, {sa_family=AF_INET, sin_port=htons(50114), sin_addr=inet_addr("192.168.122.1")}, [16]) = 5
次の方法でフィルタリングできます:
# gawk 'match($0, /^([0-9]+)[[:space:]]+([0-9.]+)[[:space:]]+accept\(.*htons\(([^)]+)\),.*inet_addr\("([^"]+)"\).*[[:space:]]+=[[:space:]]+([1-9][0-9]*)/, m) {connections[m[4]]++} END {for (addr in connections) printf("%s: %d\n", addr, connections[addr]); }' /tmp/strace
192.168.122.4: 3
192.168.122.1: 2
AKW ワンライナーの簡単な説明:m[1]
PID、m[2]
タイムスタンプ、m[3]
はリモートポートで、m[4]
はリモート アドレスです。
利点 このソリューションの最も重要な点は、サーバーが同じユーザーで実行されている場合、root は必要ないということです。 短所 すべての接続がカウントされ、フィルタリングがないため、アプリケーションが複数のポートでリッスンしている場合は機能しません。