Dengan iptables Linux, apakah mungkin untuk mencatat proses / nama perintah yang memulai koneksi keluar?

27

Saya ingin melacak proses yang memulai koneksi keluar pada desktop Linux. Yang terbaik yang bisa saya pikirkan adalah ini:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

Ini mencatat uid / gid yang memulai koneksi, tetapi bukan nama proses / perintah atau bahkan pid. Jika saya bisa mendapatkan pid, saya mungkin bisa membuat skrip yang menarik nama proses ketika log ditulis, tetapi sepertinya itu bahkan tidak mungkin.

Idealnya saya juga ingin mencatat proses yang menerima koneksi masuk juga.

Adakah ide bagaimana ini mungkin dengan iptables [atau apa pun] pada kotak Linux?

Nack
sumber
Saya percaya (tidak sepenuhnya yakin) pertanyaan ini dijawab di serverfault, cari.
niXar
Secara pribadi, saya akan menggunakan sysdig untuk pekerjaan ini.
Charles Duffy

Jawaban:

7

Anda dapat menulis sebuah program untuk memonitor / proc / net / tcp, yang hasilnya terlihat seperti ini:

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

Anda kemudian dapat menghubungkan port yang terbuka ke inode, yang dapat dihubungkan kembali ke proses dan deskriptor file dengan melakukan readlink pada deskriptor file yang terdaftar untuk setiap proses:

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

Lihat di sini bahwa inode 4847458 sesuai dengan soket tcp pertama dalam daftar di atas. Output dari netstat -tapn memverifikasi ini untuk saya (dan ingat 0x50 == 80):

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

Saat program monitor melihat adanya perubahan pada / proc / net / tcp, parsing data dan tentukan apakah perubahan tersebut merupakan soket yang baru dibuka. Kemudian Anda bisa menghitung semua deskriptor file untuk setiap proses yang terdaftar di / proc, melakukan readlink pada masing-masing untuk menemukan inode yang cocok. Setelah Anda menemukan itu, Anda memiliki pid yang memiliki, dari mana Anda bisa mendapatkan apa pun yang Anda inginkan, terutama jika Anda memiliki proses akuntansi.

Jika Anda tidak memerlukan pemberitahuan Anda secara instan, maka program monitor Anda dapat menggunakan jajak pendapat lambat (mungkin periode 50 ms atau 100 ms, atau bahkan 1000 ms).

Ben Collins
sumber
2
Terima kasih telah memberikan opsi! Tetapi membutuhkan polling dan query setiap deskriptor file terbuka setiap kali tidak terlalu kuat dan sangat tidak efisien. Saya masih berharap seseorang akan menemukan solusi yang lebih baik, atau mengklarifikasi mengapa ini bukan bagian dari iptables lagi, dan mengapa --cmd-owner dianggap tidak dapat diperbaiki.
nealmcb
Kecuali jika kernel mengubah tata letak / proc atau kecuali netstat dan readlink atau perubahan ps (tidak mungkin), saya akan mengatakan ini cukup kuat. Masalah efisiensi apa yang Anda perhatikan? Jika Anda ingin pemrosesan instan, Anda harus menulis modul kernel untuk digunakan dengan iptables.
Ben Collins
Jika saya mencatat koneksi yang ditolak maka soket dihancurkan segera oleh kernel, jadi saya memiliki sedikit kesempatan untuk melihatnya di / proc. Mungkin hanya mengubah TOLAKAN untuk DROP agar waktu koneksi habis ...
Marki555
Ini tidak membantu dalam skenario ini karena jendela waktu super-kecil, tetapi sejauh kerapuhan parsing / proc berjalan, kita juga bisa menggunakan "lsof -F -i" dan mendapatkan dump jaringan yang diabstraksi dengan baik. data. Itu juga dapat difilter (katakan, hanya pada port tertentu), dan telah melakukan semua pemetaan nama file / pid / pengguna untuk Anda.
dannysauer
9

Anda ingin modul kecocokan pemilik, yang hanya berfungsi pada rantai OUTPUT (dan mungkin PREROUTING ...?). Baca dokumen, tetapi akan berfungsi seperti ini:

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "

sumber
1
Dapatkah perintah iptables log mengatur dan menginterpolasikan variabel dengan cara ini? Sepertinya itu tidak berhasil untuk saya. Selain itu, sepertinya opsi --cmd-owner telah dihapus di kernel> = 2.6.15. Ini sangat disayangkan, karena sepertinya pilihan yang berguna.
4
Ya, --cmd-owner telah dihapus: "unfixable broken"
guettli
1
Terima kasih atas informasinya, @guettli. Ada lebih spesifik di permalink.gmane.org/... yang mengutip lebih banyak dari changelog: "[NETFILTER]: Hapus tasklist_lock penyalahgunaan di pemilik ipt {, 6}; Cabut pencocokan cmd / sid / pid karena tidak dapat diperbaiki dan berdiri di cara mengunci perubahan ke tasklist_lock. " Tapi saya masih ingin lebih banyak latar belakang, atau alternatif yang lebih baik.
nealmcb
5

Tidak ada hubungannya dengan iptables atau logging; tapi di sini ada antarmuka seperti "atas" yang memilih direktori / proc / dan menampilkan bandwidth per program / pid:

http://sourceforge.net/projects/nethogs

"NetHogs adalah alat 'net top' kecil. Alih-alih memecah traffic per protokol atau per subnet, seperti kebanyakan alat, NetHogs mengelompokkan bandwidth berdasarkan proses. NetHogs tidak bergantung pada modul kernel khusus yang akan dimuat."

Lokal
sumber
Saya telah menemukan nethogs memberikan statistik tidak dapat diandalkan, tetapi di atas 2 (+ netatop) melakukan ini dengan baik.
Tobu
1

Saat saya melihat pertanyaan serupa, mencoba untuk mempercepat skype, saya telah menemukan

$ netstat -p | grep <mycmdname>

adalah cara yang baik untuk menghubungkan nomor port ke pid / cmd, sekarang pid-pemilik / cmd-pemilik tidak lagi didukung secara langsung dalam iptables; Anda harus mem-parsing hasilnya, lalu menambahkan aturan iptables sesuai dengan port; secara alami Anda akan memerlukan beberapa kode pembersihan setelah / pada saat sistem shutdown / restart, dll; simpan nomor port ke file untuk referensi pada waktu pembersihan

sebenarnya jawaban yang bagus untuk pertanyaan nomor port adalah

$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

Anda mungkin perlu menyesuaikan elemen grep tcp sesuai dengan kebutuhan Anda

maka untuk keperluan saya, itu paling sederhana untuk menambahkan tc u32 filter sesuai dengan nomor port, entri iptables sesuai dengan nomor port yang sama

Menandai
sumber