Nyalakan iptables dan atur ke LOG
untuk koneksi masuk. Aturan contoh:
-A INPUT --state NEW -p tcp --dport 4711 -j LOG
(di mana 4711 adalah port yang ingin Anda lacak).
Kemudian jalankan log yang dihasilkan melalui skrip apa pun yang Anda suka yang dapat melakukan ringkasan untuk Anda.
Anda dapat menggunakan tcpdump untuk mencatat semua paket SYN (tanpa ACK):
tcpdump "dst port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn"
atau catat semua paket SYN+ACK (koneksi yang dibuat):
tcpdump "src port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)"
Lalu gabungkan dengan wc -l
untuk menghitung semua baris
Anda juga memerlukan cara untuk mengukur periode waktu yang tetap (Anda dapat meminta cron untuk mengirimkan SIGINT secara berkala, tcpdump akan menghitung byte dan paket tetapi hanya mencatat waktu)
Perbarui:tidak perlu dikatakan, lihat halaman manual tcpdump dan pertimbangkan untuk menggunakan beberapa opsi seperti:-i
(dengarkan hanya satu antarmuka), -p
(nonaktifkan mode promiscuous; kurang invasif), atau beberapa opsi keluaran. Tcpdump memerlukan izin root dan bos Anda mungkin tidak menyukainya karena ini adalah sejenis alat peretas. Di sisi lain, Anda tidak perlu menyentuh apa pun di sistem Anda untuk menjalankannya (berbeda dengan iptables LOG
solusi)
Harap perhatikan juga perbedaan kecil src/dsk dalam filter. Jika Anda menangkap paket SYN+ACK dan ingin menghitung koneksi to server di port 4711 Anda memerlukan src. Jika Anda menangkap paket SYN+!ACK untuk hasil yang sama, Anda perlu dst. Jika Anda menghitung koneksi di server itu sendiri, Anda harus selalu menggunakan kebalikannya.
solusi SystemTap
Skrip terinspirasi oleh contoh 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)
}
}
}
Keluaran:
[[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
solusi strace
Mulai program di bawah strace:
strace -r -f -e trace=accept -o /tmp/strace ${PROGRAM} ${ARGS}
atau lacak program yang sudah berjalan:
strace -r -f -e trace=accept -o /tmp/strace -p ${PID_OF_PROGRAM}
-r
mencetak stempel waktu relatif saat masuk ke setiap panggilan sistem jika diperlukan nanti untuk analisis kinerja tambahan. -f
melacak proses anak dan mungkin tidak diperlukan.
Outputnya terlihat seperti ini:
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
dan dapat difilter dengan:
# 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
Penjelasan singkat tentang one-liner AKW:m[1]
adalah PID, m[2]
adalah stempel waktu, m[3]
adalah port jarak jauh dan m[4]
adalah alamat jarak jauh.
Keuntungan solusi ini adalah root tidak diperlukan jika server berjalan di bawah pengguna yang sama. Kerugiannya apakah semua koneksi dihitung, tidak ada pemfilteran, sehingga tidak akan berfungsi jika aplikasi mendengarkan pada banyak port.