ชื่อไคลเอนต์ OpenVPN ใน dnsmasq: สคริปต์หรือรายการแบบคงที่?
ที่อยู่ของไคลเอนต์เปลี่ยน แต่ชื่อบริการไม่เปลี่ยน สร้างชื่อไคลเอนต์จากเซสชัน VPN ตรึงชื่อบริการไว้ในไฟล์ drop-in แล้วทำให้ไคลเอนต์ใช้งานมัน
ปัญหาชื่อสองอย่างเกิดขึ้นบนเกตเวย์ OpenVPN ขนาดเล็กแทบทุกตัว คุณเข้าถึงแล็ปท็อปที่เชื่อมต่อด้วยชื่อบนใบรับรองไม่ได้ และบริการที่อยู่หลังอุโมงค์ก็ไม่มีชื่อเลย พวกมันดูเหมือนปัญหาเดียวแต่ต้องแก้ตรงกันข้าม เพราะที่อยู่หนึ่งเปลี่ยนทุกเซสชันและอีกอันไม่เปลี่ยน ตัดสินใจก่อนแก้ไขอะไรว่าคุณกำลังเพิ่มชื่อประเภทใด
ตัดสินใจเป็นรายชื่อ ไม่ใช่รายเกตเวย์
การทดสอบง่ายมาก: ที่อยู่นี้เปลี่ยนหรือไม่เมื่อไคลเอนต์เชื่อมต่อใหม่ ถ้าใช่ ชื่อต้องถูกสร้างจากเซสชัน VPN ถ้าไม่ใช่ มันอยู่ในรายการแบบคงที่ที่คุณอ่านและตรวจสอบได้
| Name kind | Source of truth | Where it lives |
|---|---|---|
| Connected client | The address OpenVPN just assigned | Generated hosts file, rewritten per session |
| Service behind the tunnel | A fixed address you chose | Static address= drop-in |
| Anything with a certificate name | The certificate, not the pool | Either, but the name must match the certificate |
การผสมสองอย่างนี้คือความล้มเหลวที่พบบ่อย บริการที่ตรึงไว้ในไฟล์ที่สร้างขึ้นจะหายไปเมื่อสคริปต์เขียนไฟล์นั้นใหม่ครั้งแรก และไคลเอนต์ที่เขียนไว้ในรายการแบบคงที่จะชี้ไปยังคนที่ถือที่อยู่ล่าสุด ความผิดพลาดทั้งสองมองไม่เห็นจนกว่าชื่อจะแปลงไปยังเครื่องที่ผิด ตอนนั้นคนที่แก้ปัญหาจะคิดว่า DNS เสีย ไม่ใช่ไฟล์
เส้นทางไดนามิก: learn-address และพูล
OpenVPN รู้การกำหนดที่อยู่ จึงปล่อยให้มันบอกคุณ ตัวเลือกเซิร์ฟเวอร์เหล่านี้ทำให้การกำหนดอยู่คงทนและเขียนสคริปต์ได้:
client-config-dir /etc/openvpn/ccd
ifconfig-pool-persist /etc/openvpn/ip-pool 60
script-security 2
learn-address /etc/openvpn/learn-address.sh
learn-address รันสคริปต์ของคุณทุกครั้งที่มีการเพิ่ม อัปเดต หรือลบที่อยู่ และส่งการดำเนินการ ที่อยู่ และชื่อสามัญไปด้วย สคริปต์ขั้นต่ำจะเพิ่มหนึ่งบรรทัดต่อไคลเอนต์และลบบรรทัดนั้นเมื่อลบ:
#!/bin/sh
HOSTS=/etc/openvpn/hosts.lan
case "$1" in
add|update) echo "$2 $3" >> "$HOSTS" ;;
delete) sed -i "/^$2 /d" "$HOSTS" ;;
esac
kill -HUP $(cat /var/run/dnsmasq.pid)
บนอุปกรณ์ tun อาร์กิวเมนต์ที่สองคือที่อยู่ tunnel ของไคลเอนต์ บรรทัดนั้นจึงใช้ได้โดยตรง บนอุปกรณ์ tap OpenVPN จะส่งที่อยู่ MAC ของไคลเอนต์แทน เพราะเซกเมนต์ tap สามารถบรรทุกโปรโตคอลอื่นที่ไม่ใช่ IPv4 ได้ และตอนนั้นคุณต้องค้นที่อยู่ในไฟล์พูลด้วยชื่อสามัญก่อนเขียนอะไรลงไป
ทำให้ชัดเจนว่าไฟล์ที่สร้างขึ้นคืออะไร: ภาพรวมว่าใครเชื่อมต่ออยู่ตอนนี้ ชื่อจะหายไปเมื่อตัดการเชื่อมต่อ ซึ่งเป็นสิ่งที่คุณต้องการสำหรับแล็ปท็อปที่ย้ายระหว่างเครือข่าย และเป็นสิ่งที่คุณไม่ต้องการสำหรับเซิร์ฟเวอร์ที่เปิดทั้งคืน
เส้นทางคงที่: address= และการขยายโดเมน
ชี้ dnsmasq ไปที่ไฟล์ที่สร้างขึ้นแทนไฟล์ hosts ของระบบ และให้โดเมนเพื่อให้ชื่อสั้นขยายเป็นชื่อที่ระบุเต็ม:
domain=corp.example
no-hosts
addn-hosts=/etc/openvpn/hosts.lan
listen-address=127.0.0.1,10.8.0.1
bind-interfaces
เมื่อตั้ง domain แล้ว บรรทัดอย่าง 10.8.0.6 alice จะตอบทั้ง alice และ alice.corp.example จำกัด listen-address ไว้ที่เกตเวย์อุโมงค์และ loopback เพราะตัวแปลงชื่อที่เผลอประกาศบนอินเทอร์เฟซ LAN คือบริการที่คุณไม่ได้ตั้งใจให้
บริการที่ไม่เคยมาจากพูลจะมีรายการของตัวเอง ใส่ไว้ในไฟล์ drop-in แยกในไดเรกทอรีการกำหนดค่าของดิสทริบิวชัน เพื่อให้การอัปเกรดแพ็กเกจเขียนทับไม่ได้:
address=/files.corp.example/10.8.0.20
address=/db.corp.example/10.9.0.5
ส่งมอบตัวแปลงชื่อ หรือจะไม่มีอะไรเกิดขึ้น
ตัวแปลงชื่อที่ไม่มีใครถามไม่เปลี่ยนอะไร เซิร์ฟเวอร์ต้องประกาศมัน:
push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"
ไคลเอนต์ Windows ใช้ทั้งสองตัวเลือกเอง ไคลเอนต์ Linux ส่วนใหญ่ไม่ใช้: พวกมันต้องมี การผสานตัวแปลงชื่อที่รองรับ เช่นฮุก update-resolv-conf ของดิสทริบิวชัน หรือการจัดการ DNS ของ NetworkManager หรือโดเมนค้นหาและเนมเซิร์ฟเวอร์ที่ตั้งด้วยมือ ตรวจสอบตัวแปลงชื่อจริงของไคลเอนต์แทนการสันนิษฐานว่า push ถูกปฏิบัติตาม เพราะ push ที่ถูกละเลยดูเหมือนเซิร์ฟเวอร์ที่ไม่ตอบ
ตรวจสอบสามชั้น
ถามเซิร์ฟเวอร์โดยตรงก่อน แล้วจึงถามไคลเอนต์ แล้วจึงถามแอปพลิเคชัน:
dig +short @10.8.0.1 alice.corp.example
getent hosts files.corp.example
ถ้าคำถามโดยตรงตอบแต่แอปพลิเคชันไม่ตอบ ความผิดอยู่ที่การส่งต่อให้ไคลเอนต์ไม่ใช่ที่โซน ถ้าชื่อแปลงได้แต่การเชื่อมต่อยังล้มเหลว ชื่อก็ถูกต้อง และสิ่งถัดไปที่ต้องดูคือเส้นทางหรือไฟร์วอลล์
เขียนสองหมวดหมู่ไว้ข้างการกำหนดค่า: ชื่อใดถูกสร้าง ชื่อใดถูกตรึง และแต่ละชื่อต้องตรงกับใบรับรองใด คนถัดไปที่เพิ่มเซิร์ฟเวอร์จะคัดลอกรูปแบบแรกที่พบ