วิธีฆ่ากระบวนการ Linux ด้วยหมายเลขพอร์ต
เผยแพร่แล้ว: 2022-10-08ในการฆ่ากระบวนการ Linux คุณต้องมี ID หรือชื่อของมัน ถ้ารู้แค่พอร์ตที่ใช้ คุณยังสามารถฆ่ามันได้หรือไม่? ใช่ในหลายวิธี
กระบวนการฆ่า
บางครั้งกระบวนการ Linux อาจไม่ตอบสนอง อาจหยุดทำงานอย่างถูกต้อง หรืออาจทำงานต่อแต่ไม่สนใจคำขอให้ปิดเครื่อง หรือเริ่มกินหน่วยความจำ CPU หรือแบนด์วิดท์เครือข่าย
ไม่ว่าแรงจูงใจของคุณจะเป็นเช่นไร มีวิธีฆ่ากระบวนการจากบรรทัดคำสั่ง Linux วิธีคลาสสิกคือการใช้คำสั่ง kill กับ ID กระบวนการของกระบวนการที่คุณต้องการยุติ คำสั่ง kill
มีญาติสนิทบางส่วน คำสั่ง pkill
จะฆ่าโปรเซสตามชื่อ และ killall
จะฆ่าโปรเซสทั้งหมดที่สามารถค้นหาส่วนที่ใช้ร่วมกันของชื่อได้
หากสิ่งที่คุณรู้เกี่ยวกับกระบวนการคือการใช้พอร์ตบนคอมพิวเตอร์ของคุณ ก็ยังมีวิธีระบุและฆ่ามัน ในแง่ของเครือข่าย “พอร์ต” อาจหมายถึงการเชื่อมต่อทางกายภาพที่คุณเสียบสายเคเบิลด้วยปลั๊กที่ปลาย เช่น สายเครือข่าย CAT5 หรือ 6 หรืออาจหมายถึงพอร์ตซอฟต์แวร์
พอร์ตซอฟต์แวร์เป็นส่วนสุดท้ายของการเชื่อมต่อเครือข่าย ที่อยู่ IP ของอุปกรณ์ระบุคอมพิวเตอร์หรืออุปกรณ์เครือข่ายอื่นๆ แอปพลิเคชันภายในคอมพิวเตอร์ใช้พอร์ตต่างๆ สิ่งเหล่านี้ให้ความละเอียดในระดับอื่น การรับส่งข้อมูลเครือข่ายมาถึงคอมพิวเตอร์ที่ถูกต้องโดยใช้ที่อยู่ IP และด้วยการใช้ที่อยู่พอร์ต ข้อมูลดังกล่าวจะถูกส่งไปยังแอปพลิเคชันที่ถูกต้อง
เหมือนกับไปรษณียภัณฑ์ที่ส่งถึงโรงแรม แล้วจัดเรียงและส่งไปยังห้องที่เหมาะสม ที่อยู่ IP เปรียบเสมือนที่อยู่ของโรงแรม และหมายเลขห้องก็เหมือนหมายเลขพอร์ต
หากคุณเห็นกิจกรรมเครือข่ายบนพอร์ต และคุณไม่รู้จักกระบวนการที่สร้างมันขึ้นมา หรือพฤติกรรมของมันคือปัญหาหรือน่าสงสัย คุณอาจต้องการปิดกระบวนการ แม้ว่าสิ่งที่คุณรู้คือหมายเลขพอร์ต คุณก็สามารถติดตามกระบวนการและฆ่ามันได้
การสร้างการเชื่อมต่อกับ socat
เพื่อให้เรามีการเชื่อมต่อที่จะฆ่า เราจะใช้ socat
เพื่อสร้างการเชื่อมต่อเครือข่ายโดยใช้โปรโตคอลที่แตกต่างกัน คุณจะต้องติดตั้ง socat
ในการติดตั้งบน Ubuntu ให้ใช้คำสั่งนี้:
sudo apt ติดตั้ง socat
บน Fedora ใช้ dnf
:
sudo dnf ติดตั้ง socat
บน Manjaro คุณต้องพิมพ์:
sudo pacman -S socat
วากยสัมพันธ์สำหรับ socat
นั้นตรงไปตรงมาถ้าใช้ยาวไปหน่อย เราจำเป็นต้องระบุที่อยู่ต้นทางและปลายทาง สำหรับแต่ละสิ่งเหล่านี้ เราจำเป็นต้องจัดเตรียมโปรโตคอล ที่อยู่ IP และหมายเลขพอร์ต เราสามารถใช้แทน STDIN หรือ STDOUT เป็นแหล่งที่มาหรือปลายทางได้
คำสั่งนี้สร้างการเชื่อมต่อระหว่างซ็อกเก็ตฟัง TCP บนพอร์ต 7889 บนที่อยู่ IP แบบวนรอบ 127.0.0.1 และ STDOUT เครื่องหมาย " &
" จะรันคำสั่งในเบื้องหลัง เพื่อให้เรายังคงเข้าถึงบรรทัดคำสั่งได้
socat tcp-listen:7889,bind=127.0.0.1 stdout &
เราจะสร้างการเชื่อมต่อเพิ่มอีกสองรายการ เพื่อให้เราเลือกซ็อกเก็ตขนาดเล็กโดยใช้โปรโตคอลที่ต่างกัน เราจะสร้างการเชื่อมต่อ UDP และการเชื่อมต่อ SCTP ส่วนเดียวของคำสั่งที่เปลี่ยนแปลงคือโปรโตคอล
socat udp-listen:7889,bind=127.0.0.1 stdout &
socat sctp-listen:9999,bind=127.0.0.1 stdout &
ที่เกี่ยวข้อง: อะไรคือความแตกต่างระหว่าง TCP และ UDP?
ใช้ Kill
แน่นอน เราสามารถใช้ kill
เพื่อยุติกระบวนการได้ ตราบใดที่เรารู้ว่า ID ของกระบวนการคืออะไร ในการค้นหา PID เราสามารถใช้คำสั่ง lsof
ในการแสดงรายการรายละเอียดของกระบวนการบนพอร์ต 7889 ที่ใช้โปรโตคอล TCP เราใช้ตัวเลือก -i
(ที่อยู่อินเทอร์เน็ต) เช่นนี้
lsof -i tcp:7889
PID ของกระบวนการนี้คือ 3141 และเราสามารถดำเนินการต่อด้วย kill
:
sudo ฆ่า 3141
เราสามารถช่วยตัวเองได้ถ้าเราใช้ท่อ หากเราไพพ์เอาต์พุตของ lsof
ลงใน awk
และบอกให้ awk
ค้นหาบรรทัดที่มีพอร์ตที่เราสนใจ—7889—และพิมพ์ฟิลด์ที่สองจากบรรทัดนั้น เราจะแยก PID
lsof -i tcp:7889 | awk '/7889{พิมพ์ $2}'
จากนั้นเราสามารถไพพ์เอาต์พุตจาก awk
ไปยังคำสั่ง kill
โดยใช้ xargs
คำสั่ง xargs
รับอินพุตแบบไพพ์และส่งผ่านไปยังคำสั่งอื่นเป็นพารามิเตอร์บรรทัดคำสั่ง เราจะใช้ xargs
กับคำสั่ง kill
lsof -i tcp:7889 | awk '/7889{พิมพ์ $2}' | xargs ฆ่า
เราไม่ได้รับคำติชมด้วยภาพ ตามแบบฉบับของลินุกซ์ ไม่มีข่าวใดเป็นข่าวดี หากคุณต้องการตรวจสอบว่ากระบวนการถูกยกเลิก คุณสามารถใช้ lsof
ได้อีกครั้ง
lsof -i tcp:7889
เนื่องจาก lsof
ไม่ได้รายงานอะไร เราจึงรู้ว่าไม่มีการเชื่อมต่อดังกล่าว
เราสามารถลบกระบวนการโดยใช้โปรโตคอล UDP ได้ง่ายๆ โดยแทนที่ “tcp” ด้วย “udp” ในคำสั่งก่อนหน้าของเรา
lsof -i udp:7889 | awk '/7889{พิมพ์ $2}' | xargs ฆ่า
อย่างไรก็ตาม lsof
ไม่รู้จักโปรโตคอล SCTP
lsof -i sctp:7889
เราสามารถใช้คำสั่ง ss
ได้ เราใช้ตัวเลือก -S
(SCTP) เพื่อค้นหาซ็อกเก็ต SCTP ตัวเลือก -a
(ทั้งหมด) เพื่อค้นหาซ็อกเก็ตทุกประเภท (ฟัง ยอมรับ เชื่อมต่อ ฯลฯ) และตัวเลือก -p
(กระบวนการ) เพื่อแสดงรายการรายละเอียดของกระบวนการโดยใช้ซ็อกเก็ต
ss -ทรัพย์
เราสามารถแยกวิเคราะห์ผลลัพธ์นั้นโดยใช้ grep
และ awk
เราสามารถแยกวิเคราะห์ได้โดยใช้ grep
และ PERL regexes แต่วิธีนี้เข้าใจง่ายกว่ามาก หากคุณกำลังจะใช้สิ่งนี้มากกว่าหนึ่งครั้งหรือสองครั้ง คุณอาจจะสร้างนามแฝงหรือฟังก์ชันเชลล์ออกมา
เราจะไพพ์เอาต์พุตจาก ss
ไปที่ grep
และค้นหาหมายเลขพอร์ตของเรา 7889 เราจะไพพ์เอาต์พุตจาก grep
ไปที่ awk
ใน awk
เราใช้ตัวเลือก -F
(สตริงตัวคั่น) เพื่อตั้งค่าเครื่องหมายจุลภาค “ ,
” เป็นตัวคั่นฟิลด์ เราค้นหาสตริง ที่มี "pid=" และพิมพ์ฟิลด์ที่คั่นด้วยเครื่องหมายจุลภาคที่สองจากสตริงนั้น
ss -ทรัพย์ | grep "7889" | awk -F',' '/pid=/{print $2}'
นั่นทำให้เรามีสตริง “pid=2859”
เราสามารถไพพ์มันใน awk
อีกครั้ง ตั้งค่าตัวคั่นฟิลด์เป็นเครื่องหมายเท่ากับ “ =
” และพิมพ์ฟิลด์ที่สองจากสตริง นั้น ซึ่งจะเป็นข้อความที่อยู่ด้านหลังเครื่องหมายเท่ากับ
ss -ทรัพย์ | grep "7889" | awk -F',' '/pid=/{print $2}' | awk -F'=' '{พิมพ์ $2}'
ตอนนี้เราได้แยก ID กระบวนการแล้ว เราสามารถใช้ xargs
เพื่อส่ง PID เพื่อ kill
เป็นพารามิเตอร์บรรทัดคำสั่ง
ss -ทรัพย์ | grep "7889" | awk -F',' '/pid=/{print $2}' | awk -F'=' '{print $2}' | xargs ฆ่า
นั่นฆ่ากระบวนการที่ใช้ซ็อกเก็ตโปรโตคอล SCTP บนพอร์ต 7889
คำสั่งฟิวเซอร์
คำสั่ง fuser
ทำให้สิ่งต่างๆ ง่ายขึ้นมาก ข้อเสียคือใช้งานได้กับซ็อกเก็ต TCP และ UDP เท่านั้น ในด้านบวก ซ็อกเก็ตเหล่านี้เป็นซ็อกเก็ตทั่วไปสองประเภทที่คุณต้องจัดการ คำสั่ง fuser
ได้รับการติดตั้งแล้วในคอมพิวเตอร์ Ubuntu, Fedora และ Manjaro ที่เราตรวจสอบ
สิ่งที่คุณต้องทำคือใช้ตัวเลือก -k
(kill) และระบุพอร์ตและโปรโตคอล คุณสามารถใช้ตัวเลือก -n
(เนมสเปซ) และระบุโปรโตคอลและพอร์ต หรือใช้ "ฟอร์เวิร์ดสแลชรูปแบบทางลัด" และใส่หมายเลขพอร์ตก่อน
ฟิวเซอร์ -n tcp 7889
ฟิวเซอร์7889/udp
หมายเลขพอร์ต โปรโตคอล และ PID ของกระบวนการที่ยุติจะพิมพ์อยู่ในหน้าต่างเทอร์มินัล
ลองฟิวเซอร์ก่อน
มันอาจจะติดตั้งบนคอมพิวเตอร์ที่คุณกำลังทำงานอยู่ และโปรโตคอลน่าจะเป็น TCP หรือ UDP ดังนั้นจึงมีโอกาสมากที่วิธีที่ง่ายที่สุดจะได้ผลสำหรับคุณ