SSD Nodes Learn 🎉 VPS من $4.99/شهر
الأدلة Matt Connorبقلم Matt Connor

هل Vaultwarden آمن؟ تشديد الإعدادات والمخاطر الحقيقية

يشفّر Vaultwarden عناصر الخزنة على جهازك قبل إرسالها، لذلك لا يرى الخادم النص الصريح. تعرّف إلى مخاطر رمز الإدارة وملف النسخ الاحتياطي.

هل Vaultwarden آمن؟ الإجابة المختصرة

يكون Vaultwarden آمناً في الموضع الأهم، لأن كل عنصر في الخزنة يُشفَّر على جهازك قبل أن يصل إلى الخادم. يخزّن الخادم كتل بيانات لا يستطيع قراءتها. وحتى من ينسخ قاعدة البيانات بأكملها سيظل بحاجة إلى كلمة المرور الرئيسية ليستخرج منها أي بيانات مفيدة.

تتطلب هذه الإجابة افتراضات كثيرة، ونقاط الضعف تظهر في الأجزاء التي تهيئها أنت. لوحة إدارة محمية برمز يمكن تخمينه. منفذ حاوية منشور على الإنترنت بالكامل. config.json بنص صريح. أرشيف tar للنسخ الاحتياطي موجود في الدليل الرئيسي على الخادم نفسه. لا تمثل أي من هذه الحالات مشكلة في التشفير. لكنها جميعاً أسباب إفراغ الخزائن المستضافة ذاتياً.

يفترض كل ما يلي وجود تثبيت يعمل. إذا لم يكن لديك تثبيت بعد، فأعد إعداده أولاً باتباع دليل تثبيت Vaultwarden على VPS، ثم عد ونفّذ عناصر هذه القائمة بالترتيب.

ما الذي يخزّنه الخادم فعلياً

يطبّق Vaultwarden نموذج بيانات Bitwarden. يُشفَّر اسم عنصر الخزنة واسم المستخدم وكلمة المرور والملاحظات وعناوين URI باستخدام مفتاح مشتق من كلمة المرور الرئيسية، وذلك على العميل قبل إرسال أي طلب. ويُشفَّر محتوى ملفات المرفقات بالطريقة نفسها. يستقبل الخادم بيانات غير قابلة للفهم مرتبطة بـUUID (معرّف فريد عالمياً).

هناك بعض البيانات التي لا تكون مشفَّرة، ويجب أن تعرفها بدقة:

  • عنوان البريد الإلكتروني لحسابك، بنص واضح.
  • إعدادات KDF (دالة اشتقاق المفتاح) والـsalt، لأن العميل يحتاج إليها لإعادة بناء المفتاح عند تسجيل الدخول التالي.
  • تجزئة على جانب الخادم لتجزئة كلمة المرور الرئيسية التي يرسلها العميل، وتُستخدم لمصادقة تسجيل الدخول نفسه.
  • البيانات الوصفية: عضوية المؤسسة، وأسماء الأجهزة، وأوقات آخر تسجيل دخول.
  • السر الخاص بطريقة المصادقة الثنائية التي تحمي تسجيل الدخول إلى Vaultwarden. يوجد هذا السر في جدول twofactor من دون تشفير، لأن الخادم يجب أن يحسب الرمز المتوقع لمقارنته بالرمز الذي تقدمه. وهذا ليس هو سر TOTP (كلمة المرور لمرة واحدة المستندة إلى الوقت) الذي تخزّنه داخل عنصر خزنة؛ فهذا السر يُشفَّر مثل أي حقل آخر.

مجلد البيانات صغير. في تثبيت Docker، يكون هذا المجلد هو المسار الذي ربطته بـ/data.

sudo ls -l /vw-data/

يحتوي db.sqlite3 على معظم الحالة تقريباً. ويحتوي attachments/ على الملفات المرفوعة، ملفاً واحداً لكل UUID، وهو فئة البيانات المهمة الوحيدة التي لا تُخزَّن في جداول قاعدة البيانات. ويحتوي sends/ على مرفقات Send، وهو مخصص ليكون مؤقتاً. أما icon_cache/ فيمكن حذفه وإعادة إنشائه. ويوقّع rsa_key.pem والملفات المرتبطة به JWTs (رموز الويب JSON) الخاصة بالمستخدمين الذين سجّلوا الدخول، ولذلك يمكن استخدام نسخة من هذا المفتاح الخاص لتزوير جلسة تسجيل دخول إلى الخزنة. ولا يظهر config.json إلا بعد تفعيل صفحة الإدارة، والمشروع واضح بشأن محتواه: فهو يخزّن رمز الإدارة وبيانات اعتماد SMTP بنص واضح.

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

أصلح رمز الإدارة أولاً

/admin لوحة تحكم كاملة: قائمة المستخدمين، والدعوات، والحذف، وكل إعدادات التشغيل. ولا يحميها سوى سر مشترك واحد. لا يوجد اسم مستخدم. ولا توجد مصادقة ثنائية لكل مستخدم.

تطلب منك الأدلة الأقدم إنشاء ADMIN_TOKEN باستخدام openssl rand -base64 48. ينجح ذلك، لكنه يكتب السر بنص واضح في config.json وفي ملف Compose الخاص بك. يقبل Vaultwarden أيضاً سلسلة Argon2 PHC (مسابقة تجزئة كلمات المرور)، وبذلك تصبح القيمة المخزنة تجزئة بدلاً من السر نفسه. أنشئ واحدة باستخدام حاوية قيد التشغيل:

docker exec -it vaultwarden /vaultwarden hash

أو من دون لمس الحاوية قيد التشغيل إطلاقاً:

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

سيطلب منك إدخال كلمة المرور مرتين، ثم يطبع سطراً يبدأ بـ $argon2id$. في تثبيت bare-metal، نفّذ ./vaultwarden hash. وإذا أردت استخدام واجهة CLI الخاصة بـargon2 مباشرة، يوضّح المشروع الحد الأدنى من المعلمات وفق OWASP:

echo -n 'MySecretPassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1

إليك المشكلة التي تكلّف بعض المستخدمين ساعة من العمل. تحتوي سلسلة PHC على عدد كبير من محارف $، ويتعامل Docker Compose مع $ على أنّها استبدال للمتغيرات. إذا لصقتها من دون تخليص داخل كتلة environment:، فستتغير القيمة التي تصل إلى الحاوية، ولذلك يرفض /admin رمزاً تعرف أنه صحيح. توجد طريقتان آمنتان. في docker-compose.yml، ضاعف كل $:

environment:
  ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$UUZxK1FZMkZoRHFQRlVrTXZvS0E3bHpNQW55c2dBN2NORzdsa0Nxd1JhND0$$cUoId+JBUsJutlG4rfDZayExfjq4TCt48aBc9qsc3UI

في ملف .env، لا تحتاج إلى تخليص المحارف، لكن استخدم علامات اقتباس مفردة:

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$MmeKRnGK5RW5mJS7h3TOL89GrpLPXJPAtTK8FTqj9HM$DqsstvoSAETl9YhnsXbf43WeaUwJC6JhViIvuPoig78'

ثم حدّد معدل طلبات لوحة التحكم، وقلّل مدة جلستها:

ADMIN_RATELIMIT_SECONDS=300
ADMIN_RATELIMIT_MAX_BURST=3
ADMIN_SESSION_LIFETIME=20

بعد ثلاث محاولات فاشلة خلال خمس دقائق، تتوقف لوحة التحكم عن الرد على ذلك العميل. وتنتهي جلسة الإدارة بعد 20 دقيقة من عدم النشاط.

والأفضل من كل ذلك: عطّل الصفحة. تحتاج معظم البيئات إلى الصفحة مرة واحدة لإعداد SMTP ودعوة المستخدمين الأوائل، ثم لا تحتاج إليها مجدداً. لتعطيلها، لا تضبط ADMIN_TOKEN ولا DISABLE_ADMIN_TOKEN، وأزل أي مفتاح "admin_token" من config.json، ثم أعد إنشاء الحاوية. حذف المفتاح من الملف مهم لأن صفحة الإدارة تكتب الإعدادات فيه، وما يوجد في config.json له الأولوية على متغيرات البيئة. إزالة المتغير وحدها تترك الصفحة مفتوحة.

أغلِق التسجيل قبل أن يعثر أحد على النطاق

SIGNUPS_ALLOWED=false
SIGNUPS_VERIFY=true
SHOW_PASSWORD_HINT=false

تكون SIGNUPS_ALLOWED مضبوطة على true افتراضياً. اتركها كما هي، وإلا فسيحصل كل من يصل إلى نطاقك على حساب، وستُخزَّن بياناته في db.sqlite3 نفسها التي تستخدمها. اضبطها على false، وأضف المستخدمين عبر الدعوات من صفحة الإدارة، مع ضرورة عمل SMTP. تكون INVITATIONS_ALLOWED مضبوطة أيضاً على true افتراضياً، وتتيح لمالكي المؤسسات دعوة الآخرين. هذا مناسب عندما تثق بالمستخدمين، وينبغي أن تكون false مفعّلة في مثيل يستخدمه مستخدم واحد. إذا كان ينبغي السماح بالتسجيل لنطاقات معينة فقط، فإن SIGNUPS_DOMAINS_WHITELIST=example.com أضيق من التسجيل المفتوح، لكنه أضعف بكثير من الدعوات.

تكون SHOW_PASSWORD_HINT مضبوطة على false افتراضياً، وينبغي أن تبقى كذلك. عند تفعيلها، يؤدي إدخال عنوان بريد إلكتروني صالح في نموذج تسجيل الدخول إلى عرض تلميح كلمة المرور الرئيسية للحساب، ما يكشف التلميح ويؤكد في الوقت نفسه وجود العنوان.

إذا كان مثيلك قد عمل مع فتح التسجيل لأي مدة، فافتح صفحة الإدارة واقرأ قائمة المستخدمين قبل أن تفترض أن حسابك هو الحساب الوحيد فيه.

المنفذ الذي لم تكن تقصد نشره

تستمع صورة Docker على المنفذ 80 داخل الحاوية. ويستخدم التثبيت على الخادم مباشرةً القيمة الافتراضية ROCKET_PORT=8000. وينشر أمر التشغيل الموثّق هذا المنفذ كما يلي:

--publish 127.0.0.1:8000:80

البادئة 127.0.0.1: هي جوهر الأمر. إذا كتبت -p 8000:80 بدلاً منها، فسيَربط Docker 0.0.0.0، وذلك بكتابة قواعد DNAT (ترجمة عنوان شبكة الوجهة) في جدول nat. تُقيَّم هذه القواعد قبل سلاسل filter التي يديرها ufw، لذلك يعرض ufw status المنفذ على أنه مرفوض، بينما يستجيب المنفذ فعلياً للإنترنت. يشرح دليل تجاوز منافذ Docker لـufw الآلية كاملة.

تحقق مما يستمع فعلياً:

sudo ss -tlnp | grep 8000

تكون النتيجة السليمة سطراً واحداً مرتبطاً بـ127.0.0.1:8000. أما السطر المرتبط بـ0.0.0.0:8000 فيعني أن vault مكشوف مباشرةً. أصلح الربط، ثم أعد إنشاء الحاوية، لأن ربط المنفذ يُثبَّت عند إنشاء الحاوية، ولن يغيّره docker compose restart:

docker compose up -d --force-recreate

يوجد منفذ آخر في الأدلة القديمة: 3012، وهو منفذ WebSocket مستقل. أُزيل دعمه في Vaultwarden 1.31.0، لأن حركة الإشعارات انتقلت إلى منفذ HTTP الرئيسي. كان يتم تجاهل WEBSOCKET_ENABLED وWEBSOCKET_PORT منذ 1.29.0. والمفتاح الحالي هو ENABLE_WEBSOCKET، وتبلغ قيمته الافتراضية true. إذا كان جدارك الناري أو ملف compose لا يزال يفتح المنفذ 3012، فأغلقه.

إنهاء TLS عند Reverse Proxy، وليس داخل Rocket

يمكن لـVaultwarden تقديم TLS (أمان طبقة النقل) بنفسه عبر Rocket، وهو إطار الويب الخاص به، لكن المشروع ينصح بعدم فعل ذلك في بيئة الإنتاج. لا يوفّر TLS المدمج في Rocket دعماً صارماً لـSNI (إشارة اسم الخادم)، ولذلك تنص إرشادات التحصين أيضاً على الوصول إلى مثيلك باستخدام اسم المضيف، وعدم استخدام عنوان IP مجرداً إطلاقاً. تُفحص نطاقات IP العامة باستمرار، والخزنة التي تستجيب على عنوان IP هي خزنة يمكن العثور عليها.

الأجزاء المهمة من كتلة الخادم في nginx:

client_max_body_size 525M;

location / {
  proxy_pass http://127.0.0.1:8000;
  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_set_header Upgrade $http_upgrade;
  proxy_set_header Connection $connection_upgrade;
}

تعيّن nginx القيمة الافتراضية لـclient_max_body_size إلى 1 MB، ولذلك يفشل رفع المرفق من دون ذلك السطر مع 413 Request Entity Too Large في سجل أخطاء nginx، بينما لا يسجل Vaultwarden أي شيء على الإطلاق. تحمل الرأسان Upgrade وConnection مصافحة WebSocket إلى /notifications/hub. إذا حذفتهما، فستظل الخزنة تعمل، لكن التغييرات لن تظهر على أجهزتك الأخرى حتى تعيد تحميل الصفحة يدوياً.

يكون إعداد Caddy أقصر، ويحصل على الشهادة بنفسه:

vw.example.com {
  reverse_proxy 127.0.0.1:8000 {
    header_up X-Real-IP {remote_host}
  }
}

ثم أخبر Vaultwarden بذلك:

DOMAIN=https://vw.example.com
IP_HEADER=X-Real-IP

تكون قيمة IP_HEADER الافتراضية هي X-Real-IP، ولذلك تتمثل المهمة في التأكد من أن الـproxy يعيّن هذا الرأس فعلياً. إذا لم يفعل ذلك، فسيرى كل سطر في السجل وكل حد لمعدل تسجيل الدخول القيمة 127.0.0.1، أي الـproxy نفسه، ما يعني أن إخفاقات مهاجم واحد ستُحتسب على كل مستخدم في المثيل. عيّن DOMAIN إلى عنوان https الفعلي أيضاً، لأن Vaultwarden ينشئ منه روابط الدعوات وإعادة تعيين كلمات المرور، كما ترتبط مفاتيح أمان WebAuthn بذلك الأصل.

هناك تفصيل يغفل عنه بعض الأشخاص: يمرر اتصال WebSocket رمز الجلسة في سلسلة الاستعلام، كما في /notifications/hub?access_token=[JWT]. ويظهر ذلك بوضوح في سجل الوصول الخاص بالـproxy. احجب المعلمة access_token في تنسيق السجل، أو تأكد من عدم إرسال هذه السجلات إلى أي جهة لا تسيطر عليها.

حظر هجمات القوة الغاشمة على نقطة تسجيل الدخول

تكون حدود المعدل مفعّلة افتراضياً (LOGIN_RATELIMIT_SECONDS=60، LOGIN_RATELIMIT_MAX_BURST=10). وهي تبطئ المهاجم، لكنها لا توقفه. أما fail2ban فيوقفه، لكن يجب أن يكتب Vaultwarden ملف سجل أولاً، وهو لا يفعل ذلك تلقائياً:

LOG_FILE=/data/vaultwarden.log
LOG_LEVEL=info
EXTENDED_LOGGING=true

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

[2026-08-07 09:14:22][vaultwarden::api::identity][ERROR] Username or password is incorrect. Try again. IP: 203.0.113.10. Username: user@example.com.

اكتب المرشح إلى /etc/fail2ban/filter.d/vaultwarden.local:

[INCLUDES]
before = common.conf

[Definition]
failregex = ^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =

واكتب jail إلى /etc/fail2ban/jail.d/vaultwarden.local:

[vaultwarden]
enabled = true
port = 80,443
filter = vaultwarden
banaction = %(banaction_allports)s
logpath = /vw-data/vaultwarden.log
maxretry = 3
bantime = 14400
findtime = 14400

إذا أبقيت صفحة الإدارة، فأضف jail ثانية تكون قيمة failregex فيها هي ^.*Invalid admin token\. IP: <ADDR>.*$، لأن إخفاقات الإدارة تُسجَّل برسالة مختلفة، ولن يرى مرشح تسجيل الدخول هذه الإخفاقات أبداً. ثم تحقّق من إعدادك:

sudo systemctl restart fail2ban
sudo fail2ban-client status vaultwarden

تعرض jail العاملة ملف السجل ضمن File list، وتبلغ عن Currently failed: 0. اكتب كلمة مرور خاطئة ثلاث مرات من شبكة مختلفة، فيرتفع هذا العداد، ثم يظهر العنوان ضمن Banned IP list. إذا لم يتغير العداد، فالسبب المعتاد هو logpath: يجب أن يكون هذا هو مسار الملف على المضيف، لا مسار /data/... داخل الحاوية. والسبب المعتاد الثاني هو غياب X-Real-IP، ما يجعل كل حظر يستهدف وكيلك العكسي نفسه. ترد بقية الإعدادات، بما في ذلك jail الخاصة بـSSH التي يجب أن تكون قيد التشغيل لديك، في دليل fail2ban الخاص بـUbuntu 24.04.

كلمة المرور الرئيسية ما تزال تحمي النظام بأكمله

تعني التشفير من جهة العميل أن كلمة المرور الرئيسية هي المفتاح. لا يحمي كلمة المرور الرئيسية القصيرة على مثيل نسخ المهاجم قاعدة بياناته شيئاً مما يرد في هذا المنشور، لأن المهاجم يهاجم تلك النسخة دون اتصال وبالسرعة التي تسمح بها أجهزته. لا يصل أي إعداد على الخادم إلى جهاز المهاجم نفسه.

PASSWORD_ITERATIONS=600000 هو عدد تكرارات KDF الذي يُسلَّم إلى العملاء عند إنشاء حساب جديد. تحتفظ الحسابات الحالية بالقيمة التي أُنشئت بها، لذلك لا يؤدي رفعها إلى تغيير شيء للمستخدمين الذين سجّلوا العام الماضي. يجب عليهم تغييرها بأنفسهم من إعدادات أمان خزنة الويب، وهذا يعيد تشفير مفتاحهم. أخبرهم بذلك، لأن الواجهة لن تفعل ذلك.

بعد ذلك، فعّل المصادقة الثنائية لكل حساب. فهي لا تحمي النص المشفّر، لأن مفتاح الخزنة يُشتق من كلمة المرور الرئيسية وحدها. لكنها تمنع استخدام كلمة مرور مسروقة وحدها لتسجيل الدخول ومزامنة نسخة. يضيف REQUIRE_DEVICE_EMAIL=true خطوة لتأكيد البريد الإلكتروني عند تسجيل دخول الحساب لأول مرة من جهاز غير معروف.

أخطاء النسخ الاحتياطي هي موضع فشل خزائن الاستضافة الذاتية

يُبطل tar czf لمجلد البيانات، إذا تُرك في مجلد المنزل على الخادم الافتراضي الخاص نفسه، جميع الخطوات السابقة. يحتوي ذلك الأرشيف على db.sqlite3 الذي يتضمن النص المشفّر لجميع المستخدمين، وعلى rsa_key.pem الذي يتيح تزوير جلسات تسجيل الدخول، وعلى config.json الذي يتضمن رمز المسؤول وكلمة مرور SMTP بنص واضح. تمنح صلاحية القراءة لذلك الملف وحده صلاحية قراءة الخزنة.

تغطي ذلك قاعدتان. انقل الأرشيف خارج الخادم. شفّره قبل نقله.

توجد أيضاً مشكلة تتعلق بسلامة البيانات. قد يؤدي نسخ db.sqlite3 باستخدام cp أثناء تشغيل الخدمة إلى إنشاء ملف قيد الكتابة، ولن يُفتح هذا الملف. وقد لا تكتشف المشكلة إلا عند الاستعادة. استخدم اللقطة الخاصة بـSQLite بدلاً من ذلك:

sqlite3 /vw-data/db.sqlite3 ".backup '/tmp/vw-db-backup.sqlite3'"

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

ما الذي تتخلى عنه مقارنةً بخدمة Bitwarden المستضافة

تقييم صريح. يدير خدمة Bitwarden المستضافة أشخاص تتمثل وظيفتهم بدوام كامل في تشغيلها، مع عمليات تدقيق منشورة تجريها جهات خارجية، وشخص مناوب عند الساعة 3 صباحاً. عند الاستضافة الذاتية، تستبدل ذلك بجدول التصحيحات الخاص بك.

يصدر Vaultwarden إصلاحات الأمان ضمن الإصدارات العادية. الإصدار 1.37.0، الصادر في 24 July 2026، هو الإصدار الحالي حتى August 2026، وتطلب ملاحظاته من المستخدمين التحديث في أقرب وقت ممكن. إذا كانت لديك instance أعددتها قبل عام ثم نسيتها، فهي تشغّل شيفرة عمرها عام. لا يفيد الوسم latest وحده: تواصل الحاوية قيد التشغيل استخدام الصورة التي بدأت بها إلى أن تشغّل docker compose pull وتعيد إنشاءها. فعّل التحديثات غير التلقائية على Ubuntu لحزم المضيف، وحدد تذكيراً دورياً لتحديث الحاوية وتأكد من أنك ستقرأه فعلاً.

الاستنتاج الذي ينبغي للقارئ استخلاصه بصدق هو أن التشفير هنا يعتمد على تصميم Bitwarden، وهو تصميم متين، بينما تنتقل المخاطر التشغيلية بالكامل إليك. إذا ثبّتَّ التصحيحات واحتفظت بنسخة احتياطية في مكان آخر، فإن تشغيل Vaultwarden على VPS تتحكم فيه يُعد مكاناً مناسباً للاحتفاظ بكلمات المرور. إذا لم تكن ستلتزم بهاتين العادتين، فادفع مقابل الخدمة المستضافة ووجّه اهتمامك إلى أمور أخرى. توجد المقارنة التفصيلية بين الميزات في مقارنة Vaultwarden مع Bitwarden المستضاف ذاتياً.

تعزيز حماية المضيف أسفل الحاوية

يعمل Vaultwarden كعملية واحدة على جهاز Linux، ويمكن لـroot على ذلك الجهاز قراءة /vw-data مهما كانت إعدادات التطبيق. شغّل الحاوية كمستخدم غير مميّز باستخدام user: "1000:1000" في ملف compose، واضبط ملكية مجلد البيانات بما يتوافق مع ذلك، واجعل كل ما لا تكتب إليه الحاوية للقراءة فقط باستخدام :ro. ثم أغلق نقطة الدخول العامة: يشرح تعزيز حماية SSH على VPS تفعيل تسجيل الدخول بالمفاتيح فقط وتعطيل مصادقة كلمة المرور، وهذا ما يوقف الهجوم التقليدي الذي يتجاوز كل الإجراءات السابقة.

FAQ

هل يستطيع أحد قراءة كلمات المرور إذا سرق قاعدة بيانات Vaultwarden؟

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

هل ينبغي أن أستخدم ADMIN_TOKEN أم أعطّل صفحة الإدارة بالكامل؟

عطّلها إذا استطعت، لأن معظم المثيلات تحتاج إليها مرة واحدة لإعداد SMTP ودعوة المستخدمين، ثم لا تحتاج إليها مجدداً. لتعطيلها، لا تضبط ADMIN_TOKEN ولا DISABLE_ADMIN_TOKEN، وأزل أي مفتاح "admin_token" من config.json، ثم أعد إنشاء الحاوية. لا يكفي إزالة متغير البيئة وحده، لأن الإعدادات التي كُتبت من صفحة الإدارة موجودة في config.json ولها الأولوية. إذا أبقيت الصفحة مفعّلة، فخزّن الرمز في صورة تجزئة Argon2 تنتجها vaultwarden hash بدلاً من سلسلة عشوائية بنص واضح، واضبط ADMIN_RATELIMIT_MAX_BURST=3.

رمز ADMIN_TOKEN صحيح، لكن /admin يرفضه. ما المشكلة؟

في الغالب تكون المشكلة في استيفاء $. تحتوي سلسلة Argon2 PHC على عدة محارف $، ويوسّعها Docker Compose كمتغيرات داخل كتلة docker-compose.yml environment:، لذلك تتلقى الحاوية قيمة مشوّهة رغم أن الملف يبدو صحيحاً. ضاعف كل $ إلى $$ في ملف compose، أو انقل القيمة إلى ملف .env محاطة بعلامتي اقتباس مفردتين، حيث لا تحتاج إلى أي تهريب. أعد إنشاء الحاوية بعد ذلك، لأن تغييرات البيئة لا تُلتقط عند إعادة التشغيل.

هل ما زلت بحاجة إلى فتح المنفذ 3012 للإشعارات؟

لا. أزيل دعم حركة WebSocket على المنفذ 3012 في Vaultwarden 1.31.0 لأن الإشعارات نُقلت إلى منفذ HTTP الرئيسي، كما جرى تجاهل WEBSOCKET_ENABLED وWEBSOCKET_PORT منذ 1.29.0. الإعداد الحالي هو ENABLE_WEBSOCKET، وقيمته الافتراضية هي true. أغلق المنفذ 3012 في جدار الحماية واحذفه من ملف compose، ثم تأكد من أن الـreverse proxy يمرر الرأسين Upgrade وConnection، لأن المزامنة الفورية تعتمد عليهما الآن.