ฉันจะจองพอร์ตสำหรับแอปพลิเคชันของฉันได้อย่างไร


29

ฉันจะจองรายการพอร์ตสำหรับแอปพลิเคชันที่กำหนดเองได้อย่างไร

ความเฉพาะเจาะจงผลิตภัณฑ์ที่ฉันสร้างมีกระบวนการมากมายและการสื่อสารระหว่างกันมากมาย

ปัญหาที่ฉันมีคือทุกครั้งที่ระบบปฏิบัติการขโมยพอร์ตของฉัน มันหายาก แต่มันเกิดขึ้น

อาจเป็นเพราะแอปพลิเคชันอื่นใช้ ":: bind" โดยไม่ได้ระบุพอร์ต

หรือบางครั้งแอปพลิเคชันของฉันเองขโมยพอร์ตเมื่อฉันเรียกว่า ":: connect" ด้วยซ็อกเก็ตที่ไม่ได้ผูกไว้ เท่าที่เห็นจากหน้าคน:

หากซ็อกเก็ตยังไม่ได้ถูกผูกไว้กับที่อยู่ในท้องถิ่นเชื่อมต่อ () จะผูกไว้กับที่อยู่ซึ่งเว้นแต่ครอบครัวที่อยู่ของซ็อกเก็ตคือ AF_UNIX เป็นที่อยู่ในท้องถิ่นที่ไม่ได้ใช้

ดังนั้นคำถามของฉันคือฉันสามารถจองพอร์ตที่ฉันต้องการเพื่อให้ระบบปฏิบัติการไม่ได้ใช้งานได้หรือไม่? สามารถทำได้ด้วย / etc / services หรือไม่ หรือมีวิธีที่แตกต่างกันอย่างไร


1
คุณสามารถใช้ซ็อกเก็ต AF_UNIX แทนได้หรือไม่
alex

2
กังวลมากขึ้นว่าทำไมแอปพลิเคชันของคุณเองคือ 'ขโมยพอร์ต'
EightBitTony

ฉันกำลังถกเถียงกันถ้าฉันต้องผ่านซอฟต์แวร์ของฉันและผูกด้านลูกค้าของแต่ละการเชื่อมต่อกับพอร์ตเฉพาะ มันค่อนข้างงานสำหรับผมที่จะอัปเดตนี้เนื่องจากมีจำนวนมากของเส้นทางการเชื่อมต่อในการใช้งานของฉัน การสำรองพอร์ตในระบบปฏิบัติการจะเป็นวิธีแก้ปัญหาช่องว่างหยุดที่ดีจนกระทั่งฉันพบเวลาทำเช่นนี้
Michael Baker

ฉันไม่แน่ใจว่าSELinuxในโหมดการบังคับใช้สามารถตอบสนองความต้องการของคุณได้หรือไม่ฉันยังคงเรียนรู้อยู่ ดังนั้นเพียงแค่การคาดเดาบางทีคุณอาจจะสามารถกำหนดนโยบายของคุณเองสำหรับSELinuxการสำรองmy_server_port_t tcp 1111, 2222, 3333, 4444-4600พอร์ตของคุณเช่น หากแอปพลิเคชันของคุณจะทำงานทุกที่ (ไม่ใช่แอปพลิเคชันเซิร์ฟเวอร์) ฉันกลัวว่าคุณจะไม่สามารถควบคุมได้ว่าSELinuxจะเปิดหรือปิด
LiuYan 刘研

โดย "การขโมย" ฉันถือว่าคุณหมายความว่าแอปของบุคคลที่สามเชื่อมโยงกับหมายเลขพอร์ตที่คุณเลือกก่อนที่แอปพลิเคชันจะได้รับโอกาสเพราะแอปของบุคคลที่สามได้ร้องขอให้ผูกกับ 0 และระบบปฏิบัติการได้กำหนดหมายเลขพอร์ตที่คุณเลือก แอพของบุคคลที่สาม ถ้าเป็นเช่นนั้นให้ดูunix.stackexchange.com/a/38724/27865
Mark Lakata

คำตอบ:


14

ในทางเทคนิคไม่มีสิ่งเช่น "พอร์ตสงวน"

ใน TCP / UDP วิธีเดียวที่จะ "สำรอง" พอร์ตคือการbind()ใช้ซ็อกเก็ตจริง แอปพลิเคชันอื่นจะไม่ใช้พอร์ตที่ถูกผูกไว้ พอร์ตที่ไม่ได้ใช้ก็คือไม่ได้ใช้ดังนั้นแอปพลิเคชันอื่น ๆ จึงสามารถใช้งานได้ฟรี

หากคุณกำลังเขียนซอฟต์แวร์เซิร์ฟเวอร์คุณสามารถผูกซ็อกเก็ตของคุณเข้ากับพอร์ตที่ต้องการให้เร็วที่สุดเท่าที่คุณต้องการในรหัสแอปพลิเคชัน กำหนดหมายเลขพอร์ตที่สามารถกำหนดค่าได้หรืออย่างน้อยก็ระบุไว้ในเอกสารประกอบอย่างชัดเจนเพื่อให้ผู้ดูแลระบบสามารถระบุการปะทะและย้ายแอปพลิเคชั่นที่ขัดแย้งไปยังเซิร์ฟเวอร์แยกต่างหากได้อย่างรวดเร็ว


1
นอกจากนี้หลีกเลี่ยงการใช้พอร์ตที่รู้จัก / สงวนไว้หากเป็นไปได้
EightBitTony

มีพอร์ตที่สงวนไว้บางครั้ง นี่เป็นคำแนะนำทั่วไปที่ดี แต่ไม่ใช่คำตอบที่ถูกต้องบน Linux
Jason Newton

18

เพื่อให้แน่ใจว่าเคอร์เนลจะไม่มอบ 49,000 และ 49001 ให้กับลูกค้าตามที่คุณต้องการใช้สำหรับเซิร์ฟเวอร์ของคุณบน linux

sysctl -w net.ipv4.ip_local_reserved_ports = 49000, 49001

วางไว้ในและเรียกใช้/etc/sysctl.confsysctl -p

โปรดทราบว่านี่ไม่ได้ทดสอบ

อ้างอิง


ฉันลองสิ่งนี้ แต่มันก็ป้องกันไม่ให้แอปพลิเคชันของฉันเองใช้พอร์ต! แล้วการกำหนดหมายเลขพอร์ตด้วยชื่อมี/etc/servicesอะไรบ้าง

@ user134197 สิ่งนี้ไม่ควรป้องกันแอปพลิเคชันของคุณเองจากการใช้พอร์ตเหล่านั้นหากคุณใช้หมายเลขพอร์ตที่ไม่ใช่ศูนย์ในคำขอเชื่อมโยงของคุณอย่างชัดเจน มันใช้งานได้สำหรับฉัน
Mark Lakata

15

ที่จริงแล้วคำตอบข้างต้นไม่ถูกต้องทั้งหมด sysctls net.inet.ip.portrange.first และ net.inet.ip.portrange.last ระบุช่วงของพอร์ตที่ระบบปฏิบัติการสามารถจัดสรรสำหรับพอร์ตสุ่ม คุณต้องการตรวจสอบให้แน่ใจว่าช่วงของพอร์ตที่สงวนไว้สำหรับแอปพลิเคชันของคุณไม่ได้อยู่ในตัวแปรเหล่านี้

ดูใน FreeBSD Handbook หัวข้อ: 12.14 ขีด จำกัด การปรับแต่งเคอร์เนล แต่สถานที่พื้นฐานเดียวกันควรใช้กับ Linux เช่นกัน


นอกจากนี้ลิงก์นี้อาจได้รับความช่วยเหลือ: stackoverflow.com/questions/913501/…
MattK

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