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

สามเงื่อนไขที่กำหนดการออกแบบ

อย่างแรก คุณต้องได้คำนำหน้าและมาสก์ที่แม่นยำจากเจ้าของเครือข่าย เครือข่าย 10.x ไม่ใช่คำนำหน้า แต่ 10.20.0.0/16 คือคำนำหน้า ตรวจสอบว่าไม่ทับซ้อนกับ LAN ที่บ้าน สะพาน Docker หรือ VPN อื่นที่คุณรัน เพราะการทับซ้อนทำให้เส้นทางกำกวมและเคอร์เนลเลือกรายการที่คุณไม่ได้ตั้งใจ

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

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

WireGuard: AllowedIPs คือตารางเส้นทาง

บนไคลเอนต์ AllowedIPs ระบุปลายทางที่อนุญาตให้เข้าทันเนล และ wg-quick เปลี่ยนแต่ละรายการให้เป็นเส้นทางธรรมดา ดังนั้นครึ่งฝั่งไคลเอนต์ของงานนี้คือบรรทัดเดียว

[Peer]
PublicKey = ...
Endpoint = vpn.example.net:51820
AllowedIPs = 10.20.0.0/16

ตอนนี้เทียบกับรายการของเซิร์ฟเวอร์สำหรับไคลเอนต์เดียวกัน รายการนั้นอธิบายสิ่งที่เซิร์ฟเวอร์จะส่งให้ไคลเอนต์ ซึ่งปกติคือที่อยู่ทันเนลของไคลเอนต์ ไม่ใช่ซับเน็ตส่วนตัว

[Peer]
PublicKey = ...
AllowedIPs = 10.99.0.2/32

การสลับสองอย่างนี้คือข้อผิดพลาดที่ผมเห็นบ่อยที่สุด การวาง 10.20.0.0/16 ใต้ส่วน peer ของเซิร์ฟเวอร์หมายความว่าซับเน็ตทั้งหมดอยู่หลังไคลเอนต์ตัวนั้น ซึ่งเป็นการอ้างแบบไซต์ถึงไซต์ ไม่ใช่การอนุญาต แพ็กเก็ตที่ไม่ตรงกับ AllowedIPs ของ peer ใดเลยจะถูกทิ้งอย่างเงียบ ๆ รายการที่ผิดจึงดูเหมือนปัญหาไฟร์วอลล์ทุกประการ

ถ้าคุณจัดการเส้นทางเอง ให้ตั้ง Table = off ใต้ [Interface] แล้วเพิ่มเส้นทางที่ต้องการ ตอนนั้นจะไม่มีอะไรถูกเพิ่มอัตโนมัติ เส้นทางจึงต้องอยู่ในสิ่งที่ยกอินเทอร์เฟซขึ้นมา

OpenVPN: ผลักเส้นทางแล้วตรวจสอบว่ามันไปถึง

บนเซิร์ฟเวอร์ปกติ การเปลี่ยนแปลงคือคำสั่งเดียวในการตั้งค่าเซิร์ฟเวอร์ ข้างพูลไคลเอนต์

push "route 10.20.0.0 255.255.0.0"

ไคลเอนต์จะเพิ่มเมื่อเชื่อมต่อ โหมดล้มเหลวจะปรากฏเมื่อโปรไฟล์เดียวกันผลัก redirect-gateway ด้วย หรือเมื่อมีคนเพิ่ม route-nopull ไปแล้ว อย่างแรกเปลี่ยนเซสชันเป็นทันเนลเต็ม อย่างที่สองทิ้งทุกเส้นทางที่ถูกผลักรวมถึงของคุณ

ไคลเอนต์ที่ต้องการพฤติกรรมแคบ ๆ ต่อเซิร์ฟเวอร์ทันเนลเต็มควรเพิกเฉยเฉพาะส่วนที่ไม่ต้องการ ใน OpenVPN 2.4 และใหม่กว่า มี pull-filter อยู่เพื่อการนี้โดยเฉพาะ

pull-filter ignore "redirect-gateway"
route 10.20.0.0 255.255.0.0

แยกตระกูลที่อยู่ออกจากกัน เส้นทาง IPv4 ที่ถูกผลักไม่ช่วยอะไรกับบริการภายในที่แก้ชื่อเป็น IPv6 และบริการนั้นล้มเหลวผ่านทันเนลในขณะที่อย่างอื่นดูปกติ

เมื่อซับเน็ตส่วนตัวไม่ได้อยู่บนเซิร์ฟเวอร์ VPN แต่อยู่หลังไคลเอนต์อื่น ต้องแจ้งเซิร์ฟเวอร์ เพิ่มไฟล์ต่อไคลเอนต์ผ่าน client-config-dir ที่มี iroute 10.20.0.0 255.255.0.0 พร้อม route ที่ตรงกัน เพื่อให้ไคลเอนต์อื่นเรียนรู้เส้นทาง ถ้าไม่มี iroute เซิร์ฟเวอร์ก็ไม่มีเหตุผลจะส่งคำนำหน้านั้นผ่านทันเนลนั้นโดยเฉพาะ

IPsec: ตัวเลือกทราฟฟิกต้องตรงกัน

กับ IPsec ไม่มีเส้นทางให้ผลัก สองปลายเจรจาว่าที่อยู่ใดอยู่ภายในทันเนล และทราฟฟิกนอกตัวเลือกที่ตกลงกันจะไม่ถูกเข้ารหัสและไม่ถูกส่งผ่าน บนไคลเอนต์ strongSwan ตัวเลือกถูกระบุอย่างชัดเจน

leftsubnet=192.168.1.0/24
rightsubnet=10.20.0.0/16

ถ้าเกตเวย์ตั้งค่าด้วย 0.0.0.0/0 ทั้งสองฝั่ง การแคบลงของ IKEv2 มักลด SA ลูกเหลือส่วนตัดของข้อเสนอทั้งสอง ซึ่งเป็นผลที่ต้องการ เกตเวย์บางตัวกลับปฏิเสธข้อเสนอที่ไม่ตรงกับตัวเลือกที่ตั้งไว้ และบันทึกจะแสดง SA ลูกที่ล้มเหลวแทนข้อร้องเรียนเรื่องเส้นทาง เมื่อเกิดเช่นนั้น การเปลี่ยนแปลงเป็นเรื่องของเกตเวย์ เพราะเส้นทางฝั่งไคลเอนต์สร้างทันเนลให้ตัวเลือกที่อีกฝั่งไม่ยอมรับไม่ได้

บน Windows ไคลเอนต์ในตัวซ่อนการตัดสินใจเดียวกันไว้หลังการตั้งค่าสองอย่าง ต้องเปิดการแยกทันเนล และต้องลงทะเบียนคำนำหน้ากับโปรไฟล์

Set-VpnConnection -Name Office -SplitTunneling $true
Add-VpnConnectionRoute -ConnectionName Office -DestinationPrefix 10.20.0.0/16

การลงทะเบียนคำนำหน้าคือสิ่งที่ทำให้มันอยู่รอดหลังเชื่อมต่อใหม่ ซึ่งเส้นทางที่เพิ่มด้วยมือทำไม่ได้

เก็บปลายทางและ DNS ไว้นอกการตัดสินใจ

ปลายทาง VPN ต้องเข้าถึงได้โดยไม่ต้องใช้ทันเนล ไม่อย่างนั้นทันเนลจะถล่มลงในตัวเอง เมื่อกำหนดเส้นทางเฉพาะ 10.20.0.0/16 เรื่องนี้เป็นอัตโนมัติ เพราะปลายทางเป็นที่อยู่สาธารณะ ในโปรไฟล์ทันเนลเต็มไม่เป็นเช่นนั้น และไคลเอนต์ต้องมี เส้นทางโฮสต์ที่ชัดเจนไปยังปลายทางก่อนทันเนลจะขึ้น.

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

ตรวจสอบ จากนั้นรีบูตและตรวจสอบอีกครั้ง

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

ip route get 10.20.5.7
curl -sS http://10.20.5.7/health
curl -sS https://ifconfig.me

บรรทัดแรกบอกชื่ออินเทอร์เฟซ ถ้าบอกอินเทอร์เฟซกายภาพของคุณ แสดงว่าเส้นทางไม่เคยเข้า บน Windows Find-NetRoute -RemoteIPAddress 10.20.5.7 ตอบคำถามเดียวกัน และการตรวจสอบสุดท้ายควรยังแสดงที่อยู่ปกติของคุณไม่ใช่ของเซิร์ฟเวอร์ VPN

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

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

บทความที่เกี่ยวข้อง