SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor

Cara Selesaikan Masalah DNS pada WireGuard

Tunnel WireGuard aktif tetapi DNS gagal berfungsi atau bocor? Ketahui tiga punca utama kegagalan DNS dan cara membetulkan konfigurasi DNS serta routing pada sistem anda.

Mengapa DNS terputus sebaik sahaja tunnel WireGuard diaktifkan

DNS melalui WireGuard gagal dalam tiga cara, dan setiap satunya mempunyai penyelesaian tersendiri. Tiada apa-apa yang dapat diselesaikan (resolve), atau nama diselesaikan tetapi pertanyaan keluar dari mesin anda di luar tunnel, atau pengurus resolver klien sendiri menulis ganti tetapan tersebut beberapa saat selepas antara muka bermula. Masalahnya hampir tidak pernah berpunca daripada tunnel itu sendiri. Masalahnya terletak pada satu baris yang memberitahu klien resolver mana yang perlu dirujuk, dan penghalaan (routing) yang menentukan bagaimana paket ke resolver tersebut bergerak.

WireGuard memindahkan paket IP dan tidak mengetahui apa-apa tentang DNS (sistem nama domain, perkhidmatan yang menukarkan nama seperti example.com kepada alamat IP). Baris DNS = dalam blok [Interface] klien bukanlah tetapan WireGuard. Ia dibaca oleh wg-quick, pembungkus shell yang mengaktifkan antara muka, dan wg-quick kemudian menyunting konfigurasi resolver klien semasa tunnel aktif dan memulihkannya semasa wg-quick down. Jadi, setiap masalah di bawah adalah masalah penghalaan atau masalah wg-quick, bukan masalah kriptografi. Jika tunnel itu sendiri belum dibina, mulakan dengan VPN WireGuard yang dihoskan sendiri pada VPS anda dan kembali ke halaman ini selepas itu.

Pastikan tunnel dalam keadaan baik sebelum anda menyentuh DNS sama sekali.

sudo wg show
ping -c 3 10.8.0.1
ping -c 3 1.1.1.1

wg show sepatutnya menyenaraikan peer dengan latest handshake yang terkini, dan kedua-dua ping sepatutnya mendapat jawapan. Jika ping 1.1.1.1 tamat masa (timeout), anda berkemungkinan besar mempunyai masalah forwarding atau NAT (network address translation) dan bukannya masalah DNS, dan sebarang perubahan pada konfigurasi resolver tidak akan membantu. Firewall yang menggugurkan ICMP menghasilkan tamat masa yang sama, jadi sahkan dengan curl -sI https://1.1.1.1 sebelum anda mula menukar peraturan forwarding. Jika ping mendapat jawapan tetapi throughput merosot sebaik sahaja trafik sebenar bermula, itu adalah punca kerosakan yang berasingan, dan WireGuard yang perlahan hampir selalu berpunca daripada MTU dan bukannya daripada apa-apa yang terdapat pada halaman ini. Setiap contoh di sini menggunakan 10.8.0.0/24 sebagai subnet tunnel dan 10.8.0.1 sebagai alamat tunnel pelayan. Gantikan dengan alamat anda sendiri.

Kegagalan satu: tiada apa-apa yang diselesaikan, kerana resolver tidak pernah menjawab

Simptomnya adalah tepat. ping 1.1.1.1 berfungsi, dan curl https://example.com mengembalikan ini:

curl: (6) Could not resolve host: example.com

Tanya resolver terowong secara terus daripada klien. dig datang daripada pakej dnsutils pada Ubuntu dan Debian.

dig +short @1.1.1.1 example.com
dig +short @10.8.0.1 example.com

Perintah pertama mengembalikan alamat, yang membuktikan paket sampai ke internet melalui terowong. Perintah kedua tidak mengembalikan apa-apa dan mencetak ;; communication timed out; no servers could be reached. Itulah diagnosis keseluruhannya: klien anda dihalakan ke 10.8.0.1, dan 10.8.0.1 tidak menjawab pada port UDP 53.

Dua punca menghasilkannya. Sama ada tiada resolver yang berjalan pada pelayan, atau firewall pelayan menggugurkan pertanyaan tersebut sebelum ia sampai. Semak kedua-duanya pada pelayan.

sudo ss -ulnp | grep ':53'
sudo nft list ruleset

Resolver yang sedang berjalan dan terikat dengan betul akan menunjukkan baris dengan 10.8.0.1:53 atau 0.0.0.0:53. Pada Ubuntu, kejutan biasanya adalah 127.0.0.53:53: itu adalah pendengar stub systemd-resolved, yang mengikat alamat loopback dan sengaja tidak boleh dicapai daripada mesin lain. Menghalakan klien VPN ke pelayan yang resolver tunggalnya adalah stub tersebut akan menghasilkan timeout ini.

Penyelesaiannya ialah resolver yang mendengar pada alamat terowong, ditambah satu peraturan firewall yang membenarkan rakan setara (peers) mencapainya.

sudo apt update && sudo apt install -y unbound
printf 'server:\n  interface: 10.8.0.1\n  access-control: 10.8.0.0/24 allow\n' \
  | sudo tee /etc/unbound/unbound.conf.d/wireguard.conf
sudo systemctl restart unbound
sudo ss -ulnp | grep '10.8.0.1:53'

Kemudian buka port untuk trafik terowong sahaja. Dengan nftables, tambahkan dua baris ini ke dalam chain input dalam /etc/nftables.conf dan muat semula dengan sudo systemctl reload nftables.

udp dport 53 iifname "wg0" accept
tcp dport 53 iifname "wg0" accept

Dengan ufw, sudo ufw allow in on wg0 to any port 53 melakukan tugas yang sama. Jangan sekali-kali membuka port 53 kepada internet awam. Resolver rekursif yang terbuka akan ditemui oleh pengimbas dalam masa beberapa hari dan digunakan untuk menguatkan serangan penafian perkhidmatan (denial of service), dan penyedia anda akan menyedari trafik tersebut sebelum anda.

Jalankan semula dig +short @10.8.0.1 example.com daripada klien. Alamat dalam output bermakna laluan resolver berfungsi, jadi klien kini hanya perlu menggunakannya. Tambahkan baris tersebut ke dalam blok [Interface] klien dan mulakan semula antaramuka dengan sudo wg-quick down wg0 && sudo wg-quick up wg0.

[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
DNS = 10.8.0.1

Kegagalan dua: Kebocoran DNS, kerana split tunnel tidak menghalakan resolver

Masalah ini lebih buruk, kerana segala-galanya kelihatan berfungsi. Nama domain diselesaikan, halaman dimuatkan, dan pertanyaan dihantar dalam teks jelas merentasi rangkaian tempatan yang tidak sepatutnya anda percayai.

Dua konfigurasi menyebabkan perkara ini. Pertama ialah klien dengan AllowedIPs = 0.0.0.0/0, ::/0 dan tiada baris DNS =. wg-quick memasang laluan lalai dalam jadual penghalaannya sendiri dan menambah peraturan dengan suppress_prefixlength 0, yang mengekalkan laluan tempatan yang lebih khusus supaya mesin masih boleh mencapai pencetak. Resolver yang dipelajari klien melalui DHCP, biasanya penghala pada 192.168.1.1, sepadan dengan salah satu laluan tempatan tersebut. Trafik anda melalui tunnel. Rangkaian tempatan masih menerima senarai penuh nama yang anda cari.

Kedua ialah split tunnel: AllowedIPs = 10.8.0.0/24 dengan DNS = 9.9.9.9. Kerana 9.9.9.9 tidak berada di dalam AllowedIPs, klien tiada laluan ke sana melalui tunnel, jadi pertanyaan keluar melalui pautan tempatan seperti dalam kes pertama.

Buktikan resolver mana yang sebenarnya menjawab. whoami.akamai.net ialah nama ujian awam yang menjawab dengan alamat IP resolver rekursif yang bertanya, supaya anda boleh membandingkan jawapannya dengan alamat awam pelayan anda.

resolvectl status
dig +short whoami.akamai.net
sudo tcpdump -ni any -c 10 port 53

resolvectl status mencetak satu blok bagi setiap pautan. Jika blok untuk pautan ethernet atau wayarles anda masih menunjukkan Current DNS Server: 192.168.1.1 manakala blok wg0 tidak menunjukkan apa-apa, itulah kebocorannya. dig +short whoami.akamai.net yang mengembalikan alamat jalur lebar rumah anda dan bukannya alamat pelayan anda mengesahkan perkara ini dari hujung sana. Baris tcpdump ialah bukti yang menamatkan perdebatan: output yang sihat meletakkan setiap paket port 53 yang meninggalkan mesin pada wg0, dan kebocoran meletakkannya pada wlan0 atau enp3s0. Paket pada lo ke atau dari 127.0.0.53 ialah aplikasi yang bercakap dengan stub systemd-resolved tempatan, dan ia bukan kebocoran.

Pembaikannya mempunyai dua bahagian dan kedua-duanya diperlukan. Tetapkan DNS kepada alamat yang berada di dalam tunnel, dan pastikan alamat tersebut berada di dalam AllowedIPs.

[Interface]
Address = 10.8.0.2/32
DNS = 10.8.0.1

[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 10.8.0.0/24, 10.20.0.0/16

10.8.0.1 berada di dalam 10.8.0.0/24, jadi pertanyaan disulitkan dan dihantar ke pelayan. Jika anda berkeras mahukan resolver awam pada split tunnel, tambahkannya sebagai laluan hos: AllowedIPs = 10.8.0.0/24, 9.9.9.9/32. Paket kemudiannya dihantar melalui tunnel, walaupun rangkaian tempatan masih boleh melihat bahawa anda memilih penyedia tersebut daripada sesi terdahulu. Resolver yang anda kendalikan sendiri mengelakkan persoalan ini.

Penugasan resolver adalah salah satu perbezaan ketara antara WireGuard yang dibina secara manual dan mesh yang diselaraskan, yang merupakan sebahagian daripada pertukaran dalam WireGuard berbanding Tailscale. Menjalankan pelayan kawalan Headscale yang dihoskan sendiri memberikan anda penyelarasan tersebut tanpa menyerahkan bahan kunci anda kepada pihak ketiga. Jika frasa terakhir itu yang merisaukan anda, ambil perhatian bahawa Tailscale tidak pernah memegang kunci yang menyulitkan trafik anda, dan persoalan yang lebih kritikal ialah apa yang boleh ditambah oleh pelayan penyelarasan yang terjejas atau akaun identiti yang dicuri ke dalam rangkaian anda.

Kegagalan tiga: Konflik antara resolvconf dan systemd-resolved pada klien Linux

Klien macOS, Windows, iOS dan Android menggunakan DNS = melalui aplikasi rasmi dan jarang menimbulkan masalah. Pada Linux, tetapan ini digunakan oleh skrip shell yang perlu meneka pengurus resolver mana yang anda jalankan.

Kegagalan pertama adalah nyata. sudo wg-quick up wg0 terhenti dengan:

resolvconf: command not found

wg-quick memanggil resolvconf, dan binari tersebut tidak dipasang. Pada Debian 12 dan Ubuntu 24.04 atau lebih baharu, arahan resolvconf yang berhubung dengan systemd-resolved disertakan dalam pakej systemd-resolved, jadi pasang pakej tersebut, kemudian naikkan semula antaramuka. Ubuntu 22.04 tidak mempunyai pakej berasingan untuknya; di sana, cipta pautan keserasian sendiri dengan sudo ln -s /usr/bin/resolvectl /usr/local/bin/resolvconf dan langkau baris pemasangan.

sudo apt install -y systemd-resolved
sudo systemctl restart systemd-resolved
sudo wg-quick down wg0 && sudo wg-quick up wg0
resolvectl status wg0

Kegagalan kedua adalah senyap, dan ia merupakan masalah yang memakan masa sepanjang malam. Antaramuka naik, resolvectl status wg0 menunjukkan DNS Servers: 10.8.0.1 dengan betul, namun carian masih mencapai resolver lama. systemd-resolved tidak mengabaikan wg0. Nama yang tidak sepadan dengan mana-mana domain penghalaan akan dihantar ke pelayan DNS bagi setiap pautan yang dikira sebagai laluan lalai (default route), dan pautan dengan pelayan DNS tanpa domain route-only dikira sebagai laluan lalai secara automatik. Jadi, pertanyaan dihantar ke 10.8.0.1 dan ke penghala pada pautan wayarles pada masa yang sama, dan jawapan yang berjaya dahulu akan menang. Penghala berada satu hop jauhnya dan biasanya menjawab dahulu, dan pertanyaan tersebut telah pun keluar dalam teks jelas (cleartext) walau apa pun. Nama di bawah domain carian pautan wayarles itu sendiri, seperti lan, hanya pergi ke pautan tersebut, kerana domain penghalaan yang paling spesifik akan menang.

Apabila wg-quick menggunakan DNS = melalui pembungkus resolvconf milik systemd, ia sudah pun meminta domain penghalaan tangkap-semua (catch-all), jadi kegagalan ini kebanyakannya berlaku apabila pelaksanaan resolvconf lain atau pengurus rangkaian menggunakan tetapan tersebut. Menetapkannya secara eksplisit akan menghilangkan tekaan.

Tetapkan resolver dan tuntut domain penghalaan tangkap-semua dalam langkah yang sama. %i berkembang kepada nama antaramuka, jadi blok ini berfungsi tanpa perubahan pada mana-mana antaramuka.

[Interface]
Address = 10.8.0.2/32
PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~.
PostDown = resolvectl revert %i

Padamkan baris DNS = apabila anda menggunakan PostUp dengan cara ini, kerana jika tidak, dua mekanisme akan menulis status resolver dan hanya satu daripadanya yang akan melakukan pembersihan selepas itu. Argumen ~. adalah bahagian yang penting: ia menjadikan wg0 sebagai domain route-only untuk setiap nama, supaya systemd-resolved berhenti menghantar nama yang tidak sepadan dengan domain yang lebih spesifik ke pautan lain. Nama di bawah domain pautan lain, seperti lan, masih pergi ke pautan tersebut, yang biasanya merupakan apa yang anda mahukan untuk hos tempatan. Sahkan perkara ini.

resolvectl status wg0

Output yang sihat mengandungi DNS Servers: 10.8.0.1 dan DNS Domain: ~.. Jika ~. tiada, bahagian resolvectl domain tidak dijalankan, dan wg0 kembali berlumba dengan pautan lain. Jangan gunakan flag laluan lalai sebagai semakan: ia membaca yes (atau +DefaultRoute pada baris Protocols, bergantung pada versi systemd) walaupun tanpa ~., kerana pautan tanpa domain route-only adalah laluan lalai walau bagaimanapun.

Satu lagi kes yang perlu disebut. Jika /etc/resolv.conf adalah fail sebenar dan bukannya pautan simbolik ke /run/systemd/resolve/stub-resolv.conf, sesuatu yang lain memilikinya, biasanya NetworkManager atau runtime kontena. Jalankan ls -l /etc/resolv.conf sebelum anda menyahpepijat apa-apa lagi, kerana alat yang menulis semula fail tersebut pada setiap perubahan rangkaian akan membatalkan kerja anda pada saat yang paling tidak membantu.

Naik taraf: resolver penapisan anda sendiri melalui tunnel

Apabila pertanyaan bergerak dengan stabil melalui tunnel, resolver di hujung sana menjadi titik kawalan. Menjalankan AdGuard Home di sana memberikan setiap peranti yang bersambung penapisan senarai sekat dan log pertanyaan, tanpa perisian klien dan tanpa konfigurasi setiap peranti. Skrip pemasangan rasmi, yang disemak pada Oktober 2026, hanyalah satu baris.

curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v

Wizard persediaan mendengar pada port 3000 semasa kali pertama dijalankan. Capai ia melalui tunnel di http://10.8.0.1:3000 dan bukannya membuka port tersebut secara awam, dan dalam wizard tetapkan alamat pendengar DNS serta alamat pendengar admin kepada 10.8.0.1. Jika unbound daripada kegagalan satu masih memegang alamat yang sama, hentikan ia dahulu dengan sudo systemctl disable --now unbound, kerana kedua-duanya akan bersaing untuk port UDP 53 pada satu alamat dan AdGuard Home akan keluar dengan listen udp 10.8.0.1:53: bind: address already in use.

Konfigurasi klien tidak perlu diubah jika ia sudah menyatakan DNS = 10.8.0.1. Log pertanyaan kini akan menunjukkan setiap carian yang sampai kepadanya daripada setiap peer, melainkan anda mengecualikan klien daripada log, yang merupakan keputusan privasi sebenar dan bukannya keuntungan percuma: anda memindahkan kepercayaan daripada pembekal internet anda kepada diri sendiri, dan anda adalah orang yang perlu memastikan kotak itu ditampal (patched). Pelayan yang terdedah kepada internet memerlukan perkara asas disediakan terlebih dahulu, dan sepuluh minit pertama pada VPS baharu meliputinya.

FAQ

Mengapa terowong WireGuard saya bersambung tetapi nama tidak dapat diselesaikan (resolve)?

Terowong hanya membawa paket dan tidak menguruskan nama, jadi terowong yang berfungsi dengan carian yang gagal bermakna resolver yang anda tuju tidak memberikan respons. Uji dengan dig +short @10.8.0.1 example.com daripada klien. Respons communication timed out bermakna tiada resolver yang mendengar pada alamat terowong tersebut, selalunya kerana stub systemd-resolved hanya terikat pada 127.0.0.53, atau firewall pelayan menggugurkan (drop) port UDP 53 yang tiba pada wg0. Betulkan pendengar (listener) dahulu, kemudian buka port tersebut hanya untuk wg0.

Bagaimanakah cara saya menyemak sama ada DNS saya bocor melalui WireGuard?

Jalankan sudo tcpdump -ni any -c 10 port 53 pada klien dan perhatikan lajur antara muka (interface) semasa anda melayari internet. Setiap paket yang keluar dari mesin sepatutnya berada pada wg0; paket pada lo ke atau daripada 127.0.0.53 adalah stub systemd-resolved tempatan dan ini adalah perkara biasa. Jika ia muncul pada antara muka wayarles atau ethernet anda, pertanyaan tersebut keluar dalam bentuk teks jelas (cleartext). dig +short whoami.akamai.net memberikan pendapat kedua, kerana ia menjawab dengan alamat awam bagi mana-mana resolver rekursif yang bertanya, jadi jawapan yang bukan alamat pelayan anda mengesahkan kebocoran tersebut.

Adakah saya memerlukan baris DNS = jika saya menggunakan split tunnel?

Ya, dan alamat resolver juga mestilah berada di dalam AllowedIPs atau klien tidak mempunyai laluan (route) kepadanya. Dengan AllowedIPs = 10.8.0.0/24, resolver pada 10.8.0.1 dilindungi dan pertanyaan tersebut disulitkan. Resolver awam seperti 9.9.9.9 tidak dilindungi, jadi pertanyaan tersebut keluar melalui pautan tempatan walaupun baris DNS kelihatan betul.

Mengapa resolvectl menunjukkan pelayan yang betul tetapi carian masih pergi ke tempat lain?

systemd-resolved menghantar nama yang tidak sepadan dengan mana-mana domain penghalaan ke setiap pautan laluan lalai (default-route) secara serentak, termasuk wg0, dan mengembalikan jawapan pertama yang berjaya, yang biasanya datang daripada penghala tempatan. Tambahkan PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~. ke blok [Interface] klien dan buang baris DNS =. resolvectl status wg0 sepatutnya melaporkan DNS Domain: ~., dan setiap nama yang tidak dituntut oleh pautan lain dengan domain yang lebih khusus hanya akan pergi ke wg0.

Klien mana yang perlu saya baiki dahulu apabila beberapa klien rosak?

Baiki satu klien Linux, kerana ia adalah satu-satunya platform yang menunjukkan mekanisme tersebut kepada anda. resolvectl status dan tcpdump memberitahu anda resolver mana yang menjawab dan antara muka mana yang membawa paket tersebut. Aplikasi telefon dan desktop menggunakan nilai DNS dan AllowedIPs yang sama tanpa sistem dalaman yang boleh dilihat, jadi sebaik sahaja klien Linux betul, anda hanya menyalin konfigurasi yang telah anda buktikan keberkesanannya.