Jinsi ya kuhifadhi na kurejesha data ya Vaultwarden VPS
Jifunze njia sahihi ya kuhifadhi Vaultwarden kwa kutumia amri ya sqlite3 .backup. Hakikisha unanakili faili za config.json, rsa_key, na attachments ili kurejesha data kikamilifu.
Yaliyomo kwenye backup ya Vaultwarden
Backup ya Vaultwarden ni nakala ya folda nzima ya data, na database iliyo ndani yake lazima inakiliwe kwa njia sahihi. Tekeleza sqlite3 db.sqlite3 ".backup out.sqlite3" badala ya cp, kwa sababu kunakili database inayotumika kwa njia ya kawaida kunaweza kusababisha faili kutofunguka. Kisha hifadhi faili zilizopo pembeni yake, jambo ambalo watu wengi husahau.
Kwenye usakinishaji wa Docker, folda ya data ni ile uliyoiweka kwenye /data. Hii inaweza kuwa njia kwenye host au named volume, na tofauti kati ya bind mounts na named volumes ndiyo huamua mahali halisi kwenye diski ambapo vault yako ipo. Hivi ndivyo inavyohifadhi:
db.sqlite3: kila akaunti, kila kitu cha vault, kila folda na kila shirika. Kupoteza faili hii kunamaanisha kupoteza vault.db.sqlite3-walnadb.sqlite3-shm: write-ahead log (WAL) na index yake ya shared memory. Maandishi ya hivi karibuni hukaa hapa hadi SQLite inapoyajumuisha kwenye faili kuu.attachments/: faili ambazo watumiaji wameziambatanisha kwenye vitu vya vault, zikiwa zimesimbwa, katika saraka moja kwa kila kitu.sends/: faili zilizopo nyuma ya viungo vya Bitwarden Send.config.json: kila mpangilio uliouhifadhi kutoka kwenye ukurasa wa admin.rsa_key.pem, pamoja narsa_key.dernarsa_key.pub.derkwenye usakinishaji wa zamani: ufunguo unaotia saini token za kuingia.icon_cache/: aikoni za tovuti zilizopakuliwa. Hii ndiyo saraka pekee unayoweza kuiruka, kwa sababu Vaultwarden huipakua tena inapohitajika.
Je, database yangu ya Vaultwarden iko salama? Nini hasa kilichomo kwenye faili hilo
Amri mbili zinajibu swali hili, na unaweza kuziendesha zote mbili sasa hivi.
sudo apt update && sudo apt install -y sqlite3
sudo sqlite3 /opt/vaultwarden/data/db.sqlite3 "select email from users;"
sudo sqlite3 /opt/vaultwarden/data/db.sqlite3 "select name from ciphers limit 1;"Amri ya kwanza inachapisha anwani za barua pepe za watumiaji wako katika maandishi ya kawaida (cleartext). Ya pili inachapisha jina la kitu kimoja, na linaonekana hivi:
2.k9Qw1nQ0y7Yy2Xw==|E1r0J3l5s7d9f1g3h5j7k9==|Lm4nOp6qRs8tUv0wXy2zAb4cDe6fGh8i=Majina ya vitu, majina ya watumiaji, nywila na madokezo husimbwa kwa njia fiche (encrypted) na mteja (client) kabla hayajatumwa, kwa hivyo seva huhifadhi maandishi fiche (ciphertext) ambayo haiwezi kuyasoma. Kiambishi awali cha 2. ni aina ya usimbaji ya Bitwarden, ikifuatiwa na initialization vector (IV), maandishi fiche, na MAC (message authentication code), kila moja ikiwa katika base64 na kutenganishwa na |. Ufunguo unaofungua usimbaji huo hutokana na nywila kuu (master password) ya akaunti, ambayo haifiki kwenye seva katika hali inayoweza kutumika. Sehemu hii inafanana iwe unaendesha Vaultwarden au seva rasmi, kama ulinganisho wa Vaultwarden na Bitwarden inayojiendesha yenyewe unavyoeleza.
Sehemu nyingine ya database haijasimbwa. Anwani za barua pepe, majina ya akaunti, vidokezo vya nywila na misimbo ya kurejesha akaunti ya hatua mbili (two-factor recovery codes) huhifadhiwa kama maandishi ya kawaida, kando ya metadata kama nyakati za uundaji na ni shirika lipi linalomiliki kitu fulani. Kwa hivyo, faili la nakala rudufu (backup) lenyewe ni siri. Mtu yeyote anayelishikilia anajua watumiaji wako ni nani, na anaweza kushambulia blobs zilizosimbwa nje ya mtandao (offline) kwa kasi yoyote ile ambayo vifaa vyake vinairuhusu. Ukweli huo mmoja ndio unaoongoza sheria za uhifadhi hapa chini: nakala hiyo husimbwa kwa njia fiche kabla haijaondoka kwenye seva.
Kwa nini kunakili db.sqlite3 wakati Vaultwarden inafanya kazi si chelezo (backup)
Vaultwarden huendesha SQLite katika hali ya WAL kwa chaguo-msingi (ENABLE_DB_WAL=true). Andiko (write) hufika kwenye db.sqlite3-wal kwanza, na ni checkpoint pekee ndiyo inayoliingiza kwenye db.sqlite3. Ukinakili db.sqlite3 pekee, utapata hifadhidata kama ilivyokuwa wakati wa checkpoint ya mwisho; hivyo, nenosiri lililohifadhiwa dakika kumi zilizopita linaweza kukosekana kwenye kumbukumbu yako bila onyo lolote.
Kunakili faili zote tatu kwa kutumia cp si suluhisho pia. Nakala hizo huchukuliwa kwa nyakati tofauti kidogo, kwa hivyo faili ya WAL uliyohifadhi inaweza kuelezea matoleo ya kurasa ambayo faili kuu uliyohifadhi hailingani nayo tena. SQLite kisha hujaribu kurejesha moja kutoka kwa nyingine na matokeo huwa si sahihi. Unagundua hili baadaye sana:
Error: database disk image is malformed.backup huepuka tatizo hili kwa sababu hutumia Online Backup API ya SQLite, ambayo SQLite huielezea kama njia sahihi ya kunakili hifadhidata inayoweza kuwa inatumika. Inasoma kurasa hizo chini ya read lock, na huanza upya ikiwa mwandishi (writer) atabadilisha faili hiyo wakati wa mchakato, hivyo kile kinachohifadhiwa kwenye diski ni wakati mmoja thabiti.
Hifadhi nakala ya database kwa kutumia sqlite3 .backup
sudo apt update && sudo apt install -y sqlite3
sudo install -d -m 700 /var/backups/vaultwarden
OUT=/var/backups/vaultwarden/db-$(date '+%Y%m%d-%H%M').sqlite3
sudo sqlite3 /opt/vaultwarden/data/db.sqlite3 ".backup '$OUT'"
sudo sqlite3 "$OUT" "PRAGMA integrity_check;"Amri ya mwisho huchapisha ok kwenye mstari wake pekee. Kitu kingine chochote kinamaanisha kuwa nakala hiyo haifai kutumika, kwa hivyo usiihifadhi na usifute ile ya awali. Mlolongo mzima huendeshwa kwenye seva inayofanya kazi, kwa hivyo hakuna mtumiaji anayetolewa nje na hakuna container inayowashwa upya.
Zana ya sqlite3 haipo ndani ya container ya Vaultwarden. Image hiyo imejengwa kwenye debian:trixie-slim kwa kutumia ca-certificates, curl, libmariadb3, libpq5 na openssl, kwa hivyo docker exec vaultwarden sqlite3 ... inashindwa na kutoa:
exec: "sqlite3": executable file not found in $PATHBadala yake, iendeshe kwenye host dhidi ya njia iliyopachikwa (mounted path), jambo ambalo amri zilizo hapo juu hufanya. Ikiwa data iko kwenye named volume, docker volume inspect <name> huchapisha njia ya host chini ya /var/lib/docker/volumes/.
Vaultwarden pia imekuwa ikitoa amri yake yenyewe ya backup tangu toleo la 1.32.1. Kwenye seva yako:
docker exec -it vaultwarden /vaultwarden backupInaendesha VACUUM INTO na kuandika db_YYYYMMDD_HHMMSS.sqlite3 ndani ya folda ya data. Mambo mawili yanayofuata ni haya. Nakala hiyo hutua karibu na faili asilia kwenye diski ileile, kwa hivyo ni hatua ya maandalizi (staging) na bado si backup kamili. Na ni kwa ajili ya SQLite pekee: kwenye MariaDB au PostgreSQL inasimama na kutoa The database type is not SQLite. Backups only works for SQLite databases.
Faili ambazo watu husahau
attachments/ huhifadhi ciphertext kwa majina yasiyoeleweka. Safu ya database kwa kila kiambatisho hubeba jina lake la faili lililosimbwa na nyenzo za ufunguo (key material) ambazo mteja anahitaji ili kusoma faili hiyo. Viambatisho visivyo na database ni data isiyosomeka, na database isiyo na viambatisho huwapa watumiaji vitu ambavyo upakuaji wake utafeli. Chukua zote mbili katika operesheni moja.
config.json huhifadhi kila kitu ulichohifadhi kutoka kwenye ukurasa wa admin, na thamani zake zina kipaumbele kuliko variable za mazingira (environment variables) zinazolingana. Hii ina pande mbili: kurejesha config.json ya zamani kutabatilisha kimyakimya mipangilio iliyo kwenye faili yako ya compose, na faili yenyewe ni nyeti kwa sababu inaweza kuhifadhi nenosiri lako la SMTP na token yako ya admin. Hifadhi token hiyo kama mfuatano wa Argon2id PHC (password hashing competition) badala ya maandishi ya kawaida. docker run --rm -it vaultwarden/server /vaultwarden hash inakuchapishia mmoja.
rsa_key.pem hutia saini JSON web tokens (JWT) zinazowaweka wateja wakiwa wameingia kwenye mfumo. Ikiwa faili hii haipo wakati wa kuanza, Vaultwarden hutengeneza ufunguo mpya, kwa hivyo kila token iliyotiwa saini na ufunguo wa zamani huacha kuhalalishwa na wateja wote hutolewa nje ya mfumo. Yaliyomo kwenye Vault hubaki salama, kwa sababu yamesimbwa kwa funguo zinazotokana na nenosiri kuu (master password). Kurejesha faili ya ufunguo huepusha watumiaji wote kutolewa nje kwa pamoja.
sends/ huhifadhi faili zilizo nyuma ya viungo vya Send. Kukosekana kwa faili hizi huvunja upakuaji huo na hakuna kingine kinachoathirika.
Weka kila kitu kwenye script moja
#!/bin/bash
set -euo pipefail
DATA=/opt/vaultwarden/data
DEST=/var/backups/vaultwarden
STAMP=$(date '+%Y%m%d-%H%M%S')
STAGE=$(mktemp -d /tmp/vw-stage.XXXXXX)
install -d -m 700 "$DEST"
sqlite3 "$DATA/db.sqlite3" ".backup '$STAGE/db.sqlite3'"
test "$(sqlite3 "$STAGE/db.sqlite3" 'PRAGMA integrity_check;')" = "ok"
cp -a "$DATA"/rsa_key* "$STAGE/"
for extra in config.json attachments sends; do
if [ -e "$DATA/$extra" ]; then cp -a "$DATA/$extra" "$STAGE/"; fi
done
tar -C "$STAGE" -czf "$DEST/vw-$STAMP.tar.gz" .
chmod 600 "$DEST/vw-$STAMP.tar.gz"
rm -rf "$STAGE"
tar -tzf "$DEST/vw-$STAMP.tar.gz"Ihifadhi kama /usr/local/sbin/vw-backup.sh, ifanye chmod 700, na uiendeshe kama root. Mstari wa test ndio unaofanya kazi ya msingi: sqlite3 inatoka na status 0 hata wakati PRAGMA integrity_check inaripoti uharibifu, kwa hivyo kulinganisha matokeo na ok ndiko kunakogeuza nakala mbaya kuwa script iliyoshindwa. set -euo pipefail kisha inasimamisha kila kitu, badala ya kuruhusu tar kutengeneza archive nadhifu kuzunguka database iliyoharibika.
Amri ya mwisho ya tar -tzf inaorodhesha kile ulichokinasua. Ikague mara ya kwanza. Unatafuta ./db.sqlite3, ./rsa_key.pem, ./config.json na ./attachments/, na kuhakikisha kuwa ./db.sqlite3-wal haipo. Iendeshe kila usiku kwa kutumia systemd service na timer badala ya cron ikiwa unataka matokeo ya journalctl na unit inayoripoti kushindwa.
Thibitisha nakala rudufu kwa kuirejesha kwenye saraka ya muda
Nakala rudufu ambayo haijajaribiwa ni kubahatisha tu. Kurejesha data kwenye saraka ya muda huchukua dakika moja na hakugusi mfumo wowote unaofanya kazi.
sudo install -d -m 700 /tmp/vw-check
sudo tar -C /tmp/vw-check -xzf /var/backups/vaultwarden/vw-20260805-030000.tar.gz
ls -l /tmp/vw-check
sudo sqlite3 /tmp/vw-check/db.sqlite3 "PRAGMA integrity_check;"
sudo sqlite3 /tmp/vw-check/db.sqlite3 "select count(*) from users;"
sudo sqlite3 /tmp/vw-check/db.sqlite3 "select count(*) from ciphers;"
sudo du -sh /tmp/vw-check/attachmentsMatokeo manne ni muhimu. integrity_check huchapisha ok. Idadi ya watumiaji inalingana na idadi ya akaunti unazozijua. Idadi ya cipher inakaribia takwimu halisi kutoka sudo sqlite3 /opt/vaultwarden/data/db.sqlite3 "select count(*) from ciphers;", na haiwezi kuwa sifuri kwenye vault inayotumika. Saraka ya attachments ina ukubwa unaotarajiwa, jambo ambalo unaweza kuliruka ikiwa hakuna anayepakia attachments. Kisha endesha sudo rm -rf /tmp/vw-check, kwa sababu saraka hiyo sasa inashikilia nakala ya pili ya kila kitu.
Kuna kanuni moja unaporejesha folda yoyote ya data iliyonakiliwa kwa mkono: futa db.sqlite3-wal na db.sqlite3-shm kabla ya kuanzisha seva. Vinginevyo, SQLite itajaribu kurejesha hifadhidata iliyorejeshwa kwa kutumia logi inayomilikiwa na nakala nyingine, na hilo huharibu hifadhidata iliyofika ikiwa salama. Kumbukumbu zinazozalishwa na hati iliyo hapo juu hazina faili hizo kamwe, kwa sababu .backup huandika hifadhidata moja kamili.
Kurejesha data kwenye seva
Hii hufanyika kwenye seva yako mwenyewe, huku container ikiwa imesimamishwa. Vaultwarden haipaswi kuandika data wakati folda ya data inabadilishwa chini yake.
cd /opt/vaultwarden
docker compose stop vaultwarden
sudo mv data data.old.$(date '+%Y%m%d-%H%M%S')
sudo install -d -m 700 data
sudo tar -C data -xzf /var/backups/vaultwarden/vw-20260805-030000.tar.gz
sudo chown -R root:root data
docker compose start vaultwarden
docker compose logs --tail 20 vaultwardenchown lazima itaje mtumiaji anayeendesha container hiyo. Image ya kawaida huendeshwa kama root, kwa hivyo root:root ni sahihi isipokuwa kama umeweka user: kwenye faili yako ya compose; katika hali hiyo, tumia uid na gid hiyo. Folda ya data ambayo seva haiwezi kuiandikia itakupa ukurasa wa kuingia (login) unaofeli kila ombi, na logi zitaonyesha hivyo.
Kuanza kwa afya kunamalizika na mstari wa Rocket:
[INFO] Rocket has launched from http://0.0.0.0:80Kisha ingia kutoka kwenye kivinjari, fungua kipengee, na upakue kiambatisho kimoja. Kuingia kunakofanya kazi huku upakuaji wa viambatisho ukifeli inamaanisha kuwa kumbukumbu (archive) ilibeba hifadhidata lakini si attachments/. Hifadhi data.old.* hadi yote hayo yatakapothibitishwa, kisha uifute. Kurudisha nyuma (rolling back) ni hatua zilezile tatu huku saraka zikibadilishwa kwa njia nyingine.
Ikiwa njia zako (paths) hazilingani na zile zilizo hapa, mwongozo wa usakinishaji wa Vaultwarden kwa VPS unaonyesha faili ya compose ambayo amri hizi huzingatia.
Mahali ambapo hupaswi kuhifadhi nakala (backup)
- Usihifadhi kwenye diski moja na folda ya data. Volumu moja ikifeli itaharibu nakala zote mbili, na vivyo hivyo kwa
rm -rfyoyote itakayotekelezwa kwenye njia isiyo sahihi. - Usihifadhi kwenye seva hiyo hiyo, hata kama ni kwenye volumu ya pili. Mshambuliaji anayepata ufikiaji wa root atafikia nakala zako za backup katika kikao kimoja.
- Usihifadhi kwenye object storage bila encryption, kwa sababu kumbukumbu hiyo ina anwani za barua pepe, vidokezo vya nenosiri, misimbo ya kurejesha akaunti (recovery codes) na vault ciphertext ambayo inaweza kushambuliwa nje ya mtandao (offline).
- Usitegemee snapshots za mtoa huduma wako pekee. Snapshot hurejesha data haraka, jambo ambalo ni muhimu, lakini zinakaa kwenye akaunti moja na seva, hivyo tatizo lolote la akaunti litaathiri nakala hizo pia.
Nakala iliyo nje ya seva (offsite copy) ndipo restic inapofaa, kwa sababu restic repository husimbwa kwa njia ya encryption kwenye mashine kabla ya kitu chochote kupakiwa. Kwenye seva yako:
sudo apt install -y restic
export RESTIC_REPOSITORY=s3:https://s3.example.com/vaultwarden-backups
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init
restic backup /var/backups/vaultwarden --tag vaultwarden
restic snapshots --tag vaultwarden
restic forget --tag vaultwarden --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --pruneElekeza restic kwenye saraka ya kumbukumbu (archive directory) na si kwenye folda ya data inayotumika, ili kile kinachopakiwa kiwe nakala thabiti uliyokwisha kuikagua. Hifadhi nenosiri la repository mahali pengine nje ya seva inayolindwa: ukipoteza nenosiri hilo, snapshots hazitasomeka, na hili limekusudiwa hivyo. Pale ambapo hifadhi inaruhusu, ipatie seva vitambulisho (credentials) vinavyoweza kuandika lakini si kufuta, ili uvamizi wa seva usisababishe kufutwa kwa historia yake. Kusanidi nakala za restic kwenye VPS inaelezea kikamilifu kuhusu repository na ratiba, na kulinganisha restic na BorgBackup inashughulikia chaguo hilo ikiwa bado hujafanya uamuzi.
Jaribu urejeshaji wa data kulingana na ratiba
Chagua siku moja kila mwezi. Vuta snapshot mpya zaidi kwenye saraka ya muda (scratch directory) ukitumia restic restore latest --tag vaultwarden --target /tmp/vw-check, endesha PRAGMA integrity_check ileile, fanya hesabu ya safu (row counts) zilezile, kisha andika tarehe na hesabu hizo. Backup ambayo haijawahi kurejeshwa kwa miezi sita ni backup yenye hali isiyojulikana, na utajifunza hali yake wakati wa hitilafu, jambo ambalo ni wakati mbaya zaidi wa kugundua hilo.
Mara moja kwa mwaka, fanya urejeshaji kamili. Anzisha container ya pili ya Vaultwarden kwenye port ya ziada ukitumia folda ya data iliyorejeshwa, kisha ingia kwenye akaunti halisi. Hii inathibitisha njia ya master password kuanzia mwanzo hadi mwisho, jambo ambalo hesabu ya safu haiwezi kufanya. restic check --read-data-subset=10% kwa ratiba hiyo hiyo inathibitisha kuwa data iliyohifadhiwa inasomeka badala ya kuorodheshwa tu.
FAQ
Je, ninaweza kunakili db.sqlite3 kwa kutumia cp wakati Vaultwarden inaendelea kufanya kazi?
Hapana. Vaultwarden huendesha SQLite katika hali ya WAL, kwa hivyo maandishi ya hivi karibuni hukaa kwenye db.sqlite3-wal na hayapo bado kwenye db.sqlite3. cp ya faili kuu pekee itasababisha upotevu wa data kimyakimya, na kunakili faili hizo mbili kando kunaweza kuacha jozi isiyolingana ambayo itajitokeza baadaye kama Error: database disk image is malformed. Tumia sqlite3 /path/db.sqlite3 ".backup '/path/out.sqlite3'" badala yake. Inatumia API ya Online Backup ya SQLite na kutengeneza faili moja thabiti wakati seva inaendelea kuhudumia maombi.
Je, lazima nisimamishe container ya Vaultwarden ili kufanya backup?
Hapana, na hiyo ndiyo faida ya .backup. Nakala ya database ni salama kwenye seva inayofanya kazi. Viambatisho na faili za Send huandikwa wakati mtumiaji anapopakia, kwa hivyo faili iliyoongezwa kati ya nakala ya database na tar inaweza kukosa kwenye kumbukumbu ya usiku huo, jambo ambalo litakugharimu kiambatisho kimoja tu katika hali mbaya zaidi. Ikiwa sekunde chache za kutopatikana kwa huduma hazikupi shida, docker compose stop kabla ya script na docker compose start baada yake huondoa hata hatari hiyo ndogo.
Nini kitatokea nikirejesha data bila faili za rsa_key?
Vaultwarden hutengeneza ufunguo mpya wakati wa kuanza. Ufunguo huo husaini JSON web tokens (JWT) zinazoweka sessions hai, kwa hivyo kila token iliyopo huacha kuhalalishwa na wateja wote hutolewa nje na lazima waingie tena. Yaliyomo kwenye vault hayaathiriki, kwa sababu yamesimbwa kwa funguo zinazotokana na master password ya kila mtumiaji badala ya ufunguo wa RSA. Rejesha rsa_key.pem pamoja na faili nyingine za folda ya data na hakuna atakayegundua kuwa umerejesha data.
Je, ni salama kupakia archive ya backup kwenye object storage kama ilivyo?
Hapana. Majina ya vitu, nywila na madokezo ni ciphertext, lakini anwani za barua pepe, majina ya akaunti, vidokezo vya nywila na misimbo ya kurejesha akaunti (two-factor recovery codes) ni maandishi ya kawaida (plain text) ndani ya database, na mshambuliaji wa nje anaweza kuvunja ciphertext hiyo kwa kasi yake mwenyewe. Simba archive kabla haijaondoka kwenye mashine. Restic repository hufanya hivyo kwa ajili yako, na gpg --symmetric --cipher-algo AES256 vw-20260805-030000.tar.gz hutengeneza faili moja iliyosimbwa ambayo unaweza kuiweka kwenye hifadhi yoyote.
Ninafanyaje backup ya Vaultwarden kwenye PostgreSQL au MariaDB?
Hatua za SQLite hazitumiki, na amri iliyojengewa ndani itakataa kwa The database type is not SQLite. Backups only works for SQLite databases. Toa dump ya database kwa kutumia zana yake asilia, pg_dump au mysqldump, na uzingatie sheria nyingine zote kama zilivyo. Dump hiyo inapaswa kuwekwa kwenye archive moja na attachments/, sends/, config.json na faili za rsa_key, zikichukuliwa katika operesheni moja, zikisimbiwa, na kuhifadhiwa mahali pengine nje ya seva iliyozitengeneza.