WireGuard پر DNS کیوں نہیں چلتا؟ 3 حل
WireGuard ٹنل فعال ہے مگر DNS resolve نہیں ہوتا، queries مقامی router تک leak ہوتی ہیں، یا %%C17%% setting بدل دیتا ہے۔ 3 failure modes اور ان کے حل جانیں۔
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، یعنی وہ service جو example.com جیسے ناموں کو IP addresses میں تبدیل کرتی ہے)۔ client کے [Interface] block میں موجود DNS = سطر WireGuard کی setting نہیں ہے۔ اسے wg-quick پڑھتا ہے، جو interface کو فعال کرنے والا shell wrapper ہے، اور 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 ہو جائے، تو مسئلہ forwarding یا NAT (network address translation) کا ہے، DNS کا نہیں، اور resolver config میں کوئی بھی تبدیلی مدد نہیں کرے گی۔ یہاں ہر مثال میں 10.8.0.0/24 کو ٹنل subnet اور 10.8.0.1 کو server کے ٹنل address کے طور پر استعمال کیا گیا ہے۔ اپنی values استعمال کریں۔
پہلی خرابی: کچھ بھی resolve نہیں ہوتا، کیونکہ resolver کبھی جواب نہیں دیتا
علامت واضح ہے۔ ping 1.1.1.1 کام کرتا ہے، جبکہ curl https://example.com یہ واپس کرتا ہے:
curl: (6) Could not resolve host: example.comکلائنٹ سے tunnel resolver کو براہِ راست پوچھیں۔ dig، Ubuntu اور Debian کے 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 چل رہا ہو اور درست طور پر bound ہو، وہ 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 سے ناقابلِ رسائی رہتا ہے۔ VPN client کو ایسے server کی طرف بھیجنے سے، جس کا واحد 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 کے ساتھ input chain میں /etc/nftables.conf کی یہ دو 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.1خرابی دو: DNS لیکس، کیونکہ 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 تک پہنچ سکے۔ DHCP کے ذریعے client کو ملا ہوا resolver، جو عموماً 192.168.1.1 پر موجود router ہوتا ہے، ان local routes میں سے ایک سے match کرتا ہے۔ آپ کا traffic tunnel سے گزرتا ہے۔ لیکن local network کو ان تمام names کی مکمل فہرست پھر بھی مل جاتی ہے جنہیں آپ lookup کرتے ہیں۔
دوسری configuration split tunnel ہے: AllowedIPs = 10.8.0.0/24 کو DNS = 9.9.9.9 کے ساتھ استعمال کرنا۔ چونکہ 9.9.9.9، AllowedIPs کے اندر موجود نہیں ہے، اس لیے client کے پاس tunnel کے ذریعے اس تک پہنچنے کے لیے کوئی route نہیں ہوتا۔ چنانچہ query پہلے case کی طرح 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 میں کچھ نہ ہو، تو یہی leak ہے۔ dig +short whoami.akamai.net کا آپ کے server کے address کے بجائے آپ کے home broadband address کو واپس کرنا، دور موجود endpoint سے بھی اس کی تصدیق کرتا ہے۔ tcpdump line فیصلہ کن ثبوت فراہم کرتی ہے: درست output میں ہر port 53 packet wg0 سے گزرتا ہے، جبکہ leak کی صورت میں وہ 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 encrypt ہو کر 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، hand-built WireGuard اور coordinated mesh کے درمیان نمایاں فرقوں میں سے ایک ہے۔ یہ WireGuard کا Tailscale سے موازنہ میں بیان کردہ tradeoff کا حصہ ہے۔ خود میزبانی والے Headscale control server کو چلانے سے آپ کو یہ coordination مل جاتی ہے، جبکہ key material کسی third party کے حوالے نہیں کرنا پڑتا۔
ناکامی تین: Linux کلائنٹس پر resolvconf اور systemd-resolved کا باہمی تصادم
macOS، Windows، iOS اور Android کلائنٹس سرکاری app کے ذریعے DNS = لاگو کرتے ہیں اور عموماً کم مسائل پیدا کرتے ہیں۔ مسئلہ Linux میں ہوتا ہے، جہاں یہ setting ایک shell script کے ذریعے لاگو ہوتی ہے۔ اس script کو اندازہ لگانا پڑتا ہے کہ آپ کئی resolver managers میں سے کون سا چلا رہے ہیں۔
پہلی ناکامی واضح ہوتی ہے۔ sudo wg-quick up wg0 اس پیغام کے ساتھ رک جاتا ہے:
resolvconf: command not foundwg-quick، resolvconf کو چلاتا ہے، لیکن وہ binary انسٹال نہیں ہے۔ وہ implementation انسٹال کریں جو systemd-resolved کے ساتھ کام کرتی ہے، پھر interface کو دوبارہ فعال کریں۔
sudo apt install -y openresolv
sudo systemctl restart systemd-resolved
sudo wg-quick down wg0 && sudo wg-quick up wg0
resolvectl status wg0دوسری ناکامی خاموش ہوتی ہے اور عموماً پورا وقت ضائع کر دیتی ہے۔ interface فعال ہو جاتا ہے، resolvectl status wg0 درست طور پر DNS Servers: 10.8.0.1 دکھاتا ہے، لیکن name lookups پھر بھی پرانے resolver کو بھیجے جاتے ہیں۔ systemd-resolved ہر link کے لیے الگ resolver list رکھتا ہے اور ہر query کے لیے ایک link منتخب کرتا ہے۔ جب تک کسی link کو names کے لیے default route قرار نہ دیا جائے، یہ wireless link کا resolver استعمال کرتا رہتا ہے، کیونکہ اس link کے ساتھ search domain موجود ہے جبکہ آپ کے link کے ساتھ نہیں۔
Resolver مقرر کریں اور اسی مرحلے میں default route کا دعویٰ کریں۔ %i interface name میں تبدیل ہو جاتا ہے، اس لیے یہ 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 صفائی کرے گا۔ ~. 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 ہے تو اسے کوئی دوسرا component manage کر رہا ہے، عموماً NetworkManager یا container runtime۔ کسی اور debugging سے پہلے ls -l /etc/resolv.conf چلائیں، کیونکہ network میں ہر تبدیلی پر اس file کو دوبارہ لکھنے والا tool آپ کی تبدیلی کو عین نامناسب وقت پر ختم کر دے گا۔
ٹنل پر اپنا فلٹرنگ resolver
جب queries قابلِ اعتماد طور پر ٹنل کے ذریعے سفر کرنے لگیں تو دوسرے سرے پر موجود resolver ایک کنٹرول پوائنٹ بن جاتا ہے۔ وہاں AdGuard Home چلانے سے ہر منسلک 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، port 3000 پر listen کرتا ہے۔ اس port کو public طور پر کھولنے کے بجائے ٹنل کے ذریعے http://10.8.0.1:3000 پر اس تک رسائی حاصل کریں۔ Wizard میں DNS listen address اور admin listen address، دونوں کو 10.8.0.1 پر set کریں۔ اگر پہلے failure سے متعلق 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 سے متعلق ایک حقیقی فیصلہ ہے: trust آپ اپنے internet provider سے ہٹا کر خود پر منتقل کرتے ہیں، اور اس box کو patched رکھنے کی ذمہ داری بھی آپ ہی کی ہے۔ internet کے سامنے exposed server کے لیے پہلے بنیادی security اقدامات مکمل ہونا ضروری ہیں، اور نئے VPS کے پہلے دس منٹ میں ان کا احاطہ کیا گیا ہے۔
FAQ
میرا WireGuard ٹنل کنیکٹ ہو جاتا ہے، لیکن نام resolve کیوں نہیں ہوتے؟
ٹنل packets منتقل کرتا ہے اور ناموں کو بالکل handle نہیں کرتا۔ اس لیے اگر ٹنل کام کر رہا ہو لیکن lookups ناکام ہوں، تو اس کا مطلب ہے کہ آپ نے جس resolver کی طرف اشارہ کیا ہے وہ جواب نہیں دے رہا۔ کلائنٹ سے dig +short @10.8.0.1 example.com کے ذریعے ٹیسٹ کریں۔ communication timed out کا جواب اس بات کی علامت ہے کہ یا تو اس ٹنل address پر کوئی resolver listening نہیں کر رہا، جو اکثر اس لیے ہوتا ہے کہ systemd-resolved stub صرف 127.0.0.53 پر bind ہے، یا server firewall wg0 پر آنے والی UDP port 53 کو drop کر رہا ہے۔ پہلے listener درست کریں، پھر صرف wg0 کے لیے port کھولیں۔
میں کیسے جانچوں کہ میرا DNS WireGuard کے ذریعے leak تو نہیں ہو رہا؟
کلائنٹ پر 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 کے اندر ہونا چاہیے، ورنہ کلائنٹ کے پاس اس تک جانے کے لیے 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 موجود ہو۔ کلائنٹ کے [Interface] block میں PostUp = resolvectl dns %i 10.8.0.1; resolvectl domain %i ~. شامل کریں اور DNS = line ہٹا دیں۔ اس کے بعد resolvectl status wg0 کو Default Route: yes رپورٹ کرنا چاہیے۔
کئی clients خراب ہوں تو پہلے کس client کو درست کروں؟
ایک Linux client درست کریں، کیونکہ یہی واحد platform ہے جو mechanism دکھاتا ہے۔ resolvectl status اور tcpdump بتاتے ہیں کہ کس resolver نے جواب دیا اور packet کس interface سے گزرا۔ Phone اور desktop apps یہی DNS اور AllowedIPs values بغیر کسی visible plumbing کے لاگو کرتے ہیں۔ اس لیے Linux client درست ہونے کے بعد آپ ایسی configuration نقل کر رہے ہوں گے جسے آپ پہلے ہی ثابت کر چکے ہیں۔