PPTP เชื่อมต่อแล้วค้างอยู่หลัง Linux NAT: ตัวช่วย GRE
TCP 1723 เชื่อมต่อได้แต่เส้นทางข้อมูลตาย: PPTP วิ่งอยู่ใน GRE ซึ่งไม่มีพอร์ต โหลดตัวช่วย ผูกมันอย่างชัดเจน แล้วเปิดโปรโตคอล 47
มีคนส่งต่อพอร์ต 1723 ไคลเอนต์ไปถึงเซิร์ฟเวอร์ การยืนยันตัวตนเริ่มขึ้น แล้วทุกอย่างก็หยุดโดยไม่มีข้อผิดพลาด ข้อสรุปตามธรรมชาติคือรหัสผ่านผิด จึงพิมพ์รหัสผ่านซ้ำสามครั้ง การส่งต่อนั้นถูกต้องและข้อมูลรับรองก็ถูกต้อง สิ่งที่พังคือโปรโตคอลที่สองซึ่งการส่งต่อไม่เคยครอบคลุม และค่าเริ่มต้นของเคอร์เนลที่หยุดช่วยเหลือมันไปอย่างเงียบ ๆ
การส่งต่อไม่เคยเป็นปัญหา
กฎการส่งต่อพอร์ตอธิบายทราฟฟิก TCP หรือ UDP มันอธิบายเพย์โหลดที่สลับไปใช้โปรโตคอล IP อื่นกลางเซสชันไม่ได้ และ PPTP ก็ทำอย่างนั้น
นั่นคือเหตุผลที่การเชื่อมต่อดูปกติดีจนถึงวินาทีที่มันค้าง ส่วนที่กฎพอร์ตควบคุมได้สำเร็จ และส่วนที่ควบคุมไม่ได้ก็คือส่วนที่ล้มเหลว
TCP สำหรับควบคุม GRE สำหรับข้อมูล
การเรียกเจรจาผ่าน TCP 1723 เมื่อขึ้นแล้ว เพย์โหลดจะย้ายเข้า GRE ซึ่งเป็นโปรโตคอล IP 47 ที่ไม่พกหมายเลขพอร์ตเลย กฎที่อิงพอร์ตไม่มีอะไรให้จับคู่
สิ่งที่ GRE พกคือตัวระบุการเรียกในส่วนหัว และตัวแปล NAT ต้องเขียนฟิลด์นั้นใหม่ให้สอดคล้องกันทั้งสองทิศ ไม่อย่างนั้นสองครึ่งของเซสชันจะเลิกตรงกัน เขียนใหม่ทิศเดียวแต่อีกทิศไม่เขียนจะได้เซสชันที่ยืนยันตัวตนได้แล้วทิ้งทุกแพ็กเก็ตข้อมูล นั่นคือรูปร่างของอาการ: สำเร็จ แล้วเงียบ
GRE เปล่า ๆ ที่ไม่มี PPTP ไม่ต้องเขียนใหม่เช่นนั้น จึงเป็นเหตุผลที่อุโมงค์ GRE ธรรมดาทำงานผ่านเราเตอร์ที่ล้มเหลวสำหรับไคลเอนต์ PPTP บนเส้นทางเดียวกันได้
สี่โมดูลและ sysctl ที่ปิดมัน
สองโมดูลจัดการการแบ่งเฟรม nf_conntrack_proto_gre และ nf_nat_proto_gre อีกสองตัวจัดการตัวระบุการเรียก nf_conntrack_pptp และ nf_nat_pptp การโหลดตัวสุดท้ายดึงตัวอื่นมาด้วยผ่านการพึ่งพา รายการโมดูลจึงควรแสดงทั้งสี่
คำแนะนำเก่าใช้คำนำหน้า ip_ จากยุค 2.6 คำสั่งเหล่านั้นอาจดูเหมือนทำงานโดยไม่ได้โหลดอะไร จึงควรตรวจรายการที่โหลดแล้วไม่ใช่สถานะออก
การโหลดไว้อย่างเดียวไม่พออีกต่อไป ตั้งแต่ Linux 4.7 ค่าเริ่มต้นของ sysctl net.netfilter.nf_conntrack_helper เป็น 0 ซึ่งปิดการกำหนดตัวช่วยอัตโนมัติสำหรับโฟลว์ใหม่ เราเตอร์อาจมีทุกโมดูลแต่ก็ยังไม่แปลอะไรเลย ตรวจค่าที่มีผลจริงก่อนจะดูรายการโมดูลอีกครั้ง
ไม่ว่าจะเปิดการกำหนดอัตโนมัติกลับทั้งระบบ หรือผูกตัวช่วยเข้ากับโฟลว์ที่ต้องการแล้วปล่อยอย่างอื่นไว้:
iptables -t raw -A PREROUTING -p tcp --dport 1723 -j CT --helper pptpตัวเลือกที่สองน่าเลือกกว่า มันจำกัดพฤติกรรมไว้ที่ทราฟฟิก PPTP แทนที่จะเปิดการกำหนดอัตโนมัติทั่วทั้งเราเตอร์อีกครั้ง
การเปิดโปรโตคอลที่ไม่มีพอร์ต
กฎไฟร์วอลล์ที่อนุญาต 1723 ไม่ได้บอกอะไรเกี่ยวกับโปรโตคอล 47 บน firewalld ให้อนุญาตโปรโตคอลในโซนที่หันไปทางไคลเอนต์ บน iptables ธรรมดาให้ยอมรับโปรโตคอล gre ในเชนอินพุต
จากนั้นดักจับทั้งสองด้าน แพ็กเก็ตที่ออกจากไคลเอนต์โดยไม่มีคำตอบกลับมาแปลว่าเส้นทางขากลับถูกกรอง และนั่นเป็นความผิดพลาดคนละแบบกับข้อมูลรับรองที่ถูกปฏิเสธ
หลังจากเชื่อมต่อได้ ขีดจำกัดขนาด
GRE แทรกส่วนหัว และ PPP ข้างในเพิ่มอีก ดังนั้นลิงก์ที่ทำงานได้จะรายงาน MTU ต่ำกว่า 1500 มาก คำตอบเล็กโหลดได้ แต่คำตอบใหญ่ติดขัด ซึ่งดูเหมือนปัญหาที่สองที่ไม่เกี่ยวข้องโผล่ขึ้นมาในจังหวะที่ปัญหาแรกถูกแก้
อ่าน MTU บนอะแดปเตอร์ PPP ของไคลเอนต์และ เทียบกับค่าที่เราเตอร์คำนวณเอง แทนที่จะลดตัวเลขลงไปเรื่อย ๆ จนมีอะไรสักอย่างทำงาน แพ็กเก็ตขนาดเต็มที่ออกไปแล้วไม่มีอะไรกลับมาบ่งชี้ถึงขีดจำกัดนั้น ไม่ใช่การแปล
การซ่อมเส้นทางทำให้ผู้ใช้กลับมาทำงานได้ และไม่ได้ทำให้ PPTP เป็นตัวเลือกที่ดี MS-CHAPv2 และ RC4 เลิกใช้มานานแล้ว จึงควรมองการโหลดโมดูลเป็นการแก้ชั่วคราวและวางแผนย้ายไปโปรโตคอลที่ยังได้รับการดูแล