VPS-এ Vaultwarden দিয়ে পাসওয়ার্ড ম্যানেজার সেটআপ
Docker এবং VPS ব্যবহার করে Vaultwarden সেটআপ করার নিয়ম জানুন। HTTPS সুরক্ষা, admin token এবং Fail2ban সহ সম্পূর্ণ নিরাপদ self-hosting গাইড দেখুন।
আপনি যা তৈরি করছেন
একটি পাসওয়ার্ড ম্যানেজার যা সম্পূর্ণ আপনার নিয়ন্ত্রণে থাকবে: একটি reverse proxy-এর পেছনে একটি ছোট container-এ running Vaultwarden যা HTTPS terminate করে। আপনার ফোন, ল্যাপটপ এবং ব্রাউজারের অফিসিয়াল Bitwarden app গুলো এই সার্ভারটিকে target করবে। Vaultwarden, Rust ভাষায় Bitwarden server API-কে re-implement করেছে এবং bitwarden.com-এর মতো একই protocol ব্যবহার করে। তাই প্রতিটি অফিসিয়াল client কোনো পরিবর্তন ছাড়াই এটি ব্যবহার করতে পারে — তবে এটি official multi-container stack-এর পরিবর্তে মাত্র 100 MB RAM ব্যবহার করে।
ইনস্টলেশন প্রক্রিয়াটি মাত্র এক ডজন লাইন Compose দিয়ে করা সম্ভব। তিনটি গুরুত্বপূর্ণ বিষয় যা আসলে কাজ করে — এবং ভুল হলে সমস্যা তৈরি করে — সেগুলো হলো: web vault লোড করার আগেই TLS থাকতে হবে, আপনার নিজের অ্যাকাউন্ট তৈরি হওয়ার সাথে সাথে public signups বন্ধ করে দিতে হবে, এবং data volume অবশ্যই backup এবং test-restore করা থাকতে হবে, কারণ ওই একটি মাত্র directory-তে আপনার সমস্ত পাসওয়ার্ড সংরক্ষিত থাকে।
পূর্বশর্ত এবং কিছু বাস্তব সমস্যা
- একটি VPS যেখানে Docker Engine এবং Compose plugin ইনস্টল করা আছে। এটি একটি নতুন Ubuntu 24.04 KVM সার্ভারে root বা sudo ইউজার দিয়ে ব্যবহার করতে হবে। 512 MB RAM যথেষ্ট; 1 GB থাকলে সুবিধা হবে। এটি অত্যন্ত হালকা একটি সার্ভিস — এটি self-hosting করার মতো সার্ভিসের তালিকাভুক্ত অন্যতম একটি সার্ভিস।
- একটি ডোমেইন যার A record (এবং IPv6 থাকলে AAAA record)
vault.example.comহিসেবে VPS-এর দিকে পয়েন্ট করা আছে। TLS সার্টিফিকেট এই নির্দিষ্ট নামটির জন্যই ইস্যু করা হয়, তাই কাজ শুরু করার আগে DNS রেজলভ করা থাকতে হবে। - ইন্টারনেট সংযোগের জন্য 80 এবং 443 পোর্ট খোলা থাকতে হবে এবং এগুলো আপনার reverse proxy দ্বারা হ্যান্ডেল করতে হবে — কখনোই সরাসরি Vaultwarden দিয়ে নয়। Port 80 শুধুমাত্র ACME certificate challenge এবং HTTP-to-HTTPS redirect-এর জন্য ব্যবহৃত হয়।
- সবচেয়ে বড় সমস্যা: Bitwarden ক্লায়েন্টগুলো HTTPS ছাড়া কোনো সার্ভারের সাথে কানেক্ট হতে চায় না। "প্রথমে http দিয়ে পরীক্ষা করা" সম্ভব নয় — কারণটি নিচে বিস্তারিত আলোচনা করা হয়েছে।
কেন Vaultwarden ব্যবহার করবেন, অফিসিয়াল Bitwarden stack নয়
একই ক্লায়েন্ট, কিন্তু অনেক কম রিসোর্স খরচ। অফিসিয়াল self-hosted Bitwarden অনেকগুলো কন্টেইনারের (MSSQL, Nginx, Identity, Api, Admin এবং আরও অনেক কিছু) একটি বান্ডেল হিসেবে আসে এবং প্রায় 2 GB RAM প্রয়োজন হয়। অন্যদিকে, Vaultwarden হলো একটি single binary যা ডিফল্টভাবে সবকিছু একটি SQLite database-এ সংরক্ষণ করে এবং এটি চলতে মাত্র কয়েকটা মেগাবাইট RAM ব্যবহার করে। একজন ব্যক্তি, একটি পরিবার বা ছোট টিমের জন্য এটিই সবচেয়ে উপযুক্ত পছন্দ। যেহেতু এটি Bitwarden API হুবহু অনুসরণ করে, তাই আপনার ডেটা Vaultwarden এবং bitwarden.com-এর মধ্যে সহজেই স্থানান্তর করা সম্ভব।
তবে এতে আপনি কিছু এন্টারপ্রাইজ ফিচার হারাবেন: যেমন SCIM provisioning নেই (যদিও 1.35.0 ভার্সনে পরীক্ষামূলক OpenID Connect SSO যুক্ত করা হয়েছে)। এছাড়া যেহেতু আপনিই এর অপারেটর, তাই patching, HTTPS এবং backup করার দায়িত্ব আপনার। এই গাইডটি সেই তিনটি কাজের জন্যই তৈরি করা হয়েছে।
কেন HTTPS আবশ্যিক
Bitwarden web vault এবং browser extensions আপনার encryption keys ব্রাউজারে Web Crypto API (window.crypto.subtle) ব্যবহার করে তৈরি করে। ব্রাউজার শুধুমাত্র secure context-এ crypto.subtle প্রদান করে — যা হলো HTTPS, অথবা http://localhost-এর মতো বিশেষ ক্ষেত্র। সাধারণ http://vault.example.com-এর ক্ষেত্রে এটি undefined, তাই অ্যাপটি যখনই একটি key তৈরি করার চেষ্টা করে, তখনই এটি error দেয় এবং console-এ দেখায়:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importKey')পেজটি হ্যাং করে অথবা একটি সাধারণ crypto error দেখায়, এবং লগ-ইন করা সম্ভব হয় না। Desktop, mobile এবং browser client-গুলো self-hosted URL-এর বিরুদ্ধে নিজস্ব চেক চালায়; http (অথবা unreachable) endpoint-এর ক্ষেত্রে তারা নিচের error-টি দেখায়:
This is not a recognized Bitwarden server. You may need to check with your provider or update your server.উভয় ক্ষেত্রেই কারণ এক: কোনো বৈধ HTTPS নেই। তাই প্রথমে TLS সেটআপ করুন এবং কখনোই http-এর মাধ্যমে vault ওপেন করবেন না, এমনকি দ্রুত দেখার জন্যও নয়।
Step 1 — DNS এবং reverse proxy (প্রথমে TLS)
আপনার record-টি VPS-এর দিকে পয়েন্ট করুন এবং নিশ্চিত করুন যে এটি সঠিক address-এ resolve হচ্ছে:
dig +short vault.example.comআউটপুট হিসেবে আপনার VPS IP দেখা যেতে হবে। যদি এটি খালি থাকে বা ভুল থাকে, তবে DNS ঠিক করুন এবং TTL শেষ হওয়া পর্যন্ত অপেক্ষা করুন — যে name resolve হয় না, তার জন্য certificate ইস্যু করা সম্ভব নয়।
HTTPS front end-এর জন্য এই guide-এ Traefik ব্যবহার করা হয়েছে, যা Let's Encrypt certificate স্বয়ংক্রিয়ভাবে ইস্যু এবং রিনিউ করে এবং সরাসরি Compose-এর সাথে যুক্ত হয়ে যায়। আপনি যদি এটি ইতিমধ্যে ব্যবহার না করেন, তবে প্রথমে Traefik reverse proxy এবং automatic TLS setup অনুসরণ করুন; এটি একটি external Docker network (নিচে proxy) এবং একটি ACME resolver (letsencrypt) তৈরি করে যার সাথে Vaultwarden service যুক্ত হয়। Vaultwarden-এর দিক থেকে সাধারণ nginx এবং হাতে ইস্যু করা certificate ব্যবহার করলেও একই ফলাফল পাওয়া যায়।
Traefik-এর পরিবর্তে nginx এবং Certbot ব্যবহার করতে চান? Vaultwarden-কে 127.0.0.1:8080-এ স্থাপন করুন (service-এ ports: ["127.0.0.1:8080:80"] যোগ করুন এবং Traefik labels সরিয়ে ফেলুন), তারপর একটি certificate ইস্যু করে সেটির মাধ্যমে proxy করুন। Certificate সংক্রান্ত বিস্তারিত Certbot এবং nginx দিয়ে Let's Encrypt certificate ইস্যু করা অংশে দেওয়া আছে। গুরুত্বপূর্ণ অতিরিক্ত ধাপটি হলো notifications path-এ WebSocket upgrade:
server {
listen 443 ssl;
server_name vault.example.com;
client_max_body_size 525M;
location / {
proxy_pass http://127.0.0.1:8080;
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_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}X-Real-IP লাইনটি লক্ষ্য করুন — এটিই পরবর্তীতে Fail2ban-কে 127.0.0.1 এর পরিবর্তে আসল attacker শনাক্ত করতে সাহায্য করে। Traefik বা nginx—সামনে যা-ই থাকুক না কেন, এই guide-এর বাকি সব ধাপ একই থাকবে।
Step 2 — Compose file
প্রথমে প্রজেক্ট ডিরেক্টরি তৈরি করুন। এই গাইডে /opt/vaultwarden ব্যবহার করা হয়েছে, যা Compose প্রজেক্টের নাম — এবং এর ফলে ডেটা ভলিউম vaultwarden_vw-data — নিশ্চিত করে; নিচের Fail2ban এবং backup ধাপগুলো এই নির্দিষ্ট নামের ওপর নির্ভর করে।
sudo mkdir -p /opt/vaultwarden
cd /opt/vaultwardenAdmin secret এবং Compose file রাখার জন্য একটি .env তৈরি করুন।
# .env
ADMIN_TOKEN=paste-a-strong-token-hereopenssl rand -base64 48 দিয়ে টোকেনটি তৈরি করুন এবং সেটি পেস্ট করুন। (পরবর্তী ধাপে আরও শক্তিশালী hashed ফর্ম নিয়ে আলোচনা করা হবে; শুরুতে একটি লম্বা random string ব্যবহার করা যাবে।)
# docker-compose.yml
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # closed in Step 4, keep true just to register
ADMIN_TOKEN: "${ADMIN_TOKEN}"
IP_HEADER: "X-Forwarded-For" # X-Real-IP if your proxy sends that instead
LOG_FILE: "/data/vaultwarden.log"
LOG_LEVEL: "warn"
volumes:
- vw-data:/data
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.vw.rule=Host(`vault.example.com`)"
- "traefik.http.routers.vw.entrypoints=websecure"
- "traefik.http.routers.vw.tls.certresolver=letsencrypt"
- "traefik.http.services.vw.loadbalancer.server.port=80"
volumes:
vw-data:
networks:
proxy:
external: trueএই ফাইলের দুটি বিষয় পুরো ডিজাইনটি নিয়ন্ত্রণ করে। এখানে কোনো ports: mapping নেই, তাই Vaultwarden শুধুমাত্র Traefik এবং এর TLS-এর মাধ্যমে অ্যাক্সেস করা সম্ভব — হোস্টের পোর্ট পাবলিশ করলে ভুলবশত vault-টি http-এর মাধ্যমে সার্ভিস দেওয়া হয়ে যায়। এবং DOMAIN অবশ্যই পূর্ণাঙ্গ public HTTPS URL হতে হবে: এটি attachment links, WebAuthn 2FA এবং notifications endpoint-এ ব্যবহৃত হয়, তাই ভুল বা http ভ্যালু থাকলে সাইট লোড হলেও এগুলো কাজ করবে না। latest ট্যাগটি সাধারণ never-latest নিয়মের একটি ইচ্ছাকৃত ব্যতিক্রম — Vaultwarden তাদের stable release গুলো একটি single rolling image হিসেবে প্রদান করে, যেখানে :testing হলো আলাদা pre-release চ্যানেল — তাই ইমেজ pull করার আগে রিলিজ নোট দেখে নিয়ে ইচ্ছা করে আপডেট করুন।
সার্ভিসটি চালু করুন এবং log দেখুন:
docker compose up -d
docker compose logs -f vaultwardenসঠিকভাবে চালু হলে শেষে Rocket has launched from http://0.0.0.0:80 এর মতো একটি লাইন দেখা যাবে। Traefik-কে সার্টিফিকেটটি সংগ্রহ করার জন্য কয়েক সেকেন্ড সময় দিন, তারপর https://vault.example.com লোড করুন — আপনি একটি বৈধ padlock এবং কোনো certificate warning ছাড়া Bitwarden web vault দেখতে পাবেন।
Step 3 — একটি শক্তিশালী ADMIN_TOKEN, এবং $$ ট্র্যাপ
ADMIN_TOKEN হলো /admin এর সুরক্ষা নিশ্চিত করে, যা আপনার instance এর প্রতিটি user এবং setting পড়তে পারে; তাই এটিকে root password এর মতো বিবেচনা করুন। দুটি পদ্ধতি কাজ করে।
সহজ পদ্ধতিটি হলো openssl rand -base64 48 দিয়ে তৈরি করা random string। যেহেতু base64 এ কখনো $ থাকে না, তাই কোনো escaping ছাড়াই এটি সরাসরি .env এ চলে যায়।
আরও সুরক্ষিত পদ্ধতিটি হলো Argon2 PHC hash, যাতে plaintext token কখনো disk এ জমা থাকে না। একই image ব্যবহার করে এটি তৈরি করুন:
docker run --rm -it vaultwarden/server /vaultwarden hash --preset owaspএটি দুবার prompt করবে এবং $argon2id$v=19$... দিয়ে শুরু হওয়া একটি string প্রিন্ট করবে। এখানে একটি ট্র্যাপ আছে যা মানুষের এক ঘণ্টা সময় নষ্ট করে: Docker Compose, $ কে variable interpolation হিসেবে গণ্য করে; তাই Compose file এ hash টি পেস্ট করার সময় আপনাকে প্রতিটি $ কে $$ এ ডাবল করতে হবে। এটি সরাসরি environment: এর নিচে লিখুন, .env এর মাধ্যমে নয়, এবং কোনো quotes এর মধ্যে রাখবেন না:
environment:
ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$c29tZXNhbHQ$$RdescudvJCsgt3ub+b+dWRWJTmaaJObGআপনি যদি একটি মাত্র $ চিহ্ন রেখে দেন, তবে Compose, The "argon2id" variable is not set ওয়ার্নিং দেবে এবং token টি খালি করে দেবে, যার ফলে /admin আপনার সঠিক password রিজেক্ট করবে। docker compose up -d রান করুন, এবং prompt এ টাইপ করা plaintext টি আপনার নিজস্ব password store এ সংরক্ষণ করুন।
Step 4 — আপনার অ্যাকাউন্ট রেজিস্টার করুন, তারপর সুরক্ষা নিশ্চিত করুন
SIGNUPS_ALLOWED: "true" ব্যবহার করে https://vault.example.com ওপেন করুন, Create account-এ ক্লিক করুন এবং আপনার ইমেল ও একটি শক্তিশালী master password দিয়ে রেজিস্টার করুন। এই master password কখনো পুনরুদ্ধার করা সম্ভব নয় — কোনো reset অপশন নেই — তাই এটি আগে কোথাও নিরাপদভাবে সংরক্ষণ করুন।
এখন সুরক্ষা নিশ্চিত করার পালা। সাইনআপ বন্ধ করতে Compose fileটি এডিট করুন:
SIGNUPS_ALLOWED: "false"docker compose up -d দিয়ে পুনরায় apply করুন। এটি অত্যন্ত গুরুত্বপূর্ণ কাজ, তাই পরে করার জন্য ফেলে রাখা উচিত নয়। যদি এটি খোলা রাখা হয়, তবে যে কেউ URL-টি খুঁজে পেলে — এবং crawlers তা খুঁজে পায় — আপনার সার্ভারে অ্যাকাউন্ট তৈরি করতে পারবে। তারা আপনার vault পড়তে পারবে না, কিন্তু তারা আপনার সিস্টেমের resources ব্যবহার করবে এবং আপনার private instance-টিকে একটি open service-এ পরিণত করবে। আপনি যদি এটি খোলা রাখেন, তবে তার প্রমাণ হিসেবে /admin-এ এমন সব অ্যাকাউন্ট দেখা যাবে যা আপনি কখনো তৈরি করেননি।
পরবর্তীতে পাবলিক সাইনআপ চালু না করেই পরিবার বা টিমমেটদের যুক্ত করতে /admin-এর Invite User বাটনটি ব্যবহার করুন; এই পদ্ধতিটি কাজ করার জন্য SMTP কনফিগার করা থাকতে হবে যাতে আমন্ত্রিত ব্যক্তি তার লিঙ্কটি পায়।
Step 5 — /admin এ প্রবেশ করা
https://vault.example.com/admin এ যান এবং plaintext admin token (র্যান্ডম স্ট্রিং অথবা আপনার হ্যাশ করা পাসওয়ার্ড — হ্যাশটি নয়) প্রদান করুন। এখান থেকে আপনি ব্যবহারকারী তালিকাভুক্ত করতে পারবেন, সেটিংস পরিবর্তন করতে পারবেন, একটি টেস্ট ইমেইল পাঠাতে পারবেন এবং ডাটাবেস স্ন্যাপশট নিতে পারবেন।
যদি পেজটি 404 Not Found দেখায়, তবে ADMIN_TOKEN খালি বা unset আছে, যার ফলে প্যানেলটি সম্পূর্ণ নিষ্ক্রিয় হয়ে যায় — যদি আপনার এটি প্রয়োজন না হয়, তবে এটি একটি সঠিক সিদ্ধান্ত। যদি পেজটি লোড হয় কিন্তু আপনার token প্রত্যাখ্যান করে, তবে নিচের failure list এ থাকা $$ escaping trap দেখুন। Token ভুলে গেছেন? এখানে কোনো recovery prompt নেই; .env অথবা Compose file এডিট করে একটি নতুন token সেট করুন এবং docker compose up -d।
Step 6 — Bitwarden client-এর সাথে কানেক্ট করুন
প্রতিটি অফিসিয়াল ক্লায়েন্ট একটি self-hosted server-এর সাথে কানেক্ট করা সম্ভব। তাই সাধারণ স্টোর থেকে Bitwarden desktop, mobile অথবা browser client ইনস্টল করুন — আপনার কোনো বিশেষ Vaultwarden build-এর প্রয়োজন নেই।
Login করার আগে, login screen-এ থাকা settings gear আইকনটি ওপেন করুন (এটির নাম Self-hosted অথবা Region → Self-hosted), Server URL হিসেবে https://vault.example.com সেট করুন এবং save করুন। এরপর আপনার রেজিস্টার্ড email এবং master password দিয়ে login করুন; ক্লায়েন্টটি সাথে সাথে কানেক্ট হয়ে যাবে এবং credentials fill ও save করার অপশন দেখাবে।
যদি কোনো ক্লায়েন্টে This is not a recognized Bitwarden server. You may need to check with your provider or update your server. দেখায়, তবে বুঝতে হবে URL ভুল আছে, http ব্যবহার করা হয়েছে, অথবা certificate-টি untrusted — প্রথমে নিশ্চিত করুন যে https://vault.example.com ব্রাউজারে সঠিকভাবে লোড হচ্ছে। অন্যান্য ডিভাইসে আপডেট দেরিতে হওয়ার কারণ হলো WebSocket push, যা নিচে আলোচনা করা হয়েছে।
Step 7 — login endpoint-এর জন্য একটি Fail2ban jail
Vaultwarden প্রতিটি ব্যর্থ login-এর log LOG_FILE দ্বারা নির্ধারিত ফাইলে সংরক্ষণ করে — যা brute-force আক্রমণ ঠেকানোর জন্য প্রয়োজন। আপনি যদি ইতিমধ্যে Fail2ban ব্যবহার না করেন, তবে এর installation এবং মৌলিক বিষয়গুলো the Fail2ban SSH hardening guide এ দেওয়া আছে; এখানে আমরা vault-এর জন্য একটি jail যোগ করব।
প্রথমে host-এ named volume-টি কোথায় অবস্থিত তা খুঁজে বের করুন, যাতে Fail2ban log ফাইলটি পড়তে পারে:
docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}'এটি /var/lib/docker/volumes/vaultwarden_vw-data/_data এর মতো কিছু আউটপুট দেবে; এর ভেতরে log ফাইলটি হলো vaultwarden.log। filter তৈরি করুন:
# /etc/fail2ban/filter.d/vaultwarden.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =এবং jail তৈরি করুন:
# /etc/fail2ban/jail.d/vaultwarden.local
[vaultwarden]
enabled = true
filter = vaultwarden
logpath = /var/lib/docker/volumes/vaultwarden_vw-data/_data/vaultwarden.log
banaction = iptables-allports
chain = DOCKER-USER
maxretry = 5
findtime = 600
bantime = 3600sudo systemctl restart fail2ban দিয়ে reload করুন এবং sudo fail2ban-client status vaultwarden দিয়ে নিশ্চিত করুন।
তিনটি Docker সংক্রান্ত বিষয় নির্ধারণ করবে যে এটি কাজ করবে কি না। প্রথমত, যদি প্রতিটি ব্যর্থ চেষ্টার ক্ষেত্রে log ফাইলে IP: 127.0.0.1 অথবা আপনার proxy-এর address দেখায়, তবে Vaultwarden আপনার proxy-কেই ban করে দেবে — তাই IP_HEADER হিসেবে আপনার proxy যে header পাঠায় সেটি সেট করুন (Traefik-এর জন্য X-Forwarded-For, উপরের nginx block-এর জন্য X-Real-IP, এবং Cloudflare-এর জন্য CF-Connecting-IP)। দ্বিতীয়ত, সঠিক iptables chain আপনার proxy-এর ওপর নির্ভর করে: যদি Traefik একটি container হিসেবে চলে এবং port গুলো publish করা থাকে, তবে traffic Docker-এর FORWARD path দিয়ে যায়, তাই ban-টি উপরে দেখানো অনুযায়ী DOCKER-USER-এ থাকতে হবে; কিন্তু আপনি যদি Step 1 থেকে host-nginx অপশনটি বেছে নেন, তবে connection গুলো host-এর INPUT chain-এ nginx-এ শেষ হয় এবং DOCKER-USER ban সেগুলো দেখতে পায় না — সেই ক্ষেত্রে chain = DOCKER-USER লাইনটি মুছে ফেলুন যাতে Fail2ban ডিফল্ট INPUT chain ব্যবহার করে। তৃতীয়ত, port-based default-এর পরিবর্তে banaction = iptables-allports ব্যবহার করুন — এই jail-এ কোনো port ডিফাইন করা নেই, এবং DOCKER-USER-এ একটি all-ports ban করলে আক্রমণকারী ওই machine-এর প্রতিটি published service থেকে ব্লক হয়ে যাবে।
Step 8 — vault ব্যাকআপ নিন, তারপর সেটি রিস্টোর করুন
vw-data ভলিউমটিই আপনার পাসওয়ার্ড ম্যানেজার। এতে db.sqlite3 (প্রতিটি এন্ট্রি), attachments/ এবং sends/ ডিরেক্টরি, লগইন সেশন সাইন করার জন্য rsa_key.* ফাইল এবং অ্যাডমিন প্যানেল থেকে config.json থাকে। এর মধ্যে যেকোনোটি বাদ দিলে ব্যাকআপটি প্রয়োজনের সময় কাজ করবে না।
Vaultwarden যখন ডাটা লিখছে তখন db.sqlite3 কপি করলে একটি অসম্পূর্ণ বা করাপ্ট ফাইল পাওয়ার সম্ভাবনা থাকে। তাই একটি cold snapshot নিন — এতে মাত্র কয়েক সেকেন্ড সময় লাগবে:
#!/usr/bin/env bash
set -euo pipefail
STAMP=$(date +%F)
DEST=/root/vw-backups
VOL=$(docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}')
mkdir -p "$DEST"
docker compose -f /opt/vaultwarden/docker-compose.yml stop vaultwarden
tar czf "$DEST/vw-$STAMP.tgz" -C "$VOL" .
docker compose -f /opt/vaultwarden/docker-compose.yml start vaultwardenপ্রতি রাতে cron দিয়ে এটি চালান এবং .tgz ফাইলটি সার্ভার থেকে সরিয়ে নিন — যে সার্ভার আপনি রক্ষা করছেন তার মধ্যেই ব্যাকআপ রাখা কোনো ব্যাকআপ নয়। ব্যাকআপ পাঠানোর সঠিক উপায় হলো অন্য সার্ভার বা object storage-এ nightly restic backup করা, যা আর্কাইভটি এনক্রিপ্ট করে এবং ডুপ্লিকেট স্ন্যাপশটগুলো রিমুভ করে দেয়। অ্যাডমিন প্যানেলের Backup Database বাটনটি শুধুমাত্র SQLite ফাইলের একটি দ্রুত স্ন্যাপশট দেয়, কিন্তু এতে অ্যাটাচমেন্ট এবং কী (keys) থাকে না।
এখন আসল ব্যাকআপ এবং কেবল আশাবাদী ব্যাকআপের মধ্যে পার্থক্য করার প্রক্রিয়াটি শুরু করুন — একবার রিস্টোর করে দেখুন এটি কাজ করছে কি না:
mkdir -p /tmp/vw-restore
tar xzf /root/vw-backups/vw-2026-07-15.tgz -C /tmp/vw-restore
docker run --rm -p 127.0.0.1:8888:80 -v /tmp/vw-restore:/data vaultwarden/serverআপনার ল্যাপটপ থেকে ssh -L 8888:127.0.0.1:8888 you@your-vps ব্যবহার করে টানেল তৈরি করুন এবং http://localhost:8888 ওপেন করুন। যেহেতু localhost একটি secure context, তাই crypto.subtle ব্যবহার করা সম্ভব এবং এখানে plain http-এর মাধ্যমে vault ডিক্রিপ্ট হবে — এটিই একমাত্র অনুমোদিত জায়গা। আপনার মাস্টার পাসওয়ার্ড দিয়ে লগইন করুন এবং এন্ট্রিগুলো আছে কি না তা নিশ্চিত করুন: যদি এন্ট্রিগুলো থাকে, তবে আপনার ডাটাবেস, RSA keys এবং মাস্টার পাসওয়ার্ড সঠিকভাবে কাজ করছে, এবং আপনি কয়েক মিনিটের মধ্যে একটি নতুন VPS-এ সবকিছু রিবিল্ড করতে পারবেন। Ctrl-C চেপে কন্টেইনারটি বন্ধ করুন এবং /tmp/vw-restore ডিলিট করে দিন।
Failure modes, with the strings you will see
Browser console-এ Cannot read properties of undefined (reading 'importKey')। Vault-টি http-এর মাধ্যমে load করা হয়েছে, তাই crypto.subtle undefined; শুধুমাত্র https://-এর মাধ্যমে এটি ব্যবহার করুন এবং proxy-তে HTTP-to-HTTPS redirect যোগ করুন।
Client-এ This is not a recognized Bitwarden server...। Server URL-টি http, ভুলভাবে টাইপ করা হয়েছে, অথবা certificate-টি untrusted; নিশ্চিত করুন যে https://vault.example.com একটি valid padlock দেখাচ্ছে, তারপর client-এর self-hosted settings-এ এটি পুনরায় লিখুন।
/admin সঠিক password reject করছে। Argon2 hash-এর escaping হারিয়ে গেছে — Compose-এ প্রতিটি $ অবশ্যই $$ হতে হবে — অথবা আপনি plaintext-এর পরিবর্তে hash-টি ইনপুট দিয়েছেন।
Slow cross-device sync; console-এ WebSocket connection to 'wss://vault.example.com/notifications/hub' failed দেখাচ্ছে। Proxy, Upgrade/Connection headers forward করছে না; Traefik এটি স্বয়ংক্রিয়ভাবে করে, কিন্তু nginx-এর জন্য Step 1 থেকে upgrade lines দুটি প্রয়োজন। Vault কাজ করছে, তবে এটি শুধুমাত্র open করার সময় sync হচ্ছে। v1.31.0 থেকে পুরনো dedicated port 3012 সরিয়ে ফেলা হয়েছে, তাই আলাদা WebSocket route-এর প্রয়োজন নেই।
Fail2ban ban রিপোর্ট করছে কিন্তু attacker কানেক্ট করা চালিয়ে যাচ্ছে। এটি 127.0.0.1-কে ban করছে কারণ IP_HEADER ভুল, অথবা ban-টি ভুল iptables chain-এ আছে — chain = DOCKER-USER এবং banaction = iptables-allports সেট করুন।
Upgrades
নতুন image টি pull করুন এবং recreate করুন; named volume এবং আপনার সমস্ত data সংরক্ষিত থাকবে:
docker compose pull
docker compose up -dVaultwarden নিয়মিতভাবে নতুন release প্রদান করে। কোনো নির্দিষ্ট patch version ব্যবহার না করে project's release notes অনুসরণ করুন, কারণ কিছু release-এ migration notes থাকতে পারে। যেকোনো major bump করার আগে একটি fresh backup নিন; আপনি tarball টি একটি নতুন volume-এ restore করার মাধ্যমে roll back করতে পারেন।
FAQ
Vaultwarden কি Bitwarden এর মতোই?
এটি একটি compatible এবং independent server, এটি official server নয়। Vaultwarden, Bitwarden server API-কে Rust ভাষায় re-implement করেছে। ফলে official desktop, mobile, browser এবং CLI client গুলো এটি ব্যবহার করতে পারে, যা official stack এর তুলনায় অনেক কম resource ব্যবহার করে। Vault format একই হওয়ায়, আপনি export এবং import করার মাধ্যমে যেকোনো দিকে migrate করতে পারবেন।
আমার কি সত্যিই HTTPS প্রয়োজন, নাকি আমি LAN-এ http ব্যবহার করতে পারি?
localhost test ছাড়া অন্য যেকোনো কাজের জন্য আপনার HTTPS প্রয়োজন। Bitwarden web vault এবং extensions ব্রাউজারের Web Crypto API ব্যবহার করে, যা শুধুমাত্র secure context-এ পাওয়া যায়। তাই plain http ব্যবহার করলে client Cannot read properties of undefined error দেখাবে এবং লগ-in হবে না। একমাত্র http://localhost ঠিকানাটি কাজ করে, যার কারণে Step 8-এর restore test-এ SSH tunnel ব্যবহার করা হয়েছে।
আমি কীভাবে আমার সার্ভারে অপরিচিতদের register করা বন্ধ করব?
আপনার নিজের account তৈরি করার পরপরই Compose file-এ SIGNUPS_ALLOWED: "false" সেট করুন এবং docker compose up -d রান করুন। এরপর থেকে, /admin-এ Invite User button ব্যবহার করে নতুন ব্যক্তিদের যুক্ত করুন। এর জন্য SMTP configure করা থাকতে হবে যাতে তারা invitation link পায়। কোনো অনাকাঙ্ক্ষিত account তৈরি হয়েছে কিনা তা নিশ্চিত করতে মাঝে মাঝে admin user list চেক করুন।
আমি কীভাবে আমার Vaultwarden vault ব্যাকআপ নেব?
সাময়িকভাবে container টি stop করুন এবং সম্পূর্ণ vw-data volume— db.sqlite3, attachments/, sends/, config.json এবং rsa_key.* ফাইলগুলো— archive করুন। এরপর archive ফাইলটি সার্ভার থেকে কপি করে নিন, যা nightly cron দিয়ে করা সবচেয়ে ভালো। সার্ভার চলাকালীন live SQLite file কপি করলে snapshot corrupt হওয়ার ঝুঁকি থাকে, তাই server বন্ধ থাকা অবস্থায় ব্যাকআপ নিন। সবচেয়ে গুরুত্বপূর্ণ হলো, ব্যাকআপটি একটি throwaway container-এ একবার restore করে লগ-in করে দেখুন, যাতে আপনি নিশ্চিত হতে পারেন যে ব্যাকআপটি সঠিকভাবে কাজ করছে।
পাসওয়ার্ড self-host করা কি সত্যিই নিরাপদ?
হ্যাঁ, যদি আপনি এই গাইডে বর্ণিত তিনটি কাজ করেন: সঠিক HTTPS, closed signups এবং একটি শক্তিশালী admin token, এবং পরীক্ষিত backups। আপনার vault আপনার master password দিয়ে client-side এ encrypt করা থাকে, তাই সার্ভার কখনো আপনার পাসওয়ার্ড plain text হিসেবে দেখতে পায় না— ফলে db.sqlite3 চুরি হলেও সেটি কোনো কাজে আসবে না। তবে এর বিনিময়ে patching এবং backups এর দায়িত্ব আপনার নিজের, তাই এখানে Fail2ban এবং restore ritual অনুসরণ করা বাধ্যতামূলক।