เหตุใดเซิร์ฟเวอร์จึงไม่ส่งแพ็กเก็ต SYN / ACK เพื่อตอบกลับแพ็คเก็ต SYN


46

เมื่อเร็ว ๆ นี้เราได้ตระหนักถึงปัญหาการเชื่อมต่อ TCP ที่ จำกัด เฉพาะผู้ใช้ mac และ Linux ที่เรียกดูเว็บไซต์ของเรา

จากมุมมองของผู้ใช้มันนำเสนอตัวเองเป็นเวลาเชื่อมต่อนานมากไปยังเว็บไซต์ของเรา (> 11 วินาที)

เราจัดการเพื่อติดตามลายเซ็นทางเทคนิคของปัญหานี้ แต่ไม่สามารถระบุสาเหตุที่เกิดขึ้นหรือวิธีแก้ไขได้

โดยทั่วไปสิ่งที่เกิดขึ้นคือเครื่องของลูกค้ากำลังส่งแพ็กเก็ต SYN เพื่อสร้างการเชื่อมต่อ TCP และเว็บเซิร์ฟเวอร์ได้รับ แต่ไม่ตอบสนองกับแพ็คเก็ต SYN / ACK หลังจากไคลเอนต์ส่งแพคเก็ต SYN หลายครั้งสุดท้ายเซิร์ฟเวอร์ตอบกลับด้วยแพ็คเก็ต SYN / ACK และทุกอย่างเรียบร้อยสำหรับการเชื่อมต่อที่เหลือ

และแน่นอนนักเตะที่มีปัญหา: มันไม่ต่อเนื่องและไม่เกิดขึ้นตลอดเวลา (แม้ว่ามันจะเกิดขึ้นระหว่าง 10-30% ของเวลา)

เราใช้ Fedora 12 Linux เป็นระบบปฏิบัติการและ Nginx เป็นเว็บเซิร์ฟเวอร์

ภาพหน้าจอของการวิเคราะห์ wireshark

ภาพหน้าจอของการวิเคราะห์ wireshark

ปรับปรุง:

การปิดการปรับสเกลของหน้าต่างบนไคลเอนต์ทำให้ไม่สามารถเกิดปัญหาได้ ตอนนี้ฉันแค่ต้องการการแก้ปัญหาด้านเซิร์ฟเวอร์ (เราไม่สามารถทำให้ลูกค้าทุกคนทำได้) :)

การปรับปรุงครั้งสุดท้าย:

วิธีแก้ไขคือปิดทั้งการปรับสเกลหน้าต่าง TCP และการ ประทับเวลา TCPบนเซิร์ฟเวอร์ของเราที่สาธารณชนสามารถเข้าถึงได้


1
ฉันคิดว่าเราจะต้องเห็นบางส่วนของมันเกิดขึ้น
coredump

คุณมี acls หรือกฎใด ๆ ที่อิงกับ DNS ย้อนกลับหรือไม่? คุณอาจต้องดูมากกว่านั้นเพียงแค่การเชื่อมต่อระหว่างไคลเอนต์และเซิร์ฟเวอร์ บางทีการค้นหา DNS กำลังหมดเวลาหรือ
Zoredache

@coredump: นี่เป็นภาพหน้าจอของการวิเคราะห์แบบ wireshark ที่แสดงให้เห็นถึงปัญหาi.imgur.com/Bnzrm.png (ไม่สามารถหาวิธีการส่งออกเพียงสตรีม .... )
codemonkey

@Zoredache: ไม่เราไม่มี acls หรือกฎใด ๆ โดยใช้ DNS ย้อนกลับ นี่คือเว็บเซิร์ฟเวอร์สาธารณะและเราอนุญาตให้ทุกคนเข้าถึงได้
codemonkey

แค่ลางสังหรณ์ แต่คุณกำลังทำการ จำกัด อัตราการเชื่อมต่อขาเข้าบนเซิร์ฟเวอร์หรือไม่? พูดด้วย iptables
Steven จันทร์

คำตอบ:


15

เรามีปัญหาเดียวกันนี้แน่นอน เพียงปิดใช้งานการประทับเวลา TCP เพื่อแก้ไขปัญหา

sysctl -w net.ipv4.tcp_timestamps=0

/etc/sysctl.confเพื่อให้การเปลี่ยนแปลงนี้อย่างถาวรทำให้รายการใน

ระมัดระวังในการปิดการใช้งานตัวเลือก TCP Window Scale ตัวเลือกนี้มีความสำคัญสำหรับการให้บริการที่มีประสิทธิภาพสูงสุดผ่านทางอินเทอร์เน็ต คนที่มีการเชื่อมต่อ 10 เมกะบิต / วินาทีจะมีการถ่ายโอนที่ไม่ดีหากเวลาไปกลับ (โดยทั่วไปเหมือนกับ ping) มากกว่า 55 ms

เราสังเกตเห็นปัญหานี้จริงๆเมื่อมีอุปกรณ์หลายชิ้นที่อยู่ด้านหลัง NAT เดียวกัน ฉันสงสัยว่าเซิร์ฟเวอร์อาจสับสนเมื่อเห็นการประทับเวลาจากอุปกรณ์ Android และเครื่อง OSX ในเวลาเดียวกันเนื่องจากพวกเขาใส่ค่าที่แตกต่างอย่างสิ้นเชิงในฟิลด์การประทับเวลา


4
ในกรณีที่มีคนปลายอื่นขึ้นที่นี่ผ่านหลุมกระต่ายเดียวกันกับที่ผมเพิ่งลงไป: ก่อนที่จะปิด TCP timestamps หรือปรับขนาดหน้าต่างซึ่งอาจมีผลกระทบประสิทธิภาพการทำงานอย่างรุนแรงในการเชื่อมโยงการจราจรสูงตรวจสอบเพื่อดูว่า tcp_tw_recycle เป็นปัญหาของคุณ: StackOverflow .com / คำถาม / 8893888 / …
nephtes

12

ในกรณีของฉันคำสั่งต่อไปนี้แก้ไขปัญหาที่ขาดหายไป SYN / ACK ตอบกลับจากเซิร์ฟเวอร์ Linux:

sysctl -w net.ipv4.tcp_tw_recycle=0

ฉันคิดว่าถูกต้องมากกว่าการปิดใช้งานการประทับเวลา TCP เนื่องจากการประทับเวลา TCP มีประโยชน์สำหรับประสิทธิภาพสูง (PAWS การปรับขนาดหน้าต่าง ฯลฯ )

เอกสารเกี่ยวกับการtcp_tw_recycleระบุไว้อย่างชัดเจนว่าไม่แนะนำให้เปิดใช้งานเนื่องจากเราเตอร์ NAT หลายคนรักษาเวลาประทับดังนั้น PAWS จึงเตะเข้าเนื่องจากการประทับเวลาจาก IP เดียวกันไม่สอดคล้องกัน

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this
          option is not recommended for devices communicating with the
          general Internet or using NAT (Network Address Translation).
          Since some NAT gateways pass through IP timestamp values, one
          IP can appear to have non-increasing timestamps.  See RFC 1323
          (PAWS), RFC 6191.

1
คำอธิบายที่ดีที่นี่: vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux ทางฝั่งเซิร์ฟเวอร์อย่าเปิดใช้งาน net.ipv4.tcp_tw_recycle เว้นแต่ว่าคุณค่อนข้างมั่นใจว่าคุณจะไม่มีอุปกรณ์ NAT ในการผสม
Gnought

1
ในกรณีของฉันnet.ipv4.tcp_tw_recycleคือเหตุผลที่แท้จริง ขอบคุณ
bluearrow

tcp_tw_recycle ถูกลบออกในเมล็ดล่าสุด มีวิธีแก้ไขปัญหาอื่นอีกหรือไม่ @nephtes หมายถึงการปิดใช้งานการประทับเวลาทำให้เจ็บประสิทธิภาพ
MappaM

เนื่องจาก tcp_tw_recycle ถูกลบออกปัญหาไม่ควรเกิดขึ้นอีกเมื่อเกิดขึ้นกับค่าที่ไม่ใช่ค่าเริ่มต้นของ tcp_tw_recycle
Lav

5

เพิ่งสงสัย แต่ทำไมสำหรับแพ็กเก็ต SYN (เฟรม # 539; ที่ได้รับการยอมรับ) ฟิลด์ WS และ TSV หายไปในคอลัมน์ "ข้อมูล"

WS นั้นหน้าต่าง TCP ขูดหินปูนและ TSV คือการประทับเวลาราคา ทั้งคู่ถูกพบภายใต้ฟิลด์ tcp.options และ Wireshark ยังควรแสดงถ้ามี บางทีไคลเอนต์ TCP / IP สแต็คแพ็คเก็ต SYN ต่างกันในความพยายามครั้งที่ 8 และนั่นเป็นเหตุผลว่าทำไมมันจึงได้รับการตอบรับอย่างฉับพลัน?

คุณสามารถให้คุณค่าภายในเฟรม 539 แก่เราได้ไหม SYN / ACK มาสำหรับแพคเก็ต SYN ที่ไม่ได้เปิดใช้งาน WS อยู่เสมอหรือไม่


@ Anisis: นี่คือภาพหน้าจอสำหรับรายละเอียดเฟรม 539 (ต้องทำสองส่วน): i.imgur.com/D84GC.png & i.imgur.com/4riq3.png
codemonkey

@codemonkey: แพ็คเก็ต SYN 8 ของคุณดูเหมือนจะแตกต่างจากแพ็กเก็ต SYN เจ็ดรายการแรก เซิร์ฟเวอร์ตอบกลับด้วย SYN / ACK ไปยัง SYN ของไคลเอ็นต์เฉพาะเมื่อฟิลด์ tcp.options มีขนาด 8 ไบต์ (แพ็กเก็ต SYN เจ็ดรายการแรกอาจมี tcp.options ขนาด 20 ไบต์) คุณสามารถปิดการปรับขนาดหน้าต่าง TCP ที่ฝั่งไคลเอ็นต์เพื่อดูว่าปัญหาหายไปหรือไม่ ดูเหมือนว่าปัญหาเกี่ยวกับ TCP / IP stack ในฝั่งเซิร์ฟเวอร์หรือ misconfigured ไฟร์วอลล์บาง ...
ฮันโซโล

@ Anisis: ใช่ฉันได้ดูที่ตั้งแต่คุณชี้ให้เห็นและอื่น ๆ ทั้งหมดแพ็คเก็ต SYN เป็น 24 ไบต์ ฉันจะลองปิดการใช้งานการปรับขนาดหน้าต่างบนไคลเอนต์และกลับมาตรวจสอบกับผลลัพธ์ในตอนเช้า
codemonkey

@Ansis: การปิดหน้าต่างการปรับขนาดบนไคลเอนต์หยุดปัญหาเกิดขึ้น ขอบคุณ! อย่างไรก็ตามตอนนี้ฉันต้องคิดหาวิธีการแก้ไขปัญหานี้ในฝั่งเซิร์ฟเวอร์ (เนื่องจากเราไม่สามารถทำให้ลูกค้าทั้งหมดของเราปิดการใช้งานการปรับขนาดหน้าต่าง) :) เซิร์ฟเวอร์ที่สงสัยมี net.ipv4.tcp_windows_scaling = 1
codemonkey

@Codemonkey: ฉันยอมรับว่าการปิดใช้งาน WS บนไคลเอนต์ทั้งหมดไม่ใช่วิธีแก้ปัญหา แต่อย่างน้อยเราก็ติดตามปัญหาไปยังปัญหา WS / Packet Size เพื่อค้นหาสาเหตุเพิ่มเติมเราควรตรวจสอบวิธีการกำหนดค่าไฟร์วอลล์ของคุณ คุณสามารถสร้างการเชื่อมต่อ TCP ด้วย WS ไปยังพอร์ต TCP อื่นได้หรือไม่ มาจากแหล่ง IP อื่นหรือไม่
ฮันส์โซโล

4

เราเพิ่งพบปัญหาเดียวกันนี้ (ใช้เวลาสักครู่เพื่อปักหมุดไปยังเซิร์ฟเวอร์ที่ไม่ได้ส่งสัญญาณซิงค์)

"ทางออกคือการปิดการปรับขนาดหน้าต่าง tcp และการประทับเวลา tcp บนเซิร์ฟเวอร์ของเราที่สาธารณะเข้าถึงได้"


2

เพื่อดำเนินการต่อในสิ่งที่ Ansis ได้ระบุไว้ฉันได้เห็นปัญหาเช่นนี้เมื่อไฟร์วอลล์ไม่รองรับ TCP Windows Scaling ไฟร์วอลล์ยี่ห้อ / รุ่นใดที่อยู่ระหว่างโฮสต์ทั้งสองนี้


ไฟร์วอลล์คือกล่อง Fedora 13 ที่ใช้ iptables net.ipv4.tcp_windows_scaling ถูกตั้งค่าเป็น 1 ในเครื่องนี้ด้วย
codemonkey

2

SYN / ACK ที่ขาดหายไปอาจเกิดจากการ จำกัด การป้องกัน SYNFLOOD ของคุณในไฟร์วอลล์ต่ำเกินไป ขึ้นอยู่กับจำนวนการเชื่อมต่อกับผู้ใช้เซิร์ฟเวอร์ของคุณสร้างขึ้น การใช้ spdy จะลดจำนวนการเชื่อมต่อและสามารถช่วยในสถานการณ์ที่การnet.ipv4.tcp_timestampsปิดไม่ช่วยได้


1

นี่เป็นลักษณะการทำงานของซ็อกเก็ต TCP ที่รับฟังเมื่องานค้างเต็ม

Ngnix อนุญาตให้มีการตั้งค่าอาร์กิวเมนต์ค้างเพื่อรับฟังในการกำหนดค่า: http://wiki.nginx.org/HttpCoreModule#listen

คอยรับฟัง 80 คนงาน = จำนวน

ลองตั้งค่า num เป็นค่าที่มากกว่าค่าเริ่มต้นเช่น 1024

ฉันไม่รับประกันว่าการฟังคิวอย่างเต็มรูปแบบเป็นปัญหาของคุณจริง ๆ แต่นี่เป็นสิ่งแรกที่ควรตรวจสอบ


ขอบคุณสำหรับทิป. ฉันจะลองดู เราได้ตั้งค่า Backlog ไว้ที่ระดับ OS แต่ไม่ได้ระบุอย่างชัดเจนในการกำหนดค่า Nginx ฉันจะอัปเดตพร้อมกับผลลัพธ์
codemonkey

มันไม่ได้เปลี่ยนพฤติกรรมเลย คิดว่าไม่ใช่ปัญหาเหรอ? หรือปัญหาเดียว ...
codemonkey

1
พารามิเตอร์ backlog ระดับแอปพลิเคชันควบคุมขนาดของคิวสำหรับการเชื่อมต่อ tcp ที่เสร็จสมบูรณ์เช่นจับมือ 3 ทางเสร็จแล้วเช่นได้รับ syn-ack - ดังนั้นจึงไม่ตรงกับสถานการณ์ OP
ygrek

1

ฉันเพิ่งค้นพบว่าไคลเอนต์ Linux TCP เปลี่ยนแพ็กเก็ต SYN หลังจาก 3 พยายามและลบตัวเลือกการปรับขนาดหน้าต่าง ฉันเดาว่าผู้พัฒนาเคอร์เนลคิดว่านี่เป็นสาเหตุของความล้มเหลวในการเชื่อมต่ออินเทอร์เน็ต

มันอธิบายว่าทำไมไคลเอนต์เหล่านี้จัดการเชื่อมต่อหลังจาก 11 วินาที (TCP SYN แบบไร้หน้าต่างน้อยเกิดขึ้นหลังจาก 9 วินาทีในการทดสอบสั้น ๆ ของฉันด้วยการตั้งค่าเริ่มต้น)


0

ฉันมีปัญหาที่คล้ายกัน แต่ในกรณีของฉันมันเป็น TCP checksum ที่คำนวณอย่างผิดพลาด ลูกค้าอยู่ข้างหลังสัตวแพทย์และกำลังรัน ethtool -K veth0 rx off tx off ไม่ได้หลอกลวง

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