OpenVPN บน GCE: เพิ่ม Alias IP ก่อนที่จะ push route
การ push route ไม่ได้ทำให้ VM กลายเป็น next hop ต้องเพิ่มช่วง Alias IP ให้ตรงกับพูลของเซิร์ฟเวอร์ และสร้างเส้นทางกลับใน VPC ก่อนทดสอบไคลเอนต์
ไคลเอนต์เชื่อมต่อไปยังเซิร์ฟเวอร์ OpenVPN บน VM ของ Compute Engine หน้าสถานะบอกว่าเชื่อมต่อแล้ว แต่ ping ไปยังโฮสต์ภายใน VPC ก็ยังไม่ไปถึงไหน สัญชาตญาณคือการเพิ่มบรรทัด push อีกบรรทัด ซึ่งไม่เคยแก้ปัญหาได้จริง Compute Engine ตัดสินใจว่าแพ็กเก็ตจะไปที่ไหนจากตารางเส้นทางของตัวเองและจากแอดเดรสที่อินเทอร์เฟซของ VM ถืออยู่จริง ดังนั้นพูลอุโมงค์ที่ VM ไม่ได้เป็นเจ้าของก็คือพูลที่ไม่มีใครส่งถึง
ตามแพ็กเก็ตที่ล้มเหลวไปแทนที่จะตามไฟล์คอนฟิก แล้วชิ้นส่วนที่ขาดหายจะปรากฏขึ้นตามลำดับ
เริ่มที่แพ็กเก็ตที่ตาย
SYN ออกจากไคลเอนต์ เข้าสู่อุโมงค์ และไปถึง VM ในรูปแพ็กเก็ตที่ถูกห่อหุ้มสำหรับปลายทางภายใน VPC OpenVPN ถอดการห่อหุ้มแล้วพยายามส่งต่อออกทาง eth0 ซึ่งเฟบริกจะถามคำถามหนึ่งข้อก่อนสิ่งอื่นใด: อินสแตนซ์นี้เป็นเจ้าของแอดเดรสปลายทางหรือไม่ พูลอุโมงค์ที่ตัดมาจากซับเน็ตของคนอื่นจะตกคำถามนี้ และแพ็กเก็ตจะถูกทิ้งก่อนที่จะมีการตรวจเส้นทางหรือกฎไฟร์วอลล์ใด ๆ
ดังนั้นทิศทางจากไคลเอนต์ไปยัง VPC จึงมีข้อกำหนดแยกกันสองข้อ และไม่มีข้อใดเป็นคำสั่ง push เลย VM ต้องมีช่วง alias ที่ครอบคลุมพูลอุโมงค์ ซึ่งเป็นสิ่งที่ทำให้มันเป็นเจ้าของแอดเดรสเหล่านั้นอย่างชอบธรรม VPC ต้องมีเส้นทางที่ระบุ VM เป็น next hop สำหรับแต่ละคำนำหน้าที่ได้รับการป้องกัน พลาดข้อใดข้อหนึ่งแล้วแพ็กเก็ตจะตายคนละที่ แต่ไคลเอนต์เห็นความเงียบแบบเดียวกัน
อ่านความล้มเหลวตามลำดับนั้น เพราะจากฝั่งไคลเอนต์เงื่อนไขทั้งสองดูเหมือนกันทุกประการ อุโมงค์ที่รายงานว่าเชื่อมต่อแล้วแต่ไม่มีอะไรตอบสนองคือลายเซ็นของปัญหาทอโพโลยี ไม่ใช่ของรหัสลับที่แย่
อินสแตนซ์เป็นเจ้าของพูลอุโมงค์หรือไม่
ให้ช่วงทุติยภูมิแก่ VM ภายในซับเน็ตของตัวเอง แล้วทำให้ OpenVPN แจกแอดเดรสจากช่วงนั้นพอดี บนอินสแตนซ์ที่มีแอดเดรสหลักเป็น 10.156.0.10/20 alias ขนาด /28 จะแยกพูลออกจากแอดเดรสที่อินสแตนซ์อื่นถืออยู่แล้ว:
gcloud compute instances network-interfaces update openvpn-vm \
--zone=europe-west1-b \
--aliases=eth0:10.156.1.0/28จากนั้นคำสั่ง server ต้องอธิบายบล็อกเดียวกัน แอดเดรสแรกกลายเป็นเกตเวย์ของอุโมงค์ และแอดเดรสที่เหลือถูกแจกให้ไคลเอนต์ ที่นี่ตัวเลขสองตัวอธิบายหนึ่งบล็อก คือเครือข่ายและเน็ตมาสก์ ซึ่งเป็นไวยากรณ์พูลที่ OpenVPN ยังคงคาดหวัง
server 10.156.1.0 255.255.255.240ยืนยันว่าแอดเดรสลงบนอินเทอร์เฟซจริง ไม่ใช่แค่อยู่ในคอนฟิกของ OpenVPN เฟบริกส่งต่อตามสิ่งที่ NIC รายงาน ไม่ใช่ตามที่เดมอนเชื่อ คำสั่งเดียวก็ตัดสินได้:
ip -4 addr show dev eth0แอดเดรสทุติยภูมิที่ไม่เคยไปถึง eth0 หรือพูลที่ทับซ้อนกับซับเน็ตอื่นจะปรากฏในภายหลังเป็นการหลุดเป็นช่วง ๆ ไม่ใช่ข้อผิดพลาดตอนเริ่ม เดมอนเริ่มทำงาน ไคลเอนต์เชื่อมต่อได้ และมีเพียงบางปลายทางที่ทำงานผิดปกติ เก็บช่วง alias ให้เล็กเพื่อให้จำพูลได้ง่ายในตารางเส้นทาง อย่าตัดมันออกจากซับเน็ตที่อินสแตนซ์อื่นใช้อยู่แล้ว
ให้ next hop แก่ทราฟฟิกขากลับ
การตอบกลับจากโฮสต์ใน VPC ส่งไปยังแอดเดรสไคลเอนต์ในพูลอุโมงค์ ซึ่งไม่เป็นของซับเน็ตใดที่ VPC รู้จัก หากไม่มีเส้นทางสำหรับพูลนั้น การตอบกลับจะหยุดที่ฮอปแรกที่ไม่มีการจับคู่ และคำขออาจสำเร็จที่ปลายทางไกลแล้วก็ได้
gcloud compute routes create openvpn-return \
--network=prod-vpc \
--destination-range=192.168.127.0/24 \
--next-hop-instance=openvpn-vm \
--next-hop-instance-zone=europe-west1-b \
--priority=800เส้นทางเดียวกันนี้จำเป็นสำหรับคำนำหน้าใด ๆ ที่อยู่หลังไคลเอนต์แทนที่จะอยู่ใน VPC คำนำหน้าเหล่านั้นยังต้องมีรายการ iroute ในไฟล์ ccd ของไคลเอนต์นั้น รายการนั้นคือการลงบัญชีฝั่งเซิร์ฟเวอร์: มันบอกเซิร์ฟเวอร์ว่าไคลเอนต์ใดเป็นเจ้าของคำนำหน้า และไม่ได้ติดตั้งสิ่งใดบนไคลเอนต์เอง
เก็บรายการ push ไว้สำหรับฝั่งไคลเอนต์ของการสนทนา เพราะมันเพียงเพิ่มเส้นทางให้เครื่องที่เชื่อมต่อ บรรทัด push สำหรับซับเน็ตใน VPC และเส้นทาง VPC กลับไปยังพูลเป็นสองครึ่งของเส้นทางเดียวกัน และครึ่งเดียวจะให้อุโมงค์ที่พาคำขอไปแต่ไม่พาคำตอบกลับ
ไฟร์วอลล์ การส่งต่อ และฮอปที่อยู่ระหว่างนั้น
ไฟร์วอลล์ของ VPC ตรวจแพ็กเก็ตที่ถอดการห่อหุ้มแล้ว ดังนั้นกฎขาเข้าต้องอนุญาตพูลอุโมงค์และคำนำหน้าของไซต์ใด ๆ ที่มาถึง VM ทางนั้น ท่าทีปฏิเสธโดยค่าเริ่มต้นจะล้มเหลวอย่างเงียบ ๆ ที่นี่: แพ็กเก็ตถูกทิ้งหลังถอดการห่อหุ้ม และล็อกของ OpenVPN แสดงเซสชันที่แข็งแรง
บนโฮสต์ Linux ใด ๆ ที่ส่งต่อแทนที่จะเป็นปลายทาง ให้ตรวจว่า net.ipv4.ip_forward เปิดอยู่ กฎความเป็นเจ้าของใช้ที่นั่นเช่นกัน: เครื่องที่ส่งต่อให้ซับเน็ตที่ตัวเองไม่ได้ถือจะทิ้งแพ็กเก็ตเหมือนที่ VM ทำ อ่านค่าก่อนจะโทษอุโมงค์
เมื่อคำนำหน้าล้มเหลวเพียงหนึ่งเดียว
ความล้มเหลวบางส่วนเป็นกรณีที่อ่านง่ายที่สุด เพราะส่วนอื่น ๆ ในเส้นทางได้รับการพิสูจน์แล้ว เริ่มจากรายการเส้นทาง อ่านช่วงปลายทางและ next hop ของรายการที่ควรครอบคลุมคำนำหน้านั้น แล้วอ่านคำอธิบายอินสแตนซ์และเทียบช่วง alias กับพูลที่เซิร์ฟเวอร์แจก
gcloud compute routes list --filter=destination-range~10.164.0.0
gcloud compute instances describe openvpn-vm --format=get(networkInterfaces[0].aliasIpRanges)เส้นทางที่ขาดหายแสดงตัวว่าไม่มี next hop สำหรับคำนำหน้า ขณะที่ alias ที่ขาดหายแสดงตัวว่าแพ็กเก็ตถูกทิ้งที่อินเทอร์เฟซ; สองอย่างนี้ดูคล้ายกันจากฝั่งไคลเอนต์และต่างกันโดยสิ้นเชิงในผลลัพธ์สองรายการนั้น หากมีทั้งสองอย่าง ผู้ต้องสงสัยที่เหลือคือ iroute ใน ccd ของไคลเอนต์ที่อ้างคำนำหน้านั้น
จดค่าทั้งสี่ไว้ข้างอุโมงค์: ช่วง alias, พูลของเซิร์ฟเวอร์, คำนำหน้าที่ push, เส้นทางใน VPC alias ที่เก่าทำให้ทุกแอดเดรสในพูลพัง เส้นทางที่เก่าทำให้ทิศทางหนึ่งพัง push ที่ขาดทำให้ไคลเอนต์มองไม่เห็นคำนำหน้า และ iroute ที่ผิดส่งคำนำหน้าไปยังพีร์ที่ผิด คนถัดไปที่เพิ่มซับเน็ตต้องมีทั้งสี่อย่างในที่เดียว และบันทึกนั้นถูกกว่าหนึ่งคืน