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

ไม่ใช่อุโมงค์ที่พัง

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

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

รูปร่างของเส้นทาง: บอก LAN ว่าสระอยู่ที่ไหน

เส้นทางแบบคงที่บนเกตเวย์ LAN คือคำตอบที่สะอาดที่สุดเมื่อ LAN กับสระของอุโมงค์ไม่ทับกัน ชี้สระไปที่เครื่องที่สิ้นสุดอุโมงค์:

ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12   # Windows, persistent

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

push "route 192.168.1.0 255.255.255.0"

สำหรับซับเน็ตที่อยู่หลังไคลเอนต์หนึ่งตัวแทนที่จะอยู่หลังเซิร์ฟเวอร์ เซิร์ฟเวอร์ต้องมีทั้งเส้นทางระบบและรายการ iroute ในไฟล์ของไคลเอนต์นั้นภายใต้ client-config-dir หากไม่มี iroute OpenVPN รู้ว่าคำนำหน้ามีอยู่และไม่รู้ว่าไคลเอนต์ไหนเป็นเจ้าของ แพ็กเก็ตมาถึงและเดมอนไม่มีอะไรมาจับคู่

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

รูปร่างของ NAT: DNAT เข้ามา และบรรทัด SNAT ที่ทุกคนข้าม

เมื่อคุณแตะเกตเวย์ LAN ไม่ได้ หรือต้องการเผยแพร่พอร์ตเดียวเท่านั้น การแปลที่โฮสต์ VPN ทำงานได้โดยไม่มีเส้นทางใดบน LAN เผยแพร่พอร์ต ส่งต่อมัน และแปลต้นทางระหว่างทางเข้าอุโมงค์:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1

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

เฟิร์มแวร์สำหรับผู้บริโภคใช้ชื่อเชนของตัวเองและไม่ได้สร้างการแปลนั้นให้คุณ บน Tomato กฎขาเข้าจะตกลงใน WANPREROUTING แล้วจึงเข้าเชนตัวกรองอย่าง wanin และชุดกฎที่ดูสมบูรณ์ก็ยังต้องมีบรรทัด POSTROUTING ที่เขียนด้วยมือ นั่นไม่ใช่บั๊กของเฟิร์มแวร์ แต่เป็นชุดกฎที่เขียนขึ้นสำหรับทราฟฟิกขาเข้าเท่านั้น

ทำไมกฎที่ดูถูกต้องจึงยังทิ้งแพ็กเก็ต

ความล้มเหลวส่วนใหญ่ไม่ได้อยู่ในกฎที่คุณจ้องอยู่ ตรวจสอบสี่อย่างตามลำดับนี้ และหยุดที่ข้อแรกที่ไม่เป็นจริง:

  • ลำดับเชน iptables -I แทรกไว้บนสุดและ -A ต่อท้ายไว้ล่างสุด กฎที่อนุญาตหรือบล็อกก่อนหน้าจึงตัดสินก่อน
  • ผิดเชน ทราฟฟิกที่ส่งถึงเราเตอร์เองจะผ่าน INPUT และทราฟฟิกที่ถูกส่งต่อไม่เคยแตะมัน การเผยแพร่บริการเดียวอาจต้องมีกฎในทั้งสอง
  • แฟล็กทิศทาง -i tun0 ตรงกับทราฟฟิกที่มาจากไคลเอนต์ และ -o tun0 ตรงกับทราฟฟิกที่ออกไปหาไคลเอนต์ REJECT ที่ใส่แฟล็กผิดจะบล็อกสิ่งที่คุณไม่ได้ตั้งใจ
  • การจำกัดต้นทาง การส่งต่อที่ยอมรับที่อยู่ไคลเอนต์เดียวจะทำงานจากไคลเอนต์นั้นและทิ้งทุกต้นทางอื่นโดยไม่พูดอะไร

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

การส่งต่อแบบโลคัล เมื่อไม่มีอะไรบน LAN เปลี่ยนได้

การส่งต่อแบบโลคัลของ SSH เลี่ยงคำถามทั้งหมด ไม่ต้องมีเส้นทางบน LAN ไม่ต้องอาศัยความร่วมมือจากไฟร์วอลล์ของไคลเอนต์ และไม่ต้องเผยแพร่พอร์ตที่ไหนเลย:

ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host

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

ตรวจทั้งสองทิศทางก่อนเพิ่มกฎอีกข้อ

การแปลทิ้งร่องรอยไว้ และการอ่านร่องรอยดีกว่าเดา บนโฮสต์ VPN conntrack -L แสดงว่าการแปลเกิดขึ้นหรือไม่ iptables -t nat -L -n -v แสดงว่าตัวนับขยับหรือไม่ และ tcpdump -ni any port 3000 แสดงว่าที่อยู่ต้นทางใดมาถึงจริง บนไคลเอนต์ ss -ltn ยืนยันว่าตัวรับฟังอยู่บนที่อยู่ที่อุโมงค์เข้าถึงได้

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

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