ด้วย Linux iptables จะสามารถบันทึกชื่อกระบวนการ / คำสั่งที่เริ่มต้นการเชื่อมต่อขาออกได้หรือไม่?


27

ฉันต้องการติดตามกระบวนการที่เริ่มต้นการเชื่อมต่อขาออกบนเดสก์ท็อป Linux สิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือ:

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

ซึ่งจะบันทึก uid / gid ที่เริ่มต้นการเชื่อมต่อ แต่ไม่ใช่ชื่อกระบวนการ / คำสั่งหรือแม้แต่ pid หากฉันเพิ่งได้รับ pid ฉันก็อาจชักสคริปต์ที่ดึงชื่อกระบวนการเมื่อเขียนบันทึก แต่ดูเหมือนว่าเป็นไปไม่ได้

เป็นการดีที่ฉันต้องการบันทึกกระบวนการที่ยอมรับการเชื่อมต่อขาเข้าด้วย

ความคิดใด ๆ ที่อาจเป็นไปได้กับ iptables [หรืออย่างอื่น] บนกล่อง Linux?


ฉันเชื่อ (ไม่แน่ใจทั้งหมด) คำถามนี้ตอบใน serverfault แล้วค้นหา
niXar

ส่วนตัวฉันจะใช้sysdigสำหรับงานนี้
Charles Duffy

คำตอบ:


7

คุณสามารถเขียนโปรแกรมเพื่อตรวจสอบ / proc / net / tcp ซึ่งผลลัพธ์เป็นดังนี้:

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

จากนั้นคุณสามารถเชื่อมโยงพอร์ตที่เปิดอยู่กับ inodes ซึ่งสามารถสัมพันธ์กับกระบวนการและตัวอธิบายไฟล์โดยทำ readlink บนไฟล์ descriptor ที่แสดงรายการสำหรับแต่ละกระบวนการ:

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

ดูที่นี่ที่ inode 4847458 สอดคล้องกับซ็อกเก็ต tcp แรกในรายการด้านบน ผลลัพธ์ของ netstat -tapn ตรวจสอบสิ่งนี้สำหรับฉัน (และจำได้ว่า 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

เมื่อโปรแกรมมอนิเตอร์สังเกตเห็นการเปลี่ยนแปลงใน / proc / net / tcp ให้แยกวิเคราะห์ข้อมูลและพิจารณาว่าการเปลี่ยนแปลงนั้นเป็นซ็อกเก็ตที่เพิ่งเปิดใหม่หรือไม่ จากนั้นคุณสามารถระบุไฟล์ descriptors ทั้งหมดสำหรับแต่ละโพรเซสที่อยู่ใน / proc, ทำ readlink บนแต่ละตัวเพื่อค้นหา inode ที่ตรงกัน เมื่อคุณพบว่าคุณมี pid ที่เป็นเจ้าของซึ่งคุณสามารถได้รับสิ่งอื่นที่คุณอาจต้องการโดยเฉพาะอย่างยิ่งถ้าคุณมีกระบวนการบัญชี

หากคุณไม่ต้องการให้การแจ้งเตือนของคุณเป็นแบบทันทีโปรแกรมตรวจสอบของคุณอาจใช้แบบสำรวจความคิดเห็นช้า (อาจเป็นระยะเวลา 50ms หรือ 100ms หรือแม้กระทั่ง 1,000ms)


2
ขอบคุณที่ให้ทางเลือก! แต่ต้องมีการสำรวจและสอบถามทุกไฟล์บ่งชี้ที่เปิดในแต่ละครั้งไม่แข็งแกร่งมากและไม่มีประสิทธิภาพมาก ฉันยังหวังว่าจะมีใครบางคนหาทางออกที่ดีกว่าหรือชี้แจงว่าเพราะเหตุใดนี่จึงไม่ใช่ส่วนหนึ่งของ iptables อีกต่อไปและเหตุใด --cmd-owner จึงถือว่าไม่ถูกต้อง
nealmcb

นอกจากเคอร์เนลจะเปลี่ยนเค้าโครงของ / proc หรือเว้นแต่ netstat และ readlink หรือ ps เปลี่ยนแปลง (ไม่น่าจะเป็นไปได้) ฉันจะบอกว่ามันค่อนข้างแข็งแกร่ง ปัญหาเกี่ยวกับประสิทธิภาพแบบใดที่คุณเกี่ยวข้อง หากคุณต้องการประมวลผลทันทีคุณจะต้องเขียนโมดูลเคอร์เนลเพื่อใช้กับ iptables
Ben Collins

ถ้าฉันบันทึกการเชื่อมต่อปฏิเสธแล้วซ็อกเก็ตถูกทำลายโดยเคอร์เนลทันทีดังนั้นฉันมีโอกาสน้อยมากที่จะเห็นมันใน / proc อาจเปลี่ยน REJECT เป็น DROP เพื่อให้การเชื่อมต่อหมดเวลา ...
Marki555

มันไม่ได้ช่วยในสถานการณ์นี้เนื่องจากหน้าต่างเวลาขนาดเล็กพิเศษ แต่เท่าที่ความเปราะบางของการแยก / proc ไปหนึ่งสามารถเพียงแค่ใช้ "lsof -F -i" และได้รับการถ่ายโอนข้อมูลที่เป็นนามธรรมอย่างดีของเครือข่าย ข้อมูล. ซึ่งสามารถกรองได้ (พูดเพียงแค่พอร์ตที่เฉพาะเจาะจง) และได้ทำการแมปชื่อไฟล์ / pid / user ทั้งหมดสำหรับคุณแล้ว
dannysauer

9

คุณต้องการโมดูลจับคู่สำหรับเจ้าของซึ่งใช้งานได้ในห่วงโซ่เอาท์พุทเท่านั้น (และอาจจะเป็น PREROUTING ... ?) อ่านเอกสาร แต่มันจะทำงานเช่นนี้:

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

1
คำสั่ง iptables log สามารถตั้งค่าและแก้ไขตัวแปรด้วยวิธีนี้ได้หรือไม่? ดูเหมือนจะไม่ได้ผลสำหรับฉัน นอกจากนี้ดูเหมือนว่าตัวเลือก --cmd-owner ถูกลบในเคอร์เนล> = 2.6.15 สิ่งนี้โชคร้ายเพราะดูเหมือนว่าเป็นตัวเลือกที่มีประโยชน์

4
ใช่ --cmd-owner ถูกนำออก: "หักไม่ได้แยกออก"
guettli

1
ขอบคุณสำหรับข้อมูล @guettli มีข้อมูลเฉพาะเพิ่มเติมที่permalink.gmane.org/ซึ่งอ้างถึงการเปลี่ยนแปลงเพิ่มเติม: "[NETFILTER]: ลบการละเมิด tasklist_lock ใน ipt {, 6} เจ้าของถอนการจับคู่ cmd / sid / pid เนื่องจากไม่สามารถแก้ไขได้และยืนอยู่ใน วิธีการล็อกการเปลี่ยนแปลงไปยัง tasklist_lock " แต่ฉันยังต้องการพื้นหลังเพิ่มเติมหรือทางเลือกที่ดีกว่า
nealmcb

5

ไม่มีอะไรเกี่ยวข้องกับ iptables หรือการบันทึก; แต่นี่คืออินเทอร์เฟซแบบ "top" ที่โพล / proc / directory และแสดงแบนด์วิดท์ต่อ program / pid:

http://sourceforge.net/projects/nethogs

"NetHogs เป็นเครื่องมือ 'net top' ขนาดเล็กแทนที่จะทำลายทราฟฟิกลงตามโพรโทคอลหรือต่อ subnet อย่างที่เครื่องมือส่วนใหญ่ทำมันจัดกลุ่มแบนด์วิดท์ตามกระบวนการ NetHogs ไม่พึ่งพาโมดูลเคอร์เนลพิเศษที่จะโหลด"


ฉันพบว่า nethogs ให้สถิติที่ไม่น่าเชื่อถือ แต่ atop 2 (+ netatop) ทำได้ดี
Tobu

1

ในขณะที่ฉันกำลังมองหาคำถามที่คล้ายกันพยายามหา skype ที่ จำกัด ความเร็วฉันได้พบแล้ว

$ netstat -p | grep <mycmdname>

เป็นวิธีที่ดีในการเชื่อมโยงหมายเลขพอร์ตกับ pid / cmd ตอนนี้ pid-owner / cmd-owner ไม่ได้รับการสนับสนุนโดยตรงใน iptables อีกต่อไป จากนั้นคุณจะต้องแยกวิเคราะห์ผลลัพธ์จากนั้นเพิ่มกฎ iptables ตามพอร์ต โดยปกติคุณจะต้องมีโค้ดการล้างข้อมูลหลังจากนั้น / เมื่อปิดระบบ / รีสตาร์ท ฯลฯ บันทึกหมายเลขพอร์ต / s เป็นไฟล์สำหรับการอ้างอิงในเวลาทำความสะอาด

ในความเป็นจริงคำตอบที่ดีสำหรับคำถามหมายเลขพอร์ตคือ

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

คุณอาจจำเป็นต้องปรับองค์ประกอบ grep tcp ตามความต้องการของคุณ

จากนั้นสำหรับวัตถุประสงค์ของฉันมันง่ายที่สุดในการเพิ่มตัวกรอง tc u32 ตามหมายเลขพอร์ตรายการ iptables ตามหมายเลขพอร์ตที่คล้ายกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.