SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

VPS-এ Vaultwarden দিয়ে নিজের পাসওয়ার্ড ম্যানেজার তৈরি

Docker ব্যবহার করে VPS-এ Vaultwarden সেটআপ করার পূর্ণ নির্দেশিকা। HTTPS কনফিগারেশন, ADMIN_TOKEN সেটআপ এবং Fail2ban দিয়ে সার্ভার সুরক্ষিত রাখার নিয়মগুলো এখানে বিস্তারিত দেওয়া হলো।

আপনি যা তৈরি করছেন

একটি পাসওয়ার্ড ম্যানেজার যার পূর্ণ নিয়ন্ত্রণ আপনার হাতে: একটি ছোট কন্টেইনারে চলমান Vaultwarden, যা HTTPS টার্মিনেটকারী একটি reverse proxy-এর পেছনে থাকবে। আপনার ফোন, ল্যাপটপ এবং ব্রাউজারে থাকা অফিসিয়াল Bitwarden অ্যাপগুলো এই সার্ভারের দিকে নির্দেশ করা থাকবে। Vaultwarden মূলত Rust-এ Bitwarden সার্ভার API-এর একটি পুনঃবাস্তবায়ন এবং এটি bitwarden.com-এর মতোই প্রোটোকল ব্যবহার করে। ফলে প্রতিটি অফিসিয়াল ক্লায়েন্ট কোনো পরিবর্তন ছাড়াই এর সাথে কাজ করে, কিন্তু এটি অফিসিয়াল মাল্টি-কন্টেইনার স্ট্যাকের পরিবর্তে মাত্র 100 MB RAM-এ চলতে সক্ষম।

ইনস্টলেশন প্রক্রিয়াটি মূলত এক ডজন লাইনের একটি Compose ফাইল। যে তিনটি বিষয় সবচেয়ে গুরুত্বপূর্ণ এবং যা প্রায়শই সমস্যার কারণ হয়, তা হলো: ওয়েব ভল্ট লোড করার আগেই TLS কনফিগার করতে হবে, আপনার নিজের অ্যাকাউন্ট তৈরি হওয়ার সাথে সাথেই পাবলিক সাইনআপ বন্ধ করতে হবে, এবং ডেটা ভলিউমটির নিয়মিত ব্যাকআপ নিতে হবে ও তা পুনরুদ্ধার করে পরীক্ষা করতে হবে, কারণ এই একটি ডিরেক্টরিতেই আপনার সমস্ত পাসওয়ার্ড সংরক্ষিত থাকে।

পূর্বশর্ত এবং কিছু গুরুত্বপূর্ণ সতর্কতা

  • একটি নতুন Ubuntu 24.04 KVM সার্ভারে Docker Engine এবং Compose plugin ইনস্টল করা থাকতে হবে, যেখানে আপনার root বা sudo অ্যাক্সেস আছে। 512 MB RAM-ই যথেষ্ট; 1 GB হলে আরও ভালো। এটি অত্যন্ত হালকা একটি সার্ভিস, যা সেলফ-হোস্টিংয়ের যোগ্য সার্ভিসগুলোর তালিকার একদম উপরের দিকে থাকে। তবে সার্ভারে অন্য কী কী চলছে তার ওপর ভিত্তি করে RAM-এর পরিমাণ নির্ধারণ করুন: PhotoPrism বা Immich-এর মতো ফটো লাইব্রেরি একই VPS-এ চালালে RAM-এর চাহিদা কয়েক GB পর্যন্ত বাড়তে পারে, যেখানে Vaultwarden-এর জন্য খুব সামান্যই RAM প্রয়োজন। পরবর্তীতে মিডিয়া ফ্রন্ট-এন্ড যোগ করলেও একই হিসাব প্রযোজ্য, কারণ Jellyfin লাইব্রেরিকে 90-এর দশকের ভিডিও রেন্টাল স্টোরের মতো সাজাতে অতিরিক্ত কন্টেইনার এবং ট্রান্সকোডিংয়ের জন্য বাড়তি রিসোর্সের প্রয়োজন হয়।
  • একটি ডোমেইন যার A record (এবং IPv6 থাকলে AAAA record) vault.example.com সরাসরি আপনার VPS-এর IP-তে পয়েন্ট করা আছে। TLS সার্টিফিকেট এই নির্দিষ্ট নামের জন্যই ইস্যু করা হয়, তাই কাজ শুরু করার আগেই DNS রেজোলিউশন নিশ্চিত করতে হবে।
  • 80 এবং 443 নম্বর পোর্ট ইন্টারনেটের জন্য খোলা থাকতে হবে, যা আপনার reverse proxy দ্বারা টার্মিনেট হবে, সরাসরি Vaultwarden দ্বারা কখনোই নয়। 80 নম্বর পোর্ট শুধুমাত্র ACME সার্টিফিকেট চ্যালেঞ্জ এবং HTTP-to-HTTPS রিডাইরেক্টের জন্য ব্যবহৃত হয়।
  • সবচেয়ে বড় সতর্কতা: Bitwarden ক্লায়েন্টগুলো HTTPS ছাড়া অন্য কোনো সার্ভারের সাথে সংযোগ স্থাপন করে না। এখানে "প্রথমে HTTP দিয়ে পরীক্ষা করে দেখি" এমন কোনো সুযোগ নেই, কারণ পরবর্তী অংশে বর্ণিত সুনির্দিষ্ট কারণে এই পদ্ধতি কাজ করে না।

অফিসিয়াল Bitwarden স্ট্যাকের পরিবর্তে কেন Vaultwarden ব্যবহার করবেন

একই ক্লায়েন্ট, কিন্তু অনেক কম রিসোর্স খরচ। অফিসিয়াল self-hosted Bitwarden অনেকগুলো কন্টেইনারের (MSSQL, Nginx, Identity, Api, Admin এবং আরও অনেক কিছু) একটি গুচ্ছ হিসেবে রিলিজ হয় এবং এটি চালানোর জন্য প্রায় 2 GB RAM-এর প্রয়োজন হয়। Vaultwarden একটি একক বাইনারি ফাইল যা ডিফল্টভাবে SQLite ডাটাবেসে সবকিছু সংরক্ষণ করে এবং অলস অবস্থায় মাত্র কয়েক দশ মেগাবাইট RAM ব্যবহার করে। একজন ব্যক্তি, একটি পরিবার বা ছোট দলের জন্য এটিই সবচেয়ে যৌক্তিক পছন্দ। যেহেতু এটি Bitwarden API যথাযথভাবে অনুসরণ করে, তাই আপনার ডাটা Vaultwarden এবং bitwarden.com-এর মধ্যে সহজেই স্থানান্তরযোগ্য।

আপনি যা হারাবেন তা মূলত এন্টারপ্রাইজ লেভেলের ফিচারসমূহ: এতে কোনো SCIM provisioning নেই (যদিও 1.35.0 ভার্সনে পরীক্ষামূলক OpenID Connect SSO যুক্ত হয়েছে)। এছাড়া, আপনি নিজেই এর অপারেটর, তাই প্যাচিং, HTTPS এবং ব্যাকআপের দায়িত্ব আপনার। এই নির্দেশিকাটি এই তিনটি কাজের জন্যই তৈরি করা হয়েছে।

কেন HTTPS ঐচ্ছিক নয়

Bitwarden ওয়েব ভল্ট এবং ব্রাউজার এক্সটেনশনগুলো ব্রাউজারের Web Crypto API (window.crypto.subtle) ব্যবহার করে আপনার এনক্রিপশন কি (key) তৈরি করে। ব্রাউজারগুলো শুধুমাত্র secure context, HTTPS, অথবা http://localhost-এর বিশেষ ক্ষেত্রে crypto.subtle ব্যবহারের অনুমতি দেয়। সাধারণ http://vault.example.com-এর মাধ্যমে এটি undefined, তাই অ্যাপটি কি (key) তৈরি করার সাথে সাথেই ত্রুটি দেখায় এবং কনসোলে নিচের বার্তাটি আসে:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importKey')

পেজটি হ্যাং হয়ে যায় অথবা একটি সাধারণ ক্রিপ্টো ত্রুটি দেখায় এবং কোনো লগইন সম্পন্ন হয় না। ডেস্কটপ, মোবাইল এবং ব্রাউজার ক্লায়েন্টগুলো একটি self-hosted URL-এর বিপরীতে নিজস্ব পরীক্ষা চালায় এবং http (অথবা সংযোগ করা যায় না এমন) এন্ডপয়েন্টের ক্ষেত্রে তারা নিচের ত্রুটিটি দেখিয়ে প্রত্যাখ্যান করে:

This is not a recognized Bitwarden server. You may need to check with your provider or update your server.

উভয় ক্ষেত্রেই কারণ একই: কোনো বৈধ HTTPS নেই। তাই আমরা প্রথমেই TLS সেটআপ করি এবং কখনোই http-এর মাধ্যমে ভল্ট খুলি না, এমনকি দ্রুত একবার দেখার জন্যও না।

ধাপ 1, DNS এবং রিভার্স প্রক্সি (প্রথমে TLS)

আপনার রেকর্ডটি VPS-এর দিকে নির্দেশ করুন এবং নিশ্চিত করুন যে এটি সঠিক ঠিকানায় resolve হচ্ছে:

dig +short vault.example.com

এটি যে লাইনটি প্রিন্ট করবে তা অবশ্যই আপনার VPS IP হতে হবে। যদি এটি খালি থাকে বা ভুল হয়, তবে DNS ঠিক করুন এবং TTL শেষ হওয়া পর্যন্ত অপেক্ষা করুন, কারণ যে নামের বিপরীতে IP resolve হয় না তার জন্য সার্টিফিকেট ইস্যু করা ব্যর্থ হয়।

HTTPS ফ্রন্ট-এন্ডের জন্য এই নির্দেশিকায় Traefik ব্যবহার করা হয়েছে, যা স্বয়ংক্রিয়ভাবে Let's Encrypt সার্টিফিকেট ইস্যু ও রিনিউ করে এবং সরাসরি Compose-এর সাথে কাজ করে। আপনি যদি এটি আগে থেকে ব্যবহার না করে থাকেন, তবে প্রথমে Traefik রিভার্স প্রক্সি এবং স্বয়ংক্রিয় TLS সেটআপ অনুসরণ করুন; এটি একটি এক্সটারনাল Docker নেটওয়ার্ক (নিচে proxy) এবং একটি ACME রিজলভার (letsencrypt) তৈরি করে যার সাথে Vaultwarden সার্ভিস যুক্ত হয়। Vaultwarden-এর দিক থেকে হাতে ইস্যু করা সার্টিফিকেটসহ সাধারণ nginx একইভাবে কাজ করে।

Traefik-এর পরিবর্তে nginx এবং Certbot পছন্দ করেন? Vaultwarden-কে 127.0.0.1:8080-এ রাখুন (সার্ভিসে ports: ["127.0.0.1:8080:80"] যোগ করুন এবং Traefik লেবেলগুলো বাদ দিন), তারপর একটি সার্টিফিকেট ইস্যু করুন এবং সেটির দিকে প্রক্সি করুন। সার্টিফিকেটের অংশটি Certbot এবং nginx দিয়ে Let's Encrypt সার্টিফিকেট ইস্যু করা-তে কভার করা হয়েছে। এখানে গুরুত্বপূর্ণ অতিরিক্ত অংশটি হলো নোটিফিকেশন পাথে WebSocket আপগ্রেড:

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-এর পরিবর্তে প্রকৃত আক্রমণকারীকে শনাক্ত করতে সাহায্য করে। Traefik বা nginx—যেটিই সামনে থাকুক না কেন, এই নির্দেশিকার বাকি সবকিছু একই।

ধাপ 2, Compose ফাইল

প্রথমে প্রজেক্ট ডিরেক্টরি তৈরি করুন। এই নির্দেশিকায় /opt/vaultwarden ব্যবহার করা হয়েছে, যা Compose প্রজেক্টের নাম এবং সেই অনুযায়ী ডেটা ভলিউমের নাম vaultwarden_vw-data নিশ্চিত করে; নিচে উল্লিখিত Fail2ban এবং ব্যাকআপ ধাপগুলো এই নির্দিষ্ট নামের ওপর নির্ভরশীল।

sudo mkdir -p /opt/vaultwarden
cd /opt/vaultwarden

সেই ডিরেক্টরিতে অ্যাডমিন সিক্রেট এবং Compose ফাইলের জন্য একটি .env তৈরি করুন।

# .env
ADMIN_TOKEN=paste-a-strong-token-here

openssl rand -base64 48 ব্যবহার করে সেই টোকেনটি তৈরি করুন এবং এখানে পেস্ট করুন। (একটি শক্তিশালী হ্যাশড ফরম্যাট পরবর্তীতে আলোচনা করা হয়েছে; শুরুতে একটি দীর্ঘ র‍্যান্ডম স্ট্রিং ব্যবহার করাই যথেষ্ট।)

# 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: ম্যাপিং নেই, তাই Vaultwarden শুধুমাত্র Traefik এবং এর TLS-এর মাধ্যমেই অ্যাক্সেস করা সম্ভব; হোস্ট মেশিনে পোর্ট পাবলিশ করা হলে মানুষ ভুলবশত http-এর মাধ্যমে ভল্টটি সার্ভ করে ফেলে। এবং DOMAIN অবশ্যই সম্পূর্ণ পাবলিক HTTPS URL হতে হবে: এটি অ্যাটাচমেন্ট লিঙ্ক, WebAuthn 2FA এবং নোটিফিকেশন এন্ডপয়েন্টে যুক্ত থাকে, তাই ভুল বা http ভ্যালু থাকলে সাইট লোড হলেও এই ফিচারগুলো কাজ করবে না। latest ট্যাগটি সাধারণত never-latest নিয়মের একটি সচেতন ব্যতিক্রম, Vaultwarden তাদের স্টেবল রিলিজগুলো একটি সিঙ্গেল রোলিং ইমেজ হিসেবে প্রকাশ করে, যেখানে :testing হলো আলাদা প্রি-রিলিজ চ্যানেল, তাই ইচ্ছাকৃতভাবে আপডেট করুন এবং নতুন ইমেজ পুল করার আগে রিলিজ নোটগুলো দেখে নিন। তবে এই ব্যতিক্রমটি সীমিত: বেশিরভাগ দীর্ঘস্থায়ী কন্টেইনারের ক্ষেত্রে একটি নির্দিষ্ট ট্যাগ ব্যবহার করাই ভালো, যা একই VPS-এ হোস্ট করা একটি অলওয়েজ-অন এজেন্টকে রিবুট এবং পুল করার পরেও স্থিতিশীল রাখে।

এটি চালু করুন এবং লগ পর্যবেক্ষণ করুন:

docker compose up -d
docker compose logs -f vaultwarden

সঠিকভাবে শুরু হলে শেষে Rocket has launched from http://0.0.0.0:80-এর মতো একটি লাইন দেখা যাবে। Traefik-কে সার্টিফিকেট আনার জন্য কয়েক সেকেন্ড সময় দিন, তারপর https://vault.example.com লোড করুন, আপনি একটি বৈধ প্যাডলক এবং কোনো সার্টিফিকেট সতর্কতা ছাড়াই Bitwarden ওয়েব ভল্ট দেখতে পাবেন।

ধাপ 3, একটি শক্তিশালী ADMIN_TOKEN এবং $$ ট্র্যাপ

ADMIN_TOKEN হলো /admin-এর রক্ষক, এটি এমন একটি প্যানেল যা আপনার ইনস্ট্যান্সের প্রতিটি ব্যবহারকারী এবং সেটিংস পড়তে পারে, তাই এটিকে root পাসওয়ার্ডের মতোই গুরুত্ব দিন। এটি দুইভাবে কাজ করে।

সহজ পদ্ধতিটি হলো সেই র‍্যান্ডম স্ট্রিং যা আপনি ইতিমধ্যে openssl rand -base64 48 দিয়ে তৈরি করেছেন। যেহেতু base64-এ কখনোই $ থাকে না, তাই এটি কোনো এস্কেপিং ছাড়াই সরাসরি .env-এ কাজ করে।

হার্ডেনড বা সুরক্ষিত পদ্ধতিটি হলো একটি Argon2 PHC হ্যাশ, যার ফলে প্লেইনটেক্সট টোকেনটি কখনোই ডিস্কে সংরক্ষিত থাকে না। একই ইমেজ ব্যবহার করে একটি হ্যাশ তৈরি করুন:

docker run --rm -it vaultwarden/server /vaultwarden hash --preset owasp

এটি আপনাকে দুইবার প্রম্পট করবে এবং $argon2id$v=19$... দিয়ে শুরু হওয়া একটি স্ট্রিং প্রদর্শন করবে। এখানেই সেই ট্র্যাপটি রয়েছে যা অনেকের এক ঘণ্টা সময় নষ্ট করে: Docker Compose $-কে ভেরিয়েবল ইন্টারপোলেশন হিসেবে গণ্য করে, তাই Compose ফাইলে হ্যাশটি পেস্ট করার সময় আপনাকে অবশ্যই প্রতিটি $-কে ডাবল করে $$ করতে হবে। এটিকে সরাসরি environment:-এর নিচে রাখুন, .env-এর মাধ্যমে নয় এবং এটিকে কোটেশনের ভেতরে রাখবেন না:

    environment:
      ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$c29tZXNhbHQ$$RdescudvJCsgt3ub+b+dWRWJTmaaJObG

যদি আপনি সিঙ্গেল $ চিহ্ন রেখে দেন, তবে Compose The "argon2id" variable is not set সতর্কবার্তা দেবে এবং টোকেনটিকে খালি করে দেবে, যার ফলে /admin আপনার সঠিক পাসওয়ার্ডটি প্রত্যাখ্যান করবে। docker compose up -d চালান এবং প্রম্পটে যে প্লেইনটেক্সটটি টাইপ করেছিলেন তা আপনার নিজের পাসওয়ার্ড স্টোরে সংরক্ষণ করে রাখুন।

ধাপ 4, আপনার অ্যাকাউন্ট নিবন্ধন করুন, তারপর দরজা বন্ধ করুন

SIGNUPS_ALLOWED: "true" ব্যবহার করে https://vault.example.com খুলুন, Create account-এ ক্লিক করুন এবং আপনার ইমেইল ও একটি শক্তিশালী মাস্টার পাসওয়ার্ড দিয়ে নিবন্ধন করুন। এই মাস্টার পাসওয়ার্ডটি পুনরুদ্ধার করা সম্ভব নয়, এটি রিসেট করার কোনো উপায় নেই, তাই প্রথমে এটি কোথাও নিরাপদে সংরক্ষণ করুন।

এখন দরজা বন্ধ করুন। Compose ফাইলটি এডিট করে সাইনআপ বন্ধ করুন:

      SIGNUPS_ALLOWED: "false"

docker compose up -d ব্যবহার করে পুনরায় প্রয়োগ করুন। এটি এমন একটি নিরাপত্তা ব্যবস্থা যা আপনি এড়িয়ে যেতে পারবেন না। এটি খোলা রাখলে, যে কেউ আপনার URL খুঁজে পেলে—এবং ক্রলাররা তা খুঁজে পায়—আপনার সার্ভারে অ্যাকাউন্ট তৈরি করতে পারবে। তারা আপনার ভল্ট পড়তে পারবে না, কিন্তু তারা রিসোর্স ব্যবহার করবে এবং আপনার ব্যক্তিগত ইনস্ট্যান্সকে একটি উন্মুক্ত সার্ভিসে পরিণত করবে। আপনি এটি খোলা রেখেছেন কি না তা বোঝার উপায় হলো: /admin এমন সব অ্যাকাউন্টের তালিকা দেখাবে যা আপনি তৈরি করেননি।

পরবর্তীতে পরিবার বা দলের সদস্যদের যোগ করতে পাবলিক সাইনআপ পুনরায় খোলার প্রয়োজন নেই, এর পরিবর্তে /admin-এ থাকা Invite User বাটনটি ব্যবহার করুন; এই প্রক্রিয়ার জন্য SMTP কনফিগার করা থাকতে হবে যাতে আমন্ত্রিত ব্যক্তি তাদের লিঙ্কটি পেতে পারেন।

ধাপ 5, /admin এ প্রবেশ

https://vault.example.com/admin ব্রাউজ করুন এবং প্লেইনটেক্সট admin token (র‍্যান্ডম স্ট্রিং বা আপনার হ্যাশ করা পাসওয়ার্ড, হ্যাশটি নয়) প্রদান করুন। এর ভেতরে আপনি ব্যবহারকারীদের তালিকা দেখতে পারবেন, সেটিংস পরিবর্তন করতে পারবেন, একটি টেস্ট ইমেইল পাঠাতে পারবেন এবং ডাটাবেসের স্ন্যাপশট নিতে পারবেন।

যদি পেজটি 404 Not Found রিটার্ন করে, তবে ADMIN_TOKEN খালি বা সেট করা নেই, যা পুরো প্যানেলটিকে নিষ্ক্রিয় করে রাখে; যদি আপনার এটির প্রয়োজন না হয় তবে এটি একটি বৈধ পছন্দ। যদি পেজটি লোড হয় কিন্তু আপনার টোকেন প্রত্যাখ্যান করে, তবে নিচের ব্যর্থতার তালিকার $$ এস্কেপিং ট্র্যাপটি দেখুন। টোকেন ভুলে গেছেন? এখানে কোনো রিকভারি প্রম্পট নেই; .env বা Compose ফাইলটি এডিট করুন, একটি নতুন টোকেন সেট করুন এবং docker compose up -d করুন।

ধাপ 6, Bitwarden ক্লায়েন্ট সংযুক্ত করা

প্রতিটি অফিসিয়াল ক্লায়েন্ট একটি self-hosted সার্ভারের সাথে সংযুক্ত হতে পারে, তাই সাধারণ স্টোর থেকে Bitwarden ডেস্কটপ, মোবাইল বা ব্রাউজার ক্লায়েন্ট ইনস্টল করুন। আপনার কোনো বিশেষ Vaultwarden বিল্ডের প্রয়োজন নেই

লগ ইন করার আগে, লগইন স্ক্রিনে থাকা সেটিংস গিয়ার আইকনটি (যা Self-hosted বা Region → Self-hosted হিসেবে চিহ্নিত) খুলুন, Server URL-এ https://vault.example.com সেট করুন এবং সংরক্ষণ করুন। এরপর আপনার নিবন্ধিত ইমেইল এবং মাস্টার পাসওয়ার্ড দিয়ে লগ ইন করুন; ক্লায়েন্টটি অবিলম্বে সংযুক্ত হবে এবং ক্রেডেনশিয়াল পূরণ ও সংরক্ষণের প্রস্তাব দেবে।

যদি কোনো ক্লায়েন্ট This is not a recognized Bitwarden server. You may need to check with your provider or update your server. দেখায়, তবে বুঝতে হবে URL ভুল, এটি http ব্যবহার করছে অথবা সার্টিফিকেটটি বিশ্বস্ত নয়। প্রথমে ব্রাউজারে https://vault.example.com সঠিকভাবে লোড হচ্ছে কি না তা পুনরায় পরীক্ষা করুন। অন্যান্য ডিভাইসে ধীরগতির আপডেটের কারণ হলো WebSocket push, যা নিচে আলোচনা করা হয়েছে।

ধাপ 7, লগইন এন্ডপয়েন্টের জন্য একটি Fail2ban জেল

Vaultwarden প্রতিটি ব্যর্থ লগইন প্রচেষ্টাকে LOG_FILE দ্বারা নির্ধারিত ফাইলে লগ করে, যা ব্রুট-ফোর্স প্রতিরোধের জন্য ঠিক যা প্রয়োজন। আপনি যদি ইতিমধ্যে Fail2ban ব্যবহার না করে থাকেন, তবে এর ইনস্টলেশন এবং প্রাথমিক বিষয়গুলো Fail2ban SSH হার্ডেনিং গাইডে পাবেন; এখানে আমরা ভল্টের জন্য একটি জেল যোগ করব।

প্রথমে হোস্ট মেশিনে নেমড ভলিউমটি কোথায় আছে তা খুঁজে বের করুন, যাতে Fail2ban লগটি পড়তে পারে:

docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}'

এটি /var/lib/docker/volumes/vaultwarden_vw-data/_data এর মতো কিছু আউটপুট দেবে; এর ভেতরে লগ ফাইলটি হলো vaultwarden.log। ফিল্টারটি তৈরি করুন:

# /etc/fail2ban/filter.d/vaultwarden.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

এবং জেলটি তৈরি করুন:

# /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   = 3600

sudo systemctl restart fail2ban দিয়ে রিলোড করুন এবং sudo fail2ban-client status vaultwarden দিয়ে নিশ্চিত করুন।

তিনটি Docker সংক্রান্ত বিষয় নির্ধারণ করবে যে এটি আদৌ কোনো সুরক্ষা দিচ্ছে কি না। প্রথমত, যদি লগে প্রতিটি ব্যর্থ প্রচেষ্টায় IP: 127.0.0.1 বা আপনার প্রক্সির ঠিকানা দেখা যায়, তবে Vaultwarden প্রক্সিকে ব্যান করছে। সেক্ষেত্রে IP_HEADER-কে সেই হেডারে সেট করুন যা আপনার প্রক্সি প্রকৃতপক্ষে পাঠায় (Traefik-এর জন্য X-Forwarded-For, উপরের nginx ব্লকের জন্য X-Real-IP, এবং Cloudflare-এর পেছনে থাকলে CF-Connecting-IP)। দ্বিতীয়ত, সঠিক iptables চেইন আপনার প্রক্সির ওপর নির্ভর করে: যদি Traefik একটি কন্টেইনার হিসেবে পাবলিশড পোর্টে চলে, তবে ট্রাফিক Docker-এর FORWARD পাথ দিয়ে যায়, তাই ব্যানটি অবশ্যই উপরের মতো DOCKER-USER-এ থাকতে হবে। কিন্তু যদি আপনি ধাপ 1 থেকে host-nginx অপশনটি বেছে নেন, তবে সংযোগগুলো হোস্টের INPUT চেইনে nginx-এ টার্মিনেট হয় এবং একটি DOCKER-USER ব্যান সেগুলো দেখতে পায় না; সেক্ষেত্রে chain = DOCKER-USER লাইনটি মুছে ফেলুন যাতে Fail2ban ডিফল্ট INPUT চেইন ব্যবহার করে। তৃতীয়ত, পোর্ট-ভিত্তিক ডিফল্টের পরিবর্তে banaction = iptables-allports ব্যবহার করুন। এই জেলে কোনো পোর্ট নির্দিষ্ট করা নেই, এবং DOCKER-USER-এ একটি অল-পোর্ট ব্যান আক্রমণকারীকে সার্ভারের সমস্ত পাবলিশড সার্ভিস থেকে কার্যকরভাবে ব্লক করে দেয়।

ধাপ 8, ভল্ট ব্যাকআপ করুন এবং বাস্তবে তা রিস্টোর করুন

vw-data ভলিউমটিই আপনার পাসওয়ার্ড ম্যানেজার। এটি db.sqlite3 (প্রতিটি এন্ট্রি), attachments/ এবং sends/ ডিরেক্টরি, লগইন সেশন সাইন করার জন্য rsa_key.* ফাইল এবং অ্যাডমিন প্যানেল থেকে config.json ধারণ করে। যে ব্যাকআপে এর কোনো একটি বাদ পড়ে, প্রয়োজনে সেটি কোনো কাজে আসে না।

Vaultwarden যখন ডেটা লিখছে তখন db.sqlite3 কপি করলে ফাইলটি অসম্পূর্ণ বা ক্ষতিগ্রস্ত হতে পারে, তাই একটি কোল্ড স্ন্যাপশট নিন; এতে মাত্র কয়েক সেকেন্ডের ডাউনটাইম প্রয়োজন:

#!/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 সার্ভারের বাইরে কপি করুন। যে সার্ভারকে আপনি সুরক্ষিত করছেন, ব্যাকআপ কেবল সেই সার্ভারে রাখা মানে তা কোনো ব্যাকআপই নয়। এটি পাঠানোর সঠিক উপায় হলো অন্য কোনো সার্ভার বা অবজেক্ট স্টোরেজে প্রতি রাতের restic ব্যাকআপ, যা আর্কাইভটিকে এনক্রিপ্ট করে এবং বারবার নেওয়া স্ন্যাপশটগুলোকে ডিডুপ্লিকেট (deduplicate) করে। অ্যাডমিন প্যানেলের 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 একটি নিরাপদ কনটেক্সট, তাই crypto.subtle সেখানে কাজ করে এবং ভল্টটি এখানে সাধারণ http-এর মাধ্যমে ডিক্রিপ্ট হয়, যা একমাত্র অনুমোদিত ক্ষেত্র। আপনার মাস্টার পাসওয়ার্ড দিয়ে লগইন করুন এবং নিশ্চিত করুন যে আপনার এন্ট্রিগুলো সেখানে আছে: যদি থাকে, তবে আপনার ডেটাবেস, RSA কি এবং মাস্টার পাসওয়ার্ড সঠিকভাবে কাজ করছে এবং আপনি কয়েক মিনিটের মধ্যেই নতুন কোনো VPS-এ এটি পুনরায় তৈরি করতে পারবেন। Ctrl-C চেপে কন্টেইনারটি বন্ধ করুন এবং /tmp/vw-restore মুছে ফেলুন। সার্ভারের অন্য যেকোনো অ্যাডমিন UI-এর জন্য এই টানেলিং পদ্ধতি বজায় রাখুন যা ইন্টারনেটে উন্মুক্ত থাকা উচিত নয়; একইভাবে আপনি 5173 পোর্টে একটি সেলফ-হোস্টেড open-kritt সিকিউরিটি স্ক্যানার-এও পৌঁছাতে পারবেন।

ব্যর্থতার ধরন এবং যে বার্তাগুলো আপনি দেখবেন

ব্রাউজার কনসোলে Cannot read properties of undefined (reading 'importKey') ভল্টটি http-এর মাধ্যমে লোড করা হয়েছে, তাই crypto.subtle অনির্ধারিত; শুধুমাত্র https://-এর মাধ্যমে এটিতে প্রবেশ করুন এবং প্রক্সিতে HTTP-to-HTTPS রিডাইরেক্ট যোগ করুন।

ক্লায়েন্টে This is not a recognized Bitwarden server... Server URL-এ http ব্যবহার করা হয়েছে, ভুল টাইপ করা হয়েছে অথবা সার্টিফিকেটটি বিশ্বস্ত নয়; নিশ্চিত করুন যে https://vault.example.com একটি বৈধ প্যাডলক দেখাচ্ছে, তারপর ক্লায়েন্টের self-hosted সেটিংসে এটি পুনরায় লিখুন।

/admin সঠিক পাসওয়ার্ড প্রত্যাখ্যান করছে। Argon2 হ্যাশ তার এস্কেপিং হারিয়ে ফেলেছে, Compose-এ প্রতিটি $ অবশ্যই $$ হতে হবে, অথবা আপনি প্লেইনটেক্সটের পরিবর্তে হ্যাশটি প্রবেশ করিয়েছেন।

ডিভাইসগুলোর মধ্যে ধীরগতির সিঙ্ক; কনসোলে WebSocket connection to 'wss://vault.example.com/notifications/hub' failed দেখাচ্ছে। প্রক্সি Upgrade/Connection হেডারগুলো ফরোয়ার্ড করছে না; Traefik এটি স্বয়ংক্রিয়ভাবে করে, কিন্তু nginx-এর জন্য ধাপ 1-এর দুটি আপগ্রেড লাইন প্রয়োজন। ভল্টটি কাজ করবে, তবে শুধুমাত্র খোলার সময় সিঙ্ক হবে। v1.31.0 থেকে পুরনো ডেডিকেটেড পোর্ট 3012 সরিয়ে ফেলা হয়েছে, তাই আলাদা কোনো WebSocket রুটের প্রয়োজন নেই।

Fail2ban একটি ব্যান রিপোর্ট করছে কিন্তু আক্রমণকারী সংযোগ চালিয়ে যাচ্ছে। এটি 127.0.0.1-কে ব্যান করছে কারণ IP_HEADER ভুল, অথবা ব্যানটি ভুল iptables চেইনে রয়েছে, chain = DOCKER-USER এবং banaction = iptables-allports সেট করুন।

আপগ্রেড

নতুন image-টি pull করুন এবং কন্টেইনারটি পুনরায় তৈরি করুন; named volume এবং আপনার সমস্ত ডেটা অক্ষত থাকবে:

docker compose pull
docker compose up -d

Vaultwarden নিয়মিত নতুন রিলিজ প্রকাশ করে। কোনো নির্দিষ্ট patch version-এ আটকে না থেকে প্রজেক্টের রিলিজ নোট অনুসরণ করুন, কারণ কিছু রিলিজে ডেটা মাইগ্রেশন সংক্রান্ত নির্দেশনা থাকে। যেকোনো বড় ধরনের আপগ্রেডের আগে নতুন করে ব্যাকআপ নিন; কোনো সমস্যা হলে tarball থেকে নতুন volume-এ ডেটা রিস্টোর করে আপনি আগের অবস্থায় ফিরে যেতে পারবেন।

FAQ

Vaultwarden কি Bitwarden-এর মতোই?

এটি একটি সামঞ্জস্যপূর্ণ, স্বতন্ত্র সার্ভার, অফিসিয়াল সার্ভার নয়। Vaultwarden Rust ল্যাঙ্গুয়েজে Bitwarden সার্ভার API-কে নতুন করে তৈরি করেছে, তাই অফিসিয়াল ডেস্কটপ, মোবাইল, ব্রাউজার এবং CLI ক্লায়েন্টগুলো এর সাথে কাজ করে, অথচ এটি অফিসিয়াল স্ট্যাকের তুলনায় অনেক কম রিসোর্স ব্যবহার করে। ভল্টের ফরম্যাট একই, তাই এক্সপোর্ট এবং ইম্পোর্ট করার মাধ্যমে আপনি যেকোনো দিকে মাইগ্রেট করতে পারেন।

আমার কি সত্যিই HTTPS প্রয়োজন, নাকি আমি আমার LAN-এ http ব্যবহার করে এটি চালাতে পারি?

localhost টেস্ট ছাড়া অন্য যেকোনো কিছুর জন্য আপনার HTTPS প্রয়োজন। Bitwarden ওয়েব ভল্ট এবং এক্সটেনশনগুলো ব্রাউজারের Web Crypto API ব্যবহার করে, যা শুধুমাত্র নিরাপদ কনটেক্সটেই কাজ করে। তাই সাধারণ http-এর মাধ্যমে ক্লায়েন্ট Cannot read properties of undefined ত্রুটি দেখায় এবং কখনোই লগ-ইন করতে পারে না। শুধুমাত্র http://localhost ঠিকানাটি কাজ করে, যে কারণে ধাপ 8-এর রিস্টোর টেস্টে একটি SSH টানেল ব্যবহার করা হয়েছে।

অপরিচিত কাউকে আমার সার্ভারে রেজিস্ট্রেশন করা থেকে কীভাবে আটকাব?

আপনার নিজের অ্যাকাউন্ট তৈরি করার পরপরই Compose ফাইলে SIGNUPS_ALLOWED: "false" সেট করুন এবং docker compose up -d চালান। এরপর থেকে, /admin-এর Invite User বাটনের মাধ্যমে নতুন ব্যক্তিদের যোগ করুন, যার জন্য SMTP কনফিগার করা থাকতে হবে যাতে তারা ইনভাইটেশন লিঙ্কটি পায়। কোনো অপ্রত্যাশিত অ্যাকাউন্ট তৈরি হয়েছে কি না তা নিশ্চিত করতে মাঝে মাঝে অ্যাডমিন ইউজার লিস্ট চেক করুন।

আমার Vaultwarden ভল্ট কীভাবে ব্যাকআপ নেব?

সংক্ষিপ্ত সময়ের জন্য কন্টেইনারটি বন্ধ করুন এবং সম্পূর্ণ vw-data ভলিউম, db.sqlite3, attachments/, sends/, config.json এবং rsa_key.* ফাইলগুলো আর্কাইভ করুন, তারপর আর্কাইভটি সার্ভার থেকে কপি করে নিন, যা প্রতিদিন রাতে cron-এর মাধ্যমে করা সবচেয়ে ভালো। সার্ভার চলাকালীন লাইভ SQLite ফাইল কপি করলে তা নষ্ট (corrupt) হওয়ার ঝুঁকি থাকে, তাই এটি বন্ধ থাকা অবস্থায় ব্যাকআপ নিন। সবচেয়ে গুরুত্বপূর্ণ হলো, এটি একবার একটি অস্থায়ী কন্টেইনারে রিস্টোর করে লগ-ইন করে দেখুন, যাতে আপনি নিশ্চিত হতে পারেন যে ব্যাকআপটি সঠিক আছে।

নিজের পাসওয়ার্ড নিজে হোস্ট করা কি সত্যিই নিরাপদ?

হ্যাঁ, যদি আপনি এই গাইডে বর্ণিত তিনটি কাজ করেন: সঠিক HTTPS, রেজিস্ট্রেশন বন্ধ রাখা এবং শক্তিশালী অ্যাডমিন টোকেন ব্যবহার, এবং নিয়মিত ব্যাকআপ পরীক্ষা করা। আপনার ভল্ট আপনার মাস্টার পাসওয়ার্ড দিয়ে ক্লায়েন্ট-সাইডে এনক্রিপ্ট করা থাকে, তাই সার্ভারও কখনোই আপনার পাসওয়ার্ডগুলো সরাসরি দেখতে পায় না; একটি চুরি হওয়া db.sqlite3 ফাইল পাসওয়ার্ড ছাড়া অকেজো। এর বিনিময়ে প্যাচিং এবং ব্যাকআপের দায়িত্ব আপনার, যে কারণে Fail2ban এবং রিস্টোর প্রক্রিয়া এখানে ঐচ্ছিক নয়। একবার এগুলো নিশ্চিত হয়ে গেলে, সেলফ-হোস্টেড ভল্ট কোথায় আক্রান্ত হতে পারে তার একটি বিস্তারিত বিশ্লেষণ দেখা পরবর্তী কার্যকর পদক্ষেপ, কারণ এন্ট্রিগুলো ক্লায়েন্টেই এনক্রিপ্ট করা থাকে, তাই সুরক্ষার জন্য শুধু অ্যাডমিন টোকেন এবং ব্যাকআপ আর্কাইভটিই অবশিষ্ট থাকে।