พอร์ตเครือข่าย Linux หมดแรง


10

ฉันได้ทำการวิจัยมากเท่าที่จะทำได้โดยไม่ต้องขุดลงในเคอร์เนล ดูเหมือนว่ามีข้อมูลจำนวนมากถูกบิดเบือน / ไม่ถูกต้องในเรื่องดังนั้นฉันหวังว่าสิ่งนี้จะตอบคำถามสำหรับฉันและคนอื่น ๆ ในทันที

การพูด IPv4 อย่างเคร่งครัดเป็นไปได้หรือไม่ที่จะมีการอ่อนล้าของพอร์ต ให้ฉันอธิบาย:

  • ดูเหมือนว่าจะมีพอร์ต 65535 ให้ใช้งาน 0 ไม่สามารถใช้ได้
  • ฉันได้อ่านแล้วว่าการอ่อนเพลียของพอร์ตนั้นต้องการ (src ip, src port, dst ip, dst port) เพื่อให้เป็นเอกลักษณ์
  • เพื่อให้ชัดเจนและสมมติว่าฉันสามารถใช้พอร์ตชั่วคราวได้ 100% ผ่านการตั้งค่า sysctl net.ipv4.ip_local_port_range

และนี่คือคำถาม: นี่เป็นวิธีการทำงานหรือไม่

  • ฉันสามารถเชื่อมต่อได้ 65k จาก 127.0.0.1:(x) ถึง 127.0.0.1:80
  • ฉันสามารถเชื่อมต่อได้ 65k จาก 127.0.0.1:(x) ถึง 127.0.0.1:555
  • โดยทั่วไปอีกครั้งคำถามคือ (srcip, srcport, dstip, dstport) จะต้องไม่ซ้ำกันถูกต้องหรือไม่
  • ฉันไม่สามารถเปิดการเชื่อมต่อมากกว่า 65k จาก ip "A" ถึง IP "B", พอร์ต "N"
  • ในทำนองเดียวกันIP เดียวไม่สามารถเปิดการเชื่อมต่อมากกว่า 65k ไปยังเว็บเซิร์ฟเวอร์ของฉันได้ที่ xxxx: 80 แต่ฉันสามารถรองรับได้มากกว่า 65k โดยรวมตราบใดที่พวกเขามาจากแหล่ง IP ที่แตกต่างกัน?

ในที่สุดฉันก็สับสนเล็กน้อยเกี่ยวกับพอร์ตชั่วคราว (ขาออก) และพอร์ตขาเข้าที่กำลังฟังอยู่ ฉันรู้ทันทีว่าการเชื่อมต่อนั้นถูกสร้างขึ้นในแต่ละด้านของการเชื่อมต่อคือเพียร์และเท่าเทียมกัน แต่ก่อนที่จะเกิดขึ้น:

ตัวอย่างเช่นหาก tuple (srcip, srcport, dstip, dstport) ต้องไม่ซ้ำกันทำไมจึงเป็นเช่นนั้นถ้าฉันเปิดใช้งานเช่น

net.ipv4.ip_local_port_range = 1024 65535

ซึ่งอนุญาตให้ใช้พอร์ตชั่วคราวจาก 1024-65535 ว่าถ้าฉันมีบริการที่ผูกกับพอร์ต 3306 (mySQL เป็นต้น) บางครั้งพวกเขาจะไม่สามารถเริ่มทำงานได้เนื่องจากพอร์ตที่ใช้งานอยู่

สิ่งนี้เกี่ยวข้องกับข้อเท็จจริงที่: (และนี่คือคำแถลงที่ฉันขอให้ตรวจสอบ):

  • (srcip, srcport, dstip, dstport) เป็นสิ่งจำเป็นสำหรับการเชื่อมต่อแต่ละครั้งด้วยช่วงพอร์ต 1-65535 (ไม่สนใจการใช้งานชั่วคราวของระบบปฏิบัติการ)
  • อย่างไรก็ตามสำหรับซ็อกเก็ตที่จะผูกมันอาจถูกมองว่าเป็น (srcip, srcport, *, *) หรืออีกวิธีหนึ่งในการทำสิ่งนี้คือ IP จะต้องไม่ใช้พอร์ตนั้นด้วยเหตุผลใดก็ตาม

ฉันสามารถตรวจสอบพฤติกรรมดังกล่าวข้างต้นคือฉันใช้สาย sysctl ที่แน่นอนด้านบนและเพราะฉันย้าย mySQL ไปยังพอร์ตที่ต่ำกว่า 1024 เพราะบางครั้งมันจะสุ่มและล้มเหลวในการเริ่มต้นใหม่เพราะสมมติว่าระบบปฏิบัติการใช้พอร์ตนั้น (3306) สำหรับพอร์ตชั่วคราว


ฉันอัพเดตคำตอบด้วยข้อมูลเพิ่มเติม อย่าลังเลที่จะตอบคำถามใด ๆ
89c3b1b8-b1ae-11e6-b842-48d705

คำตอบ:


8

คุณมีสองคำถามหลักที่นี่:

1

การพูด IPv4 อย่างเคร่งครัดเป็นไปได้หรือไม่ที่จะมีการอ่อนล้าของพอร์ต

ใช่. ยกตัวอย่างเช่นเราเตอร์โหลดบาลานซ์ที่ส่งการเชื่อมต่อทั้งหมดไปยังที่อยู่ IP ของ NAT สิ่งนี้มีแนวโน้มที่จะเกิดขึ้นเมื่อคุณSRC IPเชื่อมต่อกับคอขวดของDST IPหลาย ๆ

ซึ่งหมายความว่าเว็บเซิร์ฟเวอร์ของคุณอาจมีการเชื่อมต่อมากมายเช่น:

root@buglab:~# netstat -pnt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 173.200.1.18:80      10.100.1.100:49923        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.200.1.200:10155        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.10.1.10:14400        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.10.1.10:50652        ESTABLISHED 13939/nginx: worker
tcp        0      0 173.200.1.18:80      10.20.1.20:57554        ESTABLISHED 13939/nginx: worker 

และนั่นเป็นเรื่องที่ดีอย่างสมบูรณ์ อย่างไรก็ตามหาก 'ที่อยู่ต่างประเทศทั้งหมด' เหมือนกันสิ่งนี้อาจทำให้เกิดปัญหาได้ (เช่น 'เราเตอร์ขนาดใหญ่ที่ทำหน้าที่เซิร์ฟเวอร์ NAT <---> ด้วยที่อยู่ IP เดียว')

ถ้าฉันต้องยืนยันว่าทำไมการหมดเวลาพอร์ตชั่วคราวไม่ใช่ปัญหาทั่วไปฉันขอแนะนำว่าเพราะทุกพอร์ตต้องการบริการฟังและทรัพยากรเพียงพอที่จะตอบสนอง - ทรัพยากรอื่น (หน่วยความจำ, cpu) เป็นคอขวดเป็นอันดับแรก

อย่างไรก็ตามฉันเองเจอปัญหาการอ่อนเพลียของพอร์ตเมื่อทำงานกับ บริษัท โหลดบาลานซ์

2. เหตุใดพอร์ตที่ใช้แล้วจึงสามารถนำเสนอปัญหาสำหรับบริการฟังได้

"ซึ่งอนุญาตการใช้พอร์ตชั่วคราวจาก 1024-65535 ว่าถ้าฉันมีบริการที่ผูกกับพอร์ต 3306 (mySQL เป็นต้น) บางครั้งพวกเขาจะไม่สามารถเริ่มทำงานได้เพราะพอร์ตใช้งานอยู่"

เซิร์ฟเวอร์ mySQL ไม่สามารถเชื่อมโยงกับพอร์ตนั้นได้หากมีการใช้งาน - พูดโดย localhost: 3306 หรือบนอินเตอร์เฟสทั้งหมด ตัวอย่างเช่นดูบรรทัด 0.0.0.0:80 ในnetstatเอาต์พุตต่อไปนี้?

root@buglab:~# netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      PID/Program name
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      964/php-fpm.conf)
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      1660/mysqld     
tcp        0      0 0.0.0.0:842             0.0.0.0:*               LISTEN      1317/inetd      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      13938/nginx     

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

โดยปกติแล้วพอร์ต 3306 นั้นใช้ได้เพราะบริการฟังมีพอร์ตที่กำหนดไว้ล่วงหน้า (หรือช่วง) ที่ร้องขอจากเครื่องโฮสต์ - เช่นพอร์ต 80 และ 443 สำหรับเว็บเซิร์ฟเวอร์


0

ฉันสามารถมีการเชื่อมต่อ 65k จาก 127.0.0.1:(x) ถึง 127.0.0.1:80 ฉันสามารถมีการเชื่อมต่อ 65k จาก 127.0.0.1:(55) ถึง 127.0.0.1:555

a: ใช่ถ้าคุณพอร์ตท้องถิ่น 1-65535 นับการเชื่อมต่อคือ 65k-1 (ฟังพอร์ตหนึ่ง)

โดยทั่วไปอีกครั้งคำถามคือ (srcip, srcport, dstip, dstport) จะต้องไม่ซ้ำกันถูกต้องหรือไม่ a: ใช่

ฉันไม่สามารถเปิดการเชื่อมต่อมากกว่า 65k จาก ip "A" ถึง IP "B", พอร์ต "N" ในทำนองเดียวกัน IP เดียวไม่สามารถเปิดการเชื่อมต่อ 65k ไปยังเว็บเซิร์ฟเวอร์ของฉันได้ที่ xxxx: 80 แต่ฉันสามารถรองรับได้มากกว่า โดยรวมแล้ว 65k ตราบใดที่พวกเขามาจากแหล่ง IP ที่แตกต่างกัน?

a: IP เดียวไม่สามารถเปิดการเชื่อมต่อมากกว่า 65k ไปยังเว็บเซิร์ฟเวอร์ของฉันได้ที่ xxxx: 80 เนื่องจาก srcip, srcport, dstip, dstport ไม่ซ้ำกัน ใช่คุณสามารถรองรับได้มากกว่า 65k ถ้า soruce ip นั้นต่างกัน

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