SSD Nodes Learn 8GB RAM — $66/বছর
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-01

WireGuard DNS ঠিক করুন: 3টি সাধারণ সমস্যা ও সমাধান

WireGuard tunnel চালু, কিন্তু নাম resolve হয় না, DNS query local router-এ leak হয়, বা কয়েক সেকেন্ডে resolver manager সেটিং বদলে দেয়? 3টি failure mode শনাক্ত করে ঠিক করুন।

WireGuard টানেল চালু হওয়ার সঙ্গে সঙ্গে DNS কেন কাজ করা বন্ধ করে

WireGuard-এর মাধ্যমে DNS 3ভাবে ব্যর্থ হতে পারে। প্রতিটির সমাধান আলাদা। কোনো নামই resolve হয় না, অথবা নাম resolve হলেও query টানেলের বাইরে থাকা আপনার মেশিন থেকে বেরিয়ে যায়, অথবা interface চালু হওয়ার কয়েক সেকেন্ড পরেই client-এর নিজস্ব resolver manager সেটিংটি প্রতিস্থাপন করে। প্রায় কখনোই টানেলটি সমস্যার কারণ নয়। সমস্যা হলো সেই এক লাইনে, যা client-কে কোন resolver-কে query করতে হবে তা জানায়, এবং সেই routing-এ, যা নির্ধারণ করে ওই resolver-এ packet কীভাবে যাবে।

WireGuard IP packet পরিবহন করে এবং DNS সম্পর্কে কিছু জানে না। DNS হলো domain name system, যা example.com-এর মতো নামকে IP address-এ রূপান্তর করে। Client-এর [Interface] block-এর DNS = line কোনো WireGuard setting নয়। Interface চালু করা shell wrapper wg-quick এই line পড়ে, এবং টানেল চালু থাকা অবস্থায় wg-quick client-এর resolver configuration সম্পাদনা করে। টানেল বন্ধ হলে এটি wg-quick down-এ configuration পুনরুদ্ধার করে। তাই নিচের প্রতিটি সমস্যা হয় 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.1

wg show-এ সাম্প্রতিক latest handshake-সহ peer-টি তালিকাভুক্ত থাকা উচিত, এবং উভয় ping-এর উত্তর পাওয়া উচিত। ping 1.1.1.1 timeout হলে এটি DNS সমস্যা নয়, forwarding বা NAT (network address translation) সমস্যা। কোনো resolver configuration দিয়েই এটি সমাধান হবে না। এখানে প্রতিটি উদাহরণে 10.8.0.0/24-কে টানেলের subnet এবং 10.8.0.1-কে server-এর tunnel address হিসেবে ব্যবহার করা হয়েছে। আপনার নিজস্ব মান বসান।

Failure one: nothing resolves, because the resolver never answers

The symptom is precise. ping 1.1.1.1 works, and curl https://example.com returns this:

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

Ask the tunnel resolver directly from the client. dig comes from the dnsutils package on Ubuntu and Debian.

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

The first command returns an address, which proves packets reach the internet through the tunnel. The second returns nothing and prints ;; communication timed out; no servers could be reached. That is the whole diagnosis: your client is pointed at 10.8.0.1, and 10.8.0.1 is not answering on UDP port 53.

Two causes produce it. Either no resolver is running on the server, or the server firewall drops the query before it arrives. Check both on the server.

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

A resolver that is running and bound correctly shows a line with 10.8.0.1:53 or 0.0.0.0:53. On Ubuntu the surprise is usually 127.0.0.53:53: that is the systemd-resolved stub listener, which binds a loopback address and is deliberately unreachable from other machines. Pointing a VPN client at a server whose only resolver is that stub produces exactly this timeout.

The fix is a resolver that listens on the tunnel address, plus one firewall rule that lets peers reach it.

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'

Then open the port for tunnel traffic only. With nftables, add these two lines to the input chain in /etc/nftables.conf and reload with sudo systemctl reload nftables.

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

With ufw, sudo ufw allow in on wg0 to any port 53 does the same job. Never open port 53 to the public internet. An open recursive resolver is found by scanners within days and used to amplify denial of service attacks, and your provider will notice that traffic before you do.

Re-run dig +short @10.8.0.1 example.com from the client. An address in the output means the resolver path works, so the client now only has to use it. Add the line to the client [Interface] block and restart the interface with 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

দ্বিতীয় ত্রুটি: DNS ফাঁস, কারণ split tunnel resolver-এর ট্র্যাফিক route করে না

এটি আরও গুরুতর, কারণ সবকিছু ঠিকঠাক কাজ করছে বলে মনে হয়। নাম resolve হয়, পৃষ্ঠা load হয়, এবং আপনি যে স্থানীয় নেটওয়ার্ককে বিশ্বাস করতে চাননি, তার মধ্য দিয়ে query-গুলো cleartext অবস্থায় যায়।

দুটি configuration-এর কারণে এটি ঘটে। প্রথমটি হলো এমন একটি client যাতে AllowedIPs = 0.0.0.0/0, ::/0 আছে, কিন্তু DNS = line নেই। wg-quick নিজের routing table-এ default route install করে এবং suppress_prefixlength 0 দিয়ে একটি rule যোগ করে। এর ফলে আরও নির্দিষ্ট local route-গুলো ইচ্ছাকৃতভাবে সক্রিয় থাকে, যাতে machine এখনও তার printer-এ পৌঁছাতে পারে। client DHCP-এর মাধ্যমে যে resolver শিখেছে, সাধারণত 192.168.1.1-এ থাকা router, সেটি ওই local route-গুলোর একটির সঙ্গে মিলে যায়। আপনার traffic tunnel-এর মধ্য দিয়ে যায়। কিন্তু আপনি যে নামগুলো lookup করেন, সেগুলোর সম্পূর্ণ তালিকা স্থানীয় নেটওয়ার্ক এখনও পেয়ে যায়।

দ্বিতীয়টি হলো split tunnel: AllowedIPs = 10.8.0.0/24 এবং DNS = 9.9.9.99.9.9.9, AllowedIPs-এর মধ্যে না থাকায় client-এর কাছে tunnel-এর মধ্য দিয়ে সেখানে যাওয়ার কোনো route নেই। তাই প্রথম case-এর মতো query local link দিয়ে বেরিয়ে যায়।

বাস্তবে কোন resolver উত্তর দিচ্ছে তা প্রমাণ করুন। whoami.akamai.net একটি public test name। এটি query করা recursive resolver-এর IP address দিয়ে উত্তর দেয়। তাই আপনি সেই address-টি আপনার server-এর public address-এর সঙ্গে তুলনা করতে পারেন।

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

resolvectl status প্রতিটি link-এর জন্য একটি করে block দেখায়। আপনার ethernet বা wireless link-এর block-এ যদি এখনও Current DNS Server: 192.168.1.1 দেখা যায়, আর wg0 block-এ কিছু না থাকে, তাহলে সেটিই ফাঁসের প্রমাণ। dig +short whoami.akamai.net যদি আপনার server-এর address-এর পরিবর্তে home broadband address ফেরত দেয়, তাহলে remote end থেকেও বিষয়টি নিশ্চিত হয়। tcpdump line-ই বিতর্কের চূড়ান্ত প্রমাণ: সঠিক output-এ প্রতিটি port 53 packet wg0-এর মধ্য দিয়ে যায়, আর ফাঁস হলে সেগুলো wlan0 বা enp3s0-এর মধ্য দিয়ে যায়।

সমাধানের দুটি অংশ আছে এবং দুটিই প্রয়োজন। DNS এমন একটি address-এ সেট করুন, যা 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/16

10.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। তখন packet-গুলো tunnel-এর মধ্য দিয়ে যায়। তবে আগের session-গুলো থেকে স্থানীয় নেটওয়ার্ক এখনও দেখতে পারে যে আপনি ওই provider বেছে নিয়েছেন। নিজে পরিচালিত resolver ব্যবহার করলে এই সমস্যা এড়ানো যায়।

Resolver assignment হলো নিজে তৈরি করা WireGuard এবং সমন্বিত mesh-এর দৃশ্যমান পার্থক্যগুলোর একটি। এটিই WireGuard এবং Tailscale-এর তুলনা-এর tradeoff-এর অংশ। নিজে পরিচালিত Headscale control server চালালে তৃতীয় পক্ষের কাছে key material না দিয়েও এই coordination পাওয়া যায়।

তৃতীয় ব্যর্থতা: Linux ক্লায়েন্টে resolvconf এবং systemd-resolved-এর মধ্যে বিরোধ

macOS, Windows, iOS এবং Android ক্লায়েন্টগুলো অফিসিয়াল অ্যাপের মাধ্যমে DNS = প্রয়োগ করে এবং সাধারণত খুব কম সমস্যা সৃষ্টি করে। Linux-এ সেটিংটি একটি shell script প্রয়োগ করে, যেটিকে আপনি কয়েকটি resolver manager-এর মধ্যে কোনটি ব্যবহার করছেন তা অনুমান করতে হয়।

প্রথম ব্যর্থতাটি স্পষ্টভাবে দেখা যায়। sudo wg-quick up wg0 এই বার্তাসহ থেমে যায়:

resolvconf: command not found

wg-quick, resolvconf চালু করার চেষ্টা করে, কিন্তু ওই binary ইনস্টল করা নেই। systemd-resolved-এর সঙ্গে কাজ করে এমন implementation ইনস্টল করুন। এরপর 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 দেখায়, কিন্তু lookup এখনও পুরোনো resolver-এ যায়। systemd-resolved প্রতিটি link-এর জন্য আলাদা resolver list রাখে এবং প্রতিটি query-এর জন্য একটি link নির্বাচন করে। কোনো link-কে name-এর default route হিসেবে চিহ্নিত না করা হলে এটি wireless link-এর resolver ব্যবহার করতে থাকে, কারণ ওই link-এ একটি search domain আছে, কিন্তু আপনার link-এ নেই।

একই ধাপে resolver সেট করুন এবং default route দাবি করুন। %i interface-এর নাম হিসেবে প্রসারিত হয়, তাই এই 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 = লাইনটি মুছে দিন। অন্যথায় দুটি mechanism resolver state লিখবে, কিন্তু পরে cleanup করবে মাত্র একটি। ~. argument-টিই গুরুত্বপূর্ণ অংশ। এটি wg0-কে প্রতিটি name-এর routing domain হিসেবে চিহ্নিত করে। ফলে systemd-resolved প্রতিটি query-এর জন্য link নির্বাচন না করে সব query সেখানে পাঠায়। এটি যাচাই করুন।

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 হয়, তাহলে অন্য কোনো উপাদান সেটির নিয়ন্ত্রণে আছে। সাধারণত সেটি NetworkManager অথবা কোনো container runtime। অন্য কিছু debug করার আগে ls -l /etc/resolv.conf চালান, কারণ প্রতিটি network change-এর সময় ওই file পুনর্লিখনকারী কোনো tool আপনার কাজটি সবচেয়ে অসুবিধাজনক মুহূর্তে বাতিল করে দিতে পারে।

টানেলের মাধ্যমে আপনার নিজস্ব ফিল্টারিং resolver আপগ্রেড করা

কোয়েরিগুলো নির্ভরযোগ্যভাবে টানেলের মাধ্যমে যাতায়াত শুরু করলে, দূরের প্রান্তের resolver একটি নিয়ন্ত্রণকেন্দ্র হয়ে ওঠে। সেখানে AdGuard Home চালালে প্রতিটি সংযুক্ত ডিভাইস blocklist filtering এবং query log পায়। এর জন্য client software বা প্রতি ডিভাইসে আলাদা 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-এ শোনে। ওই port সর্বসাধারণের জন্য খোলার বদলে টানেলের মাধ্যমে http://10.8.0.1:3000-এ এটি খুলুন। Wizard-এ DNS listen address এবং admin listen address—দুটিই 10.8.0.1 নির্ধারণ করুন। প্রথম ব্যর্থতার ক্ষেত্রে ব্যবহৃত unbound যদি এখনও একই address-এ চালু থাকে, তাহলে প্রথমে sudo systemctl disable --now unbound দিয়ে সেটি বন্ধ করুন। কারণ একই address-এ দুটি process UDP port 53-এ bind করতে পারে না, এবং দ্বিতীয় process-টি listen udp 10.8.0.1:53: bind: address already in use দিয়ে বন্ধ হয়ে যায়।

Client configuration-এ কোনো পরিবর্তন দরকার নেই, যদি সেগুলোতে ইতিমধ্যে DNS = 10.8.0.1 লেখা থাকে। এখন query log-এ প্রতিটি peer-এর প্রতিটি lookup দেখা যাবে। এটি বিনামূল্যের সুবিধা নয়, বরং গোপনীয়তা-সংক্রান্ত একটি বাস্তব সিদ্ধান্ত। আপনি আপনার internet provider-এর কাছ থেকে trust নিজের কাছে সরিয়ে আনছেন। সেই server-এ security patch প্রয়োগ করার দায়িত্বও আপনার। Internet-এর জন্য উন্মুক্ত server-এ প্রথমে প্রাথমিক নিরাপত্তা ব্যবস্থা কার্যকর থাকতে হবে, এবং নতুন VPS-এ প্রথম দশ মিনিট সেগুলো ব্যাখ্যা করে।

FAQ

আমার WireGuard টানেল সংযুক্ত হয়, কিন্তু নাম রেজলভ হয় না কেন?

টানেল প্যাকেট বহন করে, কিন্তু নাম রেজলভ করে না। তাই টানেল সচল থাকা অবস্থায় লুকআপ ব্যর্থ হলে বুঝতে হবে, আপনি যে resolver নির্ধারণ করেছেন সেটি উত্তর দিচ্ছে না। ক্লায়েন্ট থেকে dig +short @10.8.0.1 example.com দিয়ে পরীক্ষা করুন। communication timed out উত্তর পাওয়া মানে হয় ওই টানেল ঠিকানায় কোনো resolver listen করছে না—সাধারণত systemd-resolved stub শুধু 127.0.0.53-এ bind থাকার কারণে—অথবা server firewall wg0-এ আসা UDP port 53 ব্লক করছে। প্রথমে listener ঠিক করুন। এরপর শুধু wg0-এর জন্য port খুলুন।

WireGuard-এর মাধ্যমে আমার DNS leak করছে কি না কীভাবে পরীক্ষা করব?

ক্লায়েন্টে sudo tcpdump -ni any -c 10 port 53 চালান এবং ব্রাউজ করার সময় interface column পর্যবেক্ষণ করুন। প্রতিটি প্যাকেট wg0-এ থাকা উচিত। যদি সেগুলো wireless বা ethernet interface-এ দেখা যায়, তাহলে query-গুলো cleartext-এ বেরিয়ে যাচ্ছে। dig +short whoami.akamai.net দ্বিতীয়ভাবে যাচাই করে, কারণ এটি যে recursive resolver query করেছে তার public address দিয়ে উত্তর দেয়। তাই উত্তরে আপনার 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 অন্তর্ভুক্ত নয়। তাই DNS line সঠিক দেখালেও query local link দিয়ে বেরিয়ে যায়।

resolvectl সঠিক server দেখালেও lookup অন্যত্র যায় কেন?

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 report হওয়া উচিত।

একাধিক ক্লায়েন্টে সমস্যা হলে প্রথমে কোন ক্লায়েন্ট ঠিক করব?

একটি Linux ক্লায়েন্ট ঠিক করুন, কারণ একমাত্র এই platform-ই আপনাকে প্রক্রিয়াটি সরাসরি দেখায়। resolvectl status এবং tcpdump জানায় কোন resolver উত্তর দিয়েছে এবং কোন interface দিয়ে প্যাকেট গেছে। Phone ও desktop app একই DNS এবং AllowedIPs value প্রয়োগ করে, কিন্তু configuration-এর অভ্যন্তরীণ প্রক্রিয়া দেখায় না। তাই Linux ক্লায়েন্ট সঠিক হলে, ইতিমধ্যে যাচাই করা configuration-ই কপি করতে পারবেন।