WireGuard ধীর কেন: আসল কারণ খুঁজে বের করার উপায়
WireGuard ধীর হলে আগে MTU পরীক্ষা করুন। bisection-এ path MTU খুঁজে TCP MSS clamp, steal time ও path মেপে tunnel-কে অকারণে দোষ দেবেন না।
WireGuard-এর ধীর গতি আসলে কোথা থেকে আসে
WireGuard-এর ধীর গতির কারণ সাধারণত চারটির একটিতে থাকে। তবে চারটি কারণের সম্ভাবনা সমান নয়। প্রথম কারণ হলো MTU (maximum transmission unit)। পথের কোনো একটি link-এর জন্য tunnel এমন packet তৈরি করে যা অতিরিক্ত বড়। ফলে bulk transfer আটকে যায়, কিন্তু ছোট transfer স্বাভাবিক মনে হয়। দ্বিতীয় কারণ হলো path নিজেই। tunnel চালু হওয়ার আগেই path সেটিই সীমা নির্ধারণ করছিল। তৃতীয় কারণ হলো ছোট shared VPS-এর CPU। একই host-এর অন্যান্য guest-এর সঙ্গে encryption-এর কাজ CPU ব্যবহারের জন্য প্রতিযোগিতা করে। চতুর্থ কারণ হলো peer-এর নিজস্ব connection।
এই ক্রমেই কারণগুলো পরীক্ষা করুন। MTU আগে পরীক্ষা করতে হবে, কারণ তালিকার এটিই একমাত্র কারণ যা WireGuard নিজে তৈরি করে। এর উপসর্গও সাধারণ ধীর গতির মতো নয়। ভুল MTU হলে সাধারণত দেখা যায়, tunnel সঙ্গে সঙ্গে connect হয়, ping-এর উত্তর দেয়, SSH login গ্রহণ করে, তারপর প্রথমবার file copy করার সময় freeze হয়ে যায়।
এর আগে একটি উপসর্গ বাদ দেওয়া উচিত। প্রতিটি নতুন site loading শুরু করতে কয়েক সেকেন্ড সময় নেয়, কিন্তু শুরু হওয়ার পর full speed-এ transfer হলে সমস্যাটি throughput নয়, name resolution-এ। WireGuard-এর মাধ্যমে DNS-এর নিজস্ব failure mode রয়েছে। কোনো MTU পরিবর্তন সেগুলো ঠিক করে না।
WireGuard MTU 1420 কেন?
আপনি tunnel-এ পাঠানো প্রতিটি packet encrypted হয় এবং একটি নতুন packet-এর ভিতরে মোড়ানো হয়। এই wrapper কিছু byte ব্যবহার করে, আর সেই byte আপনার payload থেকে কমে যায়।
WireGuard data header-এর আকার 32 byte: একটি 4 byte type field, একটি 4 byte receiver index, একটি 8 byte counter এবং একটি 16 byte Poly1305 authentication tag। এর চারপাশে 8 byte-এর UDP header থাকে। তার চারপাশে থাকে outer IP header, যার আকার IPv4-এর জন্য 20 byte এবং IPv6-এর জন্য 40 byte। তাই আপনার Endpoint যদি IPv4 address হয়, মোট encapsulation হয় 60 byte; আর IPv6 হলে হয় 80 byte। এই সংখ্যাগুলোর ভিত্তি যে message layout, WireGuard protocol page-এ তা নথিভুক্ত আছে।
wg-quick এটি অনুমান করে না। এটি আপনার Endpoint-এ route করা interface-এর MTU পড়ে, তারপর 80 বিয়োগ করে। সাধারণ 1500 byte Ethernet path-এ এর ফল 1420, যা ip link show wg0 দেখায়। এটি 60-এর পরিবর্তে 80 বিয়োগ করে, যাতে endpoint-এ ভবিষ্যতে IPv6-এর মাধ্যমে পৌঁছালেও একই মান নিরাপদ থাকে; IPv6-এ outer header 20 byte বড়।
The data behind this chart
[
{
"label": "Ethernet, IPv4 endpoint",
"path_mtu": 1500,
"encap_overhead": 60,
"usable_wg0_mtu": 1440
},
{
"label": "Ethernet, IPv6 endpoint",
"path_mtu": 1500,
"encap_overhead": 80,
"usable_wg0_mtu": 1420
},
{
"label": "PPPoE DSL, IPv4 endpoint",
"path_mtu": 1492,
"encap_overhead": 60,
"usable_wg0_mtu": 1432
},
{
"label": "Extra tunnel in the path",
"path_mtu": 1400,
"encap_overhead": 80,
"usable_wg0_mtu": 1320
}
]এই 4টি row-এর মান arithmetic থেকে এসেছে, measurement থেকে নয়। পরিষ্কার 1500 byte path এবং IPv4 endpoint থাকলে 1440 ব্যবহারযোগ্য হতো। তাই 1420 default হিসেবে 20 byte অব্যবহৃত রাখে। এই margin ইচ্ছাকৃত এবং এটি আপনার সমস্যার কারণ নয়।
শেষ row-টিই সমস্যার কারণ। Path-এর কোনো link যদি মাত্র 1400 byte বহন করতে পারে, তাহলে 1420 MTU-তে সেট করা tunnel প্রতিটি পূর্ণ আকারের segment-এর জন্য 1500 byte-এর outer packet তৈরি করে। এটি ওই link যতটা গ্রহণ করতে পারে তার চেয়ে 100 byte বেশি। যে মানটি এতে fit করে তা হলো 1320।
1320-ও কপি করবেন না। আপনার path MTU আপনার path-এর বৈশিষ্ট্য, এবং এটি জানার একমাত্র উপায় হলো measurement করা।
ভুল MTU দেখতে কেমন
ব্যর্থতা ধীরে ধীরে ঘটে না। ছোট প্যাকেট এবং বড় প্যাকেটের মধ্যে স্পষ্ট বিভাজন দেখা যায়।
- টানেলের মধ্য দিয়ে
pingযেকোনো স্বাভাবিক আকারে কাজ করে। - SSH login সম্পন্ন হয় এবং টাইপ করার সময় প্রতিক্রিয়া স্বাভাবিক থাকে।
curl -I https://example.comসঙ্গে সঙ্গে header ফেরত দেয়।- বড় page-এ
curl https://example.comপ্রথম কয়েক kilobyte-এর পর আটকে যায়। - বড় file-এর
scpশুরু হয়, তারপর কোনো একটি percentage-এ থেমে যায়। - অনেক output দেখায় এমন command চালানোর সঙ্গে সঙ্গে SSH session স্থির হয়ে যায়।
এটি ঘটে কারণ TCP connection-এর কাছে সরানোর মতো bulk data না থাকা পর্যন্ত সেটি পূর্ণ আকারের segment তৈরি করে না। handshake এবং প্রথম request path-এর প্রতিটি MTU-এর নিচে থাকে। প্রথম পূর্ণ আকারের segment-এ গিয়েই stall শুরু হয়। তাই connection অকার্যকর হওয়ার ঠিক আগ পর্যন্ত স্বাভাবিক মনে হয়।
পরবর্তী link-এর MTU-এর চেয়ে বড় outer packet সাধারণত দুটি পরিণতির একটির মুখোমুখি হয়।
এটি fragmented হয়। একটি router packet-টিকে ভাগ করে এবং দূরের প্রান্তে অংশগুলো পুনরায় জোড়া লাগে। Transfer কাজ করে, তবে ধীর হয়। কারণ একটি packet-এর জন্য এখন দুটি packet পাঠাতে হয় এবং উভয় অংশ না আসা পর্যন্ত receiver-কে state ধরে রাখতে হয়। একটি fragment হারালে সম্পূর্ণ original packet হারায়। তাই 1% loss থাকা path বাস্তবে তার চেয়ে অনেক খারাপ path-এর মতো আচরণ করে। অনেক firewall policy অনুযায়ী IP fragment drop করে। তখন এই পরিণতি পরের পরিণতিতে রূপ নেয়।
এটি drop হয়, এবং আপনাকে জানানো হতে পারে, নাও হতে পারে। যে router packet-টি fragment করবে না, সেটি sender-এর কাছে একটি ICMP (internet control message protocol) "fragmentation needed" message পাঠায় এবং router যে MTU গ্রহণ করতে পারে তা জানায়। এই message পৌঁছালে path MTU discovery কাজ করে এবং sender নিজে থেকেই segment-এর আকার কমিয়ে দেয়। অনেক network ICMP filter করে, তাই message-টি প্রায়ই পৌঁছায় না। Loss-এর কথা জানানোর মতো অন্য কোনো ব্যবস্থা থাকে না। এটিই black hole: packet বেরিয়ে যায়, কিছুই ফিরে আসে না, কোনো প্রান্তের কোনো log-এ error দেখা যায় না, এবং কোনো timeout না হওয়া পর্যন্ত transfer আটকে থাকে।
সঠিক MTU কীভাবে নির্ধারণ করব?
পথটি মাপুন, তারপর encapsulation-এর পরিমাণ বাদ দিন। Tunnel নয়, underlay পরীক্ষা করুন। তাই client থেকে server-এর public address-এ ping পাঠিয়ে fragmentation নিষিদ্ধ করুন।
ping -M do -s 1472 -c 3 203.0.113.10-M do DF (don't fragment) bit সেট করে। তাই পথে কোনো router packet ভাগ করতে পারে না। -s হলো ICMP payload-এর আকার। একটি পূর্ণ IPv4 packet-এর আকার payload-এর সঙ্গে 8 bytes ICMP header এবং 20 bytes IP header যোগ করলে পাওয়া যায়। তাই -s 1472 wire-এ ঠিক 1500 bytes পাঠায়।
তিনটি ফল গুরুত্বপূর্ণ। কোনো error ছাড়া reply এলে 1500 bytes চলবে এবং MTU আপনার সমস্যা নয়। Local error এলে আপনার নিজের interface-ই চাওয়া আকারের চেয়ে ছোট:
ping: local error: message too long, mtu=1500মাঝপথের কোনো router থেকে reply এলে উত্তরটি সরাসরি পেয়ে গেছেন। সেখানেই থামতে পারেন:
From 203.0.113.1 icmp_seq=1 Frag needed and DF set (mtu = 1492)1472-এ 100% packet loss, কিন্তু ছোট আকারে কোনো error ছাড়া reply পাওয়া, black hole পরিস্থিতি নির্দেশ করে। কোনো router আপনাকে তথ্য দিচ্ছে না। তাই আকার অর্ধেক করে সীমা নির্ধারণ করুন। কাজ করে এমন একটি আকার এবং ব্যর্থ হয় এমন একটি আকার ধরে রাখুন। মধ্যবর্তী আকার পরীক্ষা করুন এবং ফল অনুযায়ী সংশ্লিষ্ট সীমা সরান। প্রতিটি ধাপে অবশিষ্ট range অর্ধেক হয়, তাই পাঁচ বা ছয়টি ধাপ যথেষ্ট।
এক ধাপে এক ধাপ করে একটি bisection উদাহরণ
প্রতিটি line হলো client-এ server-এর public address-এর বিরুদ্ধে চালানো একটি command। Comment-এ command-এর ফল লেখা আছে।
ping -M do -s 1472 -c 3 203.0.113.10 # 100% loss, so 1500 is too big
ping -M do -s 1272 -c 3 203.0.113.10 # replies, so 1300 fits
ping -M do -s 1372 -c 3 203.0.113.10 # replies, so 1400 fits
ping -M do -s 1422 -c 3 203.0.113.10 # 100% loss, so 1450 is too big
ping -M do -s 1397 -c 3 203.0.113.10 # 100% loss, so 1425 is too big
ping -M do -s 1384 -c 3 203.0.113.10 # 100% loss, so 1412 is too bigটিকে থাকা সর্বোচ্চ payload হলো 1372। তাই এই path-এ অন্তত 1400 bytes এবং 1412-এর চেয়ে কম বহন করা যায়। নিরাপদ সীমাটি নিন। 1400-এর path MTU থেকে 80 bytes encapsulation বাদ দিলে wg0-এর MTU হয় 1320।
tracepath নিজে একই search চালায়। Bisection শুরু করার আগে একবার এটি চালানো উপকারী:
tracepath -n 203.0.113.10এর শেষ line-এ এটি পাওয়া ফল দেখায়:
Resume: pmtu 1492 hops 12 back 12দুটি tool-কেই প্রাথমিক নির্দেশনা হিসেবে বিবেচনা করুন, চূড়ান্ত প্রমাণ হিসেবে নয়। কিছু host ICMP rate limit করে বা সম্পূর্ণ বাদ দেয়। ফলে bisection প্রকৃত path MTU-এর চেয়ে ছোট MTU দেখাতে পারে। যে transfer ব্যর্থ হচ্ছিল, সেটিই আসল পরীক্ষা।
প্রথমে value-টি live অবস্থায় প্রয়োগ করুন। ভুল অনুমান হলে তা একটি command দিয়েই ফিরিয়ে নেওয়া যাবে:
sudo ip link set mtu 1320 dev wg0যে transfer আটকে ছিল, সেটি আবার চালান। সম্পন্ন হলে client-এর [Interface] block-এ value-টি স্থায়ীভাবে লিখুন:
[Interface]
PrivateKey = <client private key>
Address = 10.8.0.2/32
MTU = 1320sudo wg-quick down wg0 && sudo wg-quick up wg0
ip link show wg0ip link show wg0 এখন mtu 1320 দেখানোর কথা। এখনও পুরোনো value দেখালে wg-quick আপনার সম্পাদনা করা file পড়েনি। আপনি /etc/wireguard/wg0.conf সম্পাদনা করেছেন কি না এবং MTU, [Interface]-এর অধীনে আছে কি না যাচাই করুন। এটি [Peer]-এর অধীনে থাকলে তা উপেক্ষা করা হবে।
MTU একটি interface-এর বৈশিষ্ট্য। এটি peers-এর মধ্যে negotiate হয় না। Client-এ সেট করলে শুধু client-এর পাঠানো packet ছোট হয়। Server নিজের wg0 MTU অনুযায়ী packet তৈরি করতে থাকে। তাই upload কাজ শুরু করার পরও download black hole হতে পারে। দুই প্রান্তেই value সেট করুন, অথবা server-এ MSS clamp করুন।
MSS clamping কেন শুধু TCP ঠিক করে, অন্য কিছু নয়
সার্ভারটি যদি তার peer-গুলোর জন্য traffic forward করে, যেমন NAT (network address translation) ব্যবহার করা যেকোনো standard WireGuard VPS setup-এ হয়, তাহলে একটি rule-ই সব peer-এর TCP ঠিক করে দেয়। যেসব client আপনার নিয়ন্ত্রণে নেই, সেগুলোতে আলাদা আলাদা value খুঁজে বেড়াতে হয় না।
MSS (maximum segment size) হলো একটি TCP option। প্রতিটি পক্ষ তার SYN packet-এ এটি পাঠিয়ে জানায়, সর্বোচ্চ কত বড় segment সে গ্রহণ করতে পারবে। Clamping চলমান packet-এর ওই option rewrite করে প্রকৃত route MTU-এর সঙ্গে মিলিয়ে দেয়। ফলে data চলাচল শুরু হওয়ার আগেই উভয় প্রান্ত ছোট segment ব্যবহারে একমত হয়। এটি কাজ করে, কারণ handshake-এর সময়ই পরিবর্তনটি করা হয়। এটি এমন কোনো ICMP message-এর ওপরও নির্ভর করে না, যা path সম্ভবত filter করছে।
nftables ব্যবহার করলে বিদ্যমান table-গুলোর নিচে /etc/nftables.conf-এ এই table যোগ করুন:
table inet mangle {
chain forward {
type filter hook forward priority mangle; policy accept;
tcp flags syn tcp option maxseg size set rt mtu
}
}sudo systemctl reload nftables দিয়ে reload করুন। iptables ব্যবহার করা server-এ এর সমতুল্য হলো একটি line:
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtuনিশ্চিত করুন, packet যে path দিয়ে যায় rule-টি সেই path-এ আছে। কোনো client নতুন connection খুললে sudo nft list table inet mangle অথবা sudo iptables -t mangle -L FORWARD -n -v চালান এবং counter বাড়ছে কি না দেখুন। counter 0-তেই থাকলে packet ওই hook-এর মধ্য দিয়ে যাচ্ছে না। তাই rule-টি কোনো কাজ করছে না।
এখন সীমাবদ্ধতাগুলো স্পষ্টভাবে জানা দরকার। Clamping শুধু TCP-কে প্রভাবিত করে, অন্য কিছু নয়। এটি শুধু forwarded traffic-এ প্রযোজ্য। তাই WireGuard server-এ নিজেই চলা কোনো service forward hook অতিক্রম করে না এবং clamped হয় না। Rule load হওয়ার পর খোলা connection-গুলোর ওপরও এটি প্রযোজ্য। Existing session-গুলো আগে যে MSS-এ একমত হয়েছিল, সেটিই রেখে দেয়।
UDP অপরিবর্তিত থাকে, কারণ rewrite করার মতো UDP-তে কোনো handshake নেই। তবু অধিকাংশ UDP traffic ঠিকমতো চলতে পারে। HTTP/3-এর নিচের transport QUIC নিজেই ব্যবহারযোগ্য packet size পরীক্ষা করে এবং ইচ্ছাকৃতভাবে ছোট packet দিয়ে শুরু করে। যে UDP traffic ঠিকমতো চলে না, তা হলো এমন traffic যা একটি বড় datagram পাঠিয়ে সেটি সম্পূর্ণভাবে পৌঁছাবে বলে ধরে নেয়। যেমন, 1400 byte-এর বেশি আকারের DNSSEC (DNS security extensions) answer। এসব query timeout হয় এবং TCP-এর মাধ্যমে retry করে। ব্যবহারকারীর কাছে এটি site নষ্ট হিসেবে নয়, বরং ধীর site হিসেবে দেখা যায়।
আমার VPS-এর CPU কি সীমা তৈরি করছে?
WireGuard ChaCha20-Poly1305 দিয়ে encryption করে এবং Curve25519 দিয়ে key বিনিময় করে। Data path-এ কোথাও AES নেই। এর একটি গুরুত্বপূর্ণ ফল আছে, যা অনেকে ভুল বোঝেন: আপনার CPU-এর AES-NI instruction WireGuard-এর কাজে আসে না। কোনো host-এ AES-NI আছে বলেই WireGuard-এর performance সুবিধা পাওয়া যাবে না। ChaCha20 বেছে নেওয়া হয়েছে, কারণ এটি সাধারণ software-এও দ্রুত কাজ করে, এমন CPU-তেও যেগুলোতে কোনো crypto acceleration নেই।
তাই বলে WireGuard-এর CPU cost নেই, এমন নয়। 1 vCPU VPS-এ একটি core-কে encryption এবং network interrupt—দুটিই সামলাতে হয়। এর সঙ্গে আপনার application-এর কাজও চলতে থাকে।
কোনো transfer চলার সময় এটি মাপুন:
sudo apt install -y sysstat
mpstat -P ALL 1তিনটি column দেখুন। %soft হলো softirq time; kernel-এর packet processing এখানে গণনা হয়। %steal হলো hypervisor অন্য কাজে যে সময় দিয়েছে। %idle হলো অবশিষ্ট সময়।
আপনার একমাত্র core-এ %soft প্রায় 100 হলে server তার packet processing ceiling-এ পৌঁছেছে। এটি একটি বাস্তব সীমা, এবং আরও core দিলে এই সীমা বাড়বে। একই সময়ে process list-এর শীর্ষে ksoftirqd/0-কে top দেখালে, ভিন্ন দৃষ্টিকোণ থেকে একই বিষয় বোঝা যায়।
%steal কয়েক শতাংশের বেশি হলে সীমাটি আপনি নিজে সমাধান করতে পারবেন না। কারণ host oversubscribed, তাই আপনার vCPU একটি physical core-এর জন্য অপেক্ষা করছে। সবচেয়ে সস্তা shared plan-এ এটি সাধারণ, এবং দিনের বিভিন্ন সময়ে এর মাত্রা পরিবর্তিত হয়। noisy neighbour-এর steal time আলাদাভাবে পরীক্ষা করতে হবে; কোনো MTU value এতে সাহায্য করবে না।
আরেকটি বিষয় হলো client কোন implementation চালাচ্ছে। Linux kernel module হলো দ্রুততম path, এবং এটি একটি peer-এর encryption একাধিক core-এ ভাগ করে দেয়। wireguard-go, অর্থাৎ userspace implementation, ধীর। macOS ও iOS client এটি ব্যবহার করে, কারণ ওই platform-গুলো কোনো app-কে kernel module load করতে দেয় না।
এটি কি পথের সমস্যা, নাকি peer-এর নিজস্ব link?
কোনো কিছু tuning করার আগে একই client থেকে কয়েক মিনিটের ব্যবধানে দুটি সংখ্যা নিন: tunnel ছাড়া throughput এবং tunnel-সহ throughput। এই জোড়া সংখ্যা না থাকলে আপনি অনুমান করছেন।
Server-এ iperf3 -s চালান। Direct test-এর জন্য public address-এ TCP 5201 reachable থাকতে হবে। তাই পরীক্ষার সময় port-টি খুলুন এবং পরে rule সরিয়ে দিন। ধরে না নিয়ে port আবার বন্ধ আছে কি না নিশ্চিত করুন।
# on the client, outside the tunnel
iperf3 -c 203.0.113.10
# then through the tunnel
iperf3 -c 10.8.0.1দুটি সংখ্যা কাছাকাছি হলে WireGuard খুব কম overhead যোগ করছে এবং সীমাবদ্ধতা path-এ। %soft কম থাকা অবস্থায় tunnel-এর সংখ্যা direct সংখ্যার তুলনায় অনেক কম হলে আবার MTU পরীক্ষা করুন। Fragmentation throughput কমায়, কিন্তু কোনো কিছু সম্পূর্ণ ব্যর্থ করে না। তাই এখানে এটি hang হিসেবে নয়, শতাংশের ক্ষতি হিসেবে দেখা যায়।
উভয় direction পরীক্ষা করুন, কারণ home connection সাধারণত asymmetric হয়। iperf3 -c 10.8.0.1 -R flow-এর direction উল্টে দেয়, ফলে server data পাঠায়। 500/20 line-এর client tunnel-এর মাধ্যমে 20 Mbit-এর বেশি upload করতে পারবে না। Server-side কোনো পরিবর্তন এটি বদলাতে পারে না।
এরপর parallel stream দিয়ে পরীক্ষা করুন:
iperf3 -c 10.8.0.1 -P 4চারটি stream একসঙ্গে একটি stream-এর তুলনায় অনেক বেশি data পাঠাতে পারলে একটি TCP connection path-টি পূর্ণ করতে পারছে না। একটি stream-এর throughput receive window-কে round trip time দিয়ে ভাগ করলে যত হয়, তার দ্বারা সীমাবদ্ধ থাকে। তাই 150 ms path-এ বেশি data বহনের জন্য বড় window দরকার। আপনার নিজের limit দেখুন:
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmemপ্রতিটির তৃতীয় value হলো Linux autotune করে যে সর্বোচ্চ মানে নিতে পারে। Packet loss একটি stream-এর throughput-ও কঠোরভাবে সীমিত করে, কারণ TCP congestion control loss-এর প্রতিক্রিয়া জানায়। দীর্ঘ path-এ recovery ব্যয়বহুল হয়। কোথায় loss দেখা দিচ্ছে তা জানতে client থেকে একশো cycle-এর জন্য mtr -rwc 100 203.0.113.10 চালান। একটি hop-এ শুরু হয়ে final hop পর্যন্ত চলতে থাকা loss বাস্তব। কোনো মাঝের hop-এ দেখা loss পরে অদৃশ্য হলে সেই router ICMP-কে কম priority দিচ্ছে; এর কোনো অর্থ নেই।
Network থেকে আলাদা করে server-এর একটি পুনরাবৃত্তিযোগ্য চিত্র পেতে নথিবদ্ধ পদ্ধতিতে VPS benchmark করুন। এতে কোনো পরিবর্তনের পরে একই test আবার চালিয়ে একই ভিত্তিতে তুলনা করতে পারবেন।
WireGuard যা সমাধান করতে পারে না
WireGuard একটি tunnel। এটি যে path ব্যবহার করে, সেই path-এর সবচেয়ে ধীর link-এর চেয়ে দ্রুত হতে পারে না। উপরন্তু, এটি যোগ করলে path সব সময় সামান্য ধীর হয়।
এটি compression করে না। OpenVPN-এর comp-lzo-এর সমতুল্য কোনো feature নেই এবং এমন feature তৈরির কোনো পরিকল্পনাও নেই, কারণ encryption-এর আগে compression করলে plaintext সম্পর্কে তথ্য ফাঁস হতে পারে। অধিকাংশ bulk data আগে থেকেই compressed থাকে, তাই বাস্তবে এতে আপনার কোনো ক্ষতি হয় না। WireGuard ও OpenVPN-এর তুলনা করার সময় বিবেচনা করার মতো এটি একটি বাস্তব পার্থক্য। এটি ইচ্ছাকৃত design choice।
একটি full tunnel প্রতিটি packet যে route দিয়ে যায়, তা পরিবর্তন করে। আগে আপনার কাছ থেকে কাছের CDN (content delivery network)-এ যে traffic যেত, এখন তা আপনার কাছ থেকে VPS-এ এবং সেখান থেকে CDN-এ যায়। VPS অন্য মহাদেশে থাকলে প্রতিটি request-কে এই অতিরিক্ত ঘুরপথ পেরোতে হয় এবং round trip time সেই অনুযায়ী বেড়ে যায়। কোনো config value এটি কমাতে পারে না। VPS কাছাকাছি সরান, অথবা split tunnel ব্যবহার করুন, যাতে শুধু VPN প্রয়োজন এমন traffic-ই দীর্ঘ route দিয়ে যায়। কোন traffic কোন পথে যাবে, তা সম্পূর্ণভাবে AllowedIPs নির্ধারণ করে, এবং cryptokey routing কীভাবে এই সিদ্ধান্ত নেয় তা ব্যাখ্যা করে।
Provider-এর limit tunnel-এর বাইরে থাকে এবং এগুলো সহজেই ভুলে যাওয়া যায়। মাসিক bandwidth allowance থাকা কোনো plan-এ allowance শেষ হয়ে গেলে port-এর speed প্রায়ই অনেক কমিয়ে দেওয়া হয়। তখন tunnel নষ্ট হয়েছে বলে মনে হয়। MTU নিয়ে একটি সন্ধ্যা ব্যয় করার আগে provider panel পরীক্ষা করুন।
PersistentKeepalive throughput-এ কোনো প্রভাব ফেলে না। এটি একটি NAT mapping খোলা রাখে, যাতে home router-এর পেছনে থাকা client-এ server এখনও পৌঁছাতে পারে। এটিকে 25 seconds-এর নিচে কমালে অতিরিক্ত packet পাঠানো হয়, কিন্তু কোনো সমস্যার সমাধান হয় না।
এই ক্রমে পরিমাপ করুন
- সমস্যাটি পুনরুৎপাদন করুন এবং এটি সম্পূর্ণ থেমে যাওয়া নাকি সমানভাবে ধীর হয়ে যাওয়া, তা নোট করুন। সম্পূর্ণ থেমে যাওয়া MTU-এর দিকে ইঙ্গিত করে। সমানভাবে ধীর হয়ে যাওয়া তা করে না।
- ক্লায়েন্ট থেকে সার্ভারের public address-এ
ping -M doব্যবহার করে ধাপে ধাপে পরীক্ষা করুন এবং path MTU লিখে রাখুন। - 80 বাদ দিন, উভয় প্রান্তের wg0-এ সেই MTU সেট করুন, তারপর যে transfer ব্যর্থ হচ্ছিল তা আবার পরীক্ষা করুন।
- সার্ভার peers-এর traffic forward করলে সেখানে MSS clamping যোগ করুন।
- একটি transfer চলাকালে
mpstat -P ALL 1চালান এবং%softও%steal-এর মান দেখুন। - tunnel-এর বাইরে এবং ভেতরে, উভয় দিকেই, single stream এবং
-P 4সহiperf3চালান। - সার্ভারে
mtr -rwc 100চালান এবং শেষ hop পর্যন্ত স্থায়ী loss আছে কি না দেখুন।
ধাপ 5-এ CPU-ই সীমা বলে নিশ্চিত হওয়ার পরেই server plan পরিবর্তন করুন। ধাপ 1 থেকে 4-এর কোনো খরচ নেই এবং ধীর tunnel-সংক্রান্ত অধিকাংশ রিপোর্টের সমাধান করে।
FAQ
আমার WireGuard tunnel-এ ping দ্রুত হলেও download ধীর কেন?
এই পার্থক্যটি MTU সমস্যার লক্ষণ। ছোট packet path-এর প্রতিটি link-এর সীমার মধ্যে থাকে, তাই ping এবং SSH login কাজ করে। Bulk transfer-এ পূর্ণ আকারের segment পাঠানো হয়। Encapsulation-এর পরে সেগুলো কোনো কোনো link গ্রহণ করতে পারে এমন আকারের চেয়ে বড় হয়ে যায়। সেই router যদি ICMP message ফেরত না পাঠিয়ে packet drop করে, তাহলে ক্ষতি শনাক্ত হয় না এবং transfer আটকে থাকে। server-এর public address-এ ping -M do bisection ব্যবহার করে path MTU নির্ধারণ করুন। Encapsulation-এর জন্য 80 bytes বাদ দিন। দুই প্রান্তেই ফলাফলটি wg0 MTU হিসেবে সেট করুন।
WireGuard-এর জন্য কোন MTU সেট করা উচিত?
সবার জন্য প্রযোজ্য কোনো একক মান নেই। এ কারণেই 1420 default কিছু ব্যবহারকারীর ক্ষেত্রে কাজ করে না। 1420 হলো 1500 থেকে WireGuard header, UDP header এবং বাইরের IPv6 header-এর 80 bytes বাদ দেওয়ার ফল। আপনার path-এ 1500-এর কম bytes বহন হলে, যা PPPoE DSL-এ এবং traffic অন্য কোনো tunnel অতিক্রম করলে স্বাভাবিক, আপনাকে আরও ছোট মান ব্যবহার করতে হবে। আগে path MTU মাপুন। তারপর সেখান থেকে 80 বাদ দিন।
MSS clamping কি MTU সেট করার বিকল্প?
না। TCP handshake-এ MSS option পরিবর্তন করে clamping, যাতে দুই প্রান্ত ছোট segment পাঠায়। এতে interface পরিবর্তন না করেই TCP সমস্যা সমাধান হয়। UDP-তে পরিবর্তন করার মতো handshake নেই, তাই এটি প্রভাবিত হয় না। Clamping শুধু server যে traffic forward করে তাতে প্রযোজ্য। তাই WireGuard server-এ নিজেই চলা service এতে সুবিধা পায় না। দুটিই ব্যবহার করুন: interface-এ সঠিক MTU এবং যেসব peer-এর configuration আপনার নিয়ন্ত্রণে নেই, তাদের জন্য clamping।
দ্রুততর VPS plan কি WireGuard-কে দ্রুত করবে?
শুধু CPU সীমাবদ্ধতা হলে করবে। একটি command দিয়েই তা জানা যায়। Transfer চলার সময় mpstat -P ALL 1 চালান। আপনার একমাত্র core-এ %soft প্রায় 100 হলে packet processing-ই সীমা তৈরি করছে। আরও core থাকলে গতি বাড়বে। %steal বেশি হলে host oversubscribed, তাই অন্য plan বা অন্য host ব্যবহার করতে হবে। Tunnel ধীর থাকা অবস্থায় উভয় সংখ্যা কম হলে CPU idle আছে এবং বড় plan-এ কোনো পরিবর্তন হবে না।
একই network-এ আমার Mac Linux client-এর চেয়ে ধীর কেন?
Linux client in-kernel WireGuard module ব্যবহার করে। এটি kernel space-এ packet process করে এবং একটি peer-এর encryption একাধিক CPU core-এ ভাগ করে। macOS এবং iOS app-গুলো wireguard-go ব্যবহার করে। কারণ এই platform-গুলো কোনো app-কে kernel module load করতে দেয় না। Userspace প্রতিটি packet kernel এবং application-এর মধ্যে copy করে। এই copying throughput কমায়। এই পার্থক্য প্রত্যাশিত, এবং কোনো client setting দিয়ে এটি দূর করা যায় না।