WireGuard میں DNS ٹھیک کریں: 3 عام خرابیاں
WireGuard tunnel فعال ہے مگر names resolve نہیں ہو رہے یا DNS queries local router کو جا رہی ہیں؟ تین خرابیوں میں اپنی وجہ پہچانیں اور درست حل اپنائیں۔
WireGuard ٹنل فعال ہوتے ہی DNS کیوں خراب ہو جاتا ہے
WireGuard کے ذریعے DNS تین طریقوں سے ناکام ہوتا ہے، اور ہر طریقے کا الگ حل ہے۔ کبھی کچھ بھی resolve نہیں ہوتا، کبھی نام resolve ہو جاتے ہیں لیکن queries آپ کی مشین سے ٹنل کے باہر بھیجی جاتی ہیں، اور کبھی client کا اپنا resolver manager interface شروع ہونے کے چند سیکنڈ بعد setting کو overwrite کر دیتا ہے۔ مسئلہ تقریباً کبھی ٹنل نہیں ہوتا۔ مسئلہ وہ ایک لائن ہوتی ہے جو client کو بتاتی ہے کہ کس resolver سے پوچھنا ہے، اور وہ routing جو طے کرتی ہے کہ اس resolver تک packets کس راستے سے جائیں گے۔
WireGuard IP packets منتقل کرتا ہے اور DNS کے بارے میں کچھ نہیں جانتا۔ DNS domain name system ہے، جو example.com جیسے ناموں کو IP addresses میں تبدیل کرتا ہے۔ client کے [Interface] block میں موجود DNS = لائن WireGuard setting نہیں ہے۔ اسے wg-quick پڑھتا ہے، جو shell wrapper ہے اور interface کو فعال کرتا ہے، جبکہ wg-quick ٹنل فعال رہنے کے دوران client کی resolver configuration میں ترمیم کرتا ہے اور wg-quick down پر اسے بحال کر دیتا ہے۔ اس لیے ذیل میں بیان کیا گیا ہر مسئلہ routing یا wg-quick کا مسئلہ ہے، cryptography کا نہیں۔ اگر ٹنل ابھی قائم نہیں کیا گیا تو پہلے اپنے VPS پر self-hosted WireGuard VPN سے آغاز کریں، پھر اس صفحے پر واپس آئیں۔
DNS کو چھیڑنے سے پہلے تصدیق کریں کہ ٹنل درست حالت میں ہے۔
sudo wg show
ping -c 3 10.8.0.1
ping -c 3 1.1.1.1wg show میں peer اور حالیہ latest handshake نظر آنا چاہیے، اور دونوں pings کا جواب آنا چاہیے۔ اگر ping 1.1.1.1 timeout ہو جائے تو مسئلہ DNS کے بجائے forwarding یا NAT (network address translation) کا ہے، اور resolver config کی کوئی بھی تبدیلی مدد نہیں کرے گی۔ یہاں ہر مثال میں ٹنل subnet کے لیے 10.8.0.0/24 اور server کے tunnel address کے لیے 10.8.0.1 استعمال کیا گیا ہے۔ اپنی values استعمال کریں۔
پہلی خرابی: کچھ بھی resolve نہیں ہوتا، کیونکہ resolver کبھی جواب نہیں دیتا
علامت واضح ہے۔ ping 1.1.1.1 کام کرتا ہے، جبکہ curl https://example.com یہ نتیجہ دیتا ہے:
curl: (6) Could not resolve host: example.comکلائنٹ سے tunnel resolver کو براہِ راست query کریں۔ Ubuntu اور Debian میں dig، dnsutils package کا حصہ ہے۔
dig +short @1.1.1.1 example.com
dig +short @10.8.0.1 example.comپہلی command ایک address واپس کرتی ہے، جس سے ثابت ہوتا ہے کہ packets tunnel کے ذریعے internet تک پہنچ رہے ہیں۔ دوسری command کچھ واپس نہیں کرتی اور ;; communication timed out; no servers could be reached دکھاتی ہے۔ یہی مکمل تشخیص ہے: آپ کا client 10.8.0.1 کی طرف متوجہ ہے، اور 10.8.0.1 UDP port 53 پر جواب نہیں دے رہا۔
اس کی دو وجوہات ہو سکتی ہیں۔ یا تو server پر کوئی resolver چل نہیں رہا، یا server firewall query کو پہنچنے سے پہلے drop کر رہا ہے۔ Server پر دونوں چیزیں چیک کریں۔
sudo ss -ulnp | grep ':53'
sudo nft list rulesetجو resolver چل رہا ہو اور درست طور پر bind ہو، اس میں 10.8.0.1:53 یا 0.0.0.0:53 والی line دکھائی دیتی ہے۔ Ubuntu پر عموماً مسئلہ 127.0.0.53:53 ہوتا ہے: یہ systemd-resolved کا stub listener ہے، جو loopback address پر bind ہوتا ہے اور جان بوجھ کر دوسری machines سے ناقابل رسائی رہتا ہے۔ ایسے server کی طرف VPN client کو متوجہ کرنے سے، جس کا واحد resolver یہی stub ہو، عین یہی timeout پیدا ہوتا ہے۔
حل یہ ہے کہ ایسا resolver استعمال کریں جو tunnel address پر listen کرے، اور ایک firewall rule شامل کریں جو peers کو اس تک پہنچنے دے۔
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'اس کے بعد port کو صرف tunnel traffic کے لیے کھولیں۔ nftables کے ساتھ /etc/nftables.conf میں input chain کے اندر یہ دو lines شامل کریں، پھر sudo systemctl reload nftables سے reload کریں۔
udp dport 53 iifname "wg0" accept
tcp dport 53 iifname "wg0" acceptufw کے ساتھ sudo ufw allow in on wg0 to any port 53 یہی کام کرتا ہے۔ port 53 کو public internet کے لیے کبھی نہ کھولیں۔ Open recursive resolver چند دنوں میں scanners کو مل جاتا ہے اور denial of service attacks کو amplify کرنے کے لیے استعمال ہوتا ہے۔ آپ کا provider یہ traffic آپ سے پہلے محسوس کر لے گا۔
Client سے dig +short @10.8.0.1 example.com دوبارہ چلائیں۔ Output میں address آنے کا مطلب ہے کہ resolver path کام کر رہا ہے، اس لیے اب client کو صرف اسے استعمال کرنا ہے۔ یہ line client کے [Interface] block میں شامل کریں اور sudo wg-quick down wg0 && sudo wg-quick up wg0 سے interface restart کریں۔
[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
DNS = 10.8.0.1DNS کا اخراج، کیونکہ split tunnel resolver تک route نہیں بناتا
یہ مسئلہ زیادہ سنگین ہے، کیونکہ سب کچھ درست دکھائی دیتا ہے۔ نام resolve ہوتے ہیں، صفحات کھلتے ہیں، اور queries اس local network سے cleartext میں گزرتی ہیں جس پر آپ اعتماد نہیں کرنا چاہتے تھے۔
اس کی دو configurations ہوتی ہیں۔ پہلی configuration میں client کے پاس AllowedIPs = 0.0.0.0/0, ::/0 ہوتا ہے، لیکن DNS = line نہیں ہوتی۔ wg-quick اپنی routing table میں default route شامل کرتا ہے اور suppress_prefixlength 0 کے ساتھ ایک rule بھی بناتا ہے۔ اس کا مقصد زیادہ specific local routes کو برقرار رکھنا ہے تاکہ machine اب بھی اپنے printer تک پہنچ سکے۔ Client نے DHCP سے جو resolver حاصل کیا ہوتا ہے، عموماً 192.168.1.1 پر موجود router، وہ انہی local routes میں سے ایک کے مطابق ہوتا ہے۔ آپ کا traffic tunnel سے گزرتا ہے، لیکن local network کو ان تمام names کی مکمل فہرست اب بھی مل جاتی ہے جنہیں آپ look up کرتے ہیں۔
دوسری configuration split tunnel ہے: AllowedIPs = 10.8.0.0/24 کے ساتھ DNS = 9.9.9.9۔ چونکہ 9.9.9.9، AllowedIPs کے اندر نہیں ہے، اس لیے client کے پاس tunnel کے ذریعے وہاں پہنچنے کا کوئی route نہیں ہوتا۔ چنانچہ query پہلے معاملے کی طرح local link سے باہر نکل جاتی ہے۔
ثابت کریں کہ حقیقت میں کون سا resolver جواب دے رہا ہے۔ whoami.akamai.net ایک public test name ہے جو اس recursive resolver کا IP address واپس کرتا ہے جس نے query بھیجی ہو۔ اس طرح آپ اس کے جواب کا اپنے server کے public address سے موازنہ کر سکتے ہیں۔
resolvectl status
dig +short whoami.akamai.net
sudo tcpdump -ni any -c 10 port 53resolvectl status ہر link کے لیے ایک block دکھاتا ہے۔ اگر آپ کے ethernet یا wireless link کے block میں اب بھی Current DNS Server: 192.168.1.1 دکھائی دے، جبکہ wg0 block میں کچھ نہ ہو، تو یہی اخراج ہے۔ dig +short whoami.akamai.net کا آپ کے server کے address کے بجائے گھر کے broadband address کو واپس کرنا، remote end سے بھی اس کی تصدیق کرتا ہے۔ tcpdump line وہ حتمی ثبوت ہے جو اختلاف ختم کرتی ہے: درست output میں port 53 کے ہر packet کو wg0 پر جانا چاہیے، جبکہ اخراج کی صورت میں وہ wlan0 یا enp3s0 پر جاتے ہیں۔
اس اصلاح کے دو حصے ہیں، اور دونوں ضروری ہیں۔ DNS کو ایسے address پر set کریں جو tunnel کے اندر موجود ہو، اور یقینی بنائیں کہ وہ address 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/1610.8.0.1، 10.8.0.0/24 کے اندر موجود ہے، اس لیے query encrypted ہو کر server کو بھیجی جاتی ہے۔ اگر آپ split tunnel پر public resolver ہی استعمال کرنا چاہتے ہیں تو اسے host route کے طور پر شامل کریں: AllowedIPs = 10.8.0.0/24, 9.9.9.9/32۔ اس کے بعد packets tunnel کے ذریعے بھیجے جائیں گے، اگرچہ local network اب بھی سابقہ sessions سے یہ دیکھ سکتا ہے کہ آپ نے کون سا provider منتخب کیا ہے۔ اپنا resolver چلانے سے یہ مسئلہ ختم ہو جاتا ہے۔
Resolver کی assignment، ہاتھ سے بنائے گئے WireGuard اور coordinated mesh کے درمیان نمایاں فرق ہے، اور یہی WireGuard کا Tailscale سے موازنہ میں بیان کردہ tradeoff کا حصہ ہے۔ self-hosted Headscale control server چلانے سے آپ کو یہ coordination حاصل ہو جاتی ہے، جبکہ آپ کا key material کسی تیسرے فریق کے حوالے نہیں ہوتا۔ اگر آخری بات آپ کے لیے تشویش کا باعث ہے تو یاد رکھیں کہ Tailscale آپ کے network traffic کو encrypt کرنے والی keys کبھی اپنے پاس نہیں رکھتا، اور زیادہ اہم سوال یہ ہے کہ کوئی breached coordination server یا چوری شدہ identity account آپ کے network میں مزید کیا رسائی حاصل کر سکتا ہے۔
Failure three: resolvconf and systemd-resolved fight on Linux clients
macOS، Windows، iOS اور Android کلائنٹس سرکاری ایپ کے ذریعے DNS = لاگو کرتے ہیں اور عموماً کوئی خاص مسئلہ پیدا نہیں کرتے۔ مسئلہ Linux میں ہوتا ہے، جہاں یہ setting ایک shell script کے ذریعے لاگو ہوتی ہے۔ اس script کو اندازہ لگانا پڑتا ہے کہ آپ کئی resolver managers میں سے کون سا چلا رہے ہیں۔
پہلی failure واضح ہوتی ہے۔ sudo wg-quick up wg0 اس پیغام کے ساتھ رک جاتا ہے:
resolvconf: command not foundwg-quick، resolvconf کو چلاتا ہے، لیکن یہ binary انسٹال نہیں ہے۔ وہ implementation انسٹال کریں جو systemd-resolved کے ساتھ کام کرتی ہے، پھر interface کو دوبارہ up کریں۔
sudo apt install -y openresolv
sudo systemctl restart systemd-resolved
sudo wg-quick down wg0 && sudo wg-quick up wg0
resolvectl status wg0دوسری failure خاموش ہوتی ہے، اور یہی ایک شام ضائع کر دیتی ہے۔ interface up ہو جاتا ہے، resolvectl status wg0 درست طور پر DNS Servers: 10.8.0.1 دکھاتا ہے، لیکن lookups اب بھی پرانے resolver کو بھیجے جاتے ہیں۔ systemd-resolved ہر link کے لیے الگ resolver list رکھتا ہے اور ہر query کے لیے ایک link منتخب کرتا ہے۔ جب تک کسی ایک link کو names کے لیے default route قرار نہ دیا جائے، یہ wireless link کا resolver استعمال کرتا رہتا ہے، کیونکہ اس link پر search domain موجود ہے جبکہ آپ کے link پر نہیں۔
Resolver set کریں اور اسی step میں default route بھی claim کریں۔ %i interface name میں expand ہوتا ہے، اس لیے یہ block کسی بھی interface پر بغیر تبدیلی کے کام کرتا ہے۔
[Interface]
Address = 10.8.0.2/32
PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~.
PostDown = resolvectl revert %iجب PostUp کو اس طریقے سے استعمال کریں تو DNS = والی line حذف کریں، کیونکہ بصورت دیگر دو mechanisms resolver state لکھیں گے اور بعد میں صرف ایک mechanism cleanup کرے گا۔ ~. argument اہم حصہ ہے: یہ wg0 کو ہر name کے لیے routing domain قرار دیتا ہے۔ اس طرح systemd-resolved ہر query کے لیے link منتخب کرنے کے بجائے تمام queries اسی طرف بھیجتا ہے۔ اس کی تصدیق کریں۔
resolvectl status wg0درست output میں DNS Servers: 10.8.0.1 اور Default Route: yes شامل ہوتے ہیں۔ اگر Default Route، no پڑھتا ہے تو resolvectl domain والا حصہ نہیں چلا، اور آپ دوبارہ link selection پر آ گئے ہیں۔
ایک اور صورت کا ذکر ضروری ہے۔ اگر /etc/resolv.conf، /run/systemd/resolve/stub-resolv.conf کی طرف symlink ہونے کے بجائے ایک حقیقی file ہے تو اسے کوئی دوسرا tool manage کر رہا ہے، عموماً NetworkManager یا container runtime۔ کسی اور debugging سے پہلے ls -l /etc/resolv.conf چلائیں، کیونکہ جو tool ہر network change پر اس file کو دوبارہ لکھتا ہے وہ کم سے کم موزوں وقت پر آپ کی تبدیلی ختم کر دے گا۔
ٹَنل کے ذریعے اپنا filtering resolver: upgrade
جب queries قابلِ اعتماد طریقے سے tunnel کے اندر سے گزرنے لگیں تو دوسری جانب موجود resolver ایک control point بن جاتا ہے۔ وہاں AdGuard Home چلانے سے ہر connected device کو blocklist filtering اور query log ملتا ہے، جبکہ client software یا فی device configuration کی ضرورت نہیں رہتی۔ جولائی 2026 میں چیک کیا گیا official install script ایک ہی لائن پر مشتمل ہے۔
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -vپہلی بار چلنے پر setup wizard پورٹ 3000 پر requests سنتا ہے۔ اسے tunnel کے ذریعے http://10.8.0.1:3000 پر کھولیں، یہ port عوامی طور پر کھولنے کے بجائے۔ Wizard میں DNS listen address اور admin listen address دونوں کو 10.8.0.1 پر set کریں۔ اگر failure one والی unbound اب بھی اسی address پر قائم ہے تو پہلے اسے sudo systemctl disable --now unbound کے ذریعے stop کریں، کیونکہ ایک ہی address پر دو processes UDP port 53 سے bind نہیں ہو سکتے اور دوسرا process listen udp 10.8.0.1:53: bind: address already in use کے ساتھ exit ہو جاتا ہے۔
اگر client configs میں پہلے ہی DNS = 10.8.0.1 درج ہے تو ان میں کوئی تبدیلی ضروری نہیں۔ اب query log ہر peer کی ہر lookup دکھائے گا۔ یہ کوئی مفت فائدہ نہیں بلکہ privacy سے متعلق حقیقی فیصلہ ہے: اعتماد internet provider سے منتقل ہو کر آپ کے اپنے پاس آ جاتا ہے، اور اس box کو patched رکھنا بھی آپ ہی کی ذمہ داری ہوتی ہے۔ internet کے سامنے exposed server پر پہلے بنیادی security اقدامات مکمل ہونے چاہییں، اور نئے VPS کے پہلے دس منٹ میں ان کا احاطہ کیا گیا ہے۔
FAQ
میرے WireGuard tunnel سے connection قائم ہو جاتا ہے، لیکن نام resolve کیوں نہیں ہوتے؟
Tunnel packets منتقل کرتا ہے اور ناموں کو بالکل handle نہیں کرتا، اس لیے working tunnel کے ساتھ broken lookups کا مطلب ہے کہ جس resolver کی طرف آپ اشارہ کر رہے ہیں وہ جواب نہیں دے رہا۔ Client سے dig +short @10.8.0.1 example.com کے ذریعے test کریں۔ communication timed out reply کا مطلب ہے کہ یا تو اس tunnel address پر کوئی resolver listening نہیں کر رہا، جو اکثر اس لیے ہوتا ہے کہ systemd-resolved stub صرف 127.0.0.53 پر bind ہوتا ہے، یا server firewall wg0 پر آنے والی UDP port 53 کی traffic drop کر رہا ہے۔ پہلے listener درست کریں، پھر صرف wg0 کے لیے port کھولیں۔
میں کیسے جانچوں کہ میرا DNS، WireGuard کے ذریعے leak تو نہیں ہو رہا؟
Client پر sudo tcpdump -ni any -c 10 port 53 چلائیں اور browse کرتے وقت interface column monitor کریں۔ ہر packet wg0 پر ہونا چاہیے۔ اگر packets wireless یا ethernet interface پر نظر آئیں تو queries cleartext میں باہر جا رہی ہیں۔ dig +short whoami.akamai.net دوسری تصدیق فراہم کرتا ہے، کیونکہ یہ اس recursive resolver کا public address واپس کرتا ہے جس نے query بھیجی تھی۔ اس لیے اگر جواب آپ کے server کے address سے مختلف ہو تو leak کی تصدیق ہو جاتی ہے۔
اگر میں split tunnel استعمال کر رہا ہوں تو کیا DNS = line ضروری ہے؟
ہاں، اور resolver address بھی AllowedIPs کے اندر ہونا چاہیے، ورنہ client کے پاس اس تک پہنچنے کے لیے route نہیں ہوگا۔ AllowedIPs = 10.8.0.0/24 کے ساتھ 10.8.0.1 پر موجود resolver شامل ہو جاتا ہے اور query encrypted رہتی ہے۔ 9.9.9.9 جیسا public resolver شامل نہیں ہوتا، اس لیے query local link کے ذریعے باہر چلی جاتی ہے، اگرچہ DNS line درست نظر آتی ہے۔
resolvectl درست server دکھاتا ہے، لیکن lookups پھر بھی کہیں اور کیوں جا رہی ہیں؟
systemd-resolved ہر link کے لیے الگ resolver list رکھتا ہے اور ہر query کے لیے ایک link منتخب کرتا ہے۔ اس لیے wg0 پر موجود درست entry نظرانداز ہو جاتی ہے، جب کسی دوسرے link کے پاس names کے لیے default route ہو۔ Client کے [Interface] block میں PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~. شامل کریں اور DNS = line ہٹا دیں۔ اس کے بعد resolvectl status wg0 کو Default Route: yes report کرنا چاہیے۔
جب کئی clients خراب ہوں تو پہلے کس client کو درست کروں؟
ایک Linux client درست کریں، کیونکہ یہی واحد platform ہے جو mechanism دکھاتا ہے۔ resolvectl status اور tcpdump سے معلوم ہوتا ہے کہ کس resolver نے جواب دیا اور packet کس interface سے گزرا۔ Phone اور desktop apps یہی DNS اور AllowedIPs values بغیر کسی visible plumbing کے apply کرتی ہیں۔ اس لیے Linux client درست ہونے کے بعد آپ ایسی configuration نقل کر رہے ہوں گے جسے آپ پہلے ہی verify کر چکے ہیں۔