NordBastion का polar-bear mascot एक अंधेरे Nordic पत्थर के vault में एक server rack के बगल में खड़ा है, एक चमकती हुई cyan key थामे हुए, जबकि padlocks से चिह्नित पाँच cyan holographic blocks की एक chain एक runic मेहराब से होकर दूर एक धुंधली aurora के नीचे दूसरे server rack की तरफ़ जाती है
How-to · Opsec·16 मिनट में पढ़ें · 45 मिनट hands-on

VPS बैकअप।
Offsite, deduplicated, और पहुंच से बाहर।

VPS बैकअप के लिए छह चरण — एक असुरक्षित server से लेकर दूसरे jurisdiction की दूसरी machine पर एक verified encrypted repository तक: restic और Borg की तुलना, साफ़ restore होने वाले database dumps, एक systemd timer, और एक append-only repository जिसे एक compromised server मिटा नहीं सकता। दूसरा VPS सिर्फ $3.90 प्रति माह का है। Debian 12 पर tested.

छह चरण
  1. 01

    इन्वेंटरी

    जो दोबारा नहीं बनाया जा सकता

  2. 02

    Install करें

    restic या Borg

  3. 03

    गंतव्य

    एक दूसरा bastion

  4. 04

    आरंभ करें

    Repository + पहला run

  5. 05

    स्वचालित करें

    Dumps, timer, रिटेंशन

  6. 06

    अभ्यास

    Restore करें, और समय नोट करें

शुरू करने से पहले · यह किसलिए है

चार तरीके जिनसे data मरता है। इनमें से सिर्फ एक टूटी हुई disk है।

backups को लेकर लगभग हर बहस पहले ही मिनट में ग़लत दिशा में चली जाती है, क्योंकि बात कर रहे दोनों लोगों के दिमाग में अलग-अलग विफलताएं होती हैं। एक व्यक्ति एक मरी हुई drive की कल्पना कर रहा होता है। दूसरा एक मंगलवार की सुबह की कल्पना कर रहा होता है जब account ही ग़ायब हो चुका है। दोनों को अलग-अलग जवाब चाहिए, और एक ऐसा setup जो सिर्फ पहली वाली से बचता है, तब तक सुरक्षित लगता है जब तक उसे दूसरी वाली से परखा नहीं जाता।

चार failure modes ऐसे हैं जिनके ख़िलाफ़ design करना ज़रूरी है, और ये किसी एक ही theme के अलग रूप नहीं हैं — हर एक अलग defence को मात देता है।

हार्डवेयर। NVMe fail हो जाता है, host node मर जाता है, array एक साथ अपने दो members खो देता है। यही वह विफलता है जिसके लिए हर कोई plan बनाता है, और यह modern virtualised infrastructure पर सबसे दुर्लभ है। Redundant storage इसे संभाल लेता है। Redundant storage और कुछ नहीं संभालता, यही वजह है कि RAID कभी backup नहीं था और न ही है: यह हर write को ईमानदारी से copy करता है, उस write को भी जो कहती है "delete everything"।

मानव। production पर चलाई गई एक migration script। ग़लत terminal में एक DROP TABLE। उल्टे arguments वाला एक rsync। असली data loss का सबसे आम कारण यही है, काफी बड़े अंतर से, और इसके ख़िलाफ़ इकलौता बचाव है इतिहास — गलती से पहले की एक copy, जो कहीं ऐसी जगह रखी हो जहां वह गलती न पहुंची हो। समय ही यहां ज़रूरी तत्व है: अगर इकलौती copy एक ऐसा mirror है जो तीस सेकंड पीछे है, तो उसमें वह गलती पहले से ही शामिल है।

दुर्भावनापूर्ण। कोई root हासिल कर लेता है, या ransomware किसी unpatched application के जरिए अंदर आ जाता है। आधुनिक ransomware सबसे पहला काम यह करता है कि backup configuration — credentials, mounted shares, cloud keys — को ढूंढता है और जो भी मिलता है उसे नष्ट कर देता है, ठीक इसलिए क्योंकि एक काम करने वाला restore किसी आपदा को एक दोपहर में बदल देता है। एक ऐसा backup credential जो delete कर सकता है, वही credential है जो हमलावर को विरासत में मिल जाता है। यही वह विफलता है जिसके लिए इस guide का append-only अध्याय मौजूद है।

कस्टोडियल में। कुछ भी टूटा नहीं और किसी पर हमला भी नहीं हुआ; आपने बस पहुंच खो दी। एक automated fraud signal पर suspend किया गया account, यात्रा के दौरान fail हुआ एक card, एक dispute, एक compliance review, provider पर दिया गया एक order। machine पूरी तरह ठीक है और अपहुंच है, और उस account के अंदर हर snapshot भी उसके साथ अपहुंच है। यही वह विफलता है जिसका जवाब एक provider के अंदर कितनी भी redundancy नहीं दे सकती, और यही वजह है कि एक गंभीर backup एक अलग छत के नीचे रहता है।

बचाव हार्डवेयर मानव त्रुटि रैनसमवेयर खोया हुआ Account
RAID / रिडंडेंट स्टोरेजहांनहींनहींनहीं
Provider snapshot, वही accountहांआंशिकनहींनहीं
Offsite repository, लिखने वाली keyहांहांनहींहां
Offsite repository, append-only, दूसरा jurisdictionहांहांहांहां

आख़िरी row वही है जिस पर इस guide का बाकी हिस्सा बनता है। यह इससे ऊपर वाली row से ज़्यादा महंगी नहीं है — append-only setting मुफ़्त है और दूसरा jurisdiction भी उतना ही $3.90 खर्च करता है जितना पहला।

3-2-1 नियम, एक अकेले VPS के लिए दोबारा बताया गया। data की तीन copies, दो अलग-अलग तरह के storage पर, जिनमें से एक offsite। यह classic formulation tape और office servers के दौर से आया है, और इसकी भावना शब्दों से बेहतर बची रहती है। एक self-hosted box के लिए इसका मतलब है: VPS पर live data, कहीं और किसी दूसरी machine पर एक repository, और — जो भी सचमुच अपूरणीय हो उसके लिए — एक तीसरी copy जिसे आप खुद पकड़ सकें, घर पर किसी disk में या किसी दराज़ में। जो नंबर असल में मायने रखता है वह तीन नहीं है। यह इस बात पर है कि data के खोने से पहले कितनी स्वतंत्र चीज़ें गलत होनी चाहिए। दो रखना कम से कम ज़रूरी है।

शुरू करने से पहले · Tool का चुनाव

restic, Borg, या rsync। इनमें से दो ही backup हैं।

जिस category की आपको ज़रूरत है उसे एक deduplicating, encrypting snapshot tool कहा जाता है। यह हर file को content-defined chunks में तोड़ता है, हर chunk को उसी machine पर encrypt करता है जिसके पास वह data है, और उसे सिर्फ एक बार store करता है चाहे कितने भी snapshots उसे reference करें। यह आपको एक साथ तीन properties देता है: एक जितनी जगह में कई restore points, plaintext जो कभी source से बाहर नहीं जाता, और एक ऐसा transfer जो सिर्फ बदली हुई चीज़ को ही move करता है।

इस जगह पर दो programs हावी हैं और दोनों ही बेहतरीन हैं। restic एक अकेला static Go binary है जिसके साथ storage backends की एक विस्तृत रेंज मिलती है। BorgBackup एक Python program है जो far end पर अपनी ही एक copy से SSH में बात करता है। नीचे दिया गया सब कुछ इन दोनों के बीच का ईमानदार फ़र्क है।

विशेषता restic BorgBackup rsync / rclone
Client की ओर से Encryptionहमेशा चालू, वैकल्पिक नहींहमेशा चालू, वैकल्पिक नहींकेवल एक rclone crypt remote के जरिए
डीडुप्लीकेशनContent के हिसाब से बंटे chunksContent के हिसाब से बंटे chunksकुछ नहीं, या hardlink trees
Snapshot इतिहासहां, retention policies के साथहां, retention policies के साथअभी इसी वक़्त का एक mirror
गंतव्य की ज़रूरतेंकुछ नहीं — SFTP, S3, REST, rcloneदोनों सिरों पर installed Borgएक SSH account या एक API
Append-only लागू करनाrest-server या object lock के जरिएअंदर built-in, plain SSH परकोई नहीं
उपयुक्ततालगभग हर कोई, ज़्यादातर backendsएक SSH box जिसके आप मालिक हैं, append-onlyMirroring, backup नहीं

rsync इस table में इसलिए है क्योंकि ज़्यादातर लोग सबसे पहले इसी की तरफ़ जाते हैं, और इसलिए भी क्योंकि यह सचमुच ग़लत tool है: एक mirror एक deletion को भी पूरी ईमानदारी से दोहरा देता है, और एक encrypted-at-rest disk का mirror खुद कहीं भी encrypted नहीं होता। यह एक backup के अंदर अपनी जगह उस चीज़ के तौर पर कमाता है जो एक बन चुके archive को move करती है, न कि खुद archive के तौर पर।

यह guide हर उस command के लिए restic और Borg दोनों दिखाती है जो अलग है, ताकि आप इनमें से किसी के साथ भी इसे follow कर सकें। जहां एक ही चुनाव करना ज़रूरी है — worked example, timer, script — वहां यह restic का इस्तेमाल करती है, क्योंकि तब destination को सिर्फ एक SSH account चाहिए और इससे दूसरी machine सीधी-सादी बनी रहती है।

चरण 01 · इन्वेंटरी

जो दोबारा नहीं बनाया जा सकता। इसे automate करने से पहले लिख लें।

पूरे filesystem का backup लेना एक ऐसा चुनाव है जिसे सही ठहराया जा सकता है, और यह फिज़ूल भी है। एक server का ज़्यादातर हिस्सा सिर्फ एक package manager की दूरी पर फिर से बनाया जा सकता है, और आप जो भी gigabyte ढोते हैं वह repository को prune करने में धीमा, रखने में ज़्यादा महंगा, और जल्दी में खोजने में धीमा बना देता है। असली काम का exercise इसका उल्टा है: यह list बनाएं कि एक fresh install आपको क्या वापस नहीं देगी।

एक typical self-hosted VPS के लिए वह list छोटी होती है, और उसमें हमेशा ये पांच चीज़ें होती हैं:

  • 01Database की सामग्री। data directory नहीं — dump। चरण 05 में इसकी वजह बताई गई है।
  • 02User द्वारा upload की गई files। Docker volumes, एक uploads या media directory, एक mail store। आमतौर पर ज़्यादातर bytes यही होते हैं।
  • 03Configuration और secrets। Compose files, .env files, encryption keys, API tokens। छोटे, और एक दो-घंटे के restore और दो-दिन के restore के बीच का फर्क।
  • 04System state जिसे आपने edit किया है। /etc पूरी तरह इतना छोटा है कि इसे साबुत ही ले लिया जाए — sshd config, firewall rules, systemd units, cron entries, वह mail routing जिस पर आपने एक शाम खर्च की थी।
  • 05ऐसा कुछ भी जिसके साथ एक पहचान जुड़ी हो। एक Tor hidden-service key, एक Matrix signing key, एक WireGuard private key, एक node wallet। इनमें से किसी एक को खो दें और service वापस नहीं आती — उसी नाम की एक अलग service वापस आती है।

उस list को source server पर दो files में बदल दें। एक include list मक़सद को साफ़ दिखाए रखती है; एक exclude list शोर को बाहर रखती है। दोनों को backup command पढ़ती है, और दोनों को खुद backup में भी शामिल होना चाहिए।

/etc/backup/include.txt

/etc
/opt
/root
/var/backups
/var/lib/docker/volumes
/home

/etc/backup/exclude.txt

# Caches and rebuildable artefacts
**/node_modules
**/.cache
**/*.tmp
/var/lib/docker/volumes/*/_data/cache
# Log noise — keep the config, drop the volume
/var/log/journal
# Never back up the mount point you restore into
/mnt/restore

उस Docker line पर दो बातें, क्योंकि यह लोगों को उलझा देती है। Named volumes /var/lib/docker/volumes के नीचे रहते हैं और यही वह है जो आपको चाहिए; bind mounts जहां भी आप उन्हें रखें वहीं रहते हैं, आमतौर पर Compose file के बगल में, और इन्हें /opt cover कर लेता है। Container images data नहीं हैं — वे एक pull के साथ वापस आ जाती हैं, और जो backup इन्हें ढोता है वह ऐसे gigabytes ढो रहा है जिनकी उसे ज़रूरत नहीं।

आख़िर में, इसके इर्द-गिर्द कुछ भी बनाने से पहले नतीजे को नापें। यह नंबर आपको बताता है कि कौन-सा repository tier order करना है और पहला run चार मिनट लेगा या चालीस:

du -sh --exclude=/var/lib/docker/overlay2 /etc /opt /root /home /var/lib/docker/volumes
चरण 02 · इंस्टॉल

source पर एक binary। और कुछ नहीं बदलता।

जिस machine के पास data है उस पर tool install करें। Debian और Ubuntu पर दोनों packaged हैं, और restic के लिए distribution package अक्सर एक-दो release पीछे होता है — जो मायने रखता है, क्योंकि repository features और performance का काम point releases में आता है। package install करें, फिर restic को अपनी जगह पर खुद को update करने दें:

apt update && apt install -y restic
restic self-update
restic version

Borg के लिए, distribution package ही सही चुनाव है, क्योंकि source पर मौजूद version और गंतव्य पर मौजूद version को एक-दूसरे को समझना ज़रूरी है, और एक ही distribution release से मिली एक matched pair इसे पाने का सबसे कम दर्दनाक तरीका है:

apt install -y borgbackup
borg --version

किसी repository में सालों का इतिहास सौंपने से पहले major versions पर एक बात: Borg का repository format इसकी major lines के बीच बदल गया है, और उस सीमा के आर-पार एक repository को move करना एक conversion है, upgrade नहीं। जो version आप install कर रहे हैं उसके release notes पढ़ें, और गंतव्य को source जैसी ही major line पर रखें। restic अपने releases में forward-compatible रहा है और एक स्पष्ट repository version के पीछे features जोड़ता है, इसलिए वहां यह चिंता उतनी बड़ी नहीं है।

किसी भी tool को source पर एक daemon, एक agent या एक खुले port की ज़रूरत नहीं है। यह बात ज़ोर से कहने लायक है: जो backup system आप install कर रहे हैं वह जिस machine की रक्षा करता है उसमें कोई listening service और कोई नई attack surface नहीं जोड़ता। यह जो कुछ भी करता है वह outbound है, एक schedule पर, SSH के ज़रिए।

चरण 03 · गंतव्य

एक दूसरा bastion, और एक ऐसी key जो delete नहीं कर सकती। यही वह चरण है जो मायने रखता है।

repository host का एक ही काम है और लगभग कोई requirement नहीं है। इसे cores की ज़रूरत नहीं, क्योंकि यह आपका data कभी पढ़ता ही नहीं — यह ऐसे encrypted blobs रखता है जिन्हें यह खोल नहीं सकता। इसे memory की ज़रूरत नहीं, क्योंकि deduplication का काम source पर होता है। इसे बस disk चाहिए, एक स्थिर address चाहिए, और ऐसी जगह चाहिए जहां source machine की परेशानियां इसका पीछा न करें।

panel में: Order → VPS → Sentinel, image Debian 12, और — असली मुद्दा यही है — वह bastion जिसमें source चल रहा है, उससे अलग एक bastionHelsinki काम कर रहा है, Reykjavík थाम रहा है। account खोलने के लिए किसी email address की ज़रूरत नहीं है और invoice Monero, Bitcoin, Lightning या किसी भी दूसरे supported asset में चुक जाता है, जिसका मतलब है दूसरी machine वह पहचान दोबारा सामने नहीं लाती जिसके बारे में पहली machine सावधान रही थी।

Repository लक्ष्य मासिक स्टोरेज जो Working set यह रखता है Restore की कीमत
Sentinel$3.90120 GB NVMe~30 GBकुछ नहीं — unmetered
Garrison$7.90240 GB NVMe~70 GBकुछ नहीं — unmetered
Ravelin$16.90480 GB NVMe~150 GBकुछ नहीं — unmetered
Bulwark$32.90960 GB NVMe~300 GBकुछ नहीं — unmetered
S3-class ऑब्जेक्ट स्टोरेज~$0.023/GBलचीलाकोई भीमीटर्ड Egress

working-set वाला column मान कर चलता है कि daily snapshots को normal churn के साथ एक साल तक रखा गया है; जो repository ज़्यादातर धीरे-धीरे बदलने वाली files रखती है वह कहीं ज़्यादा दूर तक जाती है, और जो बड़ी re-written binaries से भरी हो वह कम दूर जाती है। आख़िरी row scale के लिए है, और उस बात के लिए जिसे लोग बुरे दिन तक भूल जाते हैं: object storage download का भी पैसा लेता है, और download ही वह चीज़ है जो आप emergency में करते हैं।

गंतव्य पर — एक unprivileged user और एक directory।

adduser --disabled-password --gecos "" backup
install -d -m 0700 -o backup -g backup /srv/restic/web01

backup user के पास न कोई password है, न sudo, और न लॉग इन करने के लिए कुछ। इसका अस्तित्व सिर्फ एक directory का मालिक होने के लिए है। अगर आप कई servers backup करते हैं तो हर source machine के लिए इसकी अपनी directory रखें — प्रति source एक repository रखने से एक box का compromise दूसरे के history को छूने से बचा रहता है।

source पर — एक ऐसी key जो और कुछ के लिए इस्तेमाल नहीं होती।

ssh-keygen -t ed25519 -f /root/.ssh/id_backup -N "" -C "backup:web01"
cat /root/.ssh/id_backup.pub

अपनी login key दोबारा इस्तेमाल न करें। यह वाली disk पर unencrypted रहती है क्योंकि एक unattended timer को इसे रात के तीन बजे इस्तेमाल करना होता है, और यही बिल्कुल वैसी key है जिसे आप एक ही गंतव्य और एक ही मकसद तक सीमित रखना चाहते हैं।

वापस गंतव्य पर — वह key क्या कर सकती है, उसे सीमित करें। public key को /home/backup/.ssh/authorized_keys में एक prefix के साथ paste करें। restic को SFTP पर चलाने के लिए:

restrict,from="198.51.100.7" ssh-ed25519 AAAAC3NzaC1lZDI1... backup:web01

restrict option एक ही शब्द में port forwarding, agent forwarding, X11 और PTY allocation बंद कर देता है, बस file transfer छोड़कर बाकी कुछ नहीं। from= clause key को source address से बांध देता है, इसलिए server से चुराई गई इसकी कोई copy कहीं और बेकार है। Borg के लिए, एक कदम और आगे जाकर command को force करें, यहीं इसका append-only mode रहता है:

command="borg serve --append-only --restrict-to-path /srv/borg/web01",restrict ssh-ed25519 AAAAC3NzaC1lZDI1... borg:web01

वह लाइन पूरे ransomware defence को एक जगह समेट देती है: source जो भी भेजे, destination हमेशा सिर्फ borg serve ही run करेगा, सिर्फ उसी path के अंदर, और सिर्फ एक ऐसे mode में जो append करता है। source पर एक root shell इस key का इस्तेमाल पिछले महीने को मिटाने के लिए नहीं कर सकता।

गंतव्य को source पर एक बार नाम दें। इसे /root/.ssh/config में डालें ताकि बाद की हर command छोटी रहे और address ठीक एक ही file में रहे:

Host rkv-repo
    HostName 198.51.100.42
    User backup
    IdentityFile /root/.ssh/id_backup
    IdentitiesOnly yes

फिर host key को accept करने के लिए एक बार हाथ से connect करें — ssh rkv-repo। एक unattended timer किसी fingerprint prompt का जवाब नहीं देगा, और चुपचाप एक हफ़्ते तक अटका रहने वाला पहला backup एक क्लासिक मामला है। जब आप destination पर हों, तो इसके साथ भी वैसा ही व्यवहार करें जैसा आप अपनी किसी और machine के साथ करते हैं: इस पर भी first-hour hardening checklist चलाएं। यह हर चीज़ की एक copy रखता है, और यह पूरे एक घंटे का हकदार है।

चरण 04 · आरंभ करें

पहले passphrase, फिर पहला snapshot। इसी क्रम में, और box से बाहर।

एक ऐसा passphrase generate करें जिसे आप कभी type नहीं करेंगे। इसे एक script द्वारा एक file से पढ़ा जाता है, इसलिए लंबाई की कोई कीमत नहीं है और इसे याद रखने लायक बनाने की कोई वजह नहीं है:

openssl rand -base64 32 > /root/.restic-pass
chmod 600 /root/.restic-pass
cat /root/.restic-pass

अब रुकें और उस string को कहीं ऐसी जगह copy करें जो यह server न हो। एक password manager, दराज़ में कागज़ पर लिखा एक नोट, एक दूसरी machine — ऐसी कोई भी जगह जो source के खो जाने के बाद भी बची रहे। यही वह विफलता है जो self-hosted vaults और automation engines को तबाह करती है: हर चीज़ को decrypt करने वाली key हर चीज़ के बग़ल में रखी होती है, और दोनों एक साथ खो जाती हैं। एक ऐसी repository जिसका passphrase सिर्फ उसी machine पर था जिसकी वह रक्षा कर रही थी, वह backup नहीं है; वह शोर का एक बहुत करीने से सजाया गया ढेर है।

वह environment file लिखें जिसे बाद की हर command पढ़ेगी:

/etc/backup/restic.env

RESTIC_REPOSITORY=sftp:rkv-repo:/srv/restic/web01
RESTIC_PASSWORD_FILE=/root/.restic-pass
chmod 600 /etc/backup/restic.env
set -a; . /etc/backup/restic.env; set +a
restic init

Borg के लिए इसका बराबर जोड़ा — repokey mode encryption key को repository के अंदर ही store करता है, जो passphrase से सुरक्षित होती है, यह सुविधाजनक तो है और ठीक इसीलिए आपको इसकी एक copy भी export करनी चाहिए:

export BORG_REPO=ssh://borg@rkv-repo/srv/borg/web01
export BORG_PASSCOMMAND="cat /root/.restic-pass"
borg init --encryption=repokey-blake2
borg key export ::  /root/borg-key.txt   # copy this off the server too

पहला snapshot। इसे हाथ से run करें, इसे देखें, और कुछ भी automate करने से पहले इसे पूरा होने दें। यह वाला धीमा है — हर chunk नया है — और यही वह run है जो बताता है कि include list सही थी या नहीं:

restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system --verbose

अगर source traffic serve कर रहा है और upload link को saturate कर रहा है, तो इसे throttle करें। यह flag kibibytes प्रति सेकंड लेता है, तो 20000 का मतलब लगभग 20 MB/s होता है:

restic backup --limit-upload 20000 --files-from /etc/backup/include.txt

जब यह पूरा हो जाए, तो देखें कि आपको असल में क्या मिला। ये तीन commands वे हैं जिन्हें अभी चलाना है, और छह महीने बाद फिर से, जब आप इस सबके बारे में सोचना बंद कर चुके हों:

restic snapshots                    # the list, with dates and tags
restic stats latest                 # what the newest snapshot contains
restic ls latest /etc/backup        # confirm a path you expected is in there

वह तीसरी command थोड़ा ध्यान देने लायक है। आधे टूटे हुए backups असल में टूटे हुए होते ही नहीं हैं — वे गलत directory के पूरे, स्वस्थ repositories होते हैं। जिस path के मिलने की उम्मीद थी उसे list करना, वह भी पहले ही snapshot पर, इसे तभी पकड़ लेता है जब include file अभी भी आपके दिमाग में ताज़ा हो।

चरण 05 · स्वचालित करें

पहले dump, फिर snapshot। एक script, एक timer, एक retention policy।

database नियम, एक बार बता दिया गया। एक चलता हुआ database engine अपनी state memory में रखता है और उसे अपने समय पर disk पर लिखता है। जब वह ऐसा कर रहा हो तब उसकी files पढ़ें तो आपको कई अलग-अलग पलों के pages का एक सेट मिलता है — एक ऐसी file जो restore हो सकती है, corrupt होकर restore हो सकती है, या कुछ ऐसा बनकर restore हो सकती है जो साफ़-सुथरा खुलता तो है लेकिन चुपचाप आख़िरी घंटे को गायब किए हुए होता है। बाहर से यह बता पाने का कोई तरीका नहीं है कि कौन-सा हुआ। इसलिए backup कभी live files को नहीं छूता: पहले disk पर एक dump लिखा जाता है, और backup उस dump को उठा लेता है।

सब कुछ एक ही script में जाता है। इसे /usr/local/sbin/nb-backup.sh पर रखें, इसे executable बनाएं, और इसे खुद backup में भी रखें:

#!/bin/sh
set -eu

# ---- 1. Consistent dumps, written where the include list will find them.
install -d -m 0700 /var/backups/db

# PostgreSQL in a container:
docker exec -t app-db pg_dumpall -U postgres | gzip -9 > /var/backups/db/postgres.sql.gz

# MariaDB / MySQL, InnoDB tables:
# docker exec -t mail-db mariadb-dump --single-transaction --all-databases \
#   | gzip -9 > /var/backups/db/mariadb.sql.gz

# SQLite — never a plain file copy:
# sqlite3 /opt/app/data/app.db ".backup '/var/backups/db/app.db'"

# ---- 2. The snapshot.
restic backup \
  --files-from /etc/backup/include.txt \
  --exclude-file /etc/backup/exclude.txt \
  --tag nightly --one-file-system

# ---- 3. Retention, then reclaim the space it freed.
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 12 --prune

# ---- 4. Structural check every night; read 5% of the data on Sundays.
restic check
[ "$(date +%u)" = "7" ] && restic check --read-data-subset=5%

echo "backup ok: $(date -u +%FT%TZ)"

उस script में तीन details दिखने से कहीं ज़्यादा काम कर रही हैं। सबसे ऊपर वाला set -eu का मतलब है कि एक failed dump run को abort कर देता है, बजाय इसके कि अगले छह महीनों तक चुपचाप कल वाले dump का ही snapshot लेता रहे। forget और prune एक ही command हैं, क्योंकि एक ऐसी retention policy जो कभी जगह वापस नहीं लेती, वही disk है जो भरती चली जाती है। और Sunday वाला check सिर्फ index नहीं, बल्कि असली data का एक हिस्सा भी पढ़ता है — repository का corruption दुर्लभ है, और चुपचाप होता है, और इसे पकड़ने का इकलौता तरीका है पढ़ना।

Timer। दो छोटी unit files। यहां cron की बजाय systemd सही scheduler है, क्योंकि एक timer आपको Persistent देता है — machine के बंद रहने के दौरान जो run छूट जाता है वह चुपचाप skip होने की बजाय अगले boot पर हो जाता है — और क्योंकि इसके बाद journalctl हर run का history रखता है।

/etc/systemd/system/nb-backup.service

[Unit]
Description=Nightly encrypted offsite backup
Wants=network-online.target
After=network-online.target docker.service

[Service]
Type=oneshot
EnvironmentFile=/etc/backup/restic.env
ExecStart=/usr/local/sbin/nb-backup.sh
Nice=10
IOSchedulingClass=idle

/etc/systemd/system/nb-backup.timer

[Unit]
Description=Nightly encrypted offsite backup

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=45m
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now nb-backup.timer
systemctl list-timers nb-backup.timer
systemctl start nb-backup.service && journalctl -u nb-backup.service -n 40 --no-pager

randomised delay सिर्फ सजावट नहीं है। internet पर हर self-hosted server ठीक 03:00 बजे अपना maintenance चलाता है, और जो backup ठीक उसी सेकंड शुरू होता है जब log rotation, certificate renewal और container update चल रहे हों, वह अपनी पूरी रात उनसे I/O के लिए लड़ते हुए बिताता है। शुरुआत को पैंतालीस मिनट में फैलाने से कुछ खर्च नहीं होता और रहस्यमयी धीमी रातों की एक पूरी category ख़त्म हो जाती है।

फिर failure को साफ़ सुनाई देने लायक बनाएं। यह वह चरण है जिसे हर कोई skip कर देता है और यही तय करता है कि ऊपर की गई बाकी सब मेहनत की कोई कीमत थी या नहीं। जो backup काम करना बंद कर देता है वह कुछ भी नहीं बताता: timer चलता रहता है, service fail होती रहती है, और आख़िरी अच्छा snapshot अतीत में पीछे खिसकता रहता है जबकि dashboard हरा ही दिखता रहता है। service में एक OnFailure= unit जोड़ें जो आपको कुछ ऐसा भेजे जिसे आप वाकई देखेंगे, और महीने में एक बार snapshot list के सबसे ऊपर एक नज़र डालें। एक लाइन, एक आदत।

restic snapshots --latest 3        # is the newest one from last night?
systemctl list-timers nb-backup.timer   # is the timer still armed?
चरण 06 · अभ्यास

इसे अभी restore करें, जब कुछ भी जल न रहा हो। एक untested backup सिर्फ एक अफ़वाह है।

दो अभ्यास हैं, और ये अलग-अलग सवालों के जवाब देते हैं। छोटा वाला पूछता है "क्या data वाकई वहां है और पढ़ा जा सकता है?" और इसमें नब्बे सेकंड लगते हैं। बड़ा वाला पूछता है "service को वापस लाने में असल में कितना समय लगेगा?" और इसमें साल में एक बार, एक दोपहर लगती है। छोटा वाला हर महीने करें। बड़ा वाला कम से कम एक बार ज़रूर करें, क्योंकि जवाब कभी वैसा नहीं होता जैसा लोग अंदाज़ा लगाते हैं।

छोटा अभ्यास। एक directory और एक dump को scratch path में pull करें, फिर उनकी तुलना उससे करें जो live है:

install -d -m 0700 /mnt/restore
restic restore latest --target /mnt/restore --include /etc/backup
restic restore latest --target /mnt/restore --include /var/backups/db

diff -r /etc/backup /mnt/restore/etc/backup && echo "config identical"
gzip -t /mnt/restore/var/backups/db/postgres.sql.gz && echo "dump readable"

और भी बेहतर, जब tool यह देता है: repository को read-only mount करें और उसे एक filesystem की तरह चलें। हर snapshot एक dated directory के रूप में दिखता है, और आप बिना कुछ भी restore किए ls और cat से इतिहास browse कर सकते हैं। mount करने वाली machine पर इसे FUSE चाहिए:

restic mount /mnt/snapshots      # then: ls /mnt/snapshots/snapshots/latest/
borg mount ::  /mnt/snapshots     # the Borg equivalent

बड़ा अभ्यास। एक scratch VPS को घंटे के हिसाब से order करें, और सिर्फ repository से service को उस पर rebuild करें — न याददाश्त से नोट्स, न live box से copy की गई कोई file। एक लिखित runbook से काम करें और चलते-चलते runbook को ठीक करें, क्योंकि जो gaps आपको मिलते हैं वही इस exercise का पूरा मकसद हैं। सबसे आम discoveries, आवृत्ति के क्रम में: passphrase सिर्फ मृत machine पर थी; DNS records कभी लिखे ही नहीं गए; एक bind-mounted directory हर include path से बाहर पड़ी थी; restore को एक ऐसे package version की जरूरत पड़ी जो अब default नहीं है; किसी को पता नहीं था कि कौन-सा container पहले start होना चाहिए।

इसका समय नापें। runbook के सबसे ऊपर उस नंबर को date के साथ लिख दें। वह नंबर — न कि repository का size, न ही snapshots की संख्या — ही एकमात्र ईमानदार पैमाना है कि service असल में कितनी सुरक्षित है।

और कभी-कभी data पढ़ें भी। nightly check structure को verify करता है: कि index खुद से मेल खाता है और कोई blob गायब नहीं है। यह blobs को पढ़ता नहीं है। महीने में एक बार, या Sunday वाले run पर, उनमें से एक हिस्सा पढ़ें — एक घूमता हुआ पांच प्रतिशत बिना किसी लंबी रात की कीमत चुकाए कुछ महीनों में पूरी repository को cover कर लेता है:

restic check --read-data-subset=5%
borg check --verify-data              # the Borg equivalent, slower and thorough
सबसे मुश्किल हिस्सा · Append-only

एक ऐसी key जो लिख सकती है, लेकिन मिटा नहीं सकती। एक बुरे हफ़्ते और बंद हो चुके business के बीच का फर्क।

यहां तक सब कुछ दुर्घटनाओं से बचाता है। यह अध्याय एक adversary से बचाता है, और design की समस्या एक बार दिखने के बाद असहज हो जाती है: source machine को हर रात repository तक पहुंचना ही होता है, जिसका मतलब है source machine के पास repository का एक काम करने वाला credential होता है। जो भी source का मालिक है वही उस credential का भी मालिक है। अगर credential delete कर सकता है, तो हमलावर delete कर देता है — और modern ransomware ठीक यही करता है, जान-बूझकर, कुछ भी encrypt करने से पहले, क्योंकि एक restore हो सकने वाला पीड़ित पैसे नहीं देता।

इसका समाधान कोई बेहतर password नहीं है। यह एक असममित permission है: source data जोड़ सकता है, लेकिन कोई भी data हटा नहीं सकता। इसे बनाने के तीन तरीके हैं, इस क्रम में कि इन्हें सही करना कितना आसान है।

एक — SSH पर जबरन append-only. यह Borg का अपना मैदान है और यह किसी ऐसी machine पर उपलब्ध सबसे साफ़ जवाब है जिसकी आप मालिक हैं। step 03 वाली authorized_keys entry borg serve --append-only को force करती है, इसलिए far end deletions को मना कर देता है चाहे near end कुछ भी मांगे। Pruning फिर भी होनी चाहिए, लेकिन यह destination की तरफ़ से होती है, एक ऐसे schedule पर जिसे source प्रभावित नहीं कर सकता, और एक ऐसे account से चलती है जिस तक source की पहुंच नहीं है। source पर root वाला हमलावर repository को कचरे से भर सकता है; वे उनके आने से पिछली रात वाला archive नहीं हटा सकते।

दो — एक append-only REST endpoint। restic के साथी rest-server में भी एक --append-only mode है जिसमें वही property है: नए blobs स्वीकार होते हैं, मौजूदा हटाए नहीं जा सकते। इसे destination पर TLS के पीछे चलाएं, RESTIC_REPOSITORY को sftp: वाले की बजाय https:// URL पर point करें, और defence का ढांचा बिल्कुल वैसा ही रहता है। इसकी कीमत destination पर एक और service है, और बदले में वही गारंटी मिलती है।

तीन — object lock। S3-compatible storage पर, versioning के साथ एक object-lock retention period, period ख़त्म होने तक deletion को नामुमकिन बना देता है, और यह किसी program से नहीं बल्कि storage layer से लागू होता है। यह तीनों में सबसे मज़बूत और सबसे महंगा है, और यह एक provider account ले आता है — जो वही custodial risk वापस ले आता है जिसे यह पूरी guide फैलाने की कोशिश कर रही है। एक तीसरी copy के तौर पर समझदारी भरा, इकलौती copy के तौर पर अजीब।

अगर इनमें से कुछ भी फिट न बैठे — plain SFTP, एक ऐसी key जो लिख सकती है और इसलिए delete भी कर सकती है — तो ऐसा दिखावा न करें कि सब ठीक है; एक दूसरी, स्वतंत्र copy जोड़ें जिसे source बिल्कुल छू ही न सके। push की बजाय pull करें: गंतव्य को source में log in करने दें, जो चाहिए वह पढ़ने दें, और उसे store करने दें। फिर credentials उस machine पर रहते हैं जो exposed नहीं है, और source पर मौजूद हमलावर को backup की तरफ़ इशारा करने वाला कुछ भी नहीं मिलता। इसे set up करने में थोड़ा ज़्यादा काम लगता है और यह जोख़िम को बिल्कुल सही दिशा में उलट देता है।

आप जो भी चुनें, उसे उसी तरह verify करें जैसे आप किसी और security control को verify करते हैं — उसे तोड़ने की कोशिश करके। source से, backup key के साथ, एक delete करने की कोशिश करें। सही नतीजा एक इनकार होना चाहिए।

borg delete ::name-of-an-old-archive
# → Remote: Repository is in append-only mode. Refusing to delete.
Field notes · प्रति service

वह एक file जिसके बिना हर service वापस नहीं आ सकती। यह शायद ही कभी सबसे बड़ी वाली होती है।

हर service के पास state का एक छोटा टुकड़ा होता है जो न data है और न configuration, और उसे खो देने से service को नुक़सान नहीं होता — वह उसे एक अलग service से बदल देता है जिसका नाम बस वही रह जाता है। पुराने links टूट जाते हैं, federated peers नई identity को नकार देते हैं, clients re-key करते हैं। यह रहे वे टुकड़े, हर stack के हिसाब से, उन चीज़ों के लिए जिन पर इस site के guides मौजूद हैं।

Nextcloud

data directory, config/config.php, और एक database dump। dump के लिए maintenance mode on करें, बाद में off कर दें — वरना Nextcloud दोनों में एक साथ लिखता रहता है।

Vaultwarden

पूरी data directory: db.sqlite3 को copy करने की बजाय .backup से लिया गया, साथ ही rsa_key files, attachments और sends।

Matrix Synapse

signing key, homeserver.yaml, media store और एक PostgreSQL dump। signing key खो दें तो federation identity हमेशा के लिए चली जाती है।

Mail server

mail store खुद, virtual user tables, और DKIM private keys — एक नई DKIM key का मतलब है कि जब तक DNS अपडेट नहीं हो जाता, हर message unsigned रहता है।

n8n

पहले N8N_ENCRYPTION_KEY, फिर PostgreSQL dump। उस key के बिना database सिर्फ workflows की एक list रह जाता है जिसका हर credential अपठनीय है।

Tor onion सेवा

hidden service directory। वे चंद files ही .onion address हैं — इनके बिना service एक अलग नाम के साथ वापस आती है और उसका हर link मर जाता है।

WireGuard

पूरा /etc/wireguard। छोटा, उबाऊ, और एक पांच-मिनट के rebuild तथा आपके हर device की दोबारा re-key करने के बीच का फर्क।

Lightning node

seed और channel state, node की अपनी शर्तों पर। पुराने channel data को restore करने से आपके funds का नुकसान हो सकता है — किसी generic file copy की नहीं, बल्कि implementation की अपनी backup procedure की पालना करें।

storage के नीचे की परत

दूरी एक तकनीकी जवाब है। Jurisdiction दूसरा आधा हिस्सा है।

ज़्यादातर लोगों से पूछें कि backup कहीं और क्यों होना चाहिए, तो जवाब मिलता है आग, बाढ़, या एक datacentre की power चले जाना। सब सच है, सब लगातार दुर्लभ होता जा रहा है, और सबका जवाब सौ किलोमीटर की दूरी दे देती है। 2026 में जो विफलताएं असल में businesses को गिरा देती हैं वे administrative हैं, और अकेली दूरी उनके बारे में कुछ नहीं करती।

एक account एक ही point of failure है। एक automated fraud signal के लिए suspension, प्लेन में बैठे-बैठे एक chargeback, एक compliance review, एक ऐसा takedown जो machine को नहीं बल्कि company को संबोधित हो — इनमें से हर एक उस account के तहत हर server तक एक ही पल में पहुंचता है, उस server तक भी जिसके पास snapshots हैं। technical redundancy बिल्कुल परफेक्ट थी और बेमानी थी। दो providers, या कम से कम दो अलग legal छतों के तहत दो accounts, ही इकलौता ढांचा है जो इसका जवाब देता है।

एक jurisdiction एक ही legal ढांचा है। चारों Nordic bastions एक-दूसरे की जगह नहीं ले सकते — Sweden, Finland, Norway और Iceland हर एक थोड़ी अलग चीज़ की रक्षा करता है, और Norway तथा Iceland पूरी तरह European Union से बाहर हैं। एक working machine और उसकी repository को इन दोनों में बांटने का मतलब है कि copy सिर्फ कहीं और नहीं है; वह नियमों के एक दूसरे, स्वतंत्र सेट के अंदर है। Nordic jurisdictions reference statutes को एक-एक करके देखता है।

और गंतव्य को कुछ भी पता नहीं चलता। यही वजह है कि यह बंटवारा एक trade-off नहीं, बल्कि सस्ता सौदा बन जाता है। restic और Borg दोनों ही कुछ भी source से निकलने से पहले encrypt कर देते हैं, इसलिए repository host ऐसे blobs रखता है जिनकी key उसके पास नहीं है। उसे नहीं पता कि उसके पास कौन-सी files हैं, कितनी हैं, या उनका नाम क्या है। आप किसी दूसरे party को trust नहीं दे रहे; आप एक ऐसी disk किराए पर ले रहे हैं जो खुद को पढ़ ही नहीं सकती। "क्या मुझे backup target के तौर पर किसी ऐसे provider का इस्तेमाल करना चाहिए जिस पर मुझे पूरा भरोसा नहीं है?" — इसका ईमानदार जवाब भी यही है: एक encrypted repository के लिए, trust का सवाल लगभग आता ही नहीं।

Latency यहां कोई factor नहीं है। Helsinki से Reykjavík तक backbone पर 30 ms है, Helsinki से Stockholm तक 8 ms, Stockholm से Oslo तक 11 ms। एक nightly backup को इनमें से किसी नंबर की परवाह नहीं है, और न ही उस restore को जो disk throughput से सीमित हो। जोड़ी को legal दूरी के लिए चुनें, network दूरी के लिए नहीं — Nordics भर में network दूरी बस एक rounding error है।

एक और बात साफ़ तौर पर कहने लायक है, क्योंकि यही वजह है कि यह guide एक साधारण sysadmin blog की बजाय इस site पर है: दूसरी machine हर उस सवाल को दोबारा खोल देती है जिसका जवाब पहली ने दिया था। अगर working VPS बिना किसी identity document के और Monero में भुगतान करके order किया गया था, और फिर उसके लिए backup box एक company card और एक passport scan से order किया जाता है, तो यह जोड़ा उतना ही पहचाने जाने लायक है जितना उसका कमज़ोर आधा हिस्सा। anonymous VPS hosting पर pillar guide तीनों layers — signup, payment, network — पर चलती है, और ये एक backup target पर भी उतनी ही सचमुच लागू होती हैं जितनी एक web server पर।

Field notes · छह traps

छह तरीके जिनसे एक backup असल में backup नहीं निकलता। ये सभी बुरे दिन पर ही पता चलते हैं।

Trap 01 · अपरिवर्तनीय

passphrase सिर्फ मृत machine पर ही थी

repository बरकरार है, encrypted है, और हमेशा के लिए अपठनीय है। passphrase — और Borg के लिए exported key भी — पहले snapshot से पहले एक password manager में और कागज़ पर स्टोर करें।

Trap 02 · संगति

database restore हो जाता है, फिर पहली query पर fail हो जाता है

dump लेने की बजाय live data files copy कर ली गईं। एक pre-backup step में एक dump लिखें और उस dump का backup लें; include list को कभी भी एक चलते हुए engine की data directory पर point न करें।

Trap 03 · प्रभाव क्षेत्र

घुसपैठिए ने सबसे पहले backups delete कर दिए

एक compromised box पर लिखने वाला credential हमलावर के लिए भी लिखने वाला credential है। गंतव्य पर append-only force करें, या push की बजाय pull से दूसरी copy लें।

Trap 04 · क्षमता

repository server से बड़ी है

prune के बिना forget सिर्फ snapshots को mark करता है और कुछ भी वापस नहीं लेता। इन्हें साथ में चलाएं, destination पर खाली जगह बनाए रखें, और कभी भी container images या node_modules का backup न लें।

Trap 05 · मौन

आख़िरी अच्छा snapshot पांच महीने पुराना है

upgrade के बाद timer fail हो गया और किसी ने कुछ नहीं बताया। एक OnFailure= unit जोड़ें, और महीने में एक बार snapshot list का सबसे ऊपर वाला हिस्सा check करें — इसमें दस सेकंड लगते हैं।

Trap 06 · दायरा

एक directory को छोड़कर सब कुछ restore हो गया

/opt के बाहर एक bind mount, migration के दौरान move किया गया एक volume, एक exclude pattern जो इरादे से ज़्यादा चीज़ों से मेल खा गया। हर नए snapshot पर एक known path list करें, और stack में किसी भी बदलाव के बाद include file को दोबारा पढ़ें।

FAQ · VPS बैकअप

प्रश्न, उत्तरित।

दस सवाल जो इसे set up करते समय सामने आते हैं — और दो जो सिर्फ बाद में, एक बार सामने आते हैं।

क्या एक provider snapshot ही एक backup है?

नहीं — यह एक rollback है, और एक काम की चीज़ है, लेकिन यह ठीक उन्हीं पलों में fail होता है जिनके लिए एक backup होता है। एक snapshot उसी provider account के अंदर रहता है जिस server की वह copy है। अगर account suspend हो जाए, अगर payment को dispute किया जाए, अगर कोई support agent ग़लती से एक deletion कर बैठे, या अगर कोई हमलावर आपके panel credentials पा ले, तो snapshot machine के साथ ही चला जाता है। यह आपको कुछ भी granular भी नहीं देता: आप कल में से एक अकेली deleted file नहीं निकाल सकते, सिर्फ पूरी disk को पीछे roll कर सकते हैं और उसके बाद की हर चीज़ खो सकते हैं। snapshots रखें — एक ख़राब upgrade को undo करने का सबसे तेज़ तरीका यही है — लेकिन इन्हें उस copy के साथ मत गड्डमड्ड करें जो कहीं ऐसी जगह मौजूद हो जहां असली समस्या न पहुंच सके। अंगूठे का नियम: अगर एक compromised credential दोनों copies को तबाह कर सकता है, तो आपके पास एक ही copy है

restic या Borg में से असल में कौन-सा चुनें?

दोनों client पर encrypt करते हैं, दोनों chunk level पर deduplicate करते हैं, दोनों परिपक्व हैं, और दोनों काम कर देंगे। restic चुनें अगर आपको एक static binary चाहिए, एक ऐसी repository जो SFTP, S3-compatible object storage, एक REST server या rclone जहां भी पहुंच सके वहां रह सके, और गंतव्य पर बिल्कुल कुछ भी installed न हो। Borg चुनें अगर गंतव्य एक ऐसा SSH box है जिस पर आपका नियंत्रण है, आपको बिना object-lock storage के उपलब्ध सबसे मज़बूत append-only enforcement चाहिए, और आपको इसका थोड़ा टाइट compression पसंद है। वे practical फ़र्क जो यह तय करते हैं: Borg को दोनों सिरों पर installed borg चाहिए और यह सिर्फ SSH या एक local path से बात करता है; restic को एक prune pass चाहिए जो थोड़ी देर के लिए repository पर एक exclusive lock ले लेता है। अगर तय न कर पाएं, तो restic इस्तेमाल करें — गंतव्य पर कम moving parts किसी भी benchmark से ज़्यादा कीमती हैं।

backup box को कितनी disk चाहिए?

उस चीज़ के आकार से शुरुआत करें जिसे आप वाकई backup कर रहे हैं — न कि उस disk के आकार से जिस पर वह टिकी है। एक typical self-hosted stack में कुछ gigabytes का database और configuration होता है, साथ ही जो कुछ users ने upload किया हो। इसके बाद Deduplication और compression अपना काम दिखाते हैं: बारह महीने की retention policy वाले 20 GB working set का daily snapshot आमतौर पर 40 से 80 GB repository में आकर टिकता है, क्योंकि सिर्फ बदले हुए chunks ही दोबारा स्टोर होते हैं। एक Sentinel ($3.90/माह, 120 GB NVMe) इसे आराम से cover कर लेता है। जब कई servers एक ही repository host में backup करें तो Garrison (240 GB, $7.90) पर जाएं, और जब working set खुद ही सैकड़ों gigabytes तक पहुंच जाए तो Bulwark (960 GB, $32.90) पर। repository के हिसाब से size तय करें, फिर उसे दोगुना कर दें — एक ऐसी repository जिसमें खाली जगह न हो prune नहीं कर सकती, और जो repository prune नहीं कर सकती वह सिर्फ बढ़ती ही जाती है।

क्या मैं एक live database की files copy करके उसका backup ले सकता हूं?

आप इन्हें copy कर सकते हैं। हो सकता है आप इन्हें restore न कर पाएं। जब आप एक database को पढ़ते हैं और वह उसी समय disk पर लिख भी रहा होता है, तो आपको कई अलग-अलग instants की एक file set मिलती है, यही एक torn backup की परिभाषा है — यह या तो एक corrupted database के रूप में restore होता है, या इससे भी बुरा, एक ऐसे database के रूप में जो ठीक से खुल तो जाता है लेकिन चुपचाप उसकी rows गायब होती हैं। इसका समाधान एक dump है: PostgreSQL के लिए pg_dump या pg_dumpall, InnoDB tables पर MariaDB और MySQL के लिए mariadb-dump --single-transaction, और SQLite के लिए sqlite3 db .backup out.db या VACUUM INTO। dump को एक file में लिखें, फिर उस file का backup लें। अगर database रोज़ dump करने के लिए बहुत बड़ा है, तो विकल्प हैं: engine को थोड़ी देर के लिए quiesce करके लिया गया एक filesystem snapshot, या engine का अपना physical backup tool — लेकिन एक अकेला VPS जो भी चलाता है उसके लिए, एक dump सही और सीधा-सादा तरीका है।

अगर backup repository का passphrase खो जाए या भूल जाएं, तो क्या होगा?

backups चले जाते हैं। restic और Borg दोनों ही client-side पर encrypt करते हैं, और किसी के पास भी कोई recovery path, कोई master key, या ऐसा कोई support ticket नहीं है जो आपके लिए repository unlock कर दे। यही पूरी बात है: destination host — यहां तक कि वह host भी जो आपका नहीं है — कभी आपका plaintext नहीं देखता। इसका मतलब यह भी है कि passphrase अब एक ऐसा data है जिसकी कीमत ठीक उतनी ही है जितनी उस सबकी जिसे यह सुरक्षा देता है, और इसे सिर्फ उसी machine पर नहीं रहना चाहिए जिसका backup लिया जा रहा है। इसे अपने password manager में रखें, और इसकी एक copy कहीं physically भी रखें। Borg के लिए, borg key export से repository key भी export करें और उसे साथ में store करें; repokey mode में key repository के अंदर ही रहती है, इसलिए जिस repository तक आप अब नहीं पहुंच सकते वह key को भी अपने साथ ले जाती है।

एक compromised server को अपने ही backups delete करने से मैं कैसे रोकूं?

आप इसे ऐसा credential देते हैं जो जोड़ तो सकता है लेकिन हटा नहीं सकता। पूरी exercise में यही सबसे अहम design decision है, क्योंकि modern ransomware सबसे पहले backup configuration ढूंढता है और उसी रास्ते घर तक पहुंचता है। इसे पाने के तीन तरीके। SSH पर Append-only: destination की authorized_keys में, command borg serve --append-only --restrict-to-path /srv/borg को force करें — source नए archives लिख सकता है और पुराने delete नहीं कर सकता। REST पर Append-only: restic का rest-server --append-only के साथ चलाएं और repository को HTTPS पर उसकी तरफ़ point करें। Object lock: versioning और एक retention lock वाला एक S3-compatible bucket। सीधा SFTP इनमें से कुछ नहीं देता — जो key repository लिख सकती है वह उसे मिटा भी सकती है — इसलिए अगर SFTP आपका transport है, तो इसे destination की तरफ़ से ली गई एक pull-based दूसरी copy के साथ जोड़ें, जहां source पर हमलावर के हासिल किए गए credentials तक पहुंच नहीं होती।

backups कितनी बार चलने चाहिए, और मुझे इन्हें कितने समय तक रखना चाहिए?

इसे उल्टा पूछें: आप कितना काम दोबारा करने को तैयार हैं? वह नंबर ही आपका recovery point objective है, और वही interval तय करता है। Nightly लगभग हर self-hosted service के लिए सही है — एक mail server, एक Nextcloud, एक Matrix homeserver, एक workflow engine। Hourly तब लायक है जब data transactional हो और दोबारा entry करना नामुमकिन हो। retention के लिए, वह pattern जो असलियत से टकराने के बाद भी टिका रहता है वह है --keep-daily 7 --keep-weekly 4 --keep-monthly 12: एक हफ़्ते का बारीक undo, एक महीने के weekly checkpoints, एक साल के monthly वाले, कुल मिलाकर लगभग 23 snapshots। long tail लोगों की उम्मीद से ज़्यादा मायने रखती है, क्योंकि जो विफलता यह पकड़ती है वह कोई मरी हुई disk नहीं है — यह एक ऐसा corruption या deletion है जिसे छह हफ़्तों तक किसी ने नोटिस ही नहीं किया।

क्या दूसरी copy का सच में किसी दूसरे देश में होना ज़रूरी है?

अलग building होना तकनीकी न्यूनतम है; अलग jurisdiction होना वह हिस्सा है जिसे ज़्यादातर लोग छोड़ देते हैं और बाद में पछताते हैं। एक आग, एक बाढ़ या एक rack-level विफलता का जवाब सिर्फ दूरी दे देती है। जो चीज़ दूरी का जवाब नहीं देती वह है legal या commercial: एक provider द्वारा suspend किया गया account, एक payment dispute, एक takedown जो एक ही corporate छत के नीचे बैठी हर machine तक पहुंचता है, एक company पर दिया गया order। अगर दोनों copies एक ही provider के साथ रहती हैं, तो एक चिट्ठी दोनों तक पहुंच जाती है। इस जोड़े को दो Nordic bastions में बांटना — Helsinki में काम करने वाली machine, Reykjavík में repository, backbone पर 30 ms की दूरी पर — latency में कुछ भी खर्च नहीं करता और एक दूसरा legal ढांचा खरीद लेता है। data दोनों ही हालत में source से निकलने से पहले encrypt हो जाता है, इसलिए गंतव्य को उसे रखने से कुछ भी पता नहीं चलता।

पहला backup लेने में कितना समय लगता है, और क्या encryption इसे धीमा कर देता है?

Encryption बाधा नहीं है — modern CPUs, AES को उतनी तेज़ी से कर लेते हैं जितनी तेज़ी से एक gigabit link नतीजा ढो सकता है, और दोनों tools जहां मौजूद हो वहां hardware acceleration इस्तेमाल करते हैं। असली बाधा पहला upload है, क्योंकि सब कुछ नया होता है: एक 1 Gbps uplink पर एक 20 GB working set line rate पर कुछ मिनट लेता है, और अगर गंतव्य throttled हो या files कई और छोटी हों तो इससे कहीं ज़्यादा वक़्त लगता है। इसके बाद हर run सिर्फ उन chunks को transfer करता है जो बदले हैं, जो एक typical stack के लिए कुछ दसियों megabytes होता है और एक मिनट से भी कम में पूरा हो जाता है। अगर पहला run किसी production workload से टकराए, तो इसे rate-limit करें — restic KiB/s में --limit-upload लेता है, Borg --upload-ratelimit लेता है — और इसे nice और ionice के तहत चलाएं।

क्या मुझे restores को सच में test करना ज़रूरी है?

हां, और इसकी वजह paranoia नहीं है — बल्कि यह है कि आम विफलताएं चुपचाप होती हैं। वह timer जो package upgrade के बाद चलना बंद कर देता है। वह exclude pattern जो चुपचाप uploads directory को निगल जाता है। वह database dump जो एक ऐसे path पर लिखा जाता है जिसे backup ने कभी cover ही नहीं किया। वह repository जो हफ़्तों से अपना integrity check fail करती आ रही है, किसी ऐसे log में जिसे कोई नहीं पढ़ता। इनमें से कोई भी खुद अपने बारे में नहीं बताता; इन सबको नब्बे सेकंड में पकड़ा जा सकता है, एक file को restore करके और उसे देखकर। महीने में एक बार एक छोटा restore करें — एक database dump और एक data directory को scratch path में लाकर उनकी diff करें — और साल में एक बार एक fresh VPS पर, समय नापते हुए, पूरा rebuild करें। उस rebuild से जो नंबर निकलता है वही आपका असली recovery time है, और वह शायद ही कभी वह नंबर होता है जिसका आपने अंदाज़ा लगाया था।

दूसरी machine लें

दूसरे Nordic jurisdiction में एक repository bastion। KYC-मुक्त, crypto-भुगतान।

Sentinel — Helsinki, Stockholm, Oslo या Reykjavík में, $3.90 प्रति माह में 120 GB NVMe। Unmetered bandwidth, इसलिए restore करने पर कुछ खर्च नहीं होता। signup पर कोई email नहीं, कोई पहचान दस्तावेज़ नहीं, और एक ऐसा गंतव्य जो अपने पास मौजूद डेटा का एक byte भी नहीं पढ़ सकता।

अंतिम review · 2026-08-24 · स्रोत · restic और BorgBackup की documentation, PostgreSQL और MariaDB की backup manuals, sshd authorized_keys(5), systemd.timer(5) · आवृत्ति · वार्षिक