Headscale ব্যবহার করে নিজস্ব Tailscale সার্ভার সেটআপ
আপনার নিজস্ব VPS-এ Headscale ইনস্টল করার নিয়ম জানুন। অফিসিয়াল .deb ফাইল ব্যবহার করে server_url কনফিগার করুন এবং প্রথম নোড যুক্ত করার সঠিক কমান্ডগুলো এই গাইডে দেখুন।
headscale কী
headscale হলো Tailscale control server-এর self-hosted implementation। তাই আপনার private network সমন্বয়কারী মেশিনটি আপনার মালিকানাধীন একটি VPS। এটি একটি community project এবং Tailscale Inc. এটি পরিচালনা করে না। প্রতিটি মেশিনে এখনও official tailscale client চলে। একটি flag, --login-server ব্যবহার করে client-টিকে আপনার server-এ নির্দেশ করা হয়।
Control server জানে কারা network-এর অংশ। এটি 100.64.0.0/10 থেকে প্রতিটি node-কে একটি address দেয়, public key বিতরণ করে এবং node-গুলোকে একে অপরকে খুঁজে পেতে নির্দেশ দেয়। Tunnel-গুলো WireGuard-ই থাকে এবং node থেকে node-এ তৈরি হয়। আপনার দুটি মেশিনের মধ্যে traffic headscale box-এর মধ্য দিয়ে যায় না, যদি না সরাসরি path তৈরি করা সম্ভব না হয় এবং node-গুলো relay ব্যবহার করতে বাধ্য হয়। এই coordination role নিজে চালালে এটি কে পরিচালনা করে তা বদলে যায়, কিন্তু এটি কী করতে পারে তা বদলায় না। তাই এই পরিবর্তনকে নিজে থেকেই security improvement ধরে নেওয়ার আগে এই model-এ control server কোন কোন জায়গায় পৌঁছাতে পারে এবং পারে না তা বোঝা দরকার।
Headscale প্রতি instance-এ একটি tailnet (একটি Tailscale network) পরিচালনা করে। প্রকল্পটির বর্ণনা অনুযায়ী, এটি ব্যক্তিগত ব্যবহার বা ছোট প্রতিষ্ঠানের জন্য উপযোগী। তিন বা চারটি মেশিন থাকলে, আপনার মালিকানাধীন একটি VPS-এ সাধারণ WireGuard VPN চালানোতে কম software পরিচালনা করতে হয় এবং নষ্ট হওয়ার সম্ভাবনাও কম। প্রতিটি নতুন laptop-এর জন্য হাতে একটি [Peer] block লিখতে না চাইলে Headscale বেশি কার্যকর হয়। শুরুতে খরচের কারণেই অনেকে খোঁজ শুরু করেন। তাই server নেওয়ার আগে hosted free plan-এ আসলে কী অন্তর্ভুক্ত আছে পড়ে দেখা ভালো, কারণ কয়েকটি ব্যক্তিগত মেশিন সাধারণত এর সীমার মধ্যেই থাকে। আপনি যদি ইতিমধ্যে সেই সীমা অতিক্রম করে থাকেন, তাহলে প্রতি user এবং প্রতি tagged resource-এর জন্য paid plan-এর খরচ কত তার সঙ্গে মোট খরচ তুলনা করুন। user device-এর সংখ্যা সীমাহীন হলেও tagged resource-এর জন্য আলাদা allowance এবং charge রয়েছে। আপনি যদি self-hosted control plane চান, কিন্তু Tailscale-এর drop-in replacement-এর বদলে peer পরিচালনার জন্য নিজের client এবং web interface পছন্দ করেন, তাহলে একটি VPS-এ NetBird বিবেচনা করার মতো বিকল্প। উভয়ই WireGuard-এর মাধ্যমে আপনার traffic পাঠায়। তাই সিদ্ধান্ত নির্ভর করে আপনি কীভাবে access rule লিখবেন এবং relay কীভাবে কাজ করবে তার ওপর। কোনোটি install করার আগে এই বিষয়গুলোতে NetBird এবং Tailscale-এর তুলনা করে দেখা ভালো। দুটি model-এর বিস্তৃত তুলনার জন্য WireGuard এবং Tailscale-এর পার্থক্য দেখুন।
ইনস্টল করার আগে যা প্রয়োজন
- public IPv4 address এবং sudo access-সহ Ubuntu 24.04 চালিত একটি VPS। সার্ভারটি নতুন হলে আগে নতুন VPS-এ প্রথম দশ মিনিট নির্দেশিকাটি অনুসরণ করুন।
- ওই address-এ নির্দেশ করা একটি DNS A record। এই নির্দেশিকায়
headscale.example.comব্যবহার করা হয়েছে। - MagicDNS-এর জন্য একটি দ্বিতীয় domain বা subdomain। এই নির্দেশিকায়
tailnet.example.netব্যবহার করা হয়েছে। এটিserver_url-এ থাকা domain-এর মতো একই হতে পারবে না। - যোগ দেওয়ার জন্য Linux, macOS, Windows, Android বা iOS চালিত একটি client machine। Headscale 0.29.6-এর জন্য Tailscale client version 1.80.0 বা তার পরের সংস্করণ প্রয়োজন।
অফিসিয়াল .deb থেকে headscale ইনস্টল করুন
প্রকল্পটি GitHub releases page-এ .deb package প্রকাশ করে। October 27, 2026 অনুযায়ী সর্বশেষ stable release হলো 0.29.6, যা October 24, 2026-এ প্রকাশিত হয়েছে। প্রথমে আপনার architecture পরীক্ষা করুন, কারণ file name-এ architecture উল্লেখ থাকে।
sudo apt update
sudo apt install -y wget
dpkg --print-architectureসাধারণ x86 VPS-এ এটি amd64 এবং Ampere বা Graviton ধরনের plan-এ arm64 দেখায়। নিচের variable-এ উত্তরটি রাখুন।
HEADSCALE_VERSION="0.29.6"
HEADSCALE_ARCH="amd64"
wget --output-document=headscale.deb \\
"https://github.com/juanfont/headscale/releases/download/v${HEADSCALE_VERSION}/headscale_${HEADSCALE_VERSION}_linux_${HEADSCALE_ARCH}.deb"
sudo apt install -y ./headscale.deb
headscale versionFile name-এর আগে ./ দেওয়া আবশ্যক। এটি না দিলে apt আপনার repository-তে headscale.deb নামের package খোঁজে এবং ব্যর্থ হয়।
Package একটি headscale system user তৈরি করে, একটি default /etc/headscale/config.yaml লেখে, একটি systemd unit ইনস্টল করে এবং তারপর service চালু করে। তাই apt শেষ হলে headscale ইতিমধ্যে চলমান থাকে এবং sudo systemctl is-active headscale active দেখায়। তবে fresh install-এ package unit-টি enable করে না। তাই reboot-এর পরে service নিজে থেকে চালু হবে না, যতক্ষণ না আপনি এটি enable করেন। নিচের restart ধাপটি সেটি করে। Service-টি shipped configuration ব্যবহার করেও চলছে, এবং সেই configuration server_url-কে http://127.0.0.1:8080-এ নির্দেশ করে। এটি এমন কোনো address নয়, যেখানে আপনার কোনো client পৌঁছাতে পারে। এখনও কিছু exposed হয়নি, কারণ shipped listen_addr-ও loopback-এ রয়েছে। তবে server_url সেট করে service restart না করা পর্যন্ত কোনো client join করাবেন না। পরের দুটি ধাপ এটি করে।
কোনো client যুক্ত হওয়ার আগে server_url কনফিগার করুন
/etc/headscale/config.yaml-এ sudo nano /etc/headscale/config.yaml দিয়ে সম্পাদনা করুন, অথবা sed দিয়ে একই তিনটি পরিবর্তন প্রয়োগ করুন। মূল ফাইলটির একটি অনুলিপি সংরক্ষণ করুন, কারণ ফাইলটি দীর্ঘ এবং এতে অনেক মন্তব্য রয়েছে। বাকি settings-এর জন্য এটিই আপনার সবচেয়ে ভালো reference।
sudo cp /etc/headscale/config.yaml /etc/headscale/config.yaml.orig
sudo sed -i 's|^server_url:.*|server_url: https://headscale.example.com|' /etc/headscale/config.yaml
sudo sed -i 's|^listen_addr:.*|listen_addr: 127.0.0.1:8080|' /etc/headscale/config.yaml
sudo sed -i 's|^ base_domain:.*| base_domain: tailnet.example.net|' /etc/headscale/config.yaml
sudo grep -E '^(server_url|listen_addr):|^ base_domain:' /etc/headscale/config.yamlserver_url হলো public address, যেটি headscale registration URL তৈরি করার সময় ব্যবহার করে। Client-রা --login-server দিয়ে কনফিগার করা control address ব্যবহার করে। তাই উভয় জায়গায় https://-সহ একই public name ব্যবহার করুন; কখনো 127.0.0.1 ব্যবহার করবেন না। Headscale-এর documentation অনুযায়ী plain HTTP ব্যবহার করা যায়, অথবা 443 ছাড়া অন্য port-এ HTTPS-ও ব্যবহার করা যায়। তবে production-এর জন্য এটি port 443-এ HTTPS ব্যবহারের জোরালো পরামর্শ দেয়। এই guide-এর বাকি অংশও সেই configuration ধরে লেখা।
listen_addr নির্ধারণ করে process কোন address-এ bind করবে। এটিকে loopback-এ রাখুন। একই server-এ থাকা একটি reverse proxy TLS (transport layer security) termination করে এবং অনুরোধ সেখানে forward করে। তাই server-এর বাইরের কোনো কিছুই port 8080-এ পৌঁছানোর প্রয়োজন নেই।
base_domain হলো MagicDNS suffix; আপনার node-গুলো যে domain-এর অধীনে name পাবে, এটি সেই domain। এটি trailing dot ছাড়া একটি fully qualified domain name হতে হবে। এছাড়া server_url-এ ব্যবহৃত domain থেকে এটি আলাদা হতে হবে, কারণ তা না হলে দুটি name space পরস্পরের সঙ্গে সংঘর্ষে জড়াবে।
Database section অপরিবর্তিত রাখুন। Default হিসেবে /var/lib/headscale/db.sqlite-এ SQLite ব্যবহার করা হয়। এটি package তৈরি করে মালিকানাধীন একটি directory-তে থাকে, এবং এই আকারের tailnet-এর জন্য SQLite যথেষ্ট।
headscale পুনরায় চালু করুন এবং এটি চলছে তা নিশ্চিত করুন
sudo systemctl restart headscale
sudo systemctl enable headscale
sudo systemctl is-active headscale
sudo systemctl is-enabled headscale
curl -sS -o /dev/null -w '%{http_code}\\n' http://127.0.0.1:8080/healthis-active active প্রদর্শন করে, is-enabled enabled প্রদর্শন করে, এবং curl 200 প্রদর্শন করে। আপনার সম্পাদনাগুলো কার্যকর করার ধাপ হলো restart। headscale চালু হওয়ার সময় একবার configuration পড়ে। তাই package যে process চালু করেছে, সেটি restart না করা পর্যন্ত shipped server_url ব্যবহার করতে থাকে। sudo systemctl enable --now headscale এই কাজ করে না: service ইতিমধ্যে চলছে, তাই --now start কোনো পরিবর্তন করে না এবং পুরোনো মানই কার্যকর থাকে। Boot-এর সময় start করার কাজ enable-এর, এবং এটি স্বয়ংক্রিয়ভাবে করা হয় না: নতুন install-এ package service-টি চালু করে, কিন্তু enable করে না। তাই উপরে দেখানো মতো একবার sudo systemctl enable headscale চালান।
is-active যদি active ছাড়া অন্য কিছু প্রদর্শন করে, অথবা curl 200 প্রদর্শন না করে, তাহলে sudo journalctl -u headscale -n 50 --no-pager দিয়ে journal পড়ুন। এই পর্যায়ে ব্যর্থতার কারণ প্রায় সব সময় configuration file, কারণ headscale socket খোলার আগে পুরো file parse করে। ফলে ভুল indentation বা প্রয়োজনীয় কোনো invalid setting থাকলে process কোনো কিছু listen করার আগেই বন্ধ হয়ে যায়। file ঠিক করুন, তারপর sudo systemctl restart headscale চালান। পরবর্তী প্রতিটি configuration পরিবর্তনের পর একইভাবে restart করতে হবে। এরপর client-গুলো নিজে থেকেই reconnect করবে। systemd unit আপনার জন্য নতুন হলে, systemd দিয়ে নিজের service ও timer চালানো এখানে ব্যবহৃত command-গুলো ব্যাখ্যা করে।
Shell-এ থাকা অবস্থায় state file-গুলো পরীক্ষা করুন:
stat -c '%U %n' /var/lib/headscale/db.sqlite /var/lib/headscale/noise_private.keyউভয় line-ই headscale দিয়ে শুরু হয়, যা package তৈরি করা unprivileged user। noise_private.key হলো client-দের কাছে server-এর identity। এটি রেখে দিন। এটি মুছে ফেললে headscale নতুন একটি identity তৈরি করবে, এবং reconnect করার আগে client-গুলোকে নতুন server key সংগ্রহ করতে হবে; বিদ্যমান registration database-এ থেকে যাবে।
headscale-এর সামনে TLS দিন
ক্লায়েন্টদের HTTPS ব্যবহার করে server_url-এ পৌঁছানো উচিত। Caddy ব্যবহার করাই সবচেয়ে সংক্ষিপ্ত পথ, কারণ এটি নিজেই certificate চায় এবং renew করে।
sudo apt install -y caddy/etc/caddy/Caddyfile-এর জায়গায় headscale documentation-এর block বসান:
headscale.example.com {
reverse_proxy 127.0.0.1:8080 {
header_up True-Client-IP {remote_host}
header_up X-Real-IP {remote_host}
}
}sudo caddy validate --adapter caddyfile --config /etc/caddy/Caddyfile
sudo systemctl restart caddy
sudo systemctl is-active caddyফাইলটি parse হলে validate, adapted config to JSON দেখায়। ফাইলটি formatted নয়—এমন warning কেবল cosmetic। আপনার laptop থেকে curl -sS -o /dev/null -w '%{http_code}\\n' https://headscale.example.com/health চালালেও 200 দেখানো উচিত। এই একটিমাত্র পরীক্ষা প্রমাণ করে যে DNS, firewall, certificate এবং proxy একসঙ্গে সঠিকভাবে কাজ করছে।
এখানে proxy-সংক্রান্ত একটি বিষয় আছে, যা অনেকের একটি সন্ধ্যা নষ্ট করে। Tailscale control connection একটি HTTP upgrade। এটি GET-এর পরিবর্তে POST দিয়ে শুরু হয়, এবং Upgrade header-এর value হলো tailscale-control-protocol। Caddy কোনো অতিরিক্ত configuration ছাড়াই এটি pass through করে। nginx তা করে না। তাই nginx front end-কে Upgrade এবং Connection header স্পষ্টভাবে forward করতে হয়। headscale documentation এটি একটি upgrade map দিয়ে করে:
map $http_upgrade $connection_upgrade {
default keep-alive;
'' close;
}
server {
listen 443 ssl;
server_name headscale.example.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
proxy_pass http://127.0.0.1:8080;
}
}এই lines বাদ দিলে সাধারণ request সফল হয়। তাই /health 200 ফেরত দেয় এবং সবকিছু ঠিক মনে হয়। কিন্তু control connection তৈরি হয় না। নতুন node register করতে পারে না, আর বিদ্যমান node reconnect করে online status report করতে পারে না। nginx ব্যবহার করলে certificate-এর অংশটি Ubuntu 24.04-এ nginx সহ Certbot-এ দেখুন।
UFW-তে কোন port খুলতে হবে
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbosePort 443 প্রতিটি client-এর headscale-এর সঙ্গে control connection বহন করে। পরে embedded DERP relay চালু করলে 3478/udp-ও প্রয়োজন হবে; এটি নিচে ব্যাখ্যা করা হয়েছে। Port 80 ACME (automatic certificate management environment) HTTP challenge এবং HTTPS-এ redirect-এর জন্য ব্যবহৃত হয়। Port 80 বন্ধ থাকলেও Caddy certificate সংগ্রহ করতে পারে, কারণ এটি port 443-এ TLS-ALPN challenge ব্যবহার করতে পারে। তবে 80 খোলা থাকলে উভয় challenge-ই উপলভ্য থাকে এবং সাধারণ http:// অনুরোধ redirect করা যায়।
Port 8080 বন্ধই থাকে। listen_addr হলো 127.0.0.1:8080, তাই proxy loopback interface-এর মাধ্যমে headscale-এ পৌঁছায় এবং কোনো firewall rule প্রয়োজন হয় না। UFW-তে 8080 খুললেও বাইরে থেকে কোনো কিছু উন্মুক্ত হবে না, কারণ বাইরে থেকে সেখানে কিছু listen করে না। এতে কোনো সুবিধাও পাওয়া যায় না। মনে রাখুন, অধিকাংশ provider তাদের control panel-এ UFW থেকে আলাদা একটি দ্বিতীয় firewall চালায়। তাই সার্ভারে কোনো port খোলা থাকলেও edge-এ সেটি বন্ধ থাকতে পারে। VPS-এ UFW firewall-এর মৌলিক বিষয়-এ rule syntax আরও বিস্তারিতভাবে দেখানো হয়েছে।
একটি ইউজার এবং প্রি-অথ কি (preauth key) তৈরি করুন
sudo headscale users create alice
sudo headscale users listheadscale কমান্ডটি একটি ক্লায়েন্ট হিসেবে কাজ করে। এটি /var/run/headscale/headscale.sock-এ থাকা unix socket-এর মাধ্যমে চলমান ডেমনের সাথে যোগাযোগ করে, যার মোড হলো 0770 এবং মালিকানা headscale গ্রুপের। এর থেকে দুটি বিষয় স্পষ্ট হয়। সার্ভিস বন্ধ থাকলে কমান্ডটি ব্যর্থ হয়, আর এই গাইডে ধাপগুলোর ক্রম বজায় রাখা এজন্যই জরুরি। এছাড়া, আপনার নিজের অ্যাকাউন্টকে headscale গ্রুপে যুক্ত না করলে কমান্ডটি চালানোর জন্য sudo প্রয়োজন হয়।
users list প্রতিটি নামের পাশে একটি আইডি প্রদর্শন করে। আপনার সেই সংখ্যাটি প্রয়োজন, কারণ কি (key) কমান্ডটি নামের পরিবর্তে একটি সংখ্যাসূচক ইউজার আইডি গ্রহণ করে।
sudo headscale preauthkeys create --user 1 --expiration 24hকি-টি একবারই প্রদর্শিত হয়। এটি এখনই কপি করে নিন। একটি প্রি-অথ কি সাধারণত একবার ব্যবহারের উপযোগী এবং এক ঘণ্টার জন্য বৈধ থাকে, যদি না আপনি অন্য কিছু নির্ধারণ করেন। তাই পরীক্ষার সময় --expiration 24h সেট করে রাখা সুবিধাজনক। একাধিক মেশিন এনরোল করার জন্য --reusable যুক্ত করুন। এই কি-টিকে পাসওয়ার্ডের মতো সুরক্ষিত রাখুন, কারণ এটি যার কাছে থাকবে সে আপনার নেটওয়ার্কে যুক্ত হতে পারবে।
প্রথম client-কে --login-server দিয়ে সংযুক্ত করুন
যে মেশিনটি যুক্ত করতে চান, সেখানে:
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up --login-server https://headscale.example.com --auth-key 'hskey-auth-PASTE-YOUR-KEY-HERE'
tailscale status
tailscale ip -4tailscale ip -4 headscale যে address বরাদ্দ করেছে তা দেখায়, যেমন 100.64.0.1। এরপর server-এ ফিরে sudo headscale nodes list চালালে node-এর ID, user এবং online state দেখা যায়।
server_url থেকে পাওয়া public HTTPS address --login-server-এর জন্য ব্যবহার করুন। Client তার control URL-এর শেষে থাকা slash সরিয়ে দেয়; তাই একটি slash বাদ দেওয়া বাধ্যতামূলক এমন কোনো exact string comparison নেই।
যে মেশিন আগে Tailscale-এর hosted service-এ sign in করা ছিল, সেটি সেই login বজায় রাখে। প্রথমে সেখানে sudo tailscale logout চালান, তারপর --login-server সহ tailscale up চালান।
--auth-key বাদ দিলে client-এর বদলে একটি URL দেখায়। URL-টি খুললে সেই registration attempt-এর identifier দেখা যায়। Server-এ সেটি approve করুন:
sudo headscale auth register --user alice --auth-id PASTE-THE-ID-FROM-THE-PAGEনিজের laptop-এর জন্য এই form ব্যবহার করা সুবিধাজনক। Script-এ ব্যবহারের জন্য preauth key বেশি উপযোগী, কারণ তখন কোনো মানুষের অপেক্ষা করে থাকার দরকার হয় না। VPS নিজেই node হয়ে গেলে আপনার অন্য মেশিনগুলোর Internet traffic-ও বহন করতে পারে। এটি হলো exit node setup। পার্থক্য হলো, hosted admin console-এ নয়, server-এ headscale command ব্যবহার করে advertised route approve করতে হবে। VPS-এর মাধ্যমে Internet-এ বের হওয়ার পথ নয়, বরং VPS-এর পেছনে থাকা private network-এ পৌঁছাতে চাইলে একই approval step সেই subnet-টি আপনার tailnet-এর অন্য অংশে advertise করার কাজেও প্রযোজ্য। কোনো node থেকে পুরো network route না করে শুধু একটি application প্রকাশ করা ভিন্ন কাজ। এটি করার দুটি উপায় হলো serve এবং funnel। তবে দুটিই Tailscale-এর নিজস্ব certificate এবং ingress machinery ব্যবহার করে। তাই এগুলোকে headscale-এর দেওয়া সুবিধা নয়, hosted-tailnet feature হিসেবে বিবেচনা করুন।
DERP এবং সরাসরি path ব্যর্থ হলে যে relay traffic পাঠায়
DERP (designated encrypted relay for packets) হলো fallback path। দুটি node সরাসরি WireGuard connection তৈরি করতে না পারলে, সাধারণত উভয়ই strict NAT (network address translation)-এর পেছনে থাকলে, তারা packet relay-এর মাধ্যমে পাঠায়। Relay কোনো key ধরে রাখে না, তাই এটি আপনার traffic পড়তে পারে না। তবে কোন node কার সঙ্গে যোগাযোগ করছে এবং কত data আদান-প্রদান হচ্ছে, তা relay দেখতে পায়।
Default configuration কী করে, তা স্পষ্টভাবে বুঝে নিন। Headscale https://controlplane.tailscale.com/derpmap/default-এ auto_update_enabled: true এবং update_frequency: 3h সহ configured অবস্থায় ship হয়। ফলে control plane আপনার নিজের থাকে, কিন্তু relay থাকে Tailscale-এর। অধিকাংশ ব্যবহারকারীর জন্য এটি গ্রহণযোগ্য বিনিময়। আপনার ক্ষেত্রে তা গ্রহণযোগ্য না হলে নিজের relay চালান।
নিজের relay চালাতে config.yaml-এর derp.server-এর অধীনে enabled: true সেট করুন। Shipped ipv4: 198.51.100.1 এবং ipv6: 2001:db8::1 আপনার relay-এর public address দিয়ে প্রতিস্থাপন করুন, অথবা DNS ব্যবহার করতে উভয় setting সরিয়ে দিন। এরপর headscale restart করুন এবং sudo ufw allow 3478/udp দিয়ে STUN (session traversal utilities for NAT) port খুলুন। এই address setting-গুলো DNS-কে override করে। তাই কোনো placeholder রেখে দিলে client unreachable address-এ পাঠানো হবে। Configuration file-এ শর্তটি স্পষ্টভাবে বলা আছে: server_url-এ https ব্যবহার করতে হবে, কারণ DERP-এর জন্য TLS প্রয়োজন। derp.urls list খালি করলে Tailscale-এর relay-গুলো map থেকে সরিয়ে দেওয়া হয়। এটি করার আগে একটি কার্যকর embedded বা custom relay রাখুন। Empty relay map থাকলে Headscale start করতে অস্বীকার করে। শুধু একটি unreachable relay থাকা map-এ যে node-গুলো সরাসরি connect করতে পারে না, তারা আর যোগাযোগ করতে পারে না।
Client থেকে tailscale netcheck চালালে পরিচিত প্রতিটি relay region-এর latency দেখা যায়। tailscale status active peer connection-এর ক্ষেত্রে address সহ direct অথবা region code সহ relay দেখায়। relay-এ আটকে থাকা peer-এর direct path পরীক্ষা করতে হবে, যার মধ্যে NAT এবং firewall rule-ও রয়েছে। কোনো peer direct থাকা সত্ত্বেও ধীর হলে সেটি আলাদা সমস্যা; সেখানে সাধারণত tunnel নয়, MTU-ই মূল কারণ।
কোনো node offline দেখায় কেন?
Proxy upgrade request বাদ দিচ্ছে। এর লক্ষণ হলো /health 200 ফেরত দিচ্ছে, কিন্তু নতুন registration ব্যর্থ হচ্ছে অথবা বিদ্যমান node পুনরায় সংযোগ করতে পারছে না। Control connection হলো Upgrade: tailscale-control-protocol বহনকারী একটি POST request। Proxy এটি forward না করলে registration এবং node state জানানো channel—দুটিই বন্ধ হয়ে যায়। উপরের upgrade-সংক্রান্ত line-এর সঙ্গে আপনার nginx configuration মিলিয়ে দেখুন। অথবা proxy-কে কারণ হিসেবে বাদ দিতে Caddy ব্যবহার করুন।
Public control address পরিবর্তিত হয়েছে। Node-গুলো --login-server দিয়ে configured address-এ connection করার চেষ্টা চালিয়ে যায়। server_url পরিবর্তন করলে client-এর ওই setting আপডেট হয় না। পুরোনো address আর আপনার server-এ পৌঁছাতে না পারলে প্রতিটি node-এ sudo tailscale up --login-server https://headscale.example.com --force-reauth চালান।
Client চলছে না। Node-এ sudo systemctl is-active tailscaled এবং sudo journalctl -u tailscaled -n 50 --no-pager চালান। কোনো client আপনার domain resolve করতে বা সেখানে পৌঁছাতে না পারলে তার retry-এর তথ্য সেখানেই log হয়।
Key-এর মেয়াদ শেষ হয়েছে। পরের section-এ এটি ব্যাখ্যা করা হয়েছে।
Test করার সময় server side পর্যবেক্ষণ করতে VPS-এ sudo journalctl -u headscale -f চালান এবং client-এ tailscaled restart করুন। Client-এর journal-ও পরীক্ষা করুন। headscale-এ request পৌঁছালেই default log level-এ একটি line তৈরি হবে—এমন নিশ্চয়তা নেই। তাই শুধু server log নীরব থাকাকে DNS, firewall বা proxy failure-এর প্রমাণ ধরে নেবেন না।
কী-এর মেয়াদ শেষ হওয়া এবং কয়েক সপ্তাহ পরে কাজ বন্ধ করে দেওয়া node
এখানে দুটি পৃথক মেয়াদ শেষ হওয়ার বিষয় আছে। এগুলো গুলিয়ে ফেললে অযথা সময় নষ্ট হয়।
Preauth key পরিকল্পনা অনুযায়ী দ্রুত মেয়াদোত্তীর্ণ হয়। ডিফল্ট হলো এক ঘণ্টা এবং একবার ব্যবহার। tailscale up key গ্রহণ না করলে client-এ কিছু সম্পাদনা না করে server-এ নতুন key তৈরি করুন।
Node key হলো দীর্ঘমেয়াদি অংশ। config.yaml-এর node section-এ expiry: 0 নির্ধারিত হয়, এবং 0-এর অর্থ হলো কোনো default expiry নেই; তবে explicit client expiry বা OIDC expiry প্রযোজ্য হতে পারে। Tagged node স্বয়ংক্রিয় expiry থেকে বাদ থাকে, যদিও administrator চাইলে সেগুলোর মেয়াদ স্পষ্টভাবে শেষ করতে পারেন। Non-tagged registration-এর জন্য 180 দিনের default চাইলে expiry: 180d সেট করুন। তবে client-requested expiry অগ্রাধিকার পায় এবং OIDC default-কে override করতে পারে। এই setting পরিবর্তন করলে বিদ্যমান registration-গুলোর ওপর তা retroactively প্রযোজ্য হয় না। কোনো node-এর expiry থাকলে deadline-এর আগে sudo tailscale up --login-server https://headscale.example.com --force-reauth ব্যবহার করে পুনরায় authentication করতে হবে। যে headless server-এ কেউ পুনরায় authentication করে না, তার registration-এর মেয়াদ শেষ হলে সেটি network থেকে বিচ্ছিন্ন হয়ে যাবে।
কেউ laptop হারালে এটি হাতে করে করুন। sudo headscale nodes list আপনাকে ID দেয়, এরপর sudo headscale nodes expire -i 3 ওই node-কে logout করায়, এবং sudo headscale nodes delete -i 3 node-টিকে সম্পূর্ণভাবে network থেকে সরিয়ে দেয়।
ব্যাকআপ এবং আপগ্রেড
/var/lib/headscale এবং /etc/headscale একসঙ্গে পুরো সার্ভার তৈরি করে। এগুলো কপি করার আগে service বন্ধ করুন, কারণ SQLite-এ লেখার কাজ চলমান থাকতে পারে এবং load-এর মধ্যে কপি করা database অসঙ্গত হতে পারে।
sudo systemctl stop headscale
sudo tar czf /root/headscale-state.tgz -C /var/lib headscale
sudo tar czf /root/headscale-config.tgz -C /etc headscale
sudo systemctl start headscale
sudo chmod 600 /root/headscale-*.tgzদুটি ফাইলই সার্ভারের বাইরে সংরক্ষণ করুন। এগুলোতে private key এবং সব registration থাকে, তাই সার্ভারের মতোই এগুলোর নিরাপত্তার যত্ন নিতে হবে। VPS থেকে restic backup-এ নির্ধারিত সময়ে এবং encrypted অবস্থায় এটি করার পদ্ধতি দেখানো হয়েছে।
আপগ্রেডে ইনস্টলেশনের ধাপগুলোই পুনরাবৃত্তি হয়: নতুন .deb, sudo apt install ./headscale.deb download করুন, তারপর restart করে is-active এবং /health check আবার চালান। 0.29 থেকে আপগ্রেডের পথ কঠোর। minor version বাদ দিয়ে আপগ্রেড করা যায় না, এবং পুরোনো minor version-এ downgrade করাও নিষিদ্ধ। একবারে একটি minor version পরিবর্তন করুন, প্রতিটি ধাপের আগে backup নিন, এবং প্রথমে সেই version-এর release notes পড়ুন, কারণ ওই release-এ ACL policy-এর আচরণ পরিবর্তন করা হয়েছে এবং বেশ কয়েকটি configuration key সরানো হয়েছে। Version 0.29.6-এ certificate validation এবং dependencies-এর security update-ও রয়েছে, তাই বিদ্যমান 0.29 installation-গুলোতে এই patch release নেওয়া উচিত।
FAQ
headscale ইনস্টল করার পরই কি এটি চলতে শুরু করে?
হ্যাঁ। প্যাকেজটি ইনস্টল হওয়ার সঙ্গে সঙ্গে service চালু করে। এটি সরবরাহকৃত /etc/headscale/config.yaml-এ চলে, যা শুধু loopback-এ listen করে এবং server_url-কে http://127.0.0.1:8080 সেট করে। নতুন ইনস্টলের ক্ষেত্রে service-টি enable করা থাকে না। তাই sudo systemctl enable headscale চালানো না পর্যন্ত এটি boot-এর সময় শুরু হবে না। সরবরাহকৃত address client-এর জন্য ব্যবহারযোগ্য নয়। তাই server_url, listen_addr এবং base_domain সম্পাদনা করুন। এরপর sudo systemctl restart headscale চালান এবং sudo systemctl is-active headscale দিয়ে নিশ্চিত করুন। এটি অবশ্যই restart হতে হবে। headscale ফাইলটি শুধু শুরু হওয়ার সময় পড়ে। ইতিমধ্যে চলমান service-এ enable --now চালালে service-টি boot-এর জন্য enable হবে, কিন্তু restart হবে না। ফলে পুরোনো মানগুলোই কার্যকর থাকবে। restart-এর পরে ব্যর্থ হলে sudo journalctl -u headscale -n 50 --no-pager সমস্যাটি দেখায়। এই পর্যায়ে সমস্যাটি প্রায় সব সময় YAML error হয়, কারণ port-এ bind করার আগে headscale পুরো ফাইল parse করে।
আমার মেশিনগুলোতে কি এখনও সাধারণ Tailscale client ইনস্টল করতে হবে?
হ্যাঁ। headscale শুধু control server প্রতিস্থাপন করে। প্রতিটি node Tailscale-এর official client চালায়। sudo tailscale up --login-server https://headscale.example.com দিয়ে client-কে আপনার server নির্দেশ করুন। এই flag standard client-এ রয়েছে। তাই কোনো patch বা rebuild করার প্রয়োজন নেই।
আমার network traffic কি headscale server-এর মধ্য দিয়ে যায়?
সাধারণত না। headscale network সমন্বয় করে এবং key ও address বিতরণ করে। Data path সরাসরি আপনার node-গুলোর মধ্যে WireGuard ব্যবহার করে। দুটি node সরাসরি একে অপরের কাছে পৌঁছাতে না পারলে traffic DERP relay-এর মাধ্যমে যায়। সরবরাহকৃত configuration-এ এই relay-গুলো Tailscale-এর public relay। কোনো node-এ tailscale status চালিয়ে দেখুন নির্দিষ্ট peer direct অবস্থায় আছে কি না, অথবা relay-এ আছে কি না।
register করার পর আমার node offline অবস্থায় থেকে যায় কেন?
headscale nodes list-এ দেখা গেলেও কোনো node online না হলে তার control connection পরীক্ষা করতে হবে। এর মধ্যে reverse proxy-ও অন্তর্ভুক্ত। এই connection-এ Upgrade: tailscale-control-protocol header-সহ একটি POST হিসেবে HTTP upgrade পাঠানো হয়। nginx স্পষ্টভাবে Upgrade এবং Connection header forward না করলে এটি বাদ দেয়। উপরের configuration তার map $http_upgrade $connection_upgrade block-এর মাধ্যমে proxy_set_header ব্যবহার করে এই কাজ করে। এই header-গুলো বাদ দিলেও নতুন node register হতে পারে না। Caddy অতিরিক্ত configuration ছাড়াই এটি forward করে। তাই proxy-ই সমস্যার কারণ কি না পরীক্ষা করার জন্য Caddy দ্রুত একটি উপায়।
headscale-এর জন্য কি domain name এবং TLS প্রয়োজন?
এই setup-এর জন্য হ্যাঁ। একটি domain name এবং HTTPS ব্যবহার করুন। Certificate bare IP address-ও অন্তর্ভুক্ত করতে পারে। তবে configuration file-এ বলা আছে যে DERP-এর জন্য TLS প্রয়োজন। Domain এবং Caddy ব্যবহার করলে প্রায় পাঁচ মিনিটে এমন একটি HTTPS endpoint পাওয়া যায়, যা নিজে নিজে renew হয়। Plain HTTP ব্যবহার করা সম্ভব। তবে headscale-এর documentation production-এর জন্য port 443-এ HTTPS ব্যবহারের জোরালো সুপারিশ করে। সেখানে আরও বলা হয়েছে, কিছু পরিস্থিতিতে Tailscale client port 443-এ HTTPS ধরে নেয়।