การเชื่อมต่อ VPN ของ Windows ไม่ได้เก็บเซิร์ฟเวอร์ DNS ไว้ในโปรไฟล์ที่คุณแก้ไขในหน้าตั้งค่า เมื่ออุโมงค์ขึ้น ไคลเอนต์จะเจรจาการกำหนดค่า IP กับเกตเวย์ เกตเวย์ส่งรายการตัวแปลงชื่อลงมา และ Windows นำไปใช้กับอะแดปเตอร์ของอุโมงค์ อะแดปเตอร์นั้นเป็นอินเทอร์เฟซแยกจาก Wi-Fi หรือ Ethernet ของคุณ และรายการนั้นเป็นของอินเทอร์เฟซ ไม่ใช่ของโปรไฟล์ เมื่อรู้ว่าออบเจ็กต์ใดถือค่าไว้ การเขียนทับใน PowerShell ก็เป็นคำสั่งเดียว ส่วนการทำให้การเขียนทับอยู่รอดข้ามการเชื่อมต่อใหม่คือส่วนที่ต้องตัดสินใจ

ออบเจ็กต์ใดถือที่อยู่

RAS สร้างอะแดปเตอร์ของอุโมงค์เมื่อการเชื่อมต่อสำเร็จ และลบออกเมื่อการเชื่อมต่อหลุด เซิร์ฟเวอร์ DNS ที่คุณเห็นใน ipconfig /all มาถึงระหว่างการแลกเปลี่ยนการกำหนดค่านั้น อยู่ข้างที่อยู่ IPv4 และ IPv6 กับเส้นทาง เพราะค่าถูกผูกกับอินเทอร์เฟซ Set-DnsClientServerAddress จึงเขียนลงในสิ่งที่อยู่เพียงตราบเท่าที่การเชื่อมต่ออยู่

ข้อเท็จจริงข้อเดียวนี้อธิบายความสับสนส่วนใหญ่รอบ DNS ของ VPN ได้ โปรไฟล์สามารถตรวจดูได้ขณะไม่ได้เชื่อมต่อ แต่ไม่มีอินเทอร์เฟซให้ชี้ไป ดังนั้นสคริปต์ล็อกออนที่เรียก cmdlet กับนามแฝงของ VPN จะล้มเหลวก่อนที่ใครจะเชื่อมต่อ มันยังอธิบายการเปลี่ยนแปลงที่ดูเหมือนย้อนกลับด้วย: ไม่มีอะไรย้อนกลับ อินเทอร์เฟซถูกทำลายและสร้างใหม่ด้วยค่าที่เกตเวย์ส่งลงมา

หานามแฝงก่อนแตะ DNS

ชื่อโปรไฟล์และนามแฝงของอินเทอร์เฟซมักเป็นสตริงเดียวกัน แต่ไม่ใช่ออบเจ็กต์เดียวกัน Get-VpnConnection แสดงรายการโปรไฟล์ ส่วน Get-NetAdapter แสดงรายการอินเทอร์เฟซที่ Windows มีจริง cmdlet ของ DNS ต้องการตัวหลัง และสองสิ่งนี้แยกจากกันบ่อยกว่าที่คนคาด โดยเฉพาะเมื่อไคลเอนต์ต่อท้ายชื่ออะแดปเตอร์ด้วยคำอธิบายอย่าง "(RAS)"

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

Add-VpnConnection -Name "Corporate" -ServerAddress vpn.example.net `
  -TunnelType Ikev2 -EncryptionLevel Required `
  -AuthenticationMethod Eap -AllUserConnection

เชื่อมต่อหนึ่งครั้ง แล้วอ่านนามแฝงจริงก่อนเขียนคำสั่ง DNS ใด ๆ:

rasdial.exe "Corporate"
Get-NetAdapter | Where-Object InterfaceDescription -like "*VPN*"
Get-DnsClientServerAddress -InterfaceAlias "Corporate"

ใช้การเขียนทับตามลำดับที่ถูกต้อง

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

ตัว cmdlet เองเป็นบรรทัดเดียว มีเอกสารอยู่ใน เอกสารอ้างอิง Set-DnsClientServerAddress ของ Microsoft:

Set-DnsClientServerAddress -InterfaceAlias "Corporate" -ServerAddresses 10.20.0.53,10.20.0.54
Get-DnsClientServerAddress -InterfaceAlias "Corporate" -AddressFamily IPv4

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

ทำไมการเชื่อมต่อใหม่จึงยกเลิกการเปลี่ยนแปลงได้

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

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

ชื่อภายในที่มีป้ายเดียวก็ต้องมีรายการค้นหาซัฟฟิกซ์ด้วย Set-DnsClientGlobalSetting -SuffixSearchList มีผลทั้งเครื่อง จึงเปลี่ยนการแปลงชื่อสำหรับทุกอะแดปเตอร์ในเครื่อง รวมถึง Ethernet ทดสอบบนเครื่องห้องปฏิบัติการก่อนจะใส่ลงในอิมเมจ

ตรวจสอบการแปลงชื่อ ไม่ใช่แค่การตั้งค่า

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

Resolve-DnsName server01.corp.example -Server 10.20.0.53
Resolve-DnsName server01.corp.example

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

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

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