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

เริ่มที่ไคลเอนต์แล้วไล่ออกไปข้างนอก

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

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

การดักแพ็กเก็ตสองจุดแสดงว่าแพ็กเก็ตหยุดตรงไหน

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

sudo tcpdump -ni tun0 -c 20 icmp
sudo tcpdump -ni enp1s0 -c 20 icmp

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

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

ip -4 route get 9.9.9.9

ฟิลด์ dev ในผลลัพธ์นั้นคือชื่อที่กฎ NAT จะต้องใช้ในภายหลัง จึงเก็บไว้

การส่งต่อคือสวิตช์ในเคอร์เนลและนโยบายไฟร์วอลล์

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

sysctl net.ipv4.ip_forward
printf 'net.ipv4.ip_forward=1\n' > /etc/sysctl.d/70-vpn-forward.conf
sysctl --system

การส่งต่อเป็นเพียงครึ่งเดียว บนโฮสต์ที่ใช้ UFW นโยบายการส่งต่อถูกกำหนดใน /etc/default/ufw และต้องเป็น ACCEPT ก่อนที่การโหลดซ้ำจะมีผล การทิ้งแบบค่าเริ่มต้นบนเส้นทางการส่งต่อทำให้การจับมือยังสมบูรณ์ดี แต่ทิ้งทุกแพ็กเก็ตที่พยายามออกผ่านทันเนลอย่างเงียบ ๆ และนั่นคืออาการที่คุณเริ่มต้นมาพอดี

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

ระบุอินเทอร์เฟซขาออกจริงในกฎ NAT

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

iptables -t nat -A POSTROUTING -s 10.44.0.0/24 -o enp1s0 -j MASQUERADE

ความล้มเหลวคลาสสิกคือกฎที่คัดลอกจากคู่มือซึ่งบอก -o eth0 บนเครื่องที่อะแดปเตอร์ชื่ออื่น กฎติดตั้งได้โดยไม่มีการเตือน ไม่ตรงกับอะไรเลย และไคลเอนต์ก็ยังไม่มีอินเทอร์เน็ต พูลคืออีกครึ่งของความผิดพลาดเดียวกัน: ถ้าเซิร์ฟเวอร์แจก 10.44.0.0/24 แต่กฎครอบ 10.8.0.0/24 ก็จะไม่มีอะไรตรงกันเลย

ดูตัวนับแทนที่จะเชื่อข้อความของกฎ รายการแสดงแพ็กเก็ตต่อกฎ และกฎที่ไม่เคยตรงจะคงอยู่ที่ศูนย์ไม่ว่าจะดูถูกต้องแค่ไหน ให้เวลามันหนึ่งนาทีกับทราฟฟิกไคลเอนต์จริงก่อนจะอ่านอะไรจากตัวเลขนั้น:

iptables -t nat -L POSTROUTING -v -n

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

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

DNS คือความล้มเหลวที่สองถัดจากอันแรก

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

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

push "dhcp-option DNS 9.9.9.9"
push "dhcp-option DNS 149.112.112.112"

ไคลเอนต์ Windows อาจยังกลับไปใช้ตัวแปลงชื่อภายในอยู่ดี ซึ่งเป็นสิ่งที่ block-outside-dns มีไว้ป้องกัน โดยแลกกับการเสียชื่อที่เครือข่ายภายในเท่านั้นที่แปลงได้ ไคลเอนต์ Linux ที่ใช้ systemd-resolved มักไม่สนใจตัวแปลงชื่อที่ถูกดันมา เว้นแต่สคริปต์จะติดตั้งให้ ดังนั้นให้ตรวจ resolvectl status ของอุปกรณ์ทันเนลก่อนสรุปว่าการถูกมองข้าม

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

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