ข้ามไปยังเนื้อหา

ตรวจและแก้ DNS Leak บน Linux อย่างไร

Linux มีหลายชั้นที่ตัดสินว่าคำถาม DNS จะไปทางไหน บทความนี้สอนตรวจว่าชั้นไหนตอบอยู่ตอนเปิด VPN และวิธีแก้บน systemd-resolved, NetworkManager และ resolv.conf

อ่าน 10 นาทีอัปเดตเมื่อ 15 ต.ค. 2569โดย XPASS Editorial Team

ตรวจและแก้ DNS Leak บน Linux อย่างไร

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

บทความนี้เป็นคู่มือลงมือทำสำหรับผู้ใช้เดสก์ท็อปและเซิร์ฟเวอร์ จะพาตรวจว่าชั้นไหนเป็นผู้ตอบ พิสูจน์ด้วยการดักแพ็กเก็ต และแก้ในสามรูปแบบที่พบบ่อย คือ systemd-resolved, NetworkManager และไฟล์ /etc/resolv.conf แบบธรรมดา ถ้ายังไม่คุ้นกับแนวคิด อ่าน DNS Leak คืออะไร และ DNS ทำงานอย่างไร ก่อนได้

ทำไม Linux จึงตั้งค่าผิดได้ง่าย

บน Windows และ macOS ระบบปฏิบัติการมีบริการ resolver หลักตัวเดียว แต่บน Linux คำตอบขึ้นอยู่กับดิสโทรและวิธีตั้งค่าเครือข่าย เดสก์ท็อปทั่วไปมีชั้นซ้อนกันดังนี้

  • แอปและไลบรารี C โปรแกรมเรียกไลบรารี ซึ่งดู /etc/nsswitch.conf แล้วอ่าน /etc/resolv.conf
  • stub resolver บน Ubuntu, Fedora และอีกหลายดิสโทร ไฟล์ /etc/resolv.conf ชี้ไปที่ 127.0.0.53 ซึ่งเป็นตัวรับในเครื่องของ systemd-resolved บางระบบใช้ dnsmasq หรือแคชตัวอื่น
  • ตัวจัดการเครือข่าย NetworkManager, systemd-networkd หรือ ifupdown เป็นผู้กำหนดว่า DNS server ใดเป็นของอินเทอร์เฟซใด แล้วแจ้ง resolver
  • เบราว์เซอร์ Firefox และเบราว์เซอร์ตระกูล Chromium อาจข้าม resolver ของระบบและถาม DNS-over-HTTPS server โดยตรง
  • คอนเทนเนอร์และ VM Docker, Podman และเครื่องเสมือนมักมีค่า resolver ของตัวเอง

โปรแกรม VPN มักแตะเพียงชั้นเดียว บางครั้งไม่แตะเลย อุโมงค์ที่สร้างด้วย ip link add เปล่า ๆ หรือไฟล์ WireGuard ขั้นต่ำที่ไม่มีบรรทัด DNS = จะเปลี่ยนเส้นทางแต่ปล่อย resolver ไว้เหมือนเดิม นี่คือการรั่วแบบคลาสสิก ทราฟฟิกเว็บเข้าอุโมงค์ แต่คำถาม DNS ยังไปที่เราเตอร์

ขั้นที่ 1 หาว่าใครเป็นคนตอบ DNS

ก่อนแก้อะไร ให้ตรวจสถานะเริ่มต้นขณะเชื่อมต่อ VPN อยู่

  1. รัน resolvectl status โปรแกรมจะแสดง DNS server, search domain และบรรทัด Default Route ของแต่ละอินเทอร์เฟซ (เรียกว่า link) ถ้า link จริงอย่าง wlp3s0 ขึ้น Default Route: yes แต่ link ของ VPN ขึ้น no แปลว่าคำถามทั่วไปออกทาง link จริง
  2. รัน resolvectl query example.com บรรทัดท้ายจะบอกว่า link ใดตอบ เช่น link: wlp3s0 หรือ link: wg0 เราต้องการเห็น link ของ VPN
  3. รัน cat /etc/resolv.conf ถ้ามี nameserver 127.0.0.53 แปลว่า systemd-resolved ดูแลอยู่ ถ้าเป็นที่อยู่ส่วนตัวเช่น 192.168.1.1 ระบบคุยกับเราเตอร์ตรง ๆ
  4. รัน ip route get 1.1.1.1 ผลลัพธ์บอกชื่ออินเทอร์เฟซที่เคอร์เนลจะใช้ ถ้าเป็นอินเทอร์เฟซจริง แปลว่าทราฟฟิกทั่วไปก็ยังไม่เข้าอุโมงค์ ปัญหาคือ routing ก่อนจะเป็นปัญหา DNS

ถ้าไม่ได้ใช้ systemd-resolved คำสั่ง resolvectl จะแจ้งว่าบริการไม่ทำงาน ให้ข้ามไปหัวข้อ NetworkManager และ resolv.conf ด้านล่าง

ขั้นที่ 2 พิสูจน์บนสายจริง

ค่าที่ตั้งไว้บอกว่า "ควรเกิดอะไร" การดักแพ็กเก็ตบอกว่า "เกิดอะไรจริง" เปิดเทอร์มินัลสองหน้าต่าง

หน้าต่างแรกรัน

sudo tcpdump -ni any 'udp port 53 or tcp port 53'

หน้าต่างที่สองเรียกชื่อโดเมนที่ไม่ได้เข้าบ่อย

resolvectl flush-caches
getent hosts example.org
dig +short example.net

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

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

อ่านผลลัพธ์อย่างไร

สิ่งที่เห็น ความหมาย ขั้นต่อไป
คำถามขึ้นเฉพาะอินเทอร์เฟซ VPN เส้นทางนี้ไม่รั่ว ไปทดสอบ IPv6 และเบราว์เซอร์ต่อ
คำถามขึ้นบน link จริงไปที่เราเตอร์ resolver ยังตาม link เก่า ตั้ง DNS ต่อ link และทำให้ link VPN เป็น default route
คำถามไปที่ resolver สาธารณะบน link จริง DoH ของเบราว์เซอร์หรือค่า hard-code ตรวจการตั้งค่าเบราว์เซอร์และแอป
คำถามสลับขึ้นสอง link มี default-route หลาย link เอา DNS ออกจาก link จริง หรือใช้ routing domain
แก้แล้วไม่มีอะไรเลย การ resolve อาจเสีย ตรวจว่าที่อยู่ DNS ของ VPN เข้าถึงได้ผ่านอุโมงค์

เป็นวิธีที่สะอาดที่สุด เพราะ systemd-resolved ออกแบบมาเพื่อหลายอินเทอร์เฟซ แนวคิดคือให้ link ของ VPN มี DNS server ของตัวเอง และให้เป็นที่ตอบทุกโดเมน

  1. ตั้ง server ที่ link ของ VPN sudo resolvectl dns wg0 10.0.0.1 ใช้ที่อยู่ resolver ตามที่การตั้งค่า VPN ของคุณกำหนด
  2. ให้ link นี้ตอบทุกชื่อด้วย routing domain แบบครอบจักรวาล sudo resolvectl domain wg0 '~.' เครื่องหมาย ~ หมายถึงส่งคำถามของโดเมนนี้มาที่นี่ โดยไม่เพิ่มเข้า search list
  3. ปิด default route ของ link จริง ให้ตอบเฉพาะชื่อท้องถิ่นของมัน sudo resolvectl default-route wlp3s0 no
  4. ตรวจซ้ำด้วย resolvectl status และ resolvectl query example.com

ค่าเหล่านี้อยู่ได้แค่ตราบที่อินเทอร์เฟซยังอยู่ ถ้าต้องการให้ถาวรในการตั้งค่า WireGuard ให้ใส่บรรทัด DNS = 10.0.0.1 ในไฟล์ config แล้ว wg-quick จะส่งต่อให้เครื่องมือ resolver ตอนอินเทอร์เฟซขึ้น ในระบบที่ resolvconf มาจาก systemd การเรียกนั้นจะกลายเป็นคำสั่งข้างต้น ตรวจด้วย resolvectl status ทุกครั้งหลังรีสตาร์ท อย่าเดา

วิธีแก้ที่ 2 NetworkManager

เมื่อ NetworkManager เป็นผู้จัดการการเชื่อมต่อ ให้แก้ DNS ที่โปรไฟล์การเชื่อมต่อ เพื่อให้ค่าคงอยู่หลังเชื่อมต่อใหม่

  • โปรไฟล์ VPN ให้ priority ติดลบ nmcli connection modify "my-vpn" ipv4.dns-priority -50 ipv4.ignore-auto-dns yes ค่าติดลบบอก NetworkManager ให้ใช้เฉพาะ server จากโปรไฟล์นั้น
  • โปรไฟล์ Wi-Fi หรือ Ethernet ให้บอกว่าอย่าใช้ DNS ของเราเตอร์ขณะมี VPN nmcli connection modify "Home Wi-Fi" ipv4.ignore-auto-dns yes แล้วเชื่อมต่อใหม่
  • เพิ่ม ipv6.ignore-auto-dns yes ด้วย หากเครือข่ายประกาศ resolver แบบ IPv6
  • เปิดใช้ใหม่ด้วย nmcli connection down แล้ว up ที่โปรไฟล์ซึ่งแก้

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

วิธีแก้ที่ 3 resolv.conf ธรรมดาและ resolver แบบอื่น

บนเซิร์ฟเวอร์เล็กหรือดิสโทรเก่า /etc/resolv.conf อาจเป็นไฟล์ปกติ คุณเขียน resolver ของ VPN ลงไปได้ แต่สิ่งใดที่เขียนทับไฟล์ เช่น DHCP client ก็จะลบงานของคุณ มีสองแนวทางที่ปลอดภัยกว่า

  • ให้สคริปต์ของ VPN จัดการ เครื่องมืออย่าง resolvconf หรือ openresolv เก็บรายการแหล่งข้อมูลและผสานตามลำดับความสำคัญ รายการของ VPN จะแทนที่รายการของเราเตอร์ขณะอุโมงค์ขึ้น และหายไปเมื่ออุโมงค์ลง
  • ถ้าจำเป็นต้องล็อกไฟล์ ให้ตัดสินใจอย่างตั้งใจและจดบันทึกไว้ การใช้ chattr +i ตรึงไฟล์จะตรึงการเปลี่ยนแปลงที่ถูกต้องในอนาคตทั้งหมดด้วย และมักทำให้เครือข่ายพังเมื่อบูตหรือย้ายที่ครั้งหน้า ไม่ควรทำบนโน้ตบุ๊ก

ถ้าคุณรัน resolver แคชในเครื่อง เช่น dnsmasq หรือ unbound ให้เปลี่ยน upstream ของมันแทนการแก้ไฟล์ และรีสตาร์ทเมื่ออุโมงค์ขึ้นหรือลง

IPv6 และ DNS-over-HTTPS ของเบราว์เซอร์

มีการรั่วสองแบบที่หลบสายตาแม้ผู้ใช้ระวังแล้ว แบบแรกคือ IPv6 ถ้าเราเตอร์ประกาศ DNS server แบบ IPv6 และ VPN ครอบคลุมเฉพาะ IPv4 คำถามอาจออกทางเส้น IPv6 ให้ดู resolvectl status ว่ามีที่อยู่ IPv6 ใต้ link จริงไหม แล้วเลือกส่ง IPv6 เข้าอุโมงค์ด้วย หรือปิด IPv6 ของการเชื่อมต่อด้วย ipv6.method disabled ใน NetworkManager ระหว่างทดสอบ บทความ IPv6 Leak อธิบายลึกกว่า

แบบที่สองคือเบราว์เซอร์ Firefox ใช้ DNS-over-HTTPS กับรายชื่อผู้ให้บริการของตัวเองได้ และเบราว์เซอร์ตระกูล Chromium อาจตามค่าระบบหรือค่าของมันเอง คำถามเหล่านี้อยู่ในการเชื่อมต่อ HTTPS ที่พอร์ต 443 จึงไม่ปรากฏในการดักพอร์ต 53 และไม่สนใจ resolver ที่คุณเพิ่งแก้ ให้ตัดสินใจอย่างตั้งใจ จะให้เบราว์เซอร์ใช้ resolver ของระบบ หรือเลือก DoH server เองอย่างรู้ตัว DNS over HTTPS เทียบกับ VPN อธิบายความสัมพันธ์ของสองสิ่งนี้

ใช้กฎไฟร์วอลล์ปิดคำถามที่หลุด

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

table inet dnsguard {
  chain output {
    type filter hook output priority 0; policy accept;
    oifname != "wg0" oifname != "lo" udp dport 53 drop
    oifname != "wg0" oifname != "lo" tcp dport 53 drop
  }
}

โหลดด้วย sudo nft -f dnsguard.nft และลบด้วย sudo nft delete table inet dnsguard มีคำเตือนสองข้อ ข้อแรก ขณะที่กฎทำงานและอุโมงค์ล่ม DNS จะใช้ไม่ได้เลย ซึ่งเป็นเจตนาแต่มักทำให้คนตกใจ ควรผูกการโหลดและลบกับการขึ้นลงของอินเทอร์เฟซ เช่นผ่าน PostUp และ PostDown ข้อสอง โปรแกรม VPN ต้อง resolve ชื่อเซิร์ฟเวอร์ได้ ให้ใช้ที่อยู่ IP จริงเป็น endpoint หรือโหลดกฎหลังเชื่อมต่อครั้งแรกเท่านั้น ดูแนวคิดโดยรวมได้ที่ Kill Switch ของ VPN คืออะไร

ข้อผิดพลาดที่พบบ่อย

  • ทดสอบด้วยเว็บตรวจการรั่วอย่างเดียว ไม่เคยดูการดักแพ็กเก็ต
  • แก้ /etc/resolv.conf แล้วสงสัยว่าทำไมค่ากลับไปเหมือนเดิมหลังเครื่องตื่นจากหลับ
  • ใส่ DNS = ในไฟล์ VPN แต่ระบบไม่มี resolvconf หรือการเชื่อมต่อกับ resolver บรรทัดนั้นจึงถูกเมินเงียบ ๆ
  • ลืมคอนเทนเนอร์ ซึ่งมี resolver ของตัวเองและอาจไม่ตามค่าของเครื่องหลัก
  • แก้ IPv4 แล้วปล่อยให้เราเตอร์ประกาศ IPv6 อยู่
  • เข้าใจว่าแก้แล้วเพียงเพราะ IP สาธารณะเปลี่ยน ที่อยู่กับ resolver เป็นสองคำถามที่แยกกัน

สรุป

DNS Leak บน Linux แทบไม่เคยเป็นความผิดของอุโมงค์ แต่เป็นเพราะชั้น resolver ตัวจัดการเครือข่าย เบราว์เซอร์ หรือ IPv6 ยังยึดเส้นทางเดิมอยู่ ใช้ resolvectl หาชั้นที่ตอบ พิสูจน์ด้วย tcpdump แก้ด้วย DNS ต่อ link หรือค่า priority ของการเชื่อมต่อ และเพิ่มกฎไฟร์วอลล์ให้ความผิดพลาดล้มแบบปิด แล้วทดสอบซ้ำทุกครั้งหลังรีบูตและเปลี่ยนเครือข่าย

หากคุณเชื่อมต่อผ่านแอป VPNclient ฟรี คู่มือติดตั้งบน Linux อธิบายขั้นตอนติดตั้ง และเมื่อพร้อมก็ดูตัวเลือกได้ที่ หน้าราคา

คำถามที่พบบ่อย

ทำไม VPN บน Linux ถึงเกิด DNS Leak ได้ทั้งที่อุโมงค์ทำงานปกติ

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

คำสั่งไหนบอกได้ว่าคำถาม DNS ของฉันไปทางไหน

ถ้าระบบใช้ systemd-resolved ให้รัน resolvectl status เพื่อดู DNS server ของแต่ละอินเทอร์เฟซ และ resolvectl query example.com เพื่อดูว่า link ไหนเป็นผู้ตอบ ถ้าต้องการหลักฐานบนสาย ให้รัน sudo tcpdump -ni any port 53 ระหว่างท่องเว็บ

แก้ไฟล์ /etc/resolv.conf ด้วยมือเป็นวิธีที่ดีไหม

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

ต้องกังวลเรื่อง IPv6 กับ DNS Leak ด้วยไหม

ต้อง หากเครือข่ายแจก resolver แบบ IPv6 แต่ VPN ครอบคลุมเฉพาะ IPv4 คำถามอาจออกทางเส้น IPv6 ให้ดู resolvectl status ว่ามี server แบบ IPv6 หรือไม่ แล้วเลือกส่ง IPv6 ผ่านอุโมงค์ด้วย หรือปิด IPv6 ของการเชื่อมต่อนั้น

เกี่ยวกับผู้เขียน

Bob Kanokphon Thongdee ผู้ก่อตั้ง XPASS VPN

Bob Kanokphon Thongdee

  • ผู้ก่อตั้ง XPASS VPN
  • ผู้ร่วมก่อตั้ง eSIMonline.asia
  • ประสบการณ์ด้านการตลาดออนไลน์มากกว่า 7 ปี
  • ผู้ก่อตั้ง Cojourney Visa และ Cojourney Travel

ต้องใช้ VPN ช่วงเดินทางหรือช่วงงานยุ่ง?

XPASS ขายแพ็กเกจแบบเติมเงินตามจำนวนวัน จ่ายครั้งเดียว ไม่มีการต่ออายุอัตโนมัติ

ดูแพ็กเกจ

อ่านต่อ

ความปลอดภัยของ VPN

DNS leak คืออะไร

DNS leak เกิดเมื่ออุปกรณ์ถามหาที่อยู่ของเว็บไซต์นอกอุโมงค์ VPN มาดูว่าทำไมจึงเกิด ทดสอบอย่างไร และต้องทำอย่างไร

อ่าน 10 นาที

พื้นฐาน VPN

DNS ทำงานอย่างไร ตั้งแต่ชื่อเว็บไซต์ถึง IP

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

อ่าน 9 นาที

ความปลอดภัยของ VPN

Split DNS สำหรับ VPN คืออะไร

Split DNS ให้อุปกรณ์ถาม resolver คนละตัวตามชื่อโดเมน ชื่อภายในไปทาง VPN ชื่อทั่วไปไปทางปกติ บทความนี้อธิบายหลักการ การใช้งานจริง และวิธีทดสอบ

อ่าน 9 นาที

คู่มือตามอุปกรณ์

วิธีแก้ DNS Leak ของ VPN บน Windows

ทำไม Windows ส่งคำค้นหา DNS ออกนอก VPN ได้ วิธียืนยันด้วยเครื่องมือในตัว และลำดับการแก้ที่ได้ผลกับเครื่องส่วนใหญ่

อ่าน 10 นาที

ความปลอดภัยของ VPN

วิธีรีวิว VPN ด้วยตัวเอง เช็กลิสต์ทดสอบที่ทำตามได้

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

อ่าน 9 นาที