SSD Nodes Learn Hosting plans →
الأدلة Matt Connorبقلم Matt Connor · آخر تحديث في 2026-08-23

تثبيت Vaultwarden على VPS مع Docker وHTTPS

شغّل مدير كلمات مرور متوافقاً مع Bitwarden على VPS عبر Vaultwarden وDocker، مع HTTPS أولاً، وتعطيل التسجيل، وFail2ban، ونسخ احتياطي مستعاد ومختبَر.

ما الذي ستبنيه

مدير كلمات مرور تملكه بالكامل: سيعمل Vaultwarden داخل حاوية صغيرة واحدة خلف Reverse Proxy ينهي اتصالات HTTPS، مع توجيه تطبيقات Bitwarden الرسمية على هاتفك وحاسوبك المحمول ومتصفحك إليه. يعيد Vaultwarden تنفيذ Bitwarden server API بلغة Rust، ويتحدث بالبروتوكول نفسه الذي يستخدمه bitwarden.com، لذلك تعمل معه جميع التطبيقات الرسمية من دون تعديل، بينما يستهلك نحو 100 MB من الذاكرة بدلاً من الحزمة الرسمية متعددة الحاويات.

يتكون التثبيت نفسه من نحو 12 سطراً في Compose. لكن هناك ثلاثة أمور مهمة فعلياً، وهي أسباب الأعطال الشائعة: يجب أن يكون TLS جاهزاً قبل فتح خزنة الويب لأول مرة، ويجب إغلاق التسجيلات العامة فور إنشاء حسابك، ويجب إجراء نسخ احتياطي لـdata volume واختبار استعادته، لأن هذا الدليل الواحد يحتوي على جميع كلمات المرور التي تملكها.

المتطلبات الأساسية والمشكلات المهمة التي يجب معرفتها

  • خادم VPS مزوّد بـ Docker Engine وCompose plugin، ويعمل على نظام Ubuntu 24.04 جديد ضمن KVM، مع صلاحيات root أو sudo. تكفي ذاكرة RAM بسعة 512 MB فعلاً، بينما تكون سعة 1 GB مريحة. هذا من أخفّ التطبيقات التي يمكنك تشغيلها، ويأتي في مقدمة قائمة الخدمات التي تستحق الاستضافة الذاتية. مع ذلك، خصّص حجم الخادم وفقاً للخدمات الأخرى التي ستشاركه: إنّ تشغيل مكتبة صور مستضافة ذاتياً مثل PhotoPrism أو Immich على خادم VPS نفسه يرفع الحد الأدنى لذاكرة RAM إلى عدة GB، بينما لا يضيف Vaultwarden إلا حملاً طفيفاً. وينطبق الحساب نفسه على واجهات الوسائط التي تضيفها لاحقاً، لأنّ تحويل مكتبة Jellyfin إلى متجر تأجير من طراز التسعينيات يمكن التجول فيه يعني تشغيل حاوية أخرى باستمرار وتوفير هامش إضافي لتحويل الوسائط ضمن الميزانية نفسها.
  • نطاق يحتوي على سجل A، وسجل AAAA إذا كان لديك IPv6، ويشير vault.example.com إلى خادم VPS. تُصدر شهادة TLS لهذا الاسم المحدد، لذلك يجب أن يحل DNS الاسم قبل أن تبدأ.
  • يجب فتح المنفذين 80 و443 أمام الإنترنت، وإنهاء الاتصالات بهما لدى Reverse Proxy، وليس لدى Vaultwarden مباشرة. يُستخدم المنفذ 80 فقط لتحدي شهادة ACME وإعادة التوجيه من HTTP إلى HTTPS.
  • أهم مشكلة يجب معرفتها مسبقاً: ترفض عملاء Bitwarden الاتصال بخادم لا يستخدم HTTPS. لا توجد طريقة «لاختباره عبر http أولاً»، لأن هذا المسار لا يعمل لسبب محدد سنشرحه تالياً.

لماذا Vaultwarden وليس حزمة Bitwarden الرسمية

العملاء أنفسهم، مع استهلاك أقل بكثير للموارد. تأتي حزمة Bitwarden الرسمية للاستضافة الذاتية على هيئة مجموعة من الحاويات، تشمل MSSQL وNginx وIdentity وApi وAdmin وغيرها، وتحتاج إلى نحو 2 GB من ذاكرة RAM. أما Vaultwarden فهو ملف ثنائي واحد يخزّن كل شيء في قاعدة بيانات SQLite افتراضياً، ولا يستهلك عند الخمول سوى بضعة عشرات من الميغابايت. لشخص واحد أو عائلة أو فريق صغير، يُعد الخيار الواضح. وبما أنّه يطبّق Bitwarden API بصورة متوافقة، تظل بياناتك قابلة للنقل بينه وبين bitwarden.com.

ما تتخلى عنه هو معظم وظائف المؤسسات: لا يتوفر SCIM provisioning، رغم إضافة OpenID Connect SSO التجريبي في 1.35.0. كما أنّك تصبح المشغّل، ولذلك تقع عليك مسؤولية تثبيت التحديثات التصحيحية وتهيئة HTTPS وإنشاء النسخ الاحتياطية. يتناول هذا الدليل هذه المهام الثلاث.

لماذا لا يُعد HTTPS خياراً اختيارياً

يشتق مخزن Bitwarden على الويب وإضافات المتصفح مفاتيح التشفير داخل المتصفح باستخدام Web Crypto API (window.crypto.subtle). لا تتيح المتصفحات crypto.subtle إلا ضمن secure context، أي عبر HTTPS، أو في الحالة الخاصة المتمثلة في http://localhost. أما عبر http://vault.example.com العادي، فيكون ذلك undefined، ولذلك يظهر استثناء فور اشتقاق التطبيق للمفتاح، وتعرض وحدة التحكم ما يلي:

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

تتوقف الصفحة أو تعرض خطأ تشفير عاماً، ولا ينجح تسجيل الدخول. وتجري تطبيقات سطح المكتب والهاتف والمتصفح فحصها الخاص لعنوان URL المستضاف ذاتياً. وعند استخدام نقطة نهاية http أو نقطة نهاية يتعذر الوصول إليها، ترفض الاتصال وتعرض:

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

السبب واحد في الحالتين: عدم وجود HTTPS صالح. لذلك نُعد TLS أولاً، ولا نفتح مخزن vault عبر http أبداً، حتى لمرة واحدة لإلقاء نظرة سريعة.

الخطوة 1، DNS وReverse Proxy (TLS أولاً)

وجّه السجل إلى VPS الخاص بك، وتأكد من أنه يُحلّ إلى العنوان الصحيح:

dig +short vault.example.com

يجب أن يكون السطر الذي يطبعه هو عنوان IP الخاص بـVPS. إذا كان فارغاً أو خاطئاً، أصلح DNS وانتظر انتهاء مدة TTL، لأن إصدار الشهادة يفشل عندما يكون الاسم غير قابل للحل.

تستخدم هذه الإرشادات Traefik للواجهة الأمامية عبر HTTPS. يُصدر Traefik شهادات Let's Encrypt ويجددها تلقائياً، ويندمج مباشرةً مع Compose. إذا لم تكن تشغّله مسبقاً، فاتبع أولاً إعداد Traefik كـReverse Proxy وTLS تلقائي؛ إذ ينشئ شبكة Docker خارجية (proxy أدناه) وACME resolver (letsencrypt) تتصل بهما خدمة Vaultwarden. ويعمل nginx العادي مع شهادة مُصدرة يدوياً بالطريقة نفسها من جهة Vaultwarden.

هل تفضّل nginx وCertbot بدلاً من Traefik؟ ضع Vaultwarden على 127.0.0.1:8080 (أضف ports: ["127.0.0.1:8080:80"] إلى الخدمة واحذف تسميات Traefik)، ثم أصدر شهادة ووجّه Proxy إليها. يشرح إصدار شهادات Let's Encrypt باستخدام Certbot وnginx جانب إصدار الشهادة. والإضافة المهمة هي ترقية 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

أنشئ .env للسر الإداري وملف Compose داخل ذلك المجلد.

# .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 العام الكامل؛ إذ يُضمَّن هذا العنوان في روابط المرفقات، وWebAuthn 2FA، ونقطة نهاية الإشعارات، لذلك تؤدي قيمة خاطئة أو قيمة تستخدم http إلى تعطيل هذه الوظائف حتى عند تحميل الموقع. تُعد العلامة latest استثناءً مقصوداً لقاعدة عدم استخدام 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 من دون أي escaping.

الشكل الأكثر تحصيناً هو تجزئة 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، وانقر على إنشاء حساب، ثم سجّل باستخدام بريدك الإلكتروني وكلمة مرور رئيسية قوية. لا يمكن استعادة كلمة المرور الرئيسية هذه، ولا توجد آلية لإعادة ضبطها؛ لذلك خزّنها أولاً في مكان موثوق ودائم.

عطّل التسجيلات الآن. عدّل ملف Compose بحيث تصبح التسجيلات متوقفة:

      SIGNUPS_ALLOWED: "false"

أعد تطبيق الإعداد باستخدام docker compose up -d. لا تؤجل هذا الإجراء الأمني. إذا بقيت التسجيلات مفتوحة، فيمكن لأي شخص يعثر على الرابط، بما في ذلك برامج الزحف، إنشاء حساب على خادمك. لن يتمكنوا من قراءة خزنتك، لكنهم سيستهلكون الموارد ويحوّلون مثيلك الخاص إلى خدمة مفتوحة. والعلامة على أنك تركت التسجيلات مفعّلة هي أن /admin يعرض حسابات لم تنشئها.

لإضافة أفراد العائلة أو أعضاء الفريق لاحقاً من دون إعادة فتح التسجيلات العامة، استخدم زر دعوة مستخدم في /admin؛ ويتطلب هذا المسار إعداد SMTP حتى يتلقى المدعو رابطه.

الخطوة 5: الوصول إلى /admin

انتقل إلى https://vault.example.com/admin وأدخل رمز admin النصي الواضح، أي السلسلة العشوائية أو كلمة المرور التي أنشأت لها تجزئة، وليس التجزئة نفسها. من داخل اللوحة، يمكنك عرض المستخدمين، وضبط الإعدادات، وإرسال رسالة اختبار، وإنشاء لقطة من قاعدة البيانات.

إذا أعادت الصفحة 404 Not Found، فهذا يعني أن ADMIN_TOKEN فارغ أو غير مضبوط، ما يعطّل اللوحة بالكامل. ويُعد ذلك خياراً صالحاً إذا لم تكن تحتاج إليها مطلقاً. إذا تم تحميل الصفحة لكنها رفضت الرمز، فراجع مشكلة escaping الخاصة بـ$$ في قائمة حالات الفشل أدناه. هل نسيت الرمز؟ لا توجد مطالبة لاسترداده. عدّل .env أو ملف Compose، واضبط رمزاً جديداً، ثم docker compose up -d.

الخطوة 6، وصّل عملاء Bitwarden

يمكن لكل عميل رسمي الاتصال بخادم مستضاف ذاتياً، لذلك ثبّت عميل 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، ويجري توضيحه أدناه.

الخطوة 7، إعداد jail في Fail2ban لنقطة نهاية تسجيل الدخول

يسجّل Vaultwarden كل محاولة تسجيل دخول فاشلة في الملف الذي يحدده LOG_FILE، وهذا هو بالضبط ما يحتاج إليه نظام الحماية من محاولات القوة الغاشمة. إذا لم تكن تشغّل Fail2ban من قبل، فستجد خطوات التثبيت والأساسيات في دليل تشديد حماية SSH باستخدام Fail2ban؛ سنضيف هنا jail واحداً لـvault.

اعثر أولاً على موقع named volume على الخادم المضيف، حتى يتمكن Fail2ban من قراءة السجل:

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

يعرض ذلك شيئاً مشابهاً لـ/var/lib/docker/volumes/vaultwarden_vw-data/_data؛ ويكون السجل داخلَه في 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   = 3600

أعد التحميل باستخدام sudo systemctl restart fail2ban وتحقق باستخدام sudo fail2ban-client status vaultwarden.

تحدد ثلاث نقاط في Docker ما إذا كانت هذه الحماية ستعمل فعلاً. أولاً، إذا أظهر السجل IP: 127.0.0.1 أو عنوان proxy في كل محاولة فاشلة، فإن Vaultwarden يحظر proxy بدلاً من المهاجم. اضبط IP_HEADER على الرأس الذي يرسله proxy فعلياً: X-Forwarded-For مع Traefik، وX-Real-IP مع كتلة nginx أعلاه، وCF-Connecting-IP خلف Cloudflare. ثانياً، تعتمد سلسلة iptables الصحيحة على proxy الذي تستخدمه: عند تشغيل Traefik كحاوية ذات منافذ منشورة، تعبر حركة الشبكة مسار FORWARD في Docker، لذلك يجب أن يقع الحظر في DOCKER-USER كما سبق؛ أما إذا اخترت خيار host-nginx في الخطوة 1، فتنتهي الاتصالات لدى nginx في سلسلة INPUT على الخادم المضيف، ولن يرى حظر DOCKER-USER هذه الاتصالات. في هذه الحالة، احذف السطر chain = DOCKER-USER حتى يستخدم Fail2ban سلسلة INPUT الافتراضية. ثالثاً، استخدم banaction = iptables-allports بدلاً من الإعداد الافتراضي القائم على المنفذ. لا يعرّف هذا jail أي منفذ، كما أن الحظر على جميع المنافذ في DOCKER-USER يحظر المهاجم بوضوح من كل خدمة منشورة على الخادم.

الخطوة 8: أنشئ نسخة احتياطية من vault، ثم استعدها فعلياً

إن وحدة التخزين vw-data هي مدير كلمات المرور لديك. فهي تحتوي على db.sqlite3 (كل إدخال)، ودليلي attachments/ وsends/، وملفات rsa_key.* التي توقّع جلسات تسجيل الدخول، وconfig.json من لوحة الإدارة. تفشل النسخة الاحتياطية التي تتجاوز أيّاً من هذه المكونات عند الحاجة إليها.

قد يؤدي نسخ db.sqlite3 أثناء كتابة Vaultwarden إلى التقاط ملف مكتوب جزئياً وتالف، لذلك أنشئ لقطة باردة. مدة التوقف بضع ثوانٍ:

#!/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 إلى خادم آخر أو إلى تخزين كائنات؛ إذ يشفّر الأرشيف ويزيل التكرار بين اللقطات نيابةً عنك. يوفّر زر Backup Database في لوحة الإدارة لقطة سريعة للملف SQLite وحده، لكنه لا يتضمن المرفقات والمفاتيح.

والآن نفّذ الإجراء الذي يميّز النسخة الاحتياطية الفعلية عن النسخة التي تأمل أن تعمل: استعدها مرة واحدة وأثبت أنها تعمل:

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 متاح، ويفك vault تشفيره عبر http العادي هنا، وهو الموضع الوحيد المسموح فيه بذلك. سجّل الدخول باستخدام كلمة المرور الرئيسية وتأكد من وجود إدخالاتك. إذا كانت موجودة، فهذا يعني أن قاعدة البيانات ومفاتيح RSA وكلمة المرور الرئيسية اجتازت دورة النسخ والاستعادة بنجاح، ويمكنك إعادة البناء على VPS جديد خلال دقائق. أوقف الحاوية باستخدام Ctrl-C واحذف /tmp/vw-restore. حافظ على عادة إنشاء النفق هذه لأي واجهة إدارة أخرى على الخادم يجب ألا تكون مكشوفة على الإنترنت، وهي الطريقة التي ستصل بها أيضاً إلى ماسح أمني مفتوح المصدر مستضاف ذاتياً من open-kritt على المنفذ 5173.

أنماط الأعطال، والرسائل التي ستظهر لك

Cannot read properties of undefined (reading 'importKey') في وحدة تحكم المتصفح. تم تحميل الخزنة عبر http، لذلك تكون crypto.subtle غير معرّفة؛ لا تصل إليها إلا عبر https://، وأضف إعادة توجيه من HTTP إلى HTTPS في الـproxy.

This is not a recognized Bitwarden server... في أحد العملاء. عنوان Server URL يستخدم http، أو كُتب بشكل خاطئ، أو أن الشهادة غير موثوقة؛ تأكد من أن https://vault.example.com يعرض رمز قفل صالحاً، ثم أدخل العنوان مجدداً في إعدادات الاستضافة الذاتية للعميل.

يرفض /admin كلمة المرور الصحيحة. فُقدت محارف الهروب من تجزئة Argon2؛ يجب أن تكون كل $ على هيئة $$ في Compose، أو أنك أدخلت التجزئة بدلاً من النص العادي الذي تمثله.

مزامنة بطيئة بين الأجهزة؛ تعرض وحدة التحكم WebSocket connection to 'wss://vault.example.com/notifications/hub' failed. لا يمرر الـproxy رأسي Upgrade/Connection؛ ينفّذ Traefik ذلك تلقائياً، بينما يحتاج nginx إلى سطري الترقية من الخطوة 1. تظل الخزنة تعمل، لكنها تزامن عند الفتح فقط. أُزيل المنفذ المخصص القديم 3012 منذ v1.31.0، لذلك لا تحتاج إلى مسار WebSocket منفصل.

يُبلغ Fail2ban عن حظر، لكن المهاجم يواصل الاتصال. يحظر Fail2ban 127.0.0.1 لأن IP_HEADER غير صحيح، أو لأن الحظر موجود في سلسلة iptables الخاطئة؛ اضبط chain = DOCKER-USER وbanaction = iptables-allports.

الترقيات

اسحب الصورة الجديدة وأعد إنشاء الحاوية؛ سيبقى الـnamed volume وجميع بياناتك محفوظة:

docker compose pull
docker compose up -d

يُصدر Vaultwarden إصدارات متكررة. راقب ملاحظات إصدارات المشروع بدلاً من تثبيت إصدار تصحيحي محدد، لأن بعض الإصدارات تتضمن ملاحظات عن عمليات الترحيل. أنشئ نسخة احتياطية جديدة قبل أي ترقية رئيسية؛ ويمكنك التراجع عن الترقية باستعادة ملف tarball إلى volume جديد.

FAQ

هل Vaultwarden هو نفسه Bitwarden؟

إنه خادم مستقل ومتوافق، وليس الخادم الرسمي. يعيد Vaultwarden تنفيذ واجهة برمجة تطبيقات خادم Bitwarden باستخدام Rust، لذلك تعمل عليه جميع العملاء الرسميين لسطح المكتب والأجهزة المحمولة والمتصفح وCLI، مع استهلاك جزء صغير من موارد الحزمة الرسمية. تنسيق الخزنة واحد، لذلك يمكنك الترحيل في أي من الاتجاهين عبر التصدير والاستيراد.

هل أحتاج فعلاً إلى HTTPS، أم يمكنني تشغيله عبر http على شبكتي المحلية؟

تحتاج إلى HTTPS لأي استخدام باستثناء اختبار localhost. تستخدم خزنة Bitwarden على الويب والإضافات Browser Web Crypto API، ولا تتوفر هذه الواجهة إلا ضمن سياق آمن. لذلك، عبر http العادي، يعرض العميل Cannot read properties of undefined ولا يسجّل الدخول أبداً. عنوان http الوحيد الذي يعمل هو http://localhost، ولهذا يستخدم اختبار الاستعادة في الخطوة 8 نفق SSH.

كيف أمنع الغرباء من إنشاء حسابات على خادمي؟

اضبط SIGNUPS_ALLOWED: "false" في ملف Compose، ثم شغّل docker compose up -d مباشرة بعد إنشاء حسابك. بعد ذلك، أضف المستخدمين الجدد عبر زر دعوة مستخدم في /admin. يتطلب ذلك إعداد SMTP لكي تصلهم رسالة الدعوة. راجع قائمة المستخدمين الإداريين من وقت لآخر للتأكد من عدم ظهور حسابات غير متوقعة.

كيف أنشئ نسخة احتياطية من خزنة Vaultwarden؟

أوقف الحاوية مؤقتاً، وأرشف وحدة التخزين vw-data بأكملها، إضافة إلى db.sqlite3 وattachments/ وsends/ وconfig.json وملفات rsa_key.*، ثم انسخ الأرشيف خارج الخادم، ويفضل أن تفعل ذلك عبر cron ليلاً. يؤدي نسخ ملف SQLite أثناء تشغيل الخادم إلى خطر إنشاء لقطة تالفة، لذلك أنشئ النسخة والخادم متوقف. والأهم أن تستعيدها مرة واحدة إلى حاوية مؤقتة وتسجّل الدخول، لكي تتأكد من أن النسخة الاحتياطية صالحة قبل الاعتماد عليها.

هل استضافة كلمات المرور ذاتياً آمنة فعلاً؟

نعم، عندما تنفذ الأمور الثلاثة التي يغطيها هذا الدليل: HTTPS فعلي، وتعطيل التسجيلات مع استخدام رمز مميز إداري قوي، ونسخ احتياطية مختبرة. تُشفَّر خزنتك على جانب العميل باستخدام كلمة المرور الرئيسية، لذلك لا يرى الخادم كلمات مرورك بصيغتها المكشوفة، وتصبح db.sqlite3 المسروقة عديمة الفائدة من دونها. في المقابل، تصبح مسؤولية التحديثات والنسخ الاحتياطية عليك، ولهذا فإن Fail2ban وإجراء الاستعادة ليسا اختياريين هنا. بعد تنفيذ ذلك، ستكون نظرة أقرب إلى المواضع التي يمكن فيها مهاجمة الخزنة المستضافة ذاتياً فعلياً هي الخطوة المفيدة التالية، لأن الإدخالات نفسها مشفّرة على جانب العميل، وما يتبقى لحمايته هو الرمز المميز الإداري وأرشيف النسخة الاحتياطية.