NetKubeLab EN

Network Fundamental ออกสู่โลกกว้าง

VPN และอุโมงค์ — การห่อแพ็กเก็ตไว้ในแพ็กเก็ต

เครื่องที่ใช้เขียนบทนี้มีอินเทอร์เฟซอุโมงค์สิบห้าตัว ที่ตั้ง MTU ไว้ห้าค่าต่างกัน และหนึ่งในนั้นใหญ่กว่าสายที่มันวิ่งอยู่บน

· หมวด 8 · ออกสู่โลกกว้าง · 6 นาที

คำว่า VPN ปรากฏใน 6 บทบนเว็บนี้ ส่วนใหญ่ในฐานะสาเหตุของอาการแปลก ๆ

บทนี้อธิบายว่ามันทำอะไรจริง ๆ และคำตอบสั้นกว่าที่คนคิด — มันเอาแพ็กเก็ตใส่ไว้ ในแพ็กเก็ตอีกใบ ส่วนที่เหลือทั้งหมดเป็นผลที่ตามมาจากประโยคนั้น

ถ้ายังไม่เคยดู เริ่มตรงนี้

เครื่องคุณอาจมีอินเทอร์เฟซอุโมงค์อยู่แล้วหลายตัว

$ ifconfig | grep -E '^(utun|gif|stf)'

บนเครื่องที่ใช้เขียนบทนี้ มี 15 ตัว และค่า MTU ของพวกมันคือ

   MTU   interfaces
  1000            1
  1280            3
  1380            5
  1500            5
  2000            1

ห้าค่าที่ต่างกัน บนเครื่องเดียว ขณะที่ลิงก์จริงมีค่าเดียวคือ 1500

การห่อ — ทั้งหมดของเรื่องนี้

RFC 2003 ปี 1996 อธิบายไว้ในประโยคเดียว

"To encapsulate an IP datagram using IP in IP encapsulation, an outer IP header is inserted before the datagram's existing IP header"

แพ็กเก็ตเดิมทั้งใบกลายเป็นข้อมูลของแพ็กเก็ตใหม่ โดยมีหัวใหม่ครอบไว้ข้างหน้า

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

เอกสารระบุด้วยว่าความยาวรวมถูกนับอย่างไร

"The Total Length measures the length of the entire encapsulated IP datagram, including the outer IP header, the inner IP header, and its payload."

สองหัว หนึ่งแพ็กเก็ต และนั่นคือที่มาของทุกปัญหาในบทนี้

ราคาที่ต้องจ่าย คือที่ว่าง

หัวที่เพิ่มเข้ามากินที่จาก payload ตรง ๆ

  outer header          bytes   inner usable on a 1500 link
  IPv4 header only         20                          1480
  IPv4 + UDP               28                          1472
  IPv6 header only         40                          1460

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

นี่คือเหตุผลที่บทความ MTU บอกว่าอุโมงค์เป็น ตัวปัญหาเสมอ

ค่าที่วัดได้บนเครื่องนี้ อธิบายอะไรได้บ้าง

กลับไปดูตารางตอนต้นบท

  1500   เท่าลิงก์จริง ไม่ได้หักหัวอุโมงค์ออกเลย
  1380   หักออก 120 ไบต์
  1280   ค่าต่ำสุดที่ IPv6 รับประกัน
  1000   หักออกเยอะ เผื่อไว้มาก
  2000   ใหญ่กว่าลิงก์ที่มันวิ่งอยู่บน

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

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

อุโมงค์ต้องค้นหา MTU ของตัวเองด้วย

RFC 2003 มีหัวข้อชื่อ Tunnel MTU Discovery ซึ่งอธิบายว่า

"When the Don't Fragment bit is set by the originator and copied into the outer IP header, the proper MTU of the tunnel will be learned from ICMP Datagram Too Big (Type 3, Code 4) messages reported to the encapsulator."

กลไกค้นหา MTU ทำงานสองชั้น ชั้นในสำหรับแพ็กเก็ตเดิม และชั้นนอกสำหรับแพ็กเก็ตที่ห่อแล้ว

นี่คือกลไกเดียวกับในบทความ MTU แต่ซ้อน กันสองชั้น

  inner   เครื่องต้นทาง ค้นหา MTU ของอุโมงค์
  outer   ตัวห่อ ค้นหา MTU ของเส้นทางจริง

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

สิ่งที่อุโมงค์ให้ และสิ่งที่มันไม่ได้ให้

การห่อทำให้เราเตอร์ระหว่างทางเห็นแค่หัวใบนอก แต่การห่ออย่างเดียวไม่ได้แปลว่า เข้ารหัส

  encapsulation   ห่อไว้ในแพ็กเก็ตใหม่ ใครดักได้ก็ยังอ่านได้
  encryption      ทำให้อ่านไม่ออกถ้าไม่มีกุญแจ คนละเรื่องกัน

RFC 2003 ทั้งฉบับพูดถึงการห่ออย่างเดียว ส่วนการเข้ารหัสอยู่ในเอกสารคนละฉบับคือ RFC 4301 คำว่า VPN ในการใช้งานทั่วไปหมายถึงทั้งสองอย่างรวมกัน แต่ในทางเทคนิค มันเป็นสองชั้นที่แยกกันได้

บทความ TLS อธิบายการเข้ารหัสในบริบทของเว็บ ไว้แล้ว หลักการเรื่องกุญแจเป็นเรื่องเดียวกัน ต่างกันที่ชั้นที่มันทำงาน

เมื่อมันโกหก

"VPN แปลว่าเข้ารหัส" ไม่เสมอไป การห่อกับการเข้ารหัสเป็นคนละเรื่อง อุโมงค์ บางชนิดห่ออย่างเดียว

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

"ตั้ง MTU ของอุโมงค์เท่าลิงก์จริงก็ได้" เครื่องนี้มีตัวที่ตั้งไว้ 1500 เท่า ลิงก์จริงอยู่ ซึ่งแปลว่าไม่ได้เผื่อที่ให้หัวอุโมงค์เลย

"อุโมงค์ทำให้เราเตอร์ระหว่างทางมองไม่เห็นอะไรเลย" มันเห็นหัวใบนอก คือรู้ว่า ใครคุยกับใครในระดับปลายอุโมงค์ และรู้ปริมาณ

"ปัญหา VPN แก้ด้วยการลด MTU เสมอ" ลดแล้วดีขึ้นในหลายกรณี แต่ค่าที่ควรลด ขึ้นกับชนิดอุโมงค์ และการลดมากเกินจำเป็นก็เสีย throughput ตามที่ RFC 1191 เตือน

ตัวอย่างจริงจากงานจริง

กรณีที่ 1 — เปิด VPN แล้วบางเว็บใช้ไม่ได้

สถานการณ์ VPN ต่อติด ping ผ่าน แต่บางหน้าโหลดค้าง

คำสั่ง เทียบ MTU ของอุโมงค์กับของลิงก์จริง

$ ifconfig | grep -E 'mtu' | sort -u

อ่านอย่างไร ถ้าอินเทอร์เฟซอุโมงค์ตั้งไว้เท่าลิงก์จริง แปลว่ายังไม่ได้หักหัว ออก และอาการจะเหมือนหลุมดำ MTU ในบทความ MTU ทุกประการ

สิ่งที่ยังไม่ได้พิสูจน์ MTU เป็นสาเหตุที่พบบ่อย ไม่ใช่สาเหตุเดียว ต้องทดสอบ ด้วย ping -D ขนาดใหญ่ผ่านอุโมงค์ เพื่อยืนยันว่าขอบอยู่ตรงไหนจริง

กรณีที่ 2 — ตัดสินใจว่าจะตั้ง MTU ของอุโมงค์เท่าไหร่

สถานการณ์ ตั้งอุโมงค์ใหม่และต้องเลือกค่า

อ่านอย่างไร เริ่มจากสองตัวเลข

  1  MTU ของเส้นทางจริง ที่วัดด้วย ping -D
  2  ขนาดหัวของอุโมงค์ชนิดที่ใช้

ค่าที่ตั้งควรเป็นข้อหนึ่งลบข้อสอง ไม่ใช่ค่าที่คัดลอกมาจากที่อื่น

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

กรณีที่ 3 — ไล่ดูว่าเครื่องมีอุโมงค์อะไรอยู่บ้าง

สถานการณ์ เครื่องมีพฤติกรรมเครือข่ายแปลก ๆ และไม่แน่ใจว่ามีอะไรทำงานอยู่

คำสั่ง

$ ifconfig | grep -E '^(utun|gif|stf|ipsec)'

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

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

สิ่งที่การห่อสอน

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

MTU เปลี่ยน จำนวนฮอปที่เห็นเปลี่ยน และกลไกที่พึ่ง ICMP ต้องทำงานสองรอบแทนที่จะ รอบเดียว

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

อ้างอิง

เอกสารมาตรฐาน

  • RFC 2003 ตุลาคม 1996 IP Encapsulation within IP — นิยามการห่อ การนับความยาวรวม และหัวข้อ Tunnel MTU Discovery ที่ยกมาอ้าง
  • RFC 4301 ธันวาคม 2005 Security Architecture for the Internet Protocol — เอกสารที่ครอบคลุมชั้น การเข้ารหัส ซึ่งแยกจากการห่อ

วัดจากเครื่องที่ใช้เขียน

  • ifconfig พบอินเทอร์เฟซอุโมงค์ 15 ตัว ที่ตั้ง MTU ไว้ห้าค่าต่างกัน คือ 1000, 1280, 1380, 1500 และ 2000 ขณะที่ลิงก์จริงมีค่าเดียวคือ 1500

คำนวณเอง

  • ตารางที่ว่างที่เหลือหลังหักหัวใบนอกออกจาก 1500

สิ่งที่ยืนยันจากต้นทางไม่ได้

  • ค่า MTU ของอินเทอร์เฟซอุโมงค์แต่ละตัวถูกตั้งโดยซอฟต์แวร์ใดและด้วยเหตุผลใด
  • ขนาดหัวของอุโมงค์แต่ละชนิด บทนี้ให้เฉพาะขนาดหัว IP มาตรฐานเท่านั้น

วัดจากเครื่องจริงคำนวณเอง

อ่านหน้านี้เป็นภาษาอังกฤษ