
VPS का backup लें जिसे आप वाकई restore कर सकें
सर्वर चलाने वाला लगभग हर व्यक्ति किसी न किसी चीज़ को backup कहता है। restore करके देखने वाले कहीं कम हैं, और इन दो बातों के बीच की दूरी में ही डेटा असल में ग़ायब होता है। यह इस बारे में है कि ऐसी कॉपी कैसे बनाई जाए जो उन तीन चीज़ों से बच निकले जो सच में सर्वर बर्बाद करती हैं — आपके अपने हाथ, एक compromise, और एक ऐसा अकाउंट जिस पर आपका नियंत्रण छूट जाए — और यह सब बिना किसी गुमनाम मशीन पर चुपके से एक सत्यापित पहचान जोड़े।
इस नेटवर्क को चलाने वाले हर byte की हम तीन कॉपियाँ रखते हैं, और हमने उनसे जान-बूझकर, किसी आम मंगलवार को, उतनी बार restore किया है जितनी बार असल इमरजेंसी में कभी करना पड़ा उससे कहीं ज़्यादा। यह अपने आप में की गई मेहनत नहीं है। यह जानने का बस यही एक तरीक़ा है कि repository में पड़ी चीज़ वाक़ई एक backup है, न कि किसी भरोसा जगाने वाले नाम वाला encrypted शोर से भरा फ़ोल्डर।
नीचे दी गई सलाह जान-बूझकर पुराने ढर्रे वाली है। इसमें कोई dashboard वाला backup प्रोडक्ट, कोई मासिक subscription या कोई support queue शामिल नहीं, क्योंकि इनमें से हर चीज़ एक अकाउंट है, और एक अकाउंट यानी एक नाम, एक कार्ड और एक jurisdiction — तीन ऐसी चीज़ें जिन्हें इस सर्वर से दूर रखने में आपने शायद असली मेहनत की हो। इसमें बस एक दूसरी मशीन, तक़रीबन चालीस लाइन का shell, और एक ऐसी आदत शामिल है जो लगभग कोई नहीं निभाता।
इसे आप एक शाम में पूरा कर सकते हैं। यहाँ इस्तेमाल किए गए tools Debian 13 और Ubuntu 24.04 के हिसाब से हैं; बाक़ी सब कुछ मामूली बदलावों के साथ RHEL से मिलते-जुलते डिस्ट्रो पर भी चल जाता है। अगर आपका सर्वर नया है, तो पहले घंटे वाला hardening इस पेज के बाद नहीं, पहले कर लें — जो मशीन पहले से ही किसी और की हो चुकी है, उसका backup लेना बस उसी की मेहनत को सुरक्षित रखने जैसा है।
किराए के सर्वर पर डेटा को असल में क्या बर्बाद करता है
किसी से भी पूछिए कि वे backup क्यों लेते हैं, और जवाब अक्सर होता है “अगर डिस्क ख़राब हो जाए तो”। एक आधुनिक VPS पर आपके साथ यह होना लगभग सबसे कम संभावित बात है। आपका volume redundant array में NVMe पर टिका होता है, साथ में एक hypervisor जो किसी फेल होते host से आपको आपके नोटिस करने से पहले ही हटा देगा; drive फेल होना प्रोवाइडर की समस्या है, और वह एक सुलझी हुई समस्या है। अपनी पूरी backup रणनीति को इसके इर्द-गिर्द बनाना ऐसा है जैसे किसी ऐसे घर के लिए fire extinguisher ख़रीदना जिसमें बाढ़ आती हो।
लोगों का डेटा असल में क्या ले जाता है, यह रहा — मोटे तौर पर आवृत्ति (frequency) के क्रम में। पहला, और बड़े अंतर से: आप ख़ुद। एक rm -rf जिसमें कोई variable ख़ाली निकल गया। ग़लत terminal पर एक DROP DATABASE, क्योंकि दो tabs बिल्कुल एक जैसे दिख रहे थे। दो बार चलाई गई एक migration स्क्रिप्ट। एक docker compose down -v जिसमें -v लगाना हाथ की आदत बन चुका था। ये कोई अनोखी बातें नहीं हैं; ये तो बस एक और मंगलवार है।
दूसरा, वे application जो अपना ही डेटा मिटा देते हैं। कोई upgrade जो एक विनाशकारी migration चलाकर आधे में फेल हो जाए। कोई plugin जो एक cache डायरेक्टरी साफ़ कर दे जो असल में cache थी ही नहीं। ग़लत path पर सेट की गई log rotation। तीसरा, compromise — और ग़ौर करें कि यह वह मामला है जहाँ एक हमलावर backups का मिट जाना चाहता है, जो डिज़ाइन को उन तरीक़ों से बदल देता है जिन पर हम आगे लौटेंगे। चौथा, और no-KYC host पर भूल जाना आसान: अकाउंट खो देना। ऐसा बैलेंस जो आपकी ग़ैर-मौजूदगी में ज़ीरो हो गया, password manager की कोई ऐसी एंट्री जो आपने कभी लिखी ही नहीं, कोई ईमेल पता जिसे आपने छोड़ दिया। हम ज़ीरो बैलेंस के कुछ ही घंटों में सस्पेंड कर देते हैं और सात दिन बाद मिटा देते हैं, और यह जान-बूझकर बेरहम रखा गया है — यही वह अंकगणित है जो हमें यह पूछने से बचाता है कि आप कौन हैं। कोई support agent नहीं है जो आपकी पहचान ढूँढकर कोई अपवाद बना दे, क्योंकि ढूँढने के लिए कोई पहचान है ही नहीं।
यही आख़िरी श्रेणी है जो privacy-first hosting को मुख्यधारा वाली hosting से अलग करती है, और इसे आपकी योजना तय करनी चाहिए। हर वह नियंत्रण जो इस सर्वर को आपसे जोड़ना मुश्किल बनाता है, वह किसी के लिए भी — हमारे लिए भी — इसे आपको वापस लौटाना उतना ही मुश्किल बना देता है। Backup ही वह चीज़ है जो इस सौदे को एक जोखिम से एक विकल्प में बदल देती है।
Snapshot backup क्यों नहीं है
Snapshots शानदार हैं और आपको इन्हें इस्तेमाल करना चाहिए। हर kernel upgrade से पहले, हर database migration से पहले, और जब भी आप कुछ ऐसा करने वाले हों जिसे बाद में पलटना चाहेंगे, तब एक snapshot ले लें। ये सेकंडों में restore हो जाते हैं, इनकी क़ीमत लगभग कुछ भी नहीं है, और साल में एक दर्जन बार ये आपकी एक पूरी दोपहर बचा देंगे।
फिर भी ये backups नहीं हैं, तीन संरचनात्मक वजहों से, जिन्हें प्रोवाइडर की कितनी भी मार्केटिंग नहीं बदल सकती। ये उसी अकाउंट के भीतर रहते हैं: जो कोई भी आपके panel में लॉगिन कर सकता है वह इन्हें मिटा भी सकता है, और अगर अकाउंट काम करना बंद कर दे तो snapshots भी उसी के साथ ख़त्म हो जाते हैं। ये उसी failure domain में रहते हैं: वही प्रोवाइडर, वही control plane, अक्सर वही storage cluster — मतलब एक ही बुरी घटना असली और कॉपी, दोनों को साथ ले जा सकती है। और ये अपारदर्शी हैं: चलती हुई मशीन का एक snapshot किसी डेटाबेस को mid-write उतनी ही ईमानदारी से पकड़ता है जितनी बाक़ी सब कुछ, इसलिए किसी व्यस्त MySQL सर्वर के snapshot से restore करने पर आपको एक साफ़-सुथरा डेटाबेस नहीं, बल्कि crash-recovery वाली स्थिति मिलती है।
पुराना 3-2-1 नियम — तीन कॉपियाँ, दो तरह के मीडिया पर, जिनमें से एक off-site — आमतौर पर बिना यह नोटिस किए दोहराया जाता है कि किराए के infrastructure पर बीच वाला हिस्सा बेमानी है। आपके पास दो तरह का मीडिया होता ही नहीं। आपके पास एक virtual block device है, और एक और virtual block device, और दोनों ही किसी और का SAN हैं। VPS पर तर्जुमा होने के बाद जो हिस्सा बचता है, वही हमेशा से मायने रखता था: कम से कम एक कॉपी ऐसी जगह होनी चाहिए जहाँ एक अकेली बुरी घटना न पहुँच सके। अलग प्रोवाइडर, या कम से कम अलग क्षेत्र, अलग credentials, अलग अकाउंट, और — अगर offshore host करने की वजह क़ानूनी है न कि तकनीकी — तो एक अलग jurisdiction भी, ताकि एक ही अदालती आदेश दोनों कॉपियों पर एक साथ न आ गिरे।
गंतव्य भी आपके threat model का हिस्सा है
यह वह सेक्शन है जो बाक़ी backup ट्यूटोरियल्स में नहीं मिलता, और अगर आपने इस सर्वर के लिए Monero से भुगतान किया है तो यही सबसे ज़्यादा मायने रखता है।
इंटरनेट पर हर जगह मिलने वाली डिफ़ॉल्ट सलाह यह है कि अपने backups को किसी object store पर push करें: Backblaze B2, Amazon S3, Wasabi, या rclone के ज़रिए कोई Google Drive। यह सस्ता है, टिकाऊ है, और काम करता है। यह एक ही कमांड में आपकी अब तक की सारी मेहनत को उलट भी देता है। वह अकाउंट खोलने के लिए एक कार्ड और आमतौर पर एक पहचान दस्तावेज़ चाहिए था। जिस पल पहला snapshot अपलोड होता है, उसी पल से वह प्रोवाइडर आपका नाम और भुगतान विवरण को आपके सर्वर के IP पते से जोड़ता हुआ एक टाइमस्टैम्प वाला रिकॉर्ड रखता है, जो हर घंटे रिफ़्रेश होता है, हमेशा के लिए। आपने अपनी पहचान हमसे सत्यापित नहीं करवाई; आपने वह उनसे करवाई, और फिर आपने ख़ुद दोनों के बीच एक लकीर खींच दी।
दूसरा आधा हिस्सा और बुरा है, और यही वह हिस्सा है जिसे लोग चूक जाते हैं। जो API key उन अपलोड्स को authorise करती है, वह प्रोडक्शन सर्वर पर पड़ी एक फ़ाइल है। जो कोई भी उस बॉक्स पर root हासिल कर ले — या जो कोई भी क़ानूनी तौर पर वह डिस्क हासिल कर ले — वह सिर्फ़ आपका डेटा नहीं पाता। उसे एक ऐसा credential मिल जाता है जो एक ही API कॉल में एक billing identity तक पहुँचा देता है। गुमनाम सर्वर अब आपके बैंक की तरफ़ इशारा करता एक साइनपोस्ट बन चुका है।
इनमें से कुछ भी object storage को ग़लत नहीं बनाता। यह बस इसे एक डिफ़ॉल्ट की बजाय एक फ़ैसला बना देता है। तीन रास्ते बाहर निकलने के, इस क्रम में कि वे आपकी शुरुआत की चीज़ को कितनी अच्छी तरह बचाए रखते हैं:
- एक दूसरा no-KYC VPS, आदर्श रूप से प्रोडक्शन से अलग jurisdiction में, उसी crypto बैलेंस से भुगतान किया हुआ। गंतव्य स्रोत के गुमनामी वाले गुणों को अपना लेता है, उनके ख़िलाफ़ जाने की बजाय। यही हम करते हैं, और यही इस बाक़ी गाइड की धारणा है।
- ऐसा storage प्रोवाइडर जो बिना पहचान के crypto लेता हो। ऐसे प्रोवाइडर मौजूद हैं; वे छोटे होते हैं; marketing पर भरोसा करने से पहले जाँच लें कि payment का रास्ता वाक़ई पहचान-मुक्त है या नहीं, और egress की क़ीमत भी पहले जाँच लें, न कि किसी restore के दौरान पता चले।
- एक ऐसी मशीन जो आपकी अपनी भौतिक संपत्ति हो, जो आपके अपने कनेक्शन के पीछे से WireGuard के ज़रिए pull करे। गुमनामी के लिए बेहतरीन, उपलब्धता के लिए कमज़ोर, और इसका मतलब है कि आपकी restore स्पीड आपकी घर की अपलोड स्पीड जितनी ही होगी। तीसरी कॉपी के तौर पर ठीक-ठाक, अकेली कॉपी के तौर पर कमज़ोर।
आप जो भी चुनें, जो अकाउंट backups रखता है उसे प्रोडक्शन वाले अकाउंट के साथ credentials, ईमेल पता या recovery रास्ता साझा नहीं करना चाहिए। पूरी बात यही है कि एक compromised login दोनों तक न पहुँच सके। यह ठीक वही अनुशासन है जो कहीं और पहचानों को अलग-अलग रखने में बरता जाता है, बस यहाँ इसे सिस्टम के सबसे कम चमकदार कोने पर लागू किया गया है।
Push, pull, और वह वजह जिससे ransomware आपके backups तक पहुँच जाता है
लगभग हर backup ट्यूटोरियल एक ही architecture देता है: प्रोडक्शन सर्वर पर एक cron जॉब जो किसी दूर के repository से authenticate होकर उसमें लिखता है। यह सरल है, काम करता है, और इसमें एक ऐसा गुण है जिसका कोई ज़िक्र नहीं करता — प्रोडक्शन सर्वर के पास एक ऐसा credential होता है जो पूरी repository मिटा सकता है। पुराने snapshots की pruning के लिए delete अधिकार चाहिए होते हैं, इसलिए जो key आपका nightly जॉब चलाती है, वही key तिजोरी को भी ख़ाली कर सकती है।
ज़रा सोचिए कि compromise के दौरान इसका क्या मतलब होता है। बॉक्स पर root रखने वाले हमलावर को आपके backups ढूँढने की ज़रूरत ही नहीं; आपने बड़ी मेहरबानी से उसके लिए एक काम करता हुआ credential और repository का नाम बताने वाली एक config फ़ाइल पहले से छोड़ रखी है। कुछ भी दिखने लायक करने से पहले backups को गिनना और मिटा देना कोई काल्पनिक बारीकी नहीं है — यह मानक तरीक़ा है, क्योंकि यही किसी incident को एक सौदेबाज़ी में बदल देता है। आपकी nightly जॉब असल में एक रेकी (reconnaissance) थी।
तीन डिज़ाइन हैं, और इनके बीच का फ़र्क़ पूरी तरह इस बात पर टिका है कि कौन-सी मशीन कौन-सी key रखती है।
सादा push वही है जो ऊपर बताया गया। प्रोडक्शन के पास read-write-delete होता है। सुविधाजनक, और यह ठीक उसी परिस्थिति में पूरी तरह फेल हो जाता है जहाँ आपको backup की सबसे ज़्यादा ज़रूरत होती है। इसे सिर्फ़ तभी इस्तेमाल करें जब आपकी असली चिंता सिर्फ़ आपकी अपनी उँगलियाँ हों।
Append-only push वही ढाँचा रखता है लेकिन ख़तरनाक क्रिया हटा देता है। repository को कोई ऐसी चीज़ serve करती है जो प्रोटोकॉल समझती है और deletions को मना कर देती है: restic के लिए rest-server --append-only, या authorized_keys से force किया गया borg serve --append-only। प्रोडक्शन नए snapshots बना सकता है और पुराने नहीं हटा सकता। Pruning बाद में, कहीं और से, एक अलग key इस्तेमाल करके होती है। बीस मिनट के काम के बदले यह एक बड़ा सुधार है, और ज़्यादातर लोगों के लिए यहीं रुक जाना सही है।
Pull कनेक्शन को उलट देता है। backup host, SSH के ज़रिए प्रोडक्शन के भीतर पहुँचता है, जो चाहिए वह कॉपी करता है, और backup टूल को अपनी ही डिस्क पर locally चलाता है। प्रोडक्शन के पास कोई backup credential होता ही नहीं — उस मशीन पर ढूँढने के लिए कुछ है ही नहीं, क्योंकि उस मशीन को यह पता ही नहीं कि उसके backups कहाँ रहते हैं। यह सबसे मज़बूत इंतज़ाम है, और नीचे दिया step-by-step तरीक़ा यही बनाता है।
पर ईमानदारी से मानिए कि pull की भी क़ीमत है, क्योंकि यह मुफ़्त नहीं है। आपने key को ख़त्म नहीं किया, बस उसकी जगह बदली है: अब backup host के पास प्रोडक्शन में जाने वाली एक SSH key है, इसलिए backup host का compromise होना आगे live सिस्टम तक पहुँच सकता है। यह फिर भी एक बेहतर सौदा है — backup host कुछ नहीं चलाता, SSH के अलावा कुछ भी उजागर नहीं करता, और एक पब्लिक web सर्वर से कहीं छोटा निशाना है — लेकिन है तो यह एक सौदा ही, और बचे हुए ज़्यादातर अंतर को आप उस key को एक read-only command तक सीमित करके पाट सकते हैं, ताकि उसका इस्तेमाल फ़ाइलें पढ़ने के अलावा कुछ और न हो सके।
टूल चुनना: restic, Borg, या सादा rsync
तीन टूल लगभग हर मामला कवर कर लेते हैं, और यह चुनाव उतना दर्दनाक नहीं जितना forum की बहसें जताती हैं।
restic डिफ़ॉल्ट रूप से encrypt करता है, snapshots के बीच deduplicate करता है, SFTP, S3, REST और दर्जन भर दूसरे backends की भाषा बोलता है, और एक अकेले static बाइनरी के तौर पर आता है जिसे आप कहीं भी रख सकते हैं। इसका repository फ़ॉर्मेट content-addressed है, इसलिए एक snapshot सस्ता पड़ता है और एक जैसा डेटा सिर्फ़ एक बार स्टोर होता है, चाहे कितनी भी मशीनें उसे भेजें। इसकी क़ीमतें असली हैं पर मामूली: इसे repository index के अनुपात में मेमोरी चाहिए होती है, और कोई बीच में रुका हुआ run एक बासी lock छोड़ सकता है जिसे अगला run तब तक पार नहीं करेगा जब तक आप उसे restic unlock से साफ़ न करें। यही डिफ़ॉल्ट सिफ़ारिश है, और नीचे दिए स्टेप्स इसी का इस्तेमाल करते हैं।
Borg बेहतर deduplicate करता है, बेहतर compress करता है, और लाखों छोटी फ़ाइलों वाली repositories पर साफ़ तौर पर तेज़ है। इसकी क़ीमत जुड़ाव के रूप में चुकानी पड़ती है: Borg को दोनों सिरों पर इंस्टॉल होना चाहिए और वर्शन क़रीब-क़रीब मेल खाने चाहिए, एक repository असल में एक ही client के लिए बनाई गई होती है, और बिना किसी helper layer के इसका कोई native object-store backend नहीं है। अगर आपका स्रोत कोई बड़ा mail spool है या छोटी फ़ाइलों से भरा कोई filesystem, और आप दोनों मशीनों को नियंत्रित करते हैं, तो Borg आधी जगह इस्तेमाल करेगा। इसका --append-only मोड भी इस विचार का दोनों टूल में सबसे साफ़-सुथरा कार्यान्वयन है।
rsync कोई backup टूल नहीं है, और इसे मान लेना ही वह तरीक़ा है जिससे लोगों के पास किसी ख़राब डायरेक्टरी की एक ईमानदारी से मिरर की हुई कॉपी बचती है। इसमें कोई versioning नहीं, कोई deduplication नहीं, और आराम की हालत में कोई encryption नहीं; rsync --delete आपकी ग़लती को कॉपी तक wire की रफ़्तार से पहुँचा देता है। फिर भी यह दो ऐसी मशीनों के बीच bytes ले जाने के लिए सही टूल है जिन्हें आप नियंत्रित करते हैं, और pull डिज़ाइन में यह ठीक यही काम करता है, जबकि bytes पहुँचने के बाद versioning और encryption restic देता है। हर टूल को वही काम दें जो उसका है।
एक चीज़ जो मत कीजिए: tar और तारीख़-वाले filename के सहारे अपना ख़ुद का सिस्टम मत बनाइए। यह क़रीब चार महीने चलता है, जब तक कि वह दिन न आ जाए जब डिस्क भर जाए क्योंकि कभी कुछ expire ही नहीं हुआ, या वह दिन जब आपको पता चले कि 40 GB के डेटासेट की हर रात एक पूरी कॉपी लेने का मतलब है महीने के 1.2 TB storage का ख़र्च, सिर्फ़ तीस लगभग एक जैसी चीज़ों को रखने के लिए।
क्या शामिल करें — और वे डेटाबेस जो आपको धोखा देंगे
स्वाभाविक प्रवृत्ति पूरे filesystem का backup लेने की होती है। इससे बचिए। एक root filesystem ज़्यादातर distribution पैकेज ही होते हैं जिन्हें आप नब्बे सेकंड में दोबारा इंस्टॉल कर सकते हैं, और इन्हें शामिल करने पर storage, transfer का समय, और उससे भी बुरा — ध्यान ख़र्च होता है। एक 40 GB का backup जिसे कोई टेस्ट नहीं करना चाहता, उस 900 MB वाले backup से कम काम का है जो हर तिमाही restore होता है।
जो चीज़ें वाक़ई दोबारा नहीं बनाई जा सकतीं, वह सूची छोटी है: /etc (आपका पूरा configuration, और वह वजह जिससे rebuild एक वीकेंड की बजाय एक घंटे में हो जाता है), /home और /root, /srv और /var/www, /var/lib/ और /opt/ के तहत application state, नाम वाले Docker volumes, आपके लिखे cron और systemd units, और आपके database dumps। छोड़ दें /proc, /sys, /dev, /run, /tmp, /var/cache, swap फ़ाइलें, sockets, और /var/lib/docker/overlay2 — यह आख़िरी वाला आपकी compose फ़ाइल से दोबारा बन सकता है और अक्सर डिस्क पर अकेली सबसे बड़ी डायरेक्टरी होता है।
अब वह हिस्सा जो restores को चुपचाप बर्बाद कर देता है। डेटाबेस के चलते हुए उसकी data डायरेक्टरी कॉपी करने से जो फ़ाइल सेट बनता है, वह बहुत मुमकिन है कि बेकार निकले। इंजन अपनी स्थिति मेमोरी में रखता है, कई फ़ाइलों में एक ऐसे क्रम में लिखता है जो मायने रखता है, और आपकी कॉपी उस ट्री पर कई मिनटों तक चलती है, हर बार अलग-अलग पल पर अलग-अलग फ़ाइलें पकड़ते हुए। InnoDB कभी-कभी इससे crash-recover कर लेता है और कभी-कभी नहीं; और यह गड़बड़ महीनों बाद, किसी ऐसे restore के दौरान सामने आती है जब आपका दिन पहले से ही ख़राब चल रहा होता है।
इसकी बजाय इंजन के ज़रिए dump लें, फिर उस dump का backup लें:
# MariaDB / MySQL — InnoDB gets a consistent snapshot from one transaction
mariadb-dump --single-transaction --quick --routines --triggers --events \
--all-databases | zstd -T0 > /var/backups/db/all-$(date -u +%F).sql.zst
# PostgreSQL — pg_dump is consistent by design; grab roles separately
pg_dumpall --globals-only > /var/backups/db/globals.sql
pg_dump -Fc -Z6 mydb > /var/backups/db/mydb.dump
# SQLite — never cp a live database; WAL mode makes that a torn file
sqlite3 /var/lib/app/app.db ".backup /var/backups/db/app.db"दो टिप्पणियाँ याद रखने लायक हैं। --single-transaction सिर्फ़ InnoDB के लिए consistency देता है — अगर कोई टेबल अब भी MyISAM है तो वह transaction के बाहर कॉपी होती है और बाक़ी से असंगत हो सकती है, इसलिए उन टेबलों को बदल दें या lock कर दें। और जब आप dump ले ही रहे हैं, तो live data डायरेक्टरी को file pass से बाहर रखें। दोनों का backup लेने का मतलब है एक बड़ी फटी हुई कॉपी को अच्छी वाली के साथ स्टोर करना, और भविष्य के किसी restore को दो उम्मीदवार थमा देना जिनमें से एक चुपचाप ग़लत है।
Containers इस सिद्धांत को नहीं बदलते, बस रास्ता बदलते हैं: dump को docker compose exec -T db mariadb-dump … से चलाएँ और जो फ़ाइल बने उसी का backup लें, नीचे वाले volume का नहीं।
Encryption की key कहाँ रहती है
Client-side encryption ही वह पूरी वजह है जिससे आपके डेटा को उस मशीन से अलग किसी और मशीन पर रखना स्वीकार्य बन जाता है जहाँ से वह आया था। restic और Borg दोनों कुछ भी स्रोत छोड़ने से पहले ही encrypt कर देते हैं, इसलिए backup host के पास सिर्फ़ ciphertext रहता है और उसे untrusted storage माना जा सकता है। यह गुण ठीक उतना ही मूल्यवान है जितनी अच्छी तरह आप key संभालते हैं, उससे ज़्यादा नहीं।
फेल होने का यह तरीक़ा निराशाजनक हद तक आम है। repository का पासवर्ड प्रोडक्शन सर्वर पर /etc/restic/env में रहता है, जो automation के लिए ठीक भी है और ज़रूरी भी। फिर ठीक प्रोडक्शन ही वह चीज़ बन जाती है जिसे आप खो देते हैं — तबाह, ज़ब्त, या बस अकाउंट के साथ ग़ायब — और अब आपके सामने कई सौ गीगाबाइट encrypted ब्लॉक्स हैं, और यह धीरे-धीरे उतरता एहसास कि key की इकलौती कॉपी उसी चीज़ के भीतर थी जिससे खोने से बचाने के लिए आपने यह सब किया था।
तो: सर्वर पर मौजूद पासवर्ड एक working copy है, कभी असली रिकॉर्ड नहीं। असली रिकॉर्ड कहीं ऐसी जगह रहता है जो सर्वर से आगे बचा रहे — कोई password manager जिसका vault ख़ुद कहीं और backed up हो, या दराज़ में काग़ज़ पर लिखा हुआ, या दोनों। repository का पता और उसके ठीक बग़ल में सटीक restore command लिख लें, क्योंकि बिना किसी संदर्भ वाला पासफ़्रेज़ एक ऐसी पहेली है जिसे आप अठारह महीने बाद तनाव में सुलझा रहे होंगे। और इसे verify करने के लिए पाँच मिनट निकालें: किसी दूसरी मशीन से, सिर्फ़ वही इस्तेमाल करके जो password manager में है, repository पर restic snapshots चलाएँ। अगर यह काम कर जाए, तो आपके पास एक backup है। अगर इसके लिए कुछ ऐसा चाहिए जो सिर्फ़ प्रोडक्शन पर मौजूद है, तो आपके पास बस एक बहुत महँगा फ़ोल्डर है।
दोनों टूल एक ही repository पर कई keys रखने का समर्थन करते हैं (restic key add), जो pruning जॉब या किसी दूसरे admin को असली पासफ़्रेज़ साझा किए बिना पहुँच देने का साफ़-सुथरा तरीक़ा है। और अगर प्रोडक्शन डिस्क LUKS से encrypted है, तो दोनों secrets को वाक़ई अलग-अलग रखें — restic पासफ़्रेज़ को LUKS volume के भीतर, और LUKS पासफ़्रेज़ को restic repository के भीतर रखना एक ऐसा लूप है जो दोनों तरफ़ से बंद होकर फेल होता है।
Retention: सिर्फ़ एक हफ़्ता रखने का जाल
Retention देखने में storage-लागत का सवाल लगता है, पर असल में यह detection-latency का सवाल है। जो नंबर मायने रखता है वह यह नहीं कि आप कितनी डिस्क ख़र्च करना चाहते हैं; यह है कि आपके सिस्टम में कोई समस्या कितनी देर तक बिना पकड़ में आए रह सकती है। वह अवधि जो भी हो, आपका सबसे पुराना backup उससे भी पुराना होना चाहिए।
सात रोज़ाना snapshots उदार लगते हैं पर व्यवहार में पतले साबित होते हैं। कोई ख़राब टेबल जिस पर कोई query नहीं चलाता, किसी बदतमीज़ cron जॉब की धीमी deletion, कोई घुसपैठ जो कुछ भी दिखने लायक करने से पहले एक महीने तक चुपचाप बैठी रही — ये सब आमतौर पर सामने आने में एक हफ़्ते से ज़्यादा वक़्त लेते हैं, और अगर आपकी history सिर्फ़ सात दिन गहरी है तो आपके पास मौजूद हर snapshot पहले से ही दूषित है। असली घुसपैठों में ठहराव का समय अक्सर हफ़्तों में नापा जाता है। सस्ते मासिक snapshots ठीक इसी के ख़िलाफ़ बचाव हैं, और deduplication इन्हें वाक़ई बहुत सस्ता बना देता है: एक साल तक रखा गया मासिक snapshot एक पूरी कॉपी का बस एक छोटा-सा हिस्सा जोड़ता है, क्योंकि सिर्फ़ वही ब्लॉक्स दोबारा स्टोर होते हैं जो असल में बदले।
restic forget \
--keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 2 \
--pruneयह सीढ़ी — दिनों का एक हफ़्ता, हफ़्तों का एक महीना, महीनों का एक साल, सालों के कुछ साल — लगभग छब्बीस snapshots बनती है, और सामान्य डेटा पर, एक अकेली पूरी कॉपी के आकार से भी कहीं कम, दोगुने से भी कम में। जब तक आपके पास इससे हटने की कोई ख़ास वजह न हो, हम इसी को डिफ़ॉल्ट मानने की सलाह देंगे।
दो परिचालन टिप्पणियाँ। बिना --prune के forget सिर्फ़ लेबल हटाता है, इसलिए जगह तब तक वापस नहीं मिलती जब तक आप prune न करें — जो उन लोगों को चौंका देता है जो देख रहे होते हैं कि डिस्क सिकुड़ ही नहीं रही। और --prune को repository पर delete अधिकार चाहिए होते हैं, इसलिए append-only या pull डिज़ाइन में यह प्रोडक्शन सर्वर पर नहीं चलता। यह backup host पर, या आपके laptop से चलता है, ऐसी key के साथ जिसे प्रोडक्शन ने कभी देखा ही नहीं। यही अलगाव पूरी बात है; आख़िरी कदम पर सुविधा के लिए इसे मत मिटाइए।
इसे ऑटोमेट करना, बिना किसी ख़ामोश नाकामी के
क्लासिक backup आपदा कोई ऐसा जॉब नहीं है जो crash हो जाए। यह वह जॉब है जो चलना बंद कर दे और किसी को बताए ही नहीं, और ग्यारह महीने बाद उस किसी को पता चले जिसे उसकी ज़रूरत थी। नीचे दी गई हर चीज़ इसी ख़ास नतीजे को नामुमकिन बनाने के लिए है।
cron की बजाय एक systemd टाइमर इस्तेमाल करें। आपको journal में असली logs मिलते हैं, exit status के साथ, Persistent=true जिससे मशीन के बंद रहने के दौरान छूटा हुआ run हमेशा के लिए टलने की बजाय अगले boot पर हो जाता है, और RandomizedDelaySec जिससे कोई पूरा fleet ठीक 03:00 बजे backup host पर एक साथ टूट नहीं पड़ता। Cron का नाकामी नोटिफ़िकेशन किसी local mailbox को भेजी एक ईमेल है, जो किसी आधुनिक सर्वर पर बिल्कुल कहीं नहीं पहुँचती।
# /etc/systemd/system/backup.timer
[Unit]
Description=Nightly encrypted backup
[Timer]
OnCalendar=*-*-* 03:17:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.targetफिर एक dead man's switch जोड़ें, जो इस पूरी गाइड की सबसे ज़्यादा मूल्यवान इकलौती लाइन है। स्क्रिप्ट के बिल्कुल आख़िर में — backup सफल होने के बाद, पहले नहीं — किसी ऐसे मॉनिटर को एक HTTPS रिक्वेस्ट भेजें जो आपसे रोज़ाना सुनने की उम्मीद रखता हो और न सुनने पर अलर्ट करे। यह नोटिफ़िकेशन के तर्क को उलट देता है: किसी नाकामी के संदेश भेजने पर निर्भर रहने की बजाय, ग़ैर-मौजूदगी ख़ुद ही अलार्म बन जाती है। तीन दिन से मरा पड़ा जॉब तब किसी संकट में अचानक हुई खोज नहीं, बल्कि आपके inbox में एक संदेश भर बनकर रह जाता है। अगर आप कोई और third-party अकाउंट नहीं बनाना चाहते, तो मॉनिटर को backup host पर ही self-host कर लें; यह बस कुछ लाइनें हैं और अपना एक टाइमर।
आख़िर में, वे छोटे परिचालन ख़तरे जिनसे हम ख़ुद कम से कम एक बार टकरा चुके हैं। कोई बीच में रुका हुआ run एक lock छोड़ जाता है और हर अगला run उस संदेश के साथ फेल होता है जिसे आप चौथी रात के बाद पढ़ना बंद कर देते हैं — restic unlock को जान-बूझकर संभालें, बिना सोचे-समझे नहीं। एक भरी हुई गंतव्य डिस्क तब तक हर जॉब फेल करती रहती है जब तक कोई देखे न; job status पर नहीं, ख़ाली जगह पर अलर्ट लगाएँ। किसी SSH key का expire होना, कोई घुमाई गई host key, किसी असंबंधित काम के दौरान जोड़ा गया कोई nftables rule — इनमें से हर एक चुपचाप pull को काट देगा। और सिर्फ़ start नहीं, systemctl enable --now: जो टाइमर कभी enable ही नहीं हुआ, वह पहले reboot तक ख़ूबसूरती से चलता है और फिर कभी नहीं चलता।
Restore ड्रिल
ऊपर बताई गई हर चीज़ सिर्फ़ तैयारी है। यही वह हिस्सा है जो इसे एक backup में बदलता है, और यही वह हिस्सा है जिसे लगभग हर कोई छोड़ देता है।
हर तिमाही में एक बार, एक नया VPS deploy करें — $5 वाला Starter काफ़ी है और बिलिंग घंटे के हिसाब से, सेकंड तक की सटीक गणना के साथ होती है, इसलिए पूरी कवायद के बस कुछ ही सेंट ख़र्च होते हैं। उसमें सिर्फ़ वही इस्तेमाल करके restore करें जो किसी असली आपदा में आपके पास होता: repository का पता, password manager से लिया गया पासफ़्रेज़, और लिखी हुई प्रक्रिया। जान-बूझकर प्रोडक्शन से कुछ भी इस्तेमाल न करें, क्योंकि जिस परिदृश्य का आप अभ्यास कर रहे हैं उसमें प्रोडक्शन मौजूद ही नहीं है। Application को चालू करें, किसी hosts-file एंट्री को नए IP पर इंगित करें, इधर-उधर क्लिक करके देखें। फिर उसे मिटा दें।
# on a throwaway machine, with nothing but the passphrase
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/prod
restic snapshots # can you even see the history?
restic restore latest --target /restore
restic check --read-data-subset=10% # verify stored blocks, not just metadataयह जो पकड़ता है वह कभी वह नहीं होता जिसकी आप उम्मीद करते हैं। यह वह config फ़ाइल होती है जो किसी ऐसी डायरेक्टरी में थी जिसे include लिस्ट ने कवर ही नहीं किया। वह database dump जो पाँच हफ़्तों से ज़ीरो bytes का पड़ा है क्योंकि एक पासवर्ड बदल गया और स्क्रिप्ट ने अपना exit status जाँचा ही नहीं। वह application जो शुरू ही नहीं होगा क्योंकि एक secret orchestrator के पास मौजूद किसी environment variable में रहता है और कभी filesystem में था ही नहीं। वह DNS रिकॉर्ड जो कहीं दर्ज ही नहीं। वह certificate जिसे 443 पर कुछ भी जवाब देने से पहले दोबारा जारी करना पड़ता है। इनमें से हर एक किसी शांत दोपहर में दस मिनट का फ़िक्स है, और रात तीन बजे के दो भद्दे घंटे।
यह लिख लें कि ड्रिल को शुरू से आख़िर तक कितना समय लगा। यही नंबर — न कि backup की frequency — आपका असली recovery time है, और जब कोई पूछे कि आप कितनी देर के लिए down रहेंगे, तो यही इकलौता ईमानदार जवाब है। एक मासिक टाइमर में restic check --read-data-subset=5% भी जोड़ दें: यह सिर्फ़ index नहीं, बल्कि असल में स्टोर किए गए blocks के एक घूमते हुए नमूने को पढ़ता और verify करता है, और यही वह तरीक़ा है जिससे आप ख़ामोश corruption को तब पकड़ लेते हैं जब वापस गिरने के लिए अभी भी एक अच्छी कॉपी मौजूद हो। अगर आप कभी पूरे सर्वर को किसी नए host पर माइग्रेट करें, तो एक अभ्यास किया हुआ restore माइग्रेशन का ज़्यादातर हिस्सा पहले ही पूरा कर चुका होता है।
- जो वाक़ई दोबारा नहीं बन सकता, उसकी सूची बनाएँ
किसी भी tooling से पहले, सूची लिख लें। मशीन पर घूमें और हर डायरेक्टरी से पूछें: अगर यह ग़ायब हो जाए, तो क्या मैं इसे किसी package manager, किसी git repository या किसी compose फ़ाइल से दोबारा बना सकता हूँ? अगर हाँ, तो इसकी जगह backup में नहीं है। जो बचता है वह आमतौर पर लोगों की उम्मीद से कहीं छोटा होता है — configuration, user डेटा, application state, database dumps।
# the fast way to find what is actually big and stateful du -x -h -d2 / 2>/dev/null | sort -rh | head -30 docker volume ls # named volumes are state; overlay2 is notनतीजे को दो साफ़-साफ़ फ़ाइलों में बदल दें,
/etc/restic/include.txtऔर/etc/restic/exclude.txt। साफ़-साफ़ लिस्टें चालाकfindexpressions से बेहतर होती हैं, क्योंकि इन्हें दोबारा जाँचा जा सकता है, और क्योंकि सर्वर पर किसी नई डायरेक्टरी का आना एक जान-बूझकर लिया गया फ़ैसला होना चाहिए, न कि एक ख़ामोश समावेशन। - Backup टारगेट को एक अलग jurisdiction में deploy करें
एक दूसरा VPS किसी ऐसे क्षेत्र में ऑर्डर करें जो वह क्षेत्र न हो जहाँ प्रोडक्शन चलता है — अगर प्रोडक्शन पेरिस में है, तो कॉपी को रेक्याविक या बुख़ारेस्ट में रखें। बात बस इतनी है कि कोई एक अकेली क़ानूनी या भौतिक घटना दोनों मशीनों तक न पहुँच सके। $5/माह वाला Starter 80 GB NVMe देता है, जो deduplication के बाद किसी सामान्य छोटे सर्वर की बहुत लंबी history समा लेता है; 12 महीने वाला billing साइकिल इसे आधा कर देता है। इसे उसी crypto बैलेंस से चुकाएँ ताकि गंतव्य स्रोत की गुमनामी को अपना ले, उसके ख़िलाफ़ जाने की बजाय।
अगर आप पूरा credential अलगाव चाहते हैं, तो इसे प्रोडक्शन से अलग अकाउंट दें। फिर इसे बिल्कुल वैसे ही हार्डन करें जैसे आप किसी और चीज़ को करते — keys-only SSH, default-deny firewall — और इस पर कुछ और इंस्टॉल न करें। इस मशीन की क़ीमत यही है कि यह उबाऊ है: कोई web सर्वर नहीं, SSH के अलावा कोई खुला port नहीं, इंटरनेट से exploit करने के लिए कुछ भी नहीं।
- Backup host से प्रोडक्शन में एक read-only दरवाज़ा बनाएँ
यही वह कदम है जो इसे एक pull बनाता है। backup host पर, एक dedicated key जनरेट करें। फिर उसका public हिस्सा production पर एक forced command के साथ इंस्टॉल करें, ताकि key ठीक एक ही काम कर सके: फ़ाइलें पढ़ना। यह न कोई shell खोल सकती है, न कोई port forward कर सकती है, न कुछ लिख सकती है।
# on the backup host ssh-keygen -t ed25519 -a 100 -f ~/.ssh/pull_prod -C "pull@backup" # on production, in /root/.ssh/authorized_keys — one line command="/usr/bin/rrsync -ro /",restrict ssh-ed25519 AAAAC3Nz… pull@backuprrsync, rsync के साथ आता है (Debian 13 पर/usr/bin/rrsync; पुराने releases पर/usr/share/doc/rsync/scripts/rrsync) और-roइसे पढ़ने के अलावा कुछ भी करने से मना करवा देता है।restrictएक ही शब्द में port forwarding, agent forwarding, PTY allocation और X11 — सब बंद कर देता है। भरोसा करने से पहले जाँच लें कि यह पिंजरा टिकता है या नहीं —ssh -i ~/.ssh/pull_prod root@productionको shell देने में नाकाम होना ही चाहिए। - प्रोडक्शन पर डेटाबेस को उनके अपने schedule पर dump करें
प्रोडक्शन के पास अब भी एक जॉब है: एक staging डायरेक्टरी में consistent dumps बनाना, जिन्हें pull इकट्ठा करेगा। इसके लिए किसी backup credential की ज़रूरत नहीं, और यही ठीक वह वजह है जिससे यह डिज़ाइन काम करता है।
# /usr/local/sbin/dump-db.sh (chmod 700) set -euo pipefail D=/var/backups/db; install -d -m 700 "$D" mariadb-dump --single-transaction --quick --routines --triggers --events \ --all-databases | zstd -T0 > "$D/all.sql.zst.tmp" mv "$D/all.sql.zst.tmp" "$D/all.sql.zst"write-to-temp-then-rename वाली तरकीब पर ग़ौर करें: इसका मतलब है कि pull कभी भी आधा-लिखा dump नहीं उठा सकता, चाहे timing कुछ भी हो।
set -euo pipefailकोई सजावट नहीं है — इसके बिना एक फेल होताmariadb-dumpएक ख़ाली स्ट्रीम कोzstdमें डाल देता है, जो कामयाब हो जाता है, और आपको एक वैध compressed फ़ाइल मिलती है जिसमें कुछ भी नहीं होता। यही वह सबसे आम तरीक़ा है जिससे कोई backup चुपचाप बेकार हो जाता है। इसे pull से आधा घंटा पहले अपने ही टाइमर से चलाएँ। - डेटा को खींचकर backup host पर लाएँ
backup host पर, प्रोडक्शन की include लिस्ट को rsync करके एक staging ट्री में लाएँ। सिर्फ़ बदले हुए blocks ही wire पर से गुज़रते हैं, इसलिए पहले run के बाद यह तेज़ और सस्ता होता है।
# /usr/local/sbin/pull.sh (chmod 700, runs on the BACKUP host) set -euo pipefail [email protected] # -r is spelled out on purpose: with --files-from, -a does NOT imply # recursion, and without it you silently copy empty directories. rsync -aHAX -r --delete --numeric-ids \ -e "ssh -i /root/.ssh/pull_prod -o BatchMode=yes" \ --files-from=/etc/backup/include.txt \ --exclude-from=/etc/backup/exclude.txt \ "$SRC:/" /srv/staging/prod/-aHAXhardlinks, ACLs और extended attributes को बचाए रखता है, और--numeric-idsउन मशीनों के बीच भी ownership को सार्थक रखता है जिनकी/etc/passwdअलग-अलग हैं।--deleteयहाँ इसलिए सुरक्षित है क्योंकि staging कोई backup नहीं है — versioned history अगले step में बनी restic repository में रहती है, इसलिए जो deletion staging में फैलती है वह अब भी कल के snapshot से recover की जा सकती है। - Repository को initialise करें और key को offline स्टोर करें
अब भी backup host पर, एक local restic repository बनाएँ और staging ट्री का backup उसमें लें। Local होने का मतलब है hot path में कोई नेटवर्क नहीं, चुराने के लिए कोई remote credential नहीं, और एक ऐसा restore जो डिस्क की रफ़्तार से चलता है।
apt install -y restic install -d -m 700 /etc/backup openssl rand -base64 32 > /etc/backup/pass # write this into your password manager NOW chmod 600 /etc/backup/pass export RESTIC_REPOSITORY=/srv/restic/prod export RESTIC_PASSWORD_FILE=/etc/backup/pass restic initउस पासफ़्रेज़ को किसी password manager में कॉपी करें, और उसके बग़ल में repository का पता और restore command लिख दें। फिर इसे साबित करें: किसी तीसरी मशीन से, सिर्फ़ password manager का इस्तेमाल करके,
restic -r sftp:backup@…:/srv/restic/prod snapshotsचलाएँ। अगर यह snapshots की सूची दिखाए, तो key वाक़ई recoverable है। अगर इसके लिए कुछ ऐसा चाहिए जो सिर्फ़ किसी एक सर्वर पर मौजूद है, तो इसे बाद में खोजने की बजाय अभी ठीक कर लें। - इसे schedule करें, और ख़ामोशी को अलार्म बनाएँ
pull, restic run और prune को एक ही स्क्रिप्ट में लपेट दें और उसे एक systemd टाइमर से चलाएँ। ग़ौर करें कि यहाँ
forget --pruneचलाना सुरक्षित है क्योंकि repository पर backup host का हक़ जायज़ है — प्रोडक्शन के पास कभी किसी भी पल delete credential रहा ही नहीं।# tail of /usr/local/sbin/backup.sh restic backup /srv/staging/prod --tag nightly restic forget --keep-daily 7 --keep-weekly 5 --keep-monthly 12 \ --keep-yearly 2 --prune curl -fsS -m 10 --retry 3 https://hc.example.net/ping/<uuid> # only on successsystemctl daemon-reload systemctl enable --now backup.timer systemctl list-timers backup.timer # confirm the next run is where you expectcurlतभी चलता है जब उससे पहले की हर कमांड कामयाब रही हो, और यहset -eकी वजह से है। दूसरे छोर पर मौजूद मॉनिटर हर रोज़ एक ping की उम्मीद रखता है और उसकी ग़ैर-मौजूदगी पर अलर्ट करता है, जिससे चुपचाप रुक गया कोई जॉब किसी पुरातात्विक खोज की बजाय बस एक ईमेल बनकर रह जाता है।enable --now, न कि सिर्फ़start— जो टाइमर कभी enable ही नहीं हुआ, वह ठीक पहले reboot तक ही टिकता है। - Restore ड्रिल चलाएँ, और लिख लें कि इसमें कितना समय लगा
जो भी चीज़ आप वाक़ई पढ़ते हों, उसमें हर तिमाही एक बार का एक दोहराया जाने वाला रिमाइंडर डाल दें। एक इस्तेमाल-और-फेंक Starter deploy करें, सिर्फ़ पासफ़्रेज़ और लिखी हुई प्रक्रिया के सहारे उसमें restore करें, application चालू करें, जाँच लें कि वह असली डेटा serve कर रहा है, फिर मशीन मिटा दें। घंटे के हिसाब वाली बिलिंग का मतलब है कि पूरी ड्रिल के बस कुछ ही सेंट ख़र्च होते हैं।
restic restore latest --target /restore zstd -dc /restore/var/backups/db/all.sql.zst | mariadb systemctl start nginx app curl -H 'Host: example.com' http://127.0.0.1/healthबीता हुआ समय और हर वह हैरानी जो आपको मिली, उसे रिकॉर्ड करें, फिर उन हैरानियों को अपनी याद्दाश्त में नहीं, backup स्क्रिप्ट में ठीक करें। वही बीता हुआ समय आपका असली recovery objective है; जब तक आपने इसे एक बार नाप न लिया हो, आप जो भी नंबर बताते हैं वह बस एक अंदाज़ा है।
कॉपी कहाँ रखें
| गंतव्य | गुमनामी की क़ीमत | ख़र्च | Restore स्पीड | किससे बचता है |
|---|---|---|---|---|
| दूसरा no-KYC VPS, अलग क्षेत्र | कुछ नहीं — उसी crypto बैलेंस से भुगतान, कहीं भी कोई पहचान नहीं | $5/माह, 12-महीने के साइकिल पर आधा | तेज़ — 1–10 Gbps पर डेटासेंटर-से-डेटासेंटर | अकाउंट खोना, compromise, एक jurisdiction, आपकी अपनी ग़लतियाँ |
| प्रोवाइडर का Snapshot | कुछ नहीं | सस्ता | सेकंडों में | लगभग कुछ नहीं — वही अकाउंट, वही failure domain, दोनों के साथ ख़त्म |
| Object store (B2 / S3 / Wasabi) | ज़्यादा — अकाउंट पर कार्ड और ID, और आपके सर्वर पर पड़ी API key उसी की तरफ़ इशारा करती है | स्टोर करना बहुत सस्ता, पर restore के दौरान egress फ़ीस काटती है | तेज़, अगर आप egress का बिल मंज़ूर करें | Compromise और अकाउंट खोना, मशीन से जुड़े एक नाम की क़ीमत पर |
| Crypto स्वीकार करने वाला storage प्रोवाइडर | कम, अगर payment का रास्ता वाक़ई identity-free हो — verify करें, मान मत लें | मध्यम | बहुत अलग-अलग — ज़रूरत पड़ने से पहले egress की सीमाएँ जाँच लें | ज़्यादातर चीज़ों से, पर उस VPS से ज़्यादा counterparty जोखिम के साथ जिसे आप ख़ुद नियंत्रित करते हैं |
| WireGuard से pull किया गया घर वाला NAS | कुछ नहीं — आपके अपने नेटवर्क से कुछ भी unencrypted या unattributed होकर बाहर नहीं जाता | वह हार्डवेयर जो पहले से आपका है | धीमा — आपकी घर की अपलोड स्पीड तक सीमित | आपके घर को छोड़कर बाक़ी सब कुछ; इकलौती कॉपी के तौर पर कमज़ोर, तीसरी कॉपी के तौर पर बेहतरीन |
| कुछ नहीं / “यह तो git में है” | कुछ नहीं | मुफ़्त | कभी नहीं | कुछ भी नहीं। Git आपका कोड रखता है; यह आपका डेटाबेस, आपके uploads या आपका /etc नहीं रखता |
जवाब देने योग्य प्रश्न
क्या प्रोवाइडर का snapshot पहले से ही एक backup नहीं है?
नहीं, और यह फ़र्क़ कोई बाल की खाल निकालना नहीं है। एक snapshot उसी अकाउंट में, उन्हीं credentials के तहत, उसी failure domain में रहता है जिसमें वह सर्वर रहता है जिसे यह कॉपी करता है — इसलिए यह अकाउंट खोने पर नहीं बचता, और जो कोई भी आपके panel तक पहुँच सकता है वह इसे असली के साथ-साथ मिटा भी सकता है। यह किसी चलती हुई मशीन से भी लिया जाता है, यानी एक व्यस्त डेटाबेस को mid-write पकड़ा जाता है। जोखिम भरे बदलावों से पहले snapshots को undo बटन की तरह इस्तेमाल करें; backup के तौर पर एक off-site encrypted repository इस्तेमाल करें।
restic या Borg — मुझे कौन-सा इस्तेमाल करना चाहिए?
restic, जब तक कि आपके पास न करने की कोई ख़ास वजह न हो। यह डिफ़ॉल्ट रूप से encrypt करता है, गंतव्य पर कुछ भी इंस्टॉल करने की ज़रूरत नहीं पड़ती, इस्तेमाल के लायक हर backend की भाषा बोलता है, और एक अकेले static बाइनरी के तौर पर आता है। Borg बेहतर deduplicate और compress करता है और लाखों छोटी फ़ाइलों वाले filesystems पर सचमुच तेज़ है, लेकिन इसे दोनों सिरों पर इंस्टॉल और वर्शन-मैच करना पड़ता है और यह असल में हर repository के लिए एक ही client के हिसाब से बना है। बड़ा mail spool और दोनों मशीनें आपके नियंत्रण में: Borg। बाक़ी सब कुछ: restic।
backup टारगेट को कितनी डिस्क चाहिए?
इस गाइड वाली retention सीढ़ी के साथ एक deduplicated repository के लिए — 7 रोज़ाना, 5 साप्ताहिक, 12 मासिक, 2 सालाना — उतने ही डेटा के आकार का लगभग दो से तीन गुना बजट रखें जिसका आप असल में backup ले रहे हैं, पूरे सर्वर का नहीं। छब्बीस snapshots का मतलब छब्बीस कॉपियाँ नहीं होता, क्योंकि सिर्फ़ बदले हुए blocks ही दोबारा स्टोर होते हैं। 15 GB असली state वाली एक छोटी साइट 80 GB वाले Starter में आराम से समा जाती है, और सालों की history के लिए भी जगह बचती है।
क्या दूसरा VPS मेरा hosting बिल दोगुना नहीं कर देता?
सिर्फ़ तभी जब backup टारगेट प्रोडक्शन जैसा ही हो, और उसे वैसा होना ही नहीं चाहिए। यह कोई application नहीं चलाता और कोई traffic serve नहीं करता; इसे डिस्क चाहिए, CPU नहीं। $30 वाले प्रोडक्शन सर्वर के पीछे एक $5 वाला Starter बिल का बस छठा हिस्सा है, और 12-महीने का साइकिल उसमें से 50% और घटा देता है। सब कुछ खोने की क़ीमत के सामने रखें तो यह invoice की सबसे सस्ती लाइन है — और यह टारगेट restore ड्रिल के लिए अभ्यास वाली मशीन का काम भी करता है।
Repository का पासवर्ड कहाँ रहना चाहिए?
किसी ऐसे password manager में जिसका vault ख़ुद कहीं और backed up हो, या काग़ज़ पर, या दोनों जगह — और उसके बग़ल में, repository का पता और सटीक restore command। सर्वर पर /etc में पड़ी कॉपी automation के लिए एक working copy भर है, कभी असली रिकॉर्ड नहीं। इसे ठीक से verify करें: किसी ऐसी मशीन से जो न प्रोडक्शन है न backup host, सिर्फ़ password manager में मौजूद चीज़ का इस्तेमाल करके, restic snapshots चलाएँ। अगर इसके अलावा कुछ और चाहिए, तो अभी आपके पास recoverable backup है ही नहीं।
backups कितनी बार चलने चाहिए?
ख़ुद से पूछें कि आप कितना काम दोबारा करने को तैयार हैं। ज़्यादातर सर्वरों के लिए nightly सही है: ज़्यादा से ज़्यादा एक दिन का नुक़सान होता है, और रात भर का एक अकेला run समझने में आसान होता है। किसी व्यस्त डेटाबेस को इससे ज़्यादा चाहिए होता है — सिर्फ़ डेटाबेस के hourly dumps, जबकि पूरा file pass nightly ही रहे, यह आम ढाँचा है। इस बिंदु से आगे बढ़ी हुई frequency उतना फ़ायदा नहीं देती जितना वही मेहनत लंबी retention और एक असली restore ड्रिल पर लगाने से मिलती है, जहाँ असली जोखिम टिका होता है।
क्या मैं उस सर्वर का backup ले सकता हूँ जिसकी डिस्क LUKS से encrypted है?
हाँ, और दोनों एक-दूसरे के पूरक हैं, फ़ालतू नहीं। LUKS डिस्क की रक्षा तब करता है जब मशीन बंद हो; backup आपको deletion, corruption और मशीन पूरी तरह खो देने से बचाता है। mounted filesystem का backup बिल्कुल वैसे ही लें जैसे किसी unencrypted वाले का लेते — restic बाहर जाते वक़्त इसे दोबारा encrypt कर देता है, इसलिए repository untrusted storage पर भी सुरक्षित रहती है। दोनों secrets को वाक़ई अलग-अलग जगहों पर रखें: कोई LUKS पासफ़्रेज़ जो सिर्फ़ restic repository में स्टोर हो, या कोई restic पासफ़्रेज़ जो सिर्फ़ LUKS volume के भीतर स्टोर हो — यह एक ऐसा लूप है जो दोनों तरफ़ से बंद होकर फेल होता है।
अगर मेरा सर्वर compromise हो जाए, तो क्या backups सुरक्षित रहते हैं?
यह पूरी तरह उस एक फ़ैसले पर टिका है जो आपने महीनों पहले लिया था। अगर प्रोडक्शन सर्वर के पास repository पर delete अधिकार वाला कोई credential है, तो नहीं — एक हमलावर सबसे पहले backups गिनकर उन्हें मिटा देगा, क्योंकि यही किसी incident को एक सौदेबाज़ी में बदल देता है। अगर repository append-only है, या backup host pull करता है और प्रोडक्शन के पास कोई backup credential है ही नहीं, तो history बची रहती है और आप घुसपैठ से पहले वाले किसी snapshot पर restore कर सकते हैं। pull डिज़ाइन के पक्ष में यही पूरी दलील है, और यही वजह है कि इसे ज़रूरत पड़ने से पहले ही अपना लेना बेहतर है।
Keep exploring
बिना downtime के VPS माइग्रेट करें
एक अभ्यास किया हुआ restore माइग्रेशन का ज़्यादातर हिस्सा पहले ही पूरा कर चुका होता है — यह उसका बचा हुआ हिस्सा है, साथ में वह DNS टाइमिंग जो असल में आपका downtime तय करती है।
LUKS से VPS डिस्क एन्क्रिप्ट करें
इस पेज की पूरक: backups आपको डेटा खोने से बचाते हैं, LUKS उसे उस डिस्क पर सुरक्षित रखता है जिसे अब आप भौतिक रूप से नहीं थामे हुए।
पहले घंटे में नया VPS हार्डन करें
backup टारगेट पर भरोसा करने से पहले इसे यह दें — keys-only SSH और एक default-deny firewall, लगभग एक घंटे में।
Deploy your offshore server.
एक क्षेत्र चुनें। एक प्लान चुनें। एक कुंजी पेस्ट करें। भुगतान करें। अगले 47 सेकंड हमारे ज़िम्मे हैं।