ฉันจะป้องกันการเชื่อมต่อ TCP ค้างผ่านเครือข่าย OpenVPN ได้อย่างไร


19

มีการเพิ่มรายละเอียดใหม่ในตอนท้ายของคำถามนี้ เป็นไปได้ว่าฉันมีสาเหตุที่ศูนย์

ฉันมีการตั้งค่า VPN ที่ใช้ UDP OpenVPN ในtapโหมด (ฉันต้องการtapเพราะฉันต้องการ VPN เพื่อส่งแพ็คเก็ตแบบหลายผู้รับซึ่งดูเหมือนจะไม่สามารถทำได้กับtunเครือข่าย) กับลูกค้าจำนวนหนึ่งผ่านอินเทอร์เน็ต ฉันพบว่าการเชื่อมต่อ TCP บ่อยครั้งค้างผ่าน VPN นั่นคือฉันจะสร้างการเชื่อมต่อ TCP (เช่นการเชื่อมต่อ SSH แต่โปรโตคอลอื่น ๆ มีปัญหาที่คล้ายกัน) และในบางช่วงระหว่างเซสชันดูเหมือนว่าทราฟฟิกจะหยุดการส่งผ่านเซสชัน TCP นั้น

ดูเหมือนว่าจะเกี่ยวข้องกับจุดที่การถ่ายโอนข้อมูลขนาดใหญ่เกิดขึ้นเช่นถ้าฉันเรียกใช้lsคำสั่งในเซสชัน SSH หรือถ้าฉันcatเป็นแฟ้มบันทึกที่ยาว การค้นหาของ Google บางคำตอบจำนวนมากเช่นนี้ก่อนหน้านี้ใน Server Faultแสดงให้เห็นว่าผู้ร้ายน่าจะเป็นปัญหา MTU: ในช่วงที่มีการรับส่งข้อมูลสูง VPN พยายามส่งแพ็กเก็ตที่ทิ้งบางส่วนไว้ในท่อระหว่าง จุดสิ้นสุด VPN คำตอบที่ลิงก์ข้างต้นแนะนำให้ใช้การตั้งค่าการกำหนดค่า OpenVPN ต่อไปนี้เพื่อบรรเทาปัญหา:

fragment 1400
mssfix

สิ่งนี้ควร จำกัด MTU ที่ใช้บน VPN เป็น 1400 ไบต์และแก้ไขขนาดเซ็กเมนต์สูงสุด TCP เพื่อป้องกันการสร้างแพ็คเก็ตใด ๆ ที่ใหญ่กว่านั้น ดูเหมือนว่าจะช่วยบรรเทาปัญหาได้เล็กน้อย แต่ฉันก็ยังเห็นปัญหาค้างอยู่บ่อยครั้ง ฉันได้ลองหลายขนาดเป็นข้อโต้แย้งของfragmentคำสั่ง: 1200, 1,000, 576 ทั้งหมดมีผลลัพธ์ที่คล้ายกัน ฉันไม่สามารถคิดถึงโทโพโลยีเครือข่ายที่แปลกประหลาดใด ๆ ระหว่างปลายทั้งสองที่อาจก่อให้เกิดปัญหาดังกล่าว: เซิร์ฟเวอร์ VPN กำลังทำงานบนเครื่องpfSense ที่เชื่อมต่อโดยตรงกับอินเทอร์เน็ตและลูกค้าของฉันก็เชื่อมต่อโดยตรงกับอินเทอร์เน็ตในที่อื่น

ชิ้นส่วนปริศนาที่แปลกประหลาดอีกชิ้นหนึ่ง: ถ้าฉันเรียกใช้tracepathยูทิลิตี้นั่นก็ดูเหมือนว่าจะช่วยแก้ปัญหาได้ ตัวอย่างการรันมีลักษณะดังนี้:

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 hops 1 back 64 

วิ่งข้างต้นอยู่ระหว่างสองลูกค้าใน VPN: ฉันเริ่มต้นการสืบค้นกลับจากไปยังปลายทางของ192.168.100.90 192.168.100.91ไคลเอ็นต์ทั้งสองถูกกำหนดค่าด้วยfragment 1200; mssfix;ความพยายามที่จะ จำกัด MTU ที่ใช้ในลิงก์ ผลลัพธ์ข้างต้นดูเหมือนจะแนะนำว่าtracepathสามารถตรวจจับ MTU ของพา ธ 1500 ไบต์ระหว่างไคลเอ็นต์สองราย ฉันจะสมมติว่ามันจะค่อนข้างเล็กลงเนื่องจากการตั้งค่าการแตกแฟรกเมนต์ที่ระบุในการกำหนดค่า OpenVPN ฉันพบว่าผลลัพธ์ค่อนข้างแปลก

ถึงแม้จะเป็นคนแปลกหน้า แต่ถ้าฉันมีการเชื่อมต่อ TCP ในสถานะหยุดทำงาน (เช่นเซสชัน SSH ที่มีรายชื่อไดเรกทอรีที่ค้างอยู่ตรงกลาง) จากนั้นการดำเนินการtracepathคำสั่งที่แสดงด้านบนทำให้การเชื่อมต่อเริ่มขึ้นอีกครั้ง ! ฉันไม่สามารถหาคำอธิบายที่สมเหตุสมผลว่าเหตุใดจึงเป็นเช่นนี้ แต่ฉันรู้สึกว่านี่อาจชี้ไปที่วิธีการแก้ปัญหาในท้ายที่สุด

ไม่มีใครมีคำแนะนำสำหรับสิ่งอื่น ๆ ที่จะลอง?

แก้ไข:ฉันกลับมาและดูอีกนิดและพบข้อมูลที่น่าสับสนมากกว่านี้เท่านั้น:

  • ฉันตั้งค่าการเชื่อมต่อ OpenVPN เป็นแฟรกเมนต์ที่ 1,400 ไบต์ดังที่แสดงไว้ด้านบน จากนั้นฉันเชื่อมต่อกับ VPN จากทั่วอินเทอร์เน็ตและใช้ Wireshark เพื่อดูแพ็คเก็ต UDP ที่ส่งไปยังเซิร์ฟเวอร์ VPN ในขณะที่แผงลอยเกิดขึ้น ไม่มีใครมีค่ามากกว่าจำนวน 1,400 ไบต์ที่ระบุดังนั้นการแตกแฟรกเมนต์จึงทำงานได้อย่างถูกต้อง

  • เพื่อตรวจสอบว่าแม้กระทั่ง MTU ขนาด 1,400 ไบต์ก็เพียงพอแล้วฉันก็ส่ง Ping เซิร์ฟเวอร์ VPN โดยใช้คำสั่ง (Linux) ต่อไปนี้:

    ping <host> -s 1450 -M do
    

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

ดังนั้นนี่อาจไม่ใช่ปัญหาของ MTU เลย ฉันแค่สับสนว่ามันอาจจะเป็นอะไร!

แก้ไข 2:โพรงกระต่ายค่อยๆลึก: ตอนนี้ฉันแยกปัญหาออกไปอีกเล็กน้อย ดูเหมือนว่าจะเกี่ยวข้องกับระบบปฏิบัติการที่แน่นอนที่ไคลเอนต์ VPN ใช้ ฉันได้ทำซ้ำปัญหาสำเร็จบนเครื่อง Ubuntu อย่างน้อยสามเครื่อง (รุ่น 12.04 ถึง 13.04) ฉันสามารถทำซ้ำการเชื่อมต่อ SSH ที่เชื่อถือได้อย่างน่าเชื่อถือภายในหนึ่งนาทีหรือมากกว่านั้นโดยเพียงแค่catล็อกไฟล์ขนาดใหญ่

อย่างไรก็ตามถ้าฉันทำการทดสอบเดียวกันโดยใช้เครื่อง CentOS 6 เป็นไคลเอนต์ฉันก็ไม่เห็นปัญหา! ฉันทดสอบโดยใช้ OpenVPN รุ่นไคลเอ็นต์เดียวกันกับที่ฉันใช้บนเครื่อง Ubuntu ฉันสามารถcatล็อกไฟล์เป็นเวลาหลายชั่วโมงโดยไม่เห็นการเชื่อมต่อค้าง ดูเหมือนว่าจะให้ข้อมูลเชิงลึกเกี่ยวกับสาเหตุขั้นสูงสุด แต่ฉันไม่แน่ใจว่าข้อมูลเชิงลึกนั้นคืออะไร

ฉันตรวจสอบปริมาณการใช้งานผ่าน VPN โดยใช้ Wireshark ฉันไม่ใช่ผู้เชี่ยวชาญ TCP ดังนั้นฉันไม่แน่ใจว่าจะทำอย่างไรในรายละเอียดเต็มไปด้วยเลือด แต่สิ่งที่สำคัญคือในบางจุดแพ็กเก็ต UDP จะลดลงเนื่องจากแบนด์วิดท์ที่ จำกัด ของลิงก์อินเทอร์เน็ตทำให้เกิดการส่ง TCP ซ้ำภายใน อุโมงค์ VPN ในไคลเอนต์ CentOS การส่งสัญญาณใหม่เหล่านี้เกิดขึ้นอย่างถูกต้องและสิ่งต่าง ๆ ดำเนินไปอย่างมีความสุข ในบางจุดด้วยไคลเอนต์ Ubuntu แม้ว่าปลายทางระยะไกลจะเริ่มส่งสัญญาณ TCP เซกเตอร์เดิมซ้ำไปซ้ำมา ไคลเอนต์ส่งสิ่งที่ดูเหมือน TCP ACK ที่ถูกต้องไปยังการส่งแต่ละครั้ง แต่จุดสิ้นสุดระยะไกลยังคงส่งผ่านส่วน TCP เดียวกันเป็นระยะ สิ่งนี้จะขยายขอบเขตการโฆษณาและการเชื่อมต่อ คำถามของฉันที่นี่จะเป็น:

  • ใครบ้างมีคำแนะนำสำหรับวิธีการแก้ไขปัญหาและ / หรือตรวจสอบสาเหตุของปัญหา TCP? เหมือนกับว่าปลายทางระยะไกลไม่ยอมรับข้อความ ACK ที่ส่งโดยไคลเอนต์ VPN

ความแตกต่างทั่วไปอย่างหนึ่งระหว่างโหนด CentOS และ Ubuntu รุ่นต่าง ๆ คือ Ubuntu มีเคอร์เนลลีนุกซ์รุ่นใหม่กว่ามาก (จาก 3.2 ใน Ubuntu 12.04 เป็น 3.8 ใน 13.04) ตัวชี้ไปยังข้อบกพร่องเคอร์เนลใหม่อาจจะ? ฉันสมมติว่าถ้าเป็นเช่นนั้นฉันจะไม่เป็นคนเดียวที่ประสบปัญหา ฉันไม่คิดว่านี่จะเป็นสิ่งที่แปลกใหม่


การกำหนดเส้นทางแพ็คเก็ตมัลติคาสต์ผ่านtunเครือข่ายควรเป็นไปได้โดยใช้มัลติคาสต์การกำหนดเส้นทาง daemons (เช่นpimd ) และการให้เซิร์ฟเวอร์ OpenVPN ใช้--topologyตัวเลือกที่กำหนดเป็น "subnet" - ดูคู่มือ
kostix

ไคลเอนต์หรือเซิร์ฟเวอร์ VPN ระบุอะไรในบันทึกในเวลาที่มีปัญหาเหรอ
mgorven

@gorven: ไม่แน่นอนในลูกค้า ฉันจะต้องทำงานเพื่อรับบันทึกเซิร์ฟเวอร์
Jason R

@gorven: ในที่สุดฉันก็มีโอกาสกลับมาที่นี่อีก ไม่มีอะไรในไคลเอนต์หรือเซิร์ฟเวอร์บันทึกเมื่อเกิดเหตุการณ์นี้ มันทำให้งงงันจริงๆ
Jason R

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

คำตอบ:


10

คำสั่งนี้แก้ให้ฉัน:

$ sudo ip link set dev tun0 mtu 1350 && echo ":)"

คุณสามารถตรวจสอบการตั้งค่า tun0 ด้วย

$ ip a s

ไชโย!


ลูกค้าหรือฝั่งเซิร์ฟเวอร์?
แมตต์

ขอบคุณมาก! @ แมทมันขึ้นอยู่กับปัญหาที่พบ สำหรับเรามันอยู่บนเซิร์ฟเวอร์ แต่อาจอยู่ฝั่งไคลเอ็นต์ ด้วยค่าที่แตกต่างกันคุณสามารถทดสอบping <host> -s 1350 -M doเพื่อหาค่าที่เหมาะสม
Eino Gourdin

2

ปิดใช้งานการปรับขนาดหน้าต่างใน TCP ด้วย:

sysctl -w net.ipv4.tcp_window_scaling=0

หลังจากนั้น SSH กับระบบ Debian / Ubuntu ผ่าน VPN นั้นใช้งานได้ดีสำหรับฉัน


0

บน Windows ที่ใช้ Putty คุณต้องเปลี่ยน MTU โดยไปที่การเชื่อมต่อท้องถิ่นสำหรับการเชื่อมต่อ vpn -> รายละเอียดบนอินเทอร์เฟซเครือข่าย (ตัวแปลง windows TAP หรืออะไรทำนองนั้น) -> ขั้นสูง -> คุณสมบัติ -> MTU (เปลี่ยนเป็นอะไรบางอย่าง ต่ำกว่า 1500) คุณอาจต้องเชื่อมต่อใหม่ มันทำงานกับฉันใน Windows และ Putty


-1

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

ดูอัปเดต 1 ที่นี่: วิธีป้องกัน SSH ค้างผ่านไคลเอ็นต์ openvpn ไปยังการเชื่อมต่อไคลเอนต์

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