क्या Vaultwarden सुरक्षित है? इसे सुरक्षित कैसे बनाएं
Vaultwarden में डेटा क्लाइंट-साइड एन्क्रिप्ट होता है, इसलिए सर्वर पर कोई प्लेनटेक्स्ट नहीं होता। सुरक्षा का असली जोखिम एडमिन टोकन और असुरक्षित बैकअप फाइल में छिपा है।
क्या Vaultwarden सुरक्षित है? संक्षिप्त उत्तर
Vaultwarden उस एक जगह पर सुरक्षित है जो सबसे अधिक मायने रखती है, क्योंकि हर vault item सर्वर तक पहुँचने से पहले आपके डिवाइस पर ही encrypt हो जाता है। सर्वर केवल ऐसे blobs को स्टोर करता है जिन्हें वह पढ़ नहीं सकता। यदि कोई पूरे database की कॉपी भी कर ले, तो भी उसे उपयोगी जानकारी निकालने के लिए master password की आवश्यकता होगी।
यह उत्तर बहुत कुछ कहता है, लेकिन जो हिस्से विफल होते हैं, वे वे हैं जिन्हें आप configure करते हैं। एक अनुमान लगाने योग्य token के पीछे छिपा admin panel। पूरी internet पर publish किया गया container port। एक plaintext config.json। उसी box पर home directory में पड़ा एक backup tarball। इनमें से कोई भी cryptography की समस्या नहीं है। ये सभी वे कारण हैं जिनकी वजह से self-hosted vaults खाली हो जाते हैं।
नीचे दी गई हर बात एक कार्यशील install पर आधारित है। यदि आपके पास अभी तक यह नहीं है, तो पहले VPS के लिए Vaultwarden install guide के साथ इसे set up करें, फिर वापस आएं और इस सूची पर क्रमवार काम करें।
सर्वर वास्तव में क्या स्टोर करता है
Vaultwarden, Bitwarden के डेटा मॉडल को लागू करता है। किसी वॉल्ट आइटम का नाम, यूजरनेम, पासवर्ड, नोट्स और URI को आपके मास्टर पासवर्ड से प्राप्त एक की (key) के साथ क्लाइंट-साइड पर एन्क्रिप्ट किया जाता है, इससे पहले कि कोई भी रिक्वेस्ट भेजी जाए। अटैचमेंट फ़ाइलों की सामग्री भी इसी तरह एन्क्रिप्ट की जाती है। सर्वर को इसके साथ जुड़े एक UUID (यूनिवर्सली यूनिक आइडेंटिफ़ायर) के साथ अपारदर्शी (opaque) डेटा प्राप्त होता है।
कुछ चीजें सिफरटेक्स्ट (ciphertext) नहीं होती हैं, और आपको पता होना चाहिए कि वे क्या हैं:
- आपका अकाउंट ईमेल एड्रेस, जो प्लेनटेक्स्ट में होता है।
- आपकी KDF (की डेरिवेशन फ़ंक्शन) सेटिंग्स और साल्ट, क्योंकि क्लाइंट को अगली बार लॉगिन करने पर की को फिर से बनाने के लिए इनकी आवश्यकता होती है।
- क्लाइंट द्वारा भेजे गए मास्टर पासवर्ड हैश का एक सर्वर-साइड हैश, जिसका उपयोग लॉगिन को प्रमाणित करने के लिए किया जाता है।
- मेटाडेटा: संगठन की सदस्यता, डिवाइस के नाम, अंतिम लॉगिन का समय।
- टू-फैक्टर ऑथेंटिकेशन का सीक्रेट जो Vaultwarden लॉगिन को सुरक्षित रखता है। यह
twofactorटेबल में बिना एन्क्रिप्ट किए रहता है, क्योंकि सर्वर को आपके द्वारा दिए गए कोड की तुलना करने के लिए अपेक्षित कोड की गणना करनी होती है। यह उस TOTP (टाइम-बेस्ड वन-टाइम पासवर्ड) सीक्रेट से अलग है जिसे आप वॉल्ट आइटम के अंदर स्टोर करते हैं, जो किसी अन्य फ़ील्ड की तरह एन्क्रिप्टेड होता है।
डेटा फ़ोल्डर छोटा होता है। Docker इंस्टॉलेशन पर, यह वह होता है जिसे आपने /data पर माउंट किया है।
sudo ls -l /vw-data/db.sqlite3 में लगभग पूरी स्टेट होती है। attachments/ में अपलोड की गई फ़ाइलें होती हैं, प्रति UUID एक, और यह डेटा का एकमात्र महत्वपूर्ण वर्ग है जो डेटाबेस टेबल में नहीं रहता है। sends/ में Send अटैचमेंट होते हैं और यह अस्थायी होते हैं। icon_cache/ को हटाया जा सकता है। rsa_key.pem और इसके साथी लॉग-इन उपयोगकर्ताओं के JWTs (JSON वेब टोकन) पर हस्ताक्षर करते हैं, इसलिए उस प्राइवेट की की एक कॉपी का उपयोग वॉल्ट लॉगिन सेशन को फोर्ज (forge) करने के लिए किया जा सकता है। config.json केवल तभी मौजूद होता है जब आप एडमिन पेज को इनेबल करते हैं, और प्रोजेक्ट इस बारे में स्पष्ट है: इसमें एडमिन टोकन और आपके SMTP क्रेडेंशियल्स प्लेनटेक्स्ट में होते हैं।
इसलिए, व्यावहारिक खतरा नेटवर्क क्रिप्टोग्राफी नहीं, बल्कि फ़ाइलसिस्टम एक्सेस है। उस एक डायरेक्टरी तक रीड एक्सेस मिलने का मतलब है हर उपयोगकर्ता का ईमेल एड्रेस, उनके लॉगिन 2FA सीक्रेट्स, सेशन फोर्ज करने वाली की, और हर वॉल्ट की एक ऑफ़लाइन कॉपी जिसे फुर्सत में क्रैक किया जा सके। नीचे दिए गए हर कदम का उद्देश्य लोगों को उस डायरेक्टरी से दूर रखना है।
सबसे पहले admin token को ठीक करें
/admin एक पूर्ण control panel है: इसमें user list, invitations, deletion और हर runtime setting शामिल है। यह केवल एक shared secret द्वारा सुरक्षित है और इसके अलावा कुछ नहीं। इसमें कोई username नहीं होता। न ही प्रति-user two-factor authentication होता है।
पुराने guides आपको openssl rand -base64 48 के साथ ADMIN_TOKEN generate करने के लिए कहते हैं। यह काम करता है, और यह secret को plaintext में config.json और आपके compose file में लिख देता है। Vaultwarden एक Argon2 PHC (password hashing competition) string भी स्वीकार करता है, इसलिए संग्रहीत मान एक hash होता है। इसे एक चल रहे container के विरुद्ध generate करें:
docker exec -it vaultwarden /vaultwarden hashया चल रहे container को छुए बिना:
docker run --rm -it vaultwarden/server /vaultwarden hashयह दो बार password मांगेगा, फिर $argon2id$ से शुरू होने वाली एक line print करेगा। Bare-metal install पर, ./vaultwarden hash चलाएँ। यदि आप सीधे argon2 CLI का उपयोग करना पसंद करते हैं, तो project OWASP के न्यूनतम parameters का दस्तावेजीकरण करता है:
echo -n 'MySecretPassword' | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1अब वह जाल जिसमें लोगों का एक घंटा बर्बाद हो जाता है। एक PHC string में $ characters होते हैं, और Docker Compose $ को variable interpolation के रूप में मानता है। इसे unescaped रूप में environment: block में paste करने पर container तक पहुँचने वाला मान खराब हो जाता है, और /admin आपके द्वारा सही बताए गए token को अस्वीकार कर देता है। इसके दो सुरक्षित तरीके हैं। docker-compose.yml में, हर $ को double करें:
environment:
ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$UUZxK1FZMkZoRHFQRlVrTXZvS0E3bHpNQW55c2dBN2NORzdsa0Nxd1JhND0$$cUoId+JBUsJutlG4rfDZayExfjq4TCt48aBc9qsc3UIएक .env file में, किसी escaping की आवश्यकता नहीं है, लेकिन single quotes का उपयोग करें:
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$MmeKRnGK5RW5mJS7h3TOL89GrpLPXJPAtTK8FTqj9HM$DqsstvoSAETl9YhnsXbf43WeaUwJC6JhViIvuPoig78'फिर panel को rate limit करें और इसके session को छोटा करें:
ADMIN_RATELIMIT_SECONDS=300
ADMIN_RATELIMIT_MAX_BURST=3
ADMIN_SESSION_LIFETIME=20पाँच मिनट के भीतर तीन गलत प्रयासों के बाद panel उस client को जवाब देना बंद कर देता है। Admin session 20 मिनट की निष्क्रियता के बाद समाप्त हो जाता है।
इन सबसे बेहतर तरीका: page को बंद कर दें। अधिकांश instances को SMTP configure करने और पहले users को invite करने के लिए इसकी केवल एक बार आवश्यकता होती है, उसके बाद कभी नहीं। इसे disable करने के लिए, न तो ADMIN_TOKEN और न ही DISABLE_ADMIN_TOKEN set करें, config.json से कोई भी "admin_token" key हटा दें, और फिर container को recreate करें। file से key हटाना महत्वपूर्ण है क्योंकि admin page settings को वहीं लिखता है, और config.json में जो होता है वह environment पर हावी रहता है। केवल variable हटाने से page खुला रह जाता है।
डोमेन मिलने से पहले रजिस्ट्रेशन बंद करें
SIGNUPS_ALLOWED=false
SIGNUPS_VERIFY=true
SHOW_PASSWORD_HINT=falseSIGNUPS_ALLOWED का डिफ़ॉल्ट मान true होता है। यदि आप इसे ऐसे ही छोड़ देते हैं, तो आपके डोमेन पर आने वाला कोई भी व्यक्ति अकाउंट बना सकता है, और उनका डेटा आपके डेटा के साथ उसी db.sqlite3 में रहेगा। इसे false पर सेट करें और एडमिन पेज से आमंत्रण (invitations) भेजकर लोगों को जोड़ें, जिसके लिए SMTP का सही काम करना आवश्यक है। INVITATIONS_ALLOWED भी डिफ़ॉल्ट रूप से true होता है और यह ऑर्गनाइजेशन मालिकों को दूसरों को आमंत्रित करने की अनुमति देता है। यदि आप अपने उपयोगकर्ताओं पर भरोसा करते हैं तो यह ठीक है, लेकिन सिंगल-यूज़र इंस्टेंस पर इसे false होना चाहिए। यदि केवल कुछ विशिष्ट डोमेन को ही रजिस्टर करने की अनुमति देनी है, तो SIGNUPS_DOMAINS_WHITELIST=example.com का उपयोग करें; यह ओपन साइनअप से अधिक सीमित है लेकिन आमंत्रण प्रणाली की तुलना में काफी कमजोर है।
SHOW_PASSWORD_HINT डिफ़ॉल्ट रूप से false होता है और इसे इसी स्थिति में रहना चाहिए। यदि यह चालू है, तो लॉगिन फॉर्म में एक वैध ईमेल पता डालने पर उस अकाउंट का मास्टर पासवर्ड हिंट दिखाई देता है, जिससे हिंट लीक हो जाता है और यह भी पुष्टि हो जाती है कि वह ईमेल पता मौजूद है।
यदि आपका इंस्टेंस कुछ समय के लिए भी ओपन साइनअप के साथ चला है, तो एडमिन पेज खोलें और यह मानने से पहले कि आप उस पर एकमात्र अकाउंट हैं, उपयोगकर्ता सूची (user list) की जाँच करें।
वह पोर्ट जिसे आप पब्लिश नहीं करना चाहते थे
Docker image कंटेनर के अंदर पोर्ट 80 पर listen करती है। Bare-metal इंस्टॉलेशन डिफ़ॉल्ट रूप से ROCKET_PORT=8000 का उपयोग करता है। प्रलेखित run कमांड इसे इस तरह पब्लिश करती है:
--publish 127.0.0.1:8000:80127.0.0.1: प्रीफिक्स ही इसका मुख्य उद्देश्य है। इसके बजाय -p 8000:80 लिखें और Docker 0.0.0.0 को बाइंड कर देगा, और यह ऐसा nat टेबल में DNAT (destination network address translation) नियम लिखकर करता है। उन नियमों का मूल्यांकन ufw द्वारा प्रबंधित filter चेन से पहले किया जाता है, इसलिए ufw status पोर्ट को denied के रूप में रिपोर्ट करता है जबकि पोर्ट इंटरनेट पर सक्रिय रूप से उत्तर दे रहा होता है। पूरी कार्यप्रणाली को Docker पोर्ट्स द्वारा ufw को बायपास करने की गाइड में पढ़ना उपयोगी है।
जाँचें कि वास्तव में क्या listen कर रहा है:
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 को खोलती है, तो उसे बंद कर दें।
Rocket के बजाय reverse proxy पर TLS terminate करें
Vaultwarden अपने web framework, Rocket के माध्यम से स्वयं TLS (transport layer security) प्रदान कर सकता है, लेकिन प्रोजेक्ट इसे production में उपयोग न करने की सलाह देता है। Rocket के इन-बिल्ट TLS में सख्त SNI (server name indication) सपोर्ट की कमी है। यही कारण है कि सुरक्षा के लिए यह सलाह दी जाती है कि आप अपने instance तक hostname के जरिए ही पहुँचें, न कि सीधे IP address से। Public IP ranges को लगातार स्कैन किया जाता है, और जो vault IP address पर प्रतिक्रिया देता है, वह आसानी से खोज लिया जाता है।
nginx server block के महत्वपूर्ण हिस्से:
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 का default client_max_body_size 1 MB होता है, इसलिए उस line के बिना attachment upload विफल हो जाता है और nginx error log में 413 Request Entity Too Large दिखाई देता है, जबकि Vaultwarden logs में कुछ भी दर्ज नहीं होता। Upgrade और Connection headers WebSocket handshake को /notifications/hub तक ले जाते हैं। यदि आप इन्हें हटा देते हैं, तो vault काम तो करेगा, लेकिन आपके अन्य उपकरणों पर बदलाव तब तक दिखाई नहीं देंगे जब तक आप page को मैन्युअल रूप से reload नहीं करते।
Caddy का configuration छोटा है और यह स्वयं certificate प्राप्त कर लेता है:
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-IPIP_HEADER पहले से ही default रूप से X-Real-IP पर सेट होता है, इसलिए मुख्य कार्य यह सुनिश्चित करना है कि proxy वास्तव में उस header को सेट करे। यदि ऐसा नहीं होता है, तो प्रत्येक log line और login rate limit में proxy का IP, यानी 127.0.0.1 दिखाई देगा। इसका अर्थ यह है कि एक हमलावर की विफलताएं instance के सभी उपयोगकर्ताओं के विरुद्ध गिनी जाएंगी। DOMAIN को भी वास्तविक https URL पर सेट करें, क्योंकि Vaultwarden इसी से invitation और password reset links बनाता है, और WebAuthn security keys भी उसी origin से बंधी होती हैं।
एक विवरण जिसे लोग अक्सर अनदेखा कर देते हैं: WebSocket connection session token को query string में /notifications/hub?access_token=[JWT] के रूप में भेजता है। यह आपके proxy access log में स्पष्ट (clear text) रूप में दर्ज हो जाता है। log format में access_token parameter को redact करें, या यह सुनिश्चित करें कि वे logs ऐसी किसी जगह न भेजे जाएं जिसे आप नियंत्रित नहीं करते हैं।
Login endpoint पर brute force को रोकें
Rate limits डिफ़ॉल्ट रूप से चालू रहती हैं (LOGIN_RATELIMIT_SECONDS=60, LOGIN_RATELIMIT_MAX_BURST=10)। ये हमलावर की गति को धीमा करती हैं, लेकिन उसे पूरी तरह रोकती नहीं हैं। fail2ban ऐसा कर सकता है, लेकिन इसके लिए Vaultwarden को पहले एक log file लिखनी होगी, जो यह डिफ़ॉल्ट रूप से नहीं करता है:
LOG_FILE=/data/vaultwarden.log
LOG_LEVEL=info
EXTENDED_LOGGING=trueएक असफल login प्रयास के बाद ठीक एक line generate होती है, और यही वह string है जिसे आपके filter को match करना होगा:
[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.Filter को /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यदि आपने admin page को रखा है, तो एक दूसरी jail जोड़ें जिसका failregex, ^.*Invalid admin token\. IP: <ADDR>.*$ हो, क्योंकि admin failures एक अलग message के साथ log होते हैं और login filter उन्हें कभी नहीं देख पाएगा। फिर अपने काम की जाँच करें:
sudo systemctl restart fail2ban
sudo fail2ban-client status vaultwardenएक कार्यशील jail आपकी log file को File list के अंतर्गत सूचीबद्ध करती है और Currently failed: 0 की रिपोर्ट देती है। किसी अलग network से तीन बार गलत password डालें और वह counter बढ़ जाएगा, फिर वह address Banned IP list के अंतर्गत दिखाई देगा। यदि counter कभी नहीं बढ़ता है, तो इसका सामान्य कारण logpath है: यह host पर file का path होना चाहिए, न कि container के अंदर का /data/... path। दूसरा सामान्य कारण एक missing X-Real-IP है, जिसके कारण हर ban आपके स्वयं के proxy को target करने लगता है। सेटअप का बाकी हिस्सा, जिसमें SSH jail भी शामिल है जिसे आपको पहले से ही चलाना चाहिए, Ubuntu 24.04 के लिए fail2ban गाइड में उपलब्ध है।
मास्टर पासवर्ड ही पूरी प्रणाली की सुरक्षा है
Client-side encryption का अर्थ है कि मास्टर पासवर्ड ही मुख्य कुंजी है। यदि किसी attacker ने database की copy ले ली है, तो उस instance पर छोटा मास्टर पासवर्ड किसी काम का नहीं है। attacker उस copy पर अपने hardware की क्षमता के अनुसार offline हमला कर सकता है। सर्वर की कोई भी setting attacker की अपनी machine पर चल रहे हमले को नहीं रोक सकती।
PASSWORD_ITERATIONS=600000 वह KDF iteration count है जो clients को नया account बनाते समय दिया जाता है। पुराने accounts के पास वही value रहती है जिसके साथ वे बनाए गए थे, इसलिए इसे बढ़ाने से पिछले साल sign up करने वाले users पर कोई असर नहीं पड़ेगा। उन्हें स्वयं web vault की security settings में जाकर इसे बदलना होगा, जिससे उनकी key फिर से encrypt हो जाएगी। उन्हें इस बारे में सूचित करें, क्योंकि interface में इसके लिए कोई संकेत नहीं मिलता है।
इसके बाद, प्रत्येक account के लिए two-factor authentication सक्षम करें। यह ciphertext की सुरक्षा नहीं करता, क्योंकि vault key केवल मास्टर पासवर्ड से ही प्राप्त होती है। हालाँकि, यह चोरी हुए पासवर्ड को login करने और copy sync करने से रोकने में प्रभावी है। REQUIRE_DEVICE_EMAIL=true पहली बार किसी अज्ञात device से login करने पर email confirmation का चरण जोड़ता है।
Backups वह जगह है जहाँ self-hosted vaults विफल हो जाते हैं
उसी VPS पर home directory में छोड़ा गया data folder का tar czf ऊपर बताए गए हर कदम को बेकार कर देता है। उस archive में db.sqlite3 होता है जिसमें हर user का ciphertext होता है, rsa_key.pem जो login sessions को forge करता है, और config.json जिसमें admin token और SMTP password plaintext में होते हैं। उस एक file का read access होने का मतलब है पूरे vault का read access होना।
इसके लिए दो नियम हैं। archive को server से बाहर निकालें। इसे बाहर भेजने से पहले encrypt करें।
इसमें correctness की भी एक समस्या है। service के चलते समय cp के साथ db.sqlite3 को copy करने से ऐसी file बन सकती है जो write प्रक्रिया के बीच में हो और खुलेगी नहीं, और आपको इसका पता restore के समय तक नहीं चलेगा। इसके बजाय SQLite के अपने snapshot का उपयोग करें:
sqlite3 /vw-data/db.sqlite3 ".backup '/tmp/vw-db-backup.sqlite3'"Restore का पक्ष, जिसे कोई भी test नहीं करता, Vaultwarden backup and restore guide में शामिल है।
Hosted Bitwarden की तुलना में आप क्या खोते हैं
ईमानदार लेखा-जोखा। Bitwarden की hosted service उन लोगों द्वारा संचालित की जाती है जिनका पूर्णकालिक काम ही इसे चलाना है, जिसमें प्रकाशित third-party audits शामिल हैं और रात के 3 बजे भी कोई न कोई उपलब्ध रहता है। Self-hosting में आप इसे अपनी patch cadence से बदल लेते हैं।
Vaultwarden सुरक्षा सुधारों को सामान्य releases के रूप में भेजता है। Version 1.37.0, जिसे 24 July 2026 को release किया गया था, August 2026 तक current है, और इसके notes उपयोगकर्ताओं से जल्द से जल्द update करने के लिए कहते हैं। एक instance जिसे आपने एक साल पहले set up किया था और भूल गए, वह एक साल पुराना code चला रहा है। latest tag अपने आप में मदद नहीं करता है: एक running container उसी image को बनाए रखता है जिसके साथ वह शुरू हुआ था, जब तक कि आप docker compose pull न चलाएं और उसे recreate न करें। Host packages के लिए Ubuntu पर unattended upgrades लागू करें, और container update को एक calendar reminder पर रखें जिसे आप वास्तव में पढ़ेंगे।
एक ईमानदार पाठक को जो निष्कर्ष निकालना चाहिए: यहाँ cryptography Bitwarden का design है और यह सुरक्षित है, जबकि operational जोखिम पूरी तरह से आप पर आ जाता है। यदि आप इसे patch करते हैं और कहीं और backup लेते हैं, तो आपके द्वारा नियंत्रित VPS पर Vaultwarden instance आपके passwords रखने के लिए एक उचित जगह है। यदि ये दो आदतें आप नहीं अपना सकते, तो hosted service के लिए भुगतान करें और अपना ध्यान कहीं और लगाएं। Feature-दर-feature तुलना Vaultwarden की self-hosted Bitwarden के साथ तुलना में उपलब्ध है।
कंटेनर के नीचे होस्ट को सुरक्षित (Harden) करना
Vaultwarden एक Linux बॉक्स पर चलने वाली एक प्रक्रिया है, और उस बॉक्स पर root उपयोगकर्ता /vw-data को पढ़ सकता है, चाहे एप्लिकेशन को कैसे भी कॉन्फ़िगर किया गया हो। कंटेनर को एक unprivileged उपयोगकर्ता के रूप में चलाएं, जिसके लिए अपने compose फ़ाइल में user: "1000:1000" का उपयोग करें। डेटा फ़ोल्डर का स्वामित्व (ownership) उसी के अनुसार रखें, और जो कुछ भी कंटेनर द्वारा नहीं लिखा जाता है, उसे :ro के साथ read-only के रूप में माउंट करें। इसके बाद मुख्य द्वार बंद करें: VPS पर SSH को सुरक्षित करना लेख में key-only लॉगिन और पासवर्ड प्रमाणीकरण को अक्षम करने के बारे में बताया गया है, जो उन सामान्य हमलों को रोकता है जो उपरोक्त सभी सुरक्षा उपायों को पार कर जाते हैं।
FAQ
क्या Vaultwarden database चोरी होने पर कोई मेरे passwords पढ़ सकता है?
सीधे तौर पर नहीं। हर vault item को client-side पर master password से प्राप्त एक key के जरिए encrypt किया जाता है, इसलिए db.sqlite3 में केवल ciphertext होता है। हमलावर को तुरंत हर account का email address, KDF settings, login और device metadata मिलता है। twofactor table में मौजूद two-factor secrets unencrypted होते हैं क्योंकि server को अपेक्षित code की गणना करनी होती है। हमलावर vault ciphertext पर offline हमला कर सकते हैं, इसलिए master password की लंबाई ही सुरक्षा का मुख्य आधार है।
क्या मुझे ADMIN_TOKEN का उपयोग करना चाहिए या admin page को पूरी तरह disable कर देना चाहिए?
यदि संभव हो तो इसे disable कर दें, क्योंकि अधिकांश instances को SMTP configure करने और users को invite करने के लिए इसकी केवल एक बार आवश्यकता होती है। इसे disable करने के लिए, न तो ADMIN_TOKEN और न ही DISABLE_ADMIN_TOKEN को set करें, config.json से कोई भी "admin_token" key हटा दें, और फिर container को recreate करें। केवल environment variable को हटाना पर्याप्त नहीं है, क्योंकि admin page द्वारा लिखी गई settings config.json में रहती हैं और वे प्राथमिकता लेती हैं। यदि आप page को रखते हैं, तो token को plaintext string के बजाय vaultwarden hash द्वारा उत्पादित Argon2 hash के रूप में store करें और ADMIN_RATELIMIT_MAX_BURST=3 को set करें।
मेरा ADMIN_TOKEN सही है लेकिन /admin इसे reject कर रहा है। क्या गलत है?
यह लगभग हमेशा $ interpolation के कारण होता है। एक Argon2 PHC string में कई $ characters होते हैं, और Docker Compose उन्हें docker-compose.yml environment: block के अंदर variables के रूप में expand कर देता है। इस कारण container को एक गलत value मिलती है, जबकि आपकी file सही दिखती है। compose file में हर $ को $$ में बदलें (double करें), या value को single quotes में बंद करके एक .env file में ले जाएं, जहाँ किसी escaping की आवश्यकता नहीं होती। इसके बाद container को recreate करें, क्योंकि restart करने से environment changes लागू नहीं होते।
क्या मुझे notifications के लिए अभी भी port 3012 open रखने की आवश्यकता है?
नहीं। Vaultwarden 1.31.0 में port 3012 पर WebSocket traffic का समर्थन हटा दिया गया है क्योंकि notifications अब मुख्य HTTP port पर आ गई हैं। WEBSOCKET_ENABLED और WEBSOCKET_PORT को 1.29.0 के बाद से ignore किया जा रहा है। वर्तमान setting ENABLE_WEBSOCKET है, जो default रूप से true होती है। firewall में 3012 को close करें और इसे अपनी compose file से हटा दें। इसके बाद सुनिश्चित करें कि आपका reverse proxy Upgrade और Connection headers को forward कर रहा है, क्योंकि real-time sync अब इन्हीं पर निर्भर करता है।