SSD Nodes Learn Hosting plans →
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-31

התקנת Vaultwarden על VPS: מדריך אירוח עצמי לסיסמאות

למדו כיצד להריץ מנהל סיסמאות תואם Bitwarden באמצעות Vaultwarden ו-Docker. המדריך כולל הגדרת HTTPS, אבטחת Admin Token, חסימת תוקפים עם Fail2ban וביצוע גיבויים אמינים.

מה אתם בונים

מנהל סיסמאות בבעלותכם המלאה: Vaultwarden הרץ בתוך מכולה (container) קטנה מאחורי reverse proxy המבצע TLS termination, כאשר אפליקציות Bitwarden הרשמיות בטלפון, במחשב הנייד ובדפדפן שלכם מוגדרות לעבוד מולו. Vaultwarden הוא מימוש מחדש של ה-API של שרת Bitwarden בשפת Rust, והוא משתמש באותו פרוטוקול כמו bitwarden.com. לכן, כל לקוח רשמי עובד מולו ללא שינוי, אך הוא צורך כ-100 MB של RAM בלבד, בניגוד ל-stack הרשמי מרובה המכולות.

ההתקנה עצמה מורכבת מתריסר שורות ב-Compose. שלושת הדברים שבאמת חשובים, ואלו שנוטים להישבר, הם: חייב להיות TLS קיים לפני שאתם טוענים את ה-web vault בפעם הראשונה, יש לסגור את ההרשמה הציבורית ברגע שהחשבון שלכם נוצר, ויש לבצע גיבוי לנפח הנתונים (data volume) ולבדוק את השחזור שלו, כיוון שתיקייה אחת זו מכילה את כל הסיסמאות שלכם.

דרישות קדם ומלכודות נפוצות

  • שרת VPS עם Docker Engine ותוסף Compose, מותקן על גבי Ubuntu 24.04 KVM נקי עם הרשאות root או sudo. זיכרון RAM בנפח 512 MB מספיק בהחלט; 1 GB יספק עבודה נוחה. זהו אחד השירותים הקלים ביותר להרצה, והוא מדורג גבוה ברשימת השירותים המומלצים לאירוח עצמי. עם זאת, יש להתאים את גודל השרת לשירותים נוספים שירוצו עליו: הרצת ספריית תמונות כמו PhotoPrism או Immich על אותו VPS תדרוש נפח זיכרון של כמה גיגה-בייטים, בעוד ש-Vaultwarden כמעט אינו צורך משאבים. אותו חישוב תקף לממשקי מדיה שתוסיפו בהמשך, שכן הפיכת ספריית Jellyfin לחנות השכרת סרטים בסגנון שנות ה-90 משמעותה מכולה נוספת שרצה תמיד, בתוספת מרווח ביצועים לקידוד וידאו (transcoding) באותו תקציב.
  • שם מתחם (domain) עם רשומת A (ורשומת AAAA אם יש לכם IPv6) המצביעה vault.example.com על ה-VPS. תעודת ה-TLS מונפקת עבור שם זה בדיוק, לכן ה-DNS חייב לפתור את הכתובת לפני תחילת העבודה.
  • פורטים 80 ו-443 פתוחים לאינטרנט ומנוהלים על ידי ה-reverse proxy שלכם, לעולם לא ישירות על ידי Vaultwarden. פורט 80 משמש אך ורק עבור אתגר הנפקת התעודה (ACME challenge) והפניה מ-HTTP ל-HTTPS.
  • המלכודת הגדולה ביותר מראש: לקוחות Bitwarden מסרבים לתקשר עם שרת שאינו מאובטח ב-HTTPS. אין אפשרות ל"בדיקה ראשונית ב-HTTP"; נתיב זה אינו עובד, מסיבה קונקרטית שתידון בהמשך.

מדוע לבחור ב-Vaultwarden ולא בחבילת Bitwarden הרשמית

אותם לקוחות, שבריר מהמשאבים. חבילת ה-Bitwarden הרשמית לאירוח עצמי מופצת כאוסף של מכולות (MSSQL, Nginx, Identity, Api, Admin ועוד) ודורשת כ-2 GB של זיכרון RAM. לעומתה, Vaultwarden הוא קובץ בינארי יחיד ששומר את כל הנתונים בבסיס נתונים מסוג SQLite כברירת מחדל, וצורך עשרות בודדות של מגה-בייטים במצב המתנה. עבור משתמש בודד, משפחה או צוות קטן, זו הבחירה המובנת מאליה. מכיוון שהוא מיישם את ה-API של Bitwarden באופן נאמן למקור, הנתונים שלכם נשארים ניידים בינו לבין bitwarden.com.

מה שאתם מוותרים עליו הוא רוב המעטפת הארגונית: אין תמיכה ב-SCIM provisioning (אם כי תמיכה ניסיונית ב-OpenID Connect SSO נוספה בגרסה 1.35.0), ואתם המפעילים של המערכת, כך שעדכוני גרסה, HTTPS וגיבויים הם באחריותכם. מדריך זה עוסק בשלוש המשימות הללו.

מדוע HTTPS אינו אופציונלי

ה-web vault של Bitwarden ותוספי הדפדפן גוזרים את מפתחות ההצפנה שלכם בדפדפן באמצעות ה-Web Crypto API (window.crypto.subtle). דפדפנים חושפים את crypto.subtle רק ב-secure context, כלומר HTTPS, או במקרה המיוחד של http://localhost. מעל http://vault.example.com רגיל, הגישה ל-API היא undefined, ולכן ברגע שהיישום מנסה לגזור מפתח הוא נכשל, והקונסולה מציגה:

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

הדף נתקע או מציג שגיאת קריפטוגרפיה כללית, ושום דבר לא מתחבר. לקוחות ה-desktop, ה-mobile והדפדפן מריצים בדיקה עצמית מול ה-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)

הפנו את רשומת ה־DNS לשרת ה־VPS שלכם וודאו שהיא מתרגמת לכתובת הנכונה:

dig +short vault.example.com

השורה שתודפס חייבת להציג את כתובת ה־IP של ה־VPS שלכם. אם השורה ריקה או שגויה, תקנו את הגדרות ה־DNS והמתינו לסיום ה־TTL; הנפקת תעודה תיכשל מול שם מתחם שאינו מתרגם לכתובת IP.

עבור ה־front end של ה־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"] לשירות והסירו את ה־labels של Traefik), לאחר מכן הנפיקו תעודה ובצעו proxy אליו. החלק של התעודה מכוסה ב-הנפקת תעודות Let's Encrypt באמצעות Certbot ו־nginx. התוספת הקריטית היא ה־WebSocket upgrade בנתיב ה־notifications:

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, ובכך גם את נפח הנתונים (data volume), ל-vaultwarden_vw-data, כלומר צפויים מראש; שלבי ה-Fail2ban והגיבוי להלן תלויים בשם מדויק זה.

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

צרו .env עבור ה-secret של הניהול וקובץ ה-Compose בתוך אותה ספרייה.

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

צרו את ה-token באמצעות openssl rand -base64 48 והדביקו אותו פנימה. (צורה חזקה יותר של hash מכוסה בהמשך; מחרוזת אקראית ארוכה מספיקה להתחלה.)

# 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 שלו; פרסום הפורט שלו במארח (host) הוא הדרך שבה אנשים מגישים את ה-vault ב-http בטעות. ו-DOMAIN חייב להיות כתובת ה-HTTPS הציבורית המלאה: הוא מוטמע בקישורי קבצים מצורפים, ב-WebAuthn 2FA ובנקודת הקצה של ההתראות, לכן ערך שגוי או http ישבור אותם גם כשהאתר נטען. התג latest הוא חריג מכוון לכלל הרגיל של לעולם-לא-latest; Vaultwarden מפיצה את הגרסאות היציבות שלה כ-image מתגלגל יחיד, כאשר :testing הוא ערוץ ה-pre-release הנפרד, לכן עדכנו במכוון ועברו על הערות השחרור לפני ה-pull. חריג זה מצומצם, עם זאת: רוב המכולות ארוכות-החיים עדיף שיהיו מקובעות לתג מדויק, וזה מה ששומר על סוכן שרץ תמיד באירוח עצמי על אותו VPS צפוי לאורך אתחולים ופעולות pull.

העלו את השירות ועקבו אחר הלוג:

docker compose up -d
docker compose logs -f vaultwarden

התחלה תקינה מסתיימת בשורה כמו Rocket has launched from http://0.0.0.0:80. תנו ל-Traefik מספר שניות למשוך את התעודה, לאחר מכן טענו את https://vault.example.com, אתם אמורים לקבל את ה-web vault של Bitwarden עם מנעול תקין וללא אזהרת תעודה.

שלב 3, הגדרת ADMIN_TOKEN חזק, ומלכודת ה-$$

ADMIN_TOKEN מגן על /admin, לוח הבקרה שיכול לקרוא כל משתמש והגדרה במופע שלך, לכן התייחס אליו כאל סיסמת root. קיימות שתי דרכים לעבודה.

הדרך הפשוטה היא שימוש במחרוזת האקראית שכבר יצרת באמצעות openssl rand -base64 48. מכיוון ש-base64 לעולם אינו מכיל $, הוא מוזן ישירות לתוך .env ללא צורך ב-escaping.

הדרך המאובטחת היא שימוש ב-hash מסוג Argon2 PHC, כך שהטוקן בטקסט גלוי לעולם אינו נשמר על הדיסק. צור אחד מול אותה תמונה:

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

הפקודה תבקש ממך להקליד פעמיים ותדפיס מחרוזת המתחילה ב-$argon2id$v=19$.... כאן טמונה המלכודת שגורמת לאנשים לאבד שעה של עבודה: Docker Compose מתייחס ל-$ כאל משתנה להצבה (interpolation), לכן עליך להכפיל כל $ ל-$$ כאשר אתה מדביק את ה-hash לקובץ ה-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 יציג רשימת חשבונות שלא אתם יצרתם.

כדי להוסיף בני משפחה או חברי צוות במועד מאוחר יותר מבלי לפתוח מחדש את הרישום הציבורי, השתמשו בכפתור Invite User בתוך /admin; נתיב זה מחייב הגדרה של SMTP כדי שהמוזמן יוכל לקבל את הקישור שלו.

שלב 5, גישה ל-/admin

נווטו אל https://vault.example.com/admin והזינו את ה-token הניהולי בטקסט גלוי (המחרוזת האקראית, או הסיסמה שהמרתם ל-hash, לא ה-hash עצמו). בתוך הממשק תוכלו להציג רשימת משתמשים, לכוונן הגדרות, לשלוח דוא"ל בדיקה ולבצע snapshot למסד הנתונים.

אם הדף מחזיר 404 Not Found, סימן ש-ADMIN_TOKEN ריק או לא מוגדר, מה שמשבית את הלוח לחלוטין – בחירה לגיטימית אם אינכם זקוקים לו. אם הדף נטען אך דוחה את ה-token שלכם, עיינו במלכודת ה-escaping של $$ ברשימת הכשלים להלן. שכחתם את ה-token? אין מנגנון שחזור; ערכו את .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., הכתובת שגויה, משתמשת ב-http, או שהתעודה אינה מהימנה. ודאו תחילה ש-https://vault.example.com נטען בצורה תקינה בדפדפן. עדכונים איטיים במכשירים אחרים נובעים מ-WebSocket push, נושא המפורט בהמשך.

שלב 7, הגדרת jail ב-Fail2ban עבור נקודת הקצה של ההתחברות

Vaultwarden מתעד כל ניסיון התחברות שנכשל בקובץ שהוגדר על ידי LOG_FILE, וזה בדיוק מה שדרוש להגנה מפני מתקפות brute-force. אם 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 ל-header שה-proxy שלכם שולח בפועל (X-Forwarded-For עבור Traefik, X-Real-IP עבור בלוק ה-nginx לעיל, או CF-Connecting-IP אם אתם מאחורי Cloudflare). שנית, ה-iptables chain הנכון תלוי ב-proxy שלכם: כאשר Traefik רץ כמכולה עם פורטים חשופים, התעבורה עוברת דרך ה-path של FORWARD ב-Docker, לכן החסימה חייבת להתבצע ב-DOCKER-USER כפי שצוין לעיל. עם זאת, אם בחרתם באפשרות ה-host-nginx משלב 1, החיבורים מסתיימים ב-nginx ב-chain של INPUT על המארח, וחסימת DOCKER-USER לעולם לא תראה אותם; במקרה כזה, מחקו את השורה chain = DOCKER-USER כדי ש-Fail2ban ישתמש ב-chain ברירת המחדל של INPUT. שלישית, השתמשו ב-banaction = iptables-allports במקום בברירת המחדל המבוססת על פורטים; ה-jail הזה אינו מגדיר פורט, וחסימה של כל הפורטים ב-DOCKER-USER חוסמת בצורה נקייה את התוקף מכל שירות חשוף על השרת.

שלב 8, גיבוי ה-vault ולאחר מכן שחזורו בפועל

ה-volume מסוג vw-data הוא מנהל הסיסמאות שלכם. הוא מכיל את db.sqlite3 (כל רשומה), את הספריות attachments/ ו-sends/, את הקבצים rsa_key.* שחותמים על סשנים של התחברות, ואת config.json מלוח הבקרה של הניהול. גיבוי שמדלג על אחד מאלה ייכשל ברגע האמת.

העתקה של db.sqlite3 בזמן ש-Vaultwarden כותב עלולה ללכוד קובץ חלקי ופגום, לכן בצעו 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 אל מחוץ לשרת; גיבוי שנמצא רק על השרת שאתם מגינים עליו אינו גיבוי. הדרך הנכונה להעביר אותו היא גיבוי לילי באמצעות restic לשרת אחר או ל-object storage, שמצפין את הארכיון ומבצע דה-דופליקציה ל-snapshots חוזרים עבורכם. כפתור ה-Backup Database בלוח הבקרה הוא snapshot חם ונוח של קובץ ה-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

מהמחשב הנייד שלכם, צרו מנהרה (tunnel) אליו באמצעות ssh -L 8888:127.0.0.1:8888 you@your-vps ופתחו את http://localhost:8888. מכיוון ש-localhost הוא הקשר מאובטח, crypto.subtle זמין וה-vault מפוענח מעל http רגיל כאן – המקום היחיד שבו זה מותר. התחברו עם סיסמת האב שלכם ואשרו שהרשומות שלכם קיימות: אם הן שם, מסד הנתונים, מפתחות ה-RSA וסיסמת האב שלכם עברו את התהליך בהצלחה, ותוכלו לבנות מחדש את המערכת על VPS חדש בתוך דקות. עצרו את ה-container עם Ctrl-C ומחקו את /tmp/vw-restore. שמרו על הרגל המנהרה הזה עבור כל ממשק ניהול אחר בשרת שלעולם לא אמור להיחשף לאינטרנט; כך תגיעו גם ל-סורק אבטחה open-kritt בהתקנה עצמית בפורט 5173.

מצבי כשל והודעות השגיאה הנלוות

Cannot read properties of undefined (reading 'importKey') בקונסולת הדפדפן. ה-vault נטען דרך http, ולכן crypto.subtle אינו מוגדר; יש לגשת אליו רק דרך https:// ולהוסיף הפניה (redirect) מ-HTTP ל-HTTPS ב-proxy.

This is not a recognized Bitwarden server... בלקוח. ה-Server URL מוגדר כ-http, הוקלד בשגיאה, או שהתעודה אינה מהימנה; ודאו ש-https://vault.example.com מציג מנעול תקין, ולאחר מכן הזינו אותו מחדש בהגדרות ה-self-hosted של הלקוח.

/admin דוחה סיסמה נכונה. ה-hash מסוג Argon2 איבד את ה-escaping שלו; כל $ חייב להיות $$ ב-Compose, או שהזנתם את ה-hash במקום את הטקסט הגלוי שהוא מייצג.

סנכרון איטי בין מכשירים; הקונסולה מציגה WebSocket connection to 'wss://vault.example.com/notifications/hub' failed. ה-proxy אינו מעביר את ה-headers מסוג Upgrade/Connection; ב-Traefik זה קורה אוטומטית, אך ב-nginx יש להוסיף את שתי שורות ה-upgrade משלב 1. ה-vault עדיין עובד, אך הסנכרון מתבצע רק בעת פתיחה. הפורט הייעודי הישן 3012 בוטל החל מגרסה v1.31.0, לכן אין צורך בנתיב נפרד עבור WebSocket.

Fail2ban מדווח על חסימה אך התוקף ממשיך להתחבר. הוא חוסם את 127.0.0.1 כיוון ש-IP_HEADER שגוי, או שהחסימה נמצאת ב-chain הלא נכון ב-iptables; הגדירו את chain = DOCKER-USER ו-banaction = iptables-allports.

שדרוגים

משכו את ה-image החדש ובצעו יצירה מחדש; ה-named volume וכל הנתונים שלכם יישמרו:

docker compose pull
docker compose up -d

Vaultwarden מפיצה גרסאות בתדירות גבוהה. עקבו אחר הערות השחרור של הפרויקט במקום להצמיד גרסת patch, כיוון שחלק מהגרסאות כוללות הערות על תהליכי הגירה (migration). בצעו גיבוי טרי לפני כל שדרוג גרסה משמעותי; ניתן לבצע rollback על ידי שחזור ה-tarball לתוך volume חדש.

FAQ

האם Vaultwarden זהה ל-Bitwarden?

מדובר בשרת עצמאי ותואם, ולא בשרת הרשמי. Vaultwarden מממש מחדש את ה-API של שרת Bitwarden בשפת Rust, ולכן כל הלקוחות הרשמיים (שולחן עבודה, מובייל, דפדפן ו-CLI) עובדים מולו, תוך צריכת משאבים נמוכה משמעותית מהמערך הרשמי. פורמט הכספת זהה, כך שניתן לבצע הגירה לכל כיוון באמצעות ייצוא וייבוא.

האם אני באמת זקוק ל-HTTPS, או שאפשר להריץ את זה על http ברשת המקומית (LAN)?

אתה זקוק ל-HTTPS לכל מטרה שאינה בדיקת localhost. הכספת המקוונת של Bitwarden והתוספים משתמשים ב-Web Crypto API של הדפדפן, הזמין רק בהקשר מאובטח. לכן, בחיבור http רגיל, הלקוח יציג Cannot read properties of undefined ולעולם לא יתחבר. כתובת ה-http היחידה שעובדת היא http://localhost, וזו הסיבה שבדיקת השחזור בשלב 8 משתמשת ב-SSH tunnel.

איך אוכל למנוע מזרים להירשם לשרת שלי?

הגדר את SIGNUPS_ALLOWED: "false" בקובץ ה-Compose והרצ את docker compose up -d מיד לאחר יצירת החשבון שלך. מעתה ואילך, הוסף משתמשים חדשים דרך כפתור ה-Invite User ב-/admin, מה שמחייב הגדרת SMTP כדי שהם יקבלו את קישור ההזמנה. בדוק את רשימת המשתמשים ב-admin מדי פעם כדי לוודא שלא הופיעו חשבונות לא צפויים.

איך מגבים את כספת ה-Vaultwarden שלי?

עצור את ה-container לזמן קצר וגבה את כל ה-volume של vw-data, את db.sqlite3, attachments/, sends/, config.json ואת הקבצים של rsa_key.*. לאחר מכן, העתק את הארכיון מחוץ לשרת, רצוי באמצעות cron לילי. העתקת קובץ ה-SQLite בזמן שהשרת רץ מסתכנת ביצירת snapshot פגום, לכן בצע זאת כשהשרת כבוי. החשוב מכל: שחזר את הגיבוי פעם אחת ל-container זמני והתחבר אליו, כדי לוודא שהגיבוי תקין לפני שתסתמך עליו.

האם זה באמת בטוח לארח את הסיסמאות שלי בעצמי?

כן, בתנאי שאתה מבצע את שלושת הדברים המכוסים במדריך זה: HTTPS אמיתי, סגירת הרשמות יחד עם admin token חזק, ובדיקת גיבויים. הכספת שלך מוצפנת בצד הלקוח עם סיסמת האב שלך, כך שהשרת לעולם לא רואה את הסיסמאות שלך בטקסט גלוי; גניבה של db.sqlite3 תהיה חסרת תועלת בלעדיה. המחיר הוא שעדכוני אבטחה וגיבויים הם כעת באחריותך, וזו הסיבה ש-Fail2ban וטקס השחזור אינם אופציונליים כאן. ברגע שאלו מיושמים, מבט מעמיק יותר על נקודות התורפה של כספת בניהול עצמי הוא הצעד הבא המועיל, שכן כאשר הערכים עצמם מוצפנים בלקוח, מה שנותר להגן עליו הוא ה-admin token וארכיון הגיבוי.