
Gerçekten geri yükleyebileceğiniz bir VPS'i yedekle
Sunucu çalıştıran hemen herkesin yedek dediği bir şey vardır. Bunlardan birini gerçekten geri yüklemiş olanlar çok daha azdır ve verinin gerçekte kaybolduğu yer, bu iki cümle arasındaki mesafedir. Bu sayfa, sunucuları gerçekten yok eden üç şeyden — kendi ellerinizden, bir ele geçirilmeden ve kontrolünü kaybettiğiniz bir hesaptan — sağ çıkan bir kopyayı, anonim bir makineye sessizce doğrulanmış bir kimlik cıvatalamadan nasıl kuracağınızı anlatıyor.
Bu ağı çalıştıran her byte'ın üç kopyasını tutuyoruz ve bunlardan, bir acil durumda ihtiyaç duyduğumuzdan çok daha fazla kez, bilerek ve sıradan bir salı günü geri yükleme yaptık. Bu, kendi iyiliği için gösterilen bir titizlik değil. Depodaki şeyin, güven veren bir adı olan şifreli gürültü klasöründen ibaret olmadığını, gerçek bir yedek olduğunu bilmenin tek yolu bu.
Aşağıdaki tavsiye bilerek modaya aykırı. Bir gösterge paneli, aylık bir abonelik veya bir destek kuyruğu olan bir yedekleme ürünü içermiyor, çünkü bunların her biri bir hesaptır ve bir hesap; bir isim, bir kart ve bir yargı bölgesidir — bu sunucudan gerçek bir çabayla uzak tutmuş olabileceğiniz üç şey. Bunun yerine ikinci bir makine, kabaca kırk satır shell ve neredeyse kimsenin sürdürmediği tek bir alışkanlık gerekiyor.
Bunu bir akşamda bitirebilmeniz gerekir. Araçlar Debian 13 ve Ubuntu 24.04 aromalı; her şey, bariz karşılıklarıyla RHEL türevlerine de aktarılır. Sunucunuz yeniyse, ilk saat sertleştirmesini bu sayfadan sonra değil önce yapın — zaten başkasına ait olan bir makineyi yedeklemek, onun işini korumanın bir yoludur.
Kiralık bir sunucuda veriyi gerçekte ne yok eder
Birine neden yedek aldığını sorun, cevap genellikle “disk ölürse diye” olur. Modern bir VPS'te bu, başınıza gelebilecek en düşük ihtimalli şeye yakındır. Diskiniz, siz fark etmeden sizi arızalanan bir sunucudan taşıyacak bir hipervizörle birlikte yedekli bir dizide NVMe üzerinde durur; disk arızası sağlayıcının sorunudur ve çözülmüş bir sorundur. Tüm yedekleme stratejinizi bunun üzerine kurmak, sel baskınına uğrayan bir ev için yangın söndürücü almaya benzer.
İnsanların verisini gerçekte alıp götüren şey, kabaca sıklık sırasına göre, şudur. Birincisi ve açık ara: siz. Boşa genişleyen bir değişkenle çalıştırılmış bir rm -rf. İki sekme birbirinin aynı göründüğü için yanlış terminalde çalıştırılmış bir DROP DATABASE. İki kez çalıştırılmış bir migration betiği. -v'nin kas hafızasından geldiği bir docker compose down -v. Bunlar egzotik değil; bunlar bir salı günü.
İkincisi, kendi verisini silen uygulamalar. Yıkıcı bir migration çalıştırıp yarı yolda başarısız olan bir yükseltme. Önbellek olmadığı ortaya çıkan bir önbellek dizinini temizleyen bir eklenti. Yanlış yola karşı yapılandırılmış bir log rotasyonu. Üçüncüsü, ele geçirilme — ve burada dikkat edin, bu artık bir saldırganın yedeklerin yok olmasını istediği bir durumdur, ki bu da tasarımı aşağıda tekrar döneceğimiz şekillerde değiştirir. Dördüncüsü, ve bir no-KYC sunucusunda unutulması kolay olanı: hesabı kaybetmek. Siz yokken sıfırlanan bir bakiye, hiç yazıya dökmediğiniz bir parola yöneticisi girdisi, terk ettiğiniz bir e-posta adresi. Biz bakiye sıfırlandıktan saatler sonra askıya alıyor, yedi gün sonra da yok ediyoruz ve bu bilerek affetmeyen bir tutum — kim olduğunuzu sormamamızı sağlayan aritmetik bu. Kimliğinize bakıp bir istisna yapabilecek bir destek temsilcisi yok, çünkü bakılacak bir kimlik yok.
Bu son kategori, gizliliği önceleyen barındırmayı ana akım türden ayıran kategoridir ve planınızı şekillendirmelidir. Bu sunucuyu size atfetmeyi zorlaştıran her kontrol, aynı zamanda herkesin — bizim de dahil olduğumuz — onu size geri vermesini zorlaştırır. Yedek, bu değiş tokuşu bir riskten bir tercihe çeviren şeydir.
Bir snapshot neden bir yedek değildir
Snapshot'lar harikadır ve onları kullanmalısınız. Her çekirdek yükseltmesinden önce, her veritabanı migration'ından önce, geri alabilmeyi tercih edeceğiniz bir şey yapmak üzereyken bir tane alın. Saniyeler içinde geri yüklenirler, neredeyse hiçbir şeye mal olmazlar ve yılda düzinelerce kez bir öğleden sonranızı kurtarırlar.
Yine de hiçbir sağlayıcı pazarlamasının değiştiremeyeceği üç yapısal nedenden ötürü yedek değildirler. Aynı hesabın içinde yaşarlar: panelinize giriş yapabilen herkes onları silebilir ve hesap çalışmayı durdurursa snapshot'lar da onunla birlikte var olmayı bırakır. Aynı arıza alanında yaşarlar: aynı sağlayıcı, aynı kontrol düzlemi, çoğu zaman aynı depolama kümesi — yani tek bir kötü olay, hem orijinali hem de kopyayı makul biçimde götürebilir. Ve opaktırlar: çalışan bir makinenin snapshot'ı, bir veritabanını yazma sırasında, diğer her şeyi yakaladığı kadar sadakatle yakalar; yani meşgul bir MySQL sunucusunun snapshot'tan geri yüklenmesi size temiz bir veritabanı değil, bir çökme kurtarma senaryosu verir.
Eski 3-2-1 kuralı — üç kopya, iki tür ortamda, biri site dışında — genellikle ortadaki koşulun kiralık altyapıda anlamsız olduğu fark edilmeden tekrarlanır. İki tür ortamınız yoktur. Bir sanal blok cihazınız ve bir başka sanal blok cihazınız vardır, ikisi de birinin SAN'ıdır. VPS'e çevrildiğinde hayatta kalan kısım, zaten en başından beri önemli olan kısımdır: en az bir kopya, tek bir kötü olayın ulaşamayacağı bir yerde olmalıdır. Farklı bir sağlayıcı ya da en azından farklı bir bölge, farklı kimlik bilgileri, farklı bir hesap ve — offshore barındırmanızın nedeni teknik değil hukukiyse — farklı bir yargı bölgesi, böylece tek bir mahkeme kararı iki kopyaya birden inmez.
Hedef, tehdit modelinizin bir parçasıdır
Bu, diğer yedekleme rehberlerinde bulunmayan bölümdür ve bu sunucu için Monero ile ödeme yaptıysanız en çok önem taşıyan bölümdür.
İnternetteki her yerin varsayılan tavsiyesi, yedeklerinizi bir nesne deposuna push etmenizdir: Backblaze B2, Amazon S3, Wasabi, rclone üzerinden bir Google Drive. Ucuzdur, dayanıklıdır, işe yarar. Aynı zamanda, tek bir komutla, yaptığınız işin büyük bölümünü boşa çıkarır. O hesabı açmak bir kart ve genellikle bir kimlik belgesi gerektirmiştir. İlk snapshot yüklendiği andan itibaren, o sağlayıcı adınızı ve ödeme bilgilerinizi sunucunuzun IP adresiyle ilişkilendiren, her saat yenilenen, sonsuza kadar duran zaman damgalı bir kayıt tutar. Kimliğinizi bizimle doğrulamadınız; onlarla doğruladınız ve ardından ikisi arasına bir çizgi çektiniz.
İkinci yarısı daha kötüdür ve insanların kaçırdığı kısım budur. Bu yüklemeleri yetkilendiren API anahtarı, üretim sunucusunda duran bir dosyadır. O kutuda root ele geçiren biri — ya da diski hukuka uygun biçimde ele geçiren biri — yalnızca verinizi almaz. Tek bir API çağrısında bir fatura kimliğine çözülen bir kimlik bilgisi de alır. Anonim sunucu, bankanızı gösteren bir tabelaya dönüşmüştür.
Bunların hiçbiri nesne depolamayı yanlış yapmaz. Onu bir varsayılan yerine bir karar haline getirir. Başladığınız şeyi ne kadar iyi koruduklarına göre azalan sırada üç çıkış yolu:
- İkinci bir no-KYC VPS, tercihen üretimden farklı bir yargı bölgesinde, aynı kripto bakiyesinden ödenmiş. Hedef, kaynağın anonimlik özellikleriyle çelişmek yerine onları devralır. Bizim yaptığımız budur ve bu rehberin geri kalanı da bunu varsayar.
- Kimlik istemeden kripto kabul eden bir depolama sağlayıcısı. Bunlar var; daha küçükler; pazarlamaya güvenmeden önce ödeme yolunun gerçekten kimliksiz olup olmadığını kontrol edin ve bunu bir geri yükleme sırasında öğrenmeden önce egress fiyatlandırmasını kontrol edin.
- Fiziksel olarak sahip olduğunuz bir makine, kendi bağlantınızın arkasından WireGuard üzerinden pull yaparak. Anonimlik için mükemmel, erişilebilirlik için zayıf ve geri yükleme hızınızın ev yükleme hızınız olacağı anlamına gelir. Üçüncü kopya olarak makul, tek kopya olarak zayıf.
Ne seçerseniz seçin, yedekleri tutan hesap, üretimi tutan hesapla kimlik bilgilerini, e-posta adresini veya kurtarma yolunu paylaşmamalıdır. Bütün mesele, tek bir ele geçirilmiş girişin ikisine birden ulaşmamasıdır. Bu, kimlikleri başka yerlerde de ayrı tutma disiplininin, sistemin en gösterişsiz köşesine uygulanmış halidir.
Push, pull ve fidye yazılımının yedeklerinizi bulma nedeni
Neredeyse her yedekleme rehberi aynı mimariyi üretir: üretim sunucusunda, uzak bir depoda kimlik doğrulayıp ona yazan bir cron görevi. Basittir, işe yarar ve kimsenin bahsetmediği bir özelliği vardır — üretim sunucusu, deponun tamamını silebilecek bir kimlik bilgisi tutar. Eski snapshot'ları budamak silme hakkı gerektirir, yani gece görevinizi çalıştıran anahtar aynı zamanda kasayı boşaltan anahtardır.
Bunun bir ele geçirilme sırasında ne anlama geldiğini düşünün. Kutuda root'a sahip bir saldırganın yedeklerinizi bulmasına gerek yoktur; ona yardımseverce çalışan bir kimlik bilgisi ve depoyu adlandıran bir yapılandırma dosyası bırakmışsınızdır. Görünür herhangi bir şeyi tetiklemeden önce yedekleri numaralandırıp yok etmek varsayımsal bir incelik değildir — standart uygulamadır, çünkü bir olayı bir pazarlığa çeviren şey budur. Gece göreviniz keşif çalışmasıydı.
Üç tasarım vardır ve aralarındaki fark tamamen hangi makinenin hangi anahtarı tuttuğuyla ilgilidir.
Düz push, yukarıdakidir. Üretim, okuma-yazma-silme hakkına sahiptir. Kullanışlıdır ve tam olarak bir yedeğe en çok ihtiyaç duyduğunuz senaryoya karşı tamamen başarısız olur. Bunu yalnızca gerçekten önemsediğiniz tek tehdit kendi parmaklarınızsa kullanın.
Append-only push aynı şekli korur ama tehlikeli fiili kaldırır. Depo, protokolü anlayan ve silmeleri reddeden bir şey tarafından sunulur: restic için rest-server --append-only, ya da authorized_keys'ten zorlanan borg serve --append-only. Üretim yeni snapshot'lar oluşturabilir ama eskilerini kaldıramaz. Budama daha sonra, başka bir yerden, farklı bir anahtar kullanılarak yapılır. Bu, yaklaşık yirmi dakikalık bir çalışma karşılığında büyük bir iyileşmedir ve çoğu insan için doğru durak noktasıdır.
Pull bağlantıyı tersine çevirir. Yedekleme sunucusu, SSH üzerinden üretime uzanır, ihtiyacı olanı kopyalar ve yedekleme aracını kendi diskinde yerel olarak çalıştırır. Üretim hiçbir yedekleme kimlik bilgisi tutmaz — o makinede bulunacak hiçbir şey yoktur, çünkü makine yedeklerinin nerede yaşadığını bilmez. Bu en güçlü düzenlemedir ve aşağıdaki adım adım bölüm tam olarak bunu kurar.
Pull'un neye mal olduğu konusunda dürüst olun, çünkü bedava değildir. Anahtarı ortadan kaldırmadınız, sadece taşıdınız: yedekleme sunucusu artık üretime giden bir SSH anahtarı tutuyor, yani yedekleme sunucusunun ele geçirilmesi ileriye, canlı sisteme kadar uzanır. Bu daha iyi bir değiş tokuştur — yedekleme sunucusu hiçbir şey çalıştırmaz, SSH dışında hiçbir şeyi açığa çıkarmaz ve herkese açık bir web sunucusundan çok daha küçük bir hedeftir — ama yine de bir değiş tokuştur ve o anahtarı yalnızca okuma yapan bir komuta zorlayarak kalan boşluğun çoğunu kapatırsınız, böylece dosyaları okumak dışında hiçbir şey için kullanılamaz.
Aracı seçmek: restic, Borg ya da düz rsync
Üç araç neredeyse her durumu kapsar ve seçim, forum başlıklarının ima ettiğinden çok daha az can sıkıcıdır.
restic varsayılan olarak şifreler, snapshot'lar arasında deduplication yapar, SFTP, S3, REST ve düzinelerce başka backend ile konuşur ve herhangi bir şeyin üzerine bırakabileceğiniz tek bir statik ikili dosya olarak gelir. Depo biçimi içerik-adresli olduğundan bir snapshot ucuzdur ve kaç makine gönderirse göndersin aynı veri yalnızca bir kez saklanır. Maliyetler gerçektir ama küçüktür: depo indeksiyle orantılı bellek ister ve yarıda kesilen bir çalıştırma, restic unlock ile temizlemediğiniz sürece bir sonraki çalıştırmanın üzerinden geçmeyi reddettiği bayat bir kilit bırakabilir. Bu varsayılan öneridir ve aşağıdaki adımlar bunu kullanır.
Borg daha iyi deduplication yapar, daha iyi sıkıştırır ve milyonlarca küçük dosya içeren depolarda belirgin biçimde daha hızlıdır. Değiş tokuşu bağımlılıktır: Borg'un her iki uçta da kurulu olması ve sürümlerin yakından eşleşmesi gerekir, bir depo gerçekten tek bir istemci için tasarlanmıştır ve bir yardımcı katman olmadan yerel bir nesne deposu backend'i yoktur. Kaynağınız büyük bir posta havuzuysa ya da küçük dosyalarla dolu bir dosya sistemiyse ve her iki makineyi de kontrol ediyorsanız, Borg yarı yarıya daha az yer kullanır. --append-only modu da fikrin iki araçtan en temiz uygulamasıdır.
rsync bir yedekleme aracı değildir ve aksini varsaymak, insanların bozuk bir dizinin sadakatle aynalanmış tek bir kopyasıyla kalmasının nedenidir. Sürümlemesi, deduplication'ı ve bekleyen veri şifrelemesi yoktur; rsync --delete hatanızı tel hızında kopyaya yayar. Yine de kontrol ettiğiniz iki makine arasında byte taşımak için doğru araçtır — ki bu, bir pull tasarımında yaptığı iştir tam olarak, byte'lar indikten sonra sürümlemeyi ve şifrelemeyi restic sağlar. Her birini olduğu şey için kullanın.
Yapılmaması gereken bir şey: tar ve tarih damgalı bir dosya adıyla kendi çözümünüzü uydurmayın. Kabaca dört ay işe yarar, ta ki hiçbir şey süresi dolmadığı için diskin dolduğu güne, ya da 40 GB'lık bir veri kümesinin her gece tam bir kopyasının, neredeyse birbirinin aynı otuz şeyi tutmak için ödediğiniz ayda 1,2 TB depolama olduğunu keşfettiğiniz güne kadar.
Nelerin dahil edileceği — ve sizi ele verecek veritabanları
İçgüdü, tüm dosya sistemini yedeklemektir. Buna direnin. Bir kök dosya sistemi çoğunlukla doksan saniyede yeniden kurabileceğiniz dağıtım paketlerinden oluşur ve bunları dahil etmek depolama alanına, aktarım süresine ve daha kötüsü dikkate mal olur — kimsenin test etmek istemediği 40 GB'lık bir yedek, üç ayda bir geri yüklenen 900 MB'lık bir yedekten daha az işe yarar.
Gerçekten yeniden inşa edilemeyen şey kısadır: /etc (tüm yapılandırmanız ve bir yeniden kurulumun bir hafta sonu yerine bir saat sürmesinin nedeni), /home ve /root, /srv ve /var/www, /var/lib/ ve /opt/ altındaki uygulama durumu, adlandırılmış Docker volume'ları, kendi yazdığınız cron ve systemd unit'leri ve veritabanı dökümleriniz. /proc, /sys, /dev, /run, /tmp, /var/cache, takas dosyalarını, socket'leri ve /var/lib/docker/overlay2'yi atlayın — sonuncusu compose dosyanızdan yeniden inşa edilebilir ve genellikle disk üzerindeki tek en büyük dizindir.
Şimdi geri yüklemeleri sessizce mahveden kısım. Veritabanı çalışırken veri dizinini kopyalamak, kullanılamaz olma ihtimali çok yüksek bir dosya kümesi üretir. Motor, durumu bellekte tutar, önemli bir sırayla birden çok dosyaya yazar ve kopyanız o ağacı dakikalarca gezerek farklı dosyaları farklı anlarda yakalar. InnoDB bazen bundan çökme kurtarması yapabilir, bazen yapamaz; hata, zaten kötü geçen bir gününüzde yaptığınız bir geri yükleme sırasında aylar sonra ortaya çıkar.
Motor üzerinden döküm alın, sonra dökümü yedekleyin:
# 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"Sahip olunmaya değer iki dipnot. --single-transaction size yalnızca InnoDB için tutarlılık verir — herhangi bir tablo hâlâ MyISAM ise işlemin dışında kopyalanır ve geri kalanla tutarsız olabilir, bu yüzden o tabloları dönüştürün ya da kilitleyin. Ve döküm almaya başladığınızda, canlı veri dizinini dosya geçişinden hariç tutun. İkisini birden yedeklemek, iyi olanın yanına büyük, yırtık bir kopya daha depolamak ve gelecekteki bir geri yüklemeye, biri sessizce yanlış olan iki aday vermek anlamına gelir.
Konteynerler ilkeyi değiştirmez, yalnızca yolu değiştirir: dökümü docker compose exec -T db mariadb-dump … ile alın ve altındaki volume'u değil, ortaya çıkan dosyayı yedekleyin.
Şifreleme anahtarı nerede yaşar
İstemci taraflı şifreleme, verinizi geldiği makine olmayan bir makinede saklamanın kabul edilebilir olmasının tüm nedenidir. restic de Borg da hiçbir şey kaynaktan ayrılmadan önce şifreler, bu yüzden yedekleme sunucusu şifreli metin tutar ve güvenilmeyen bir depolama olarak ele alınabilir. Bu özellik, tam olarak anahtarı ele alışınız kadar değerlidir, ne fazla ne az.
Başarısızlık biçimi iç karartıcı derecede yaygındır. Depo parolası, üretim sunucusunda /etc/restic/env içinde durur, ki bu otomasyon için gerekli ve sorunsuzdur. Sonra kaybettiğiniz şey üretimin ta kendisi olur — yok edilmiş, el konulmuş ya da hesapla birlikte basitçe gitmiş — ve karşınızda birkaç yüz gigabaytlık şifreli blok ve anahtarın tek kopyasının, kaybetmeye karşı kendinizi korumaya çalıştığınız şeyin içinde olduğu gerçeğinin ağır ağır çöken farkındalığı vardır.
Yani: sunucudaki parola bir çalışma kopyasıdır, asla asıl kayıt değildir. Asıl kayıt, sunucudan sağ çıkan bir yerde yaşar — kasası kendisi de başka bir yerde yedeklenen bir parola yöneticisi, ya da bir çekmecede kağıda yazılmış, ya da her ikisi. Depo konumunu ve tam geri yükleme komutunu yanına yazın, çünkü bağlamı olmayan bir parola öbeği, on sekiz ay sonra stres altında çözeceğiniz bir bulmacadır. Ve onu doğrulamak için beş dakika ayırın: farklı bir makineden, yalnızca parola yöneticisinde olanla, depoya karşı restic snapshots çalıştırın. İşe yararsa, bir yedeğiniz vardır. Yalnızca üretimde var olan bir şeye ihtiyaç duyuyorsa, çok pahalı bir klasörünüz vardır.
Her iki araç da bir depoda birden fazla anahtarı destekler (restic key add), ki bu, orijinal parola öbeğini paylaşmadan budama görevine veya ikinci bir yöneticiye erişim vermenin temiz yoludur. Ve üretim diski LUKS ile şifrelenmişse, iki sırrı gerçekten ayrı tutun — restic parola öbeğini LUKS volume'ünün içinde ve LUKS parola öbeğini restic deposunun içinde saklamak, her iki tarafta da kapalı kalarak başarısız olan bir döngüdür.
Saklama süresi: yalnızca bir hafta tutma tuzağı
Saklama süresi bir depolama maliyeti sorusu gibi görünür ama gerçekte bir tespit gecikmesi sorusudur. Önemli olan sayı, ne kadar disk harcamak istediğiniz değildir; sisteminizde bir sorunun ne kadar süre fark edilmeden kalabileceğidir. Bu süre her ne ise, en eski yedeğiniz ondan daha eski olmalıdır.
Yedi günlük snapshot cömert hissettirir ama pratikte incedir. Kimsenin sorgulamadığı bozuk bir tablo, yanlış davranan bir cron görevinin yavaş silmesi, görünür bir şey yapmadan önce bir ay sessizce oturan bir sızma — bunların hepsi rutin olarak bir haftadan uzun sürede ortaya çıkar ve geçmişiniz yedi gün derinliğindeyse elinizdeki her snapshot zaten kirlenmiştir. Gerçek sızmalarda bekleme süresi düzenli olarak haftalarla ölçülür. Ucuz aylık snapshot'lar buna karşı özel savunmadır ve deduplication onları gerçekten çok ucuz kılar: bir yıl tutulan aylık bir snapshot, tam bir kopyanın yalnızca bir kısmını ekler, çünkü yalnızca gerçekten değişen bloklar iki kez saklanır.
restic forget \
--keep-daily 7 --keep-weekly 5 --keep-monthly 12 --keep-yearly 2 \
--pruneBu merdiven — bir haftalık günler, bir aylık haftalar, bir yıllık aylar, birkaç yıllık yıllar — yaklaşık yirmi altı snapshot'tır ve tipik veride tek bir tam kopyanın iki katının epey altındadır. Bundan sapmak için özel bir nedeniniz olmadıkça savunacağımız varsayılan budur.
İki operasyonel not. --prune olmadan forget yalnızca etiketleri kaldırır, yani siz budayana kadar alan geri kazanılmaz — bu da küçülmeyen bir diski izleyen insanları şaşırtır. Ve --prune, depo üzerinde silme hakkı gerektirir, bu yüzden bir append-only ya da pull tasarımında üretim sunucusunda çalışmaz. Yedekleme sunucusunda, ya da üretimin hiç görmediği bir anahtarla dizüstü bilgisayarınızdan çalışır. Bu ayrım bütün meselenin ta kendisidir; son adımda kolaylık olsun diye bunu bozmayın.
Sessiz başarısızlık olmadan otomatikleştirmek
Klasik yedekleme felaketi, çöken bir görev değildir. Çalışmayı durduran ve kimseye söylemeyen, on bir ay sonra ona ihtiyacı olan biri tarafından keşfedilen bir görevdir. Aşağıdaki her unsur, tam olarak bu sonucu imkansız kılmak için var.
Cron yerine bir systemd timer kullanın. Journal'da çıkış durumları eklenmiş gerçek günlükler elde edersiniz, makine kapalıyken kaçırılan bir çalıştırmanın sonsuza kadar atlanmak yerine bir sonraki açılışta gerçekleşmesi için Persistent=true, ve bir filonun yedekleme sunucusunu tam saat 03:00'te bir arada bastırmaması için RandomizedDelaySec alırsınız. Cron'un başarısızlık bildirimi, modern bir sunucuda tam olarak hiçbir yere gitmeyen yerel bir posta kutusuna gönderilen bir e-postadır.
# /etc/systemd/system/backup.timer
[Unit]
Description=Nightly encrypted backup
[Timer]
OnCalendar=*-*-* 03:17:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.targetSonra, bu rehberin tamamındaki en yüksek değerli tek satır olan bir dead-man's switch ekleyin. Betiğin en sonunda — yedekleme başarılı olduktan sonra, önce değil — sizden günlük olarak haber almayı bekleyen ve almadığında uyaran bir monitöre bir HTTPS isteği yapın. Bu, bildirim mantığını tersine çevirir: bir mesaj üretmek için başarısızlığa güvenmek yerine, yokluğun kendisi alarm haline gelir. Üç gündür ölü olan bir görev, o zaman bir kriz sırasında yapılan bir keşif yerine gelen kutunuzdaki bir mesaj olur. Başka bir üçüncü taraf hesabı oluşturmak istemiyorsanız monitörü yedekleme sunucusunda kendiniz barındırın; birkaç satır ve kendi timer'ından ibarettir.
Son olarak, hepsini en az bir kez yaşadığımız küçük operasyonel tehlikeler. Yarıda kesilen bir çalıştırma bir kilit bırakır ve sonraki her çalıştırma, dördüncü geceden sonra okumayı bıraktığınız bir mesajla başarısız olur — restic unlock'u refleksle değil bilerek ele alın. Dolu bir hedef disk, biri bakana kadar her görevi başarısız kılar; yalnızca görev durumunu değil, boş alanı da izleyin. Sona eren bir SSH anahtarı, döndürülmüş bir host anahtarı, ilgisiz bir çalışma sırasında eklenmiş bir nftables kuralı — her biri pull'u sessizce koparır. Ve yalnızca start değil, systemctl enable --now: hiç etkinleştirilmemiş bir timer, ilk yeniden başlatmaya kadar güzelce çalışır ve bir daha asla çalışmaz.
Geri yükleme tatbikatı
Yukarıdakilerin hepsi hazırlıktır. Bunu bir yedeğe dönüştüren kısım budur ve neredeyse herkesin atladığı kısım da budur.
Üç ayda bir, yepyeni bir VPS devreye alın — 5 dolarlık Starter fazlasıyla yeterlidir ve faturalandırma saatlik, saniyeye kadar orantılıdır, yani tüm bu alıştırma birkaç sent tutar. İçine, gerçek bir felakette elinizde olacak şeylerle — depo adresi, parola yöneticinizdeki parola öbeği ve yazılı prosedür — ve yalnızca bunlarla geri yükleme yapın. Üretimden hiçbir şeyi bilerek kullanmayın, çünkü prova ettiğiniz senaryoda üretim var olmuyor. Uygulamayı ayağa kaldırın, bir hosts dosyası girdisini yeni IP'ye yönlendirin, biraz gezinin. Sonra makineyi yok edin.
# 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 metadataBunun yakaladığı şey hiçbir zaman beklediğiniz şey değildir. Include listesinin kapsamadığı bir dizinde duran yapılandırma dosyasıdır. Bir parola değiştiği ve betik çıkış durumunu kontrol etmediği için beş haftadır sıfır byte olan veritabanı dökümüdür. Bir sır, orkestratörün tuttuğu bir ortam değişkeninde yaşadığı ve hiçbir zaman dosya sisteminde bulunmadığı için başlamayan uygulamadır. Belgelenmemiş DNS kaydıdır. 443'te herhangi bir şey yanıt vermeden önce yeniden verilmesi gereken sertifikadır. Bunların her biri, sakin bir öğleden sonrada on dakikalık bir düzeltme, sabahın üçünde ise çirkin iki saattir.
Tatbikatın baştan sona ne kadar sürdüğünü yazın. Bu sayı — yedekleme sıklığı değil — gerçek geri kazanım süreniz ve biri ne kadar süre kesintide kalacağınızı sorduğunda verebileceğiniz tek dürüst cevaptır. Aylık bir timer'a restic check --read-data-subset=5% de ekleyin: bu, yalnızca indeksi değil, gerçekten saklanan blokların dönen bir örneğini okuyup doğrular — sessiz bozulmayı, hâlâ geri dönebileceğiniz iyi bir kopya varken bulmanızı sağlayan yöntem budur. Eğer bir gün tüm sunucuyu yeni bir sunucuya taşırsanız, provası yapılmış bir geri yükleme, taşımanın da zaten büyük bölümünü bitirmiş olur.
- Gerçekten yeniden inşa edilemeyeni envanterleyin
Herhangi bir araçtan önce listeyi yazın. Makineyi gezin ve her dizin için sorun: bu yok olsaydı, onu bir paket yöneticisinden, bir git deposundan ya da bir compose dosyasından yeniden oluşturabilir miydim? Cevap evetse, yedeğe ait değildir. Geriye kalan genellikle insanların beklediğinden çok daha küçüktür — yapılandırma, kullanıcı verisi, uygulama durumu, veritabanı dökümleri.
# 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 notSonucu iki açık dosyaya dönüştürün:
/etc/restic/include.txtve/etc/restic/exclude.txt. Açık listeler zekicefindifadelerinden üstündür, çünkü gözden geçirilebilirler ve sunucuda ortaya çıkan yeni bir dizin, sessiz bir dahil etme yerine bilinçli bir karar olmalıdır. - Yedekleme hedefini farklı bir yargı bölgesinde devreye alın
Üretimin çalıştığı bölgeden farklı bir bölgede ikinci bir VPS sipariş edin — üretim Paris'teyse kopyayı Reykjavík'e ya da Bükreş'e koyun. Mesele, tek bir hukuki ya da fiziksel olayın her iki makineye birden ulaşmamasıdır. Aylık 5 dolarlık bir Starter, 80 GB NVMe taşır; bu da deduplication sonrası tipik küçük bir sunucunun çok uzun bir geçmişini tutar — 12 aylık faturalandırma döngüsü bunu yarıya indirir. Hedefin, kaynağın anonimliğiyle çelişmek yerine onu devralması için aynı kripto bakiyesinden ödeyin.
Tam kimlik bilgisi izolasyonu istiyorsanız üretimden ayrı bir hesap verin. Sonra onu tam olarak başka her şeyi sertleştirdiğiniz gibi sertleştirin — sadece anahtarla SSH, varsayılan reddet güvenlik duvarı — ve üzerine başka hiçbir şey kurmayın. Bu makinenin değeri sıkıcı olmasıdır: web sunucusu yok, SSH dışında açık port yok, internetten istismar edilecek hiçbir şey yok.
- Yedekleme sunucusundan üretime salt okunur bir kapı oluşturun
Bunu bir pull yapan adım budur. Yedekleme sunucusunda özel bir anahtar üretin. Sonra ortak yarısını üretime, anahtarın tam olarak tek bir şeyi yapabilmesi için zorlanmış bir komutla kurun: dosya okumak. Bir shell açamaz, bir portu yönlendiremez ya da hiçbir şey yazamaz.
# 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 ile birlikte gelir (Debian 13'te/usr/bin/rrsync; daha eski sürümlerde/usr/share/doc/rsync/scripts/rrsync) ve-ro, okuma dışında her şeyi reddetmesini sağlar.restrict, port yönlendirmeyi, agent yönlendirmeyi, PTY tahsisini ve X11'i tek kelimeyle devre dışı bırakır. Ona güvenmeden önce kafesin tuttuğunu doğrulayın —ssh -i ~/.ssh/pull_prod root@productionsize bir shell vermemek üzere başarısız olmalıdır. - Veritabanlarını üretimde, kendi programlarında dökün
Üretim hâlâ bir görevin sahibidir: pull'un toplayacağı bir staging dizinine tutarlı dökümler üretmek. Bu, hiçbir yedekleme kimlik bilgisi gerektirmez — tasarımın işe yaramasının tam nedeni de budur.
# /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"Önce geçiciye yaz sonra yeniden adlandır düzenine dikkat edin: bu, zamanlama ne olursa olsun pull'un asla yarım yazılmış bir dökümü toplayamayacağı anlamına gelir.
set -euo pipefailbir süsleme değildir — o olmadan başarısız olan birmariadb-dump,zstd'ye boş bir akış aktarır, bu da başarılı olur ve içinde hiçbir şey olmayan geçerli bir sıkıştırılmış dosya elde edersiniz. Bir yedeğin sessizce işe yaramaz hale gelmesinin en yaygın tek yolu budur. Bunu, pull'dan yarım saat önce kendi timer'ından çalıştırın. - Veriyi yedekleme sunucusuna pull ile indirin
Yedekleme sunucusunda, üretimin include listesini rsync ile bir staging ağacına aktarın. Yalnızca değişen bloklar tel üzerinden geçer, bu yüzden ilk çalıştırmadan sonra bu hızlı ve ucuzdur.
# /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/-aHAX, hardlink'leri, ACL'leri ve genişletilmiş öznitelikleri korur ve--numeric-ids,/etc/passwd'ı farklı olan makineler arasında sahipliği anlamlı tutar.--deleteburada tam olarak güvenlidir çünkü staging yedeğin kendisi değildir — sürümlenmiş geçmiş, bir sonraki adımda kurulan restic deposunda yaşar, bu yüzden staging'e yayılan bir silme işlemi hâlâ dünkü snapshot'tan kurtarılabilir. - Depoyu başlatın ve anahtarı çevrimdışı saklayın
Hâlâ yedekleme sunucusunda, yerel bir restic deposu oluşturun ve staging ağacını içine yedekleyin. Yerel olması, sıcak yolda ağ olmaması, çalınacak uzak bir kimlik bilgisi olmaması ve disk hızında çalışan bir geri yükleme anlamına gelir.
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 initO parola öbeğini bir parola yöneticisine kopyalayın ve yanına depo yolunu ve geri yükleme komutunu yazın. Sonra bunu kanıtlayın: üçüncü bir makineden, yalnızca parola yöneticisini kullanarak
restic -r sftp:backup@…:/srv/restic/prod snapshotsçalıştırın. Bu snapshot'ları listeliyorsa, anahtar gerçekten kurtarılabilirdir. Yalnızca sunuculardan birinde var olan bir şeye ihtiyaç duyuyorsa, bunu daha sonra keşfetmek yerine şimdi düzeltin. - Programlayın ve sessizliği bir alarma dönüştürün
Pull'u, restic çalıştırmasını ve budamayı tek bir betikte sarın ve onu bir systemd timer'ından çalıştırın.
forget --prune'un burada çalıştırılmasının güvenli olduğuna dikkat edin, çünkü depoya meşru olarak yedekleme sunucusu sahiptir — üretim hiçbir zaman bir silme kimlik bilgisi tutmamıştır.# 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, yalnızca kendinden önceki her komut başarılı olduysa çalışır, çünküset -evardır. Diğer uçtaki monitör günlük bir ping bekler ve yokluğunda uyarır — bu, sessizce duran bir görevi arkeolojik bir keşif yerine bir e-postaya dönüştürür.startdeğilenable --now— hiç etkinleştirilmemiş bir timer tam olarak ilk yeniden başlatmaya kadar hayatta kalır. - Geri yükleme tatbikatını çalıştırın ve ne kadar sürdüğünü yazın
Üç ayda bir, gerçekten okuduğunuz bir yere tekrarlayan bir hatırlatma koyun. Kullan-at bir Starter devreye alın, yalnızca parola öbeği ve yazılı prosedürle içine geri yükleyin, uygulamayı ayağa kaldırın, gerçek veri sunduğunu doğrulayın, makineyi yok edin. Saatlik faturalandırma, tüm tatbikatın birkaç sent tuttuğu anlamına gelir.
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/healthGeçen süreyi ve karşılaştığınız her sürprizi kaydedin, sonra sürprizleri hafızanızda değil yedekleme betiğinde düzeltin. O geçen süre gerçek geri kazanım hedefinizdir; onu bir kez ölçene kadar söyleyeceğiniz herhangi bir sayı bir tahmindir.
Kopyayı nereye koymalı
| Hedef | Anonimlik maliyeti | Para | Geri yükleme hızı | Hayatta kaldığı şeyler |
|---|---|---|---|---|
| İkinci no-KYC VPS, farklı bölge | Yok — aynı kripto bakiyesinden ödenmiş, hiçbir yerde kimlik yok | Aylık 5 dolar, 12 aylık döngüde yarıya iner | Hızlı — 1-10 Gbps üzerinden veri merkezinden veri merkezine | Hesap kaybı, ele geçirilme, tek bir yargı bölgesi, kendi hatalarınız |
| Sağlayıcı snapshot'ı | Yok | Ucuz | Saniyeler | Neredeyse hiçbir şey — aynı hesap, aynı arıza alanı, ikisiyle birlikte ölür |
| Nesne deposu (B2 / S3 / Wasabi) | Yüksek — hesapta kart ve kimlik var, sunucunuzdaki API anahtarı da ona işaret ediyor | Saklamak çok ucuz, geri yükleme sırasında egress ücretleri ısırıyor | Hızlı, egress faturasını kabul ederseniz | Ele geçirilme ve hesap kaybı, makineye iliştirilmiş bir isim pahasına |
| Kripto kabul eden depolama sağlayıcısı | Düşük, ödeme yolu gerçekten kimliksizse — varsaymayın, doğrulayın | Orta | Büyük ölçüde değişir — egress limitlerini ihtiyaç duymadan önce kontrol edin | Çoğu şeye, ama kontrol ettiğiniz bir VPS'e göre daha fazla karşı taraf riskiyle |
| WireGuard üzerinden pull yapılan ev NAS'ı | Yok — kendi ağınızdan hiçbir şey şifresiz ya da atıfsız çıkmaz | Zaten sahip olduğunuz donanım | Yavaş — ev yükleme hızınızla sınırlı | Eviniz dışında her şeye; tek kopya olarak zayıf, üçüncü kopya olarak mükemmel |
| Hiçbir şey / “git'te zaten var” | Yok | Bedava | Asla | Hiçbir şey. Git kodunuzu tutar; veritabanınızı, yüklemelerinizi ya da /etc'inizi tutmaz |
Yanıtlanmaya değer sorular
Bir sağlayıcı snapshot'ı zaten bir yedek değil mi?
Hayır ve bu ayrım kılı kırk yarmak değildir. Bir snapshot, kopyaladığı sunucuyla aynı hesapta, aynı kimlik bilgileri altında, aynı arıza alanında yaşar — bu yüzden hesabın kaybedilmesinden sağ çıkmaz ve panelinize ulaşan herkes onu orijinaliyle birlikte silebilir. Ayrıca çalışan bir makineden alınır, yani meşgul bir veritabanı yazma sırasında yakalanır. Snapshot'ları riskli değişikliklerden önce bir geri al düğmesi olarak kullanın; yedek olarak site dışında tutulan şifreli bir depo kullanın.
restic mi, Borg mu — hangisini kullanmalıyım?
Aksine özel bir nedeniniz olmadıkça restic. Varsayılan olarak şifreler, hedefte hiçbir şeyin kurulu olmasına gerek duymaz, kullanmaya değer her backend ile konuşur ve tek bir statik ikili dosya olarak gelir. Borg daha iyi deduplication yapar, daha iyi sıkıştırır ve milyonlarca küçük dosya içeren dosya sistemlerinde belirgin biçimde daha hızlıdır, ama her iki uçta da kurulu ve sürüm eşleşmeli olmalıdır ve gerçekten depo başına tek bir istemci için tasarlanmıştır. Büyük bir posta havuzu ve her iki makine de kontrolünüzdeyse: Borg. Geri kalan her şey için: restic.
Yedekleme hedefinin ne kadar diske ihtiyacı var?
Bu rehberdeki saklama merdiveniyle — 7 günlük, 5 haftalık, 12 aylık, 2 yıllık — deduplication yapılmış bir depo için, tüm sunucunun değil, gerçekte yedeklediğiniz verinin büyüklüğünün kabaca iki ila üç katını hesaba katın. Yirmi altı snapshot, yirmi altı kopya anlamına gelmez, çünkü yalnızca değişen bloklar yeniden saklanır. 15 GB gerçek durumu olan küçük bir site, yıllarca geçmişi artacak şekilde 80 GB'lık Starter'a rahatça sığar.
İkinci bir VPS, barındırma faturamı ikiye katlamaz mı?
Yalnızca yedekleme hedefi üretimle eşleşirse, ki eşleşmemelidir. Hiçbir uygulama çalıştırmaz ve hiçbir trafiğe hizmet etmez; CPU değil disk ister. 30 dolarlık bir üretim sunucusunun arkasındaki 5 dolarlık bir Starter, faturanın altıda biridir ve 12 aylık döngü bunun yüzde 50'sini düşürür. Her şeyi kaybetmenin maliyetine karşı, faturadaki en ucuz kalemdir — üstelik hedef, geri yükleme tatbikatı için bir prova makinesi olarak da iki katlı görev görür.
Depo parolası nerede yaşamalı?
Kasası kendisi de başka bir yerde yedeklenen bir parola yöneticisinde, ya da kağıt üzerinde, ya da her ikisinde birden — ve yanında, depo adresi ve tam geri yükleme komutu. Sunucudaki /etc içindeki kopya, otomasyon için bir çalışma kopyasıdır, asla asıl kayıt değildir. Bunu doğru şekilde doğrulayın: ne üretim ne de yedekleme sunucusu olan bir makineden, yalnızca parola yöneticisinde olanı kullanarak restic snapshots çalıştırın. Başka bir şey gerekiyorsa, henüz kurtarılabilir bir yedeğiniz yok demektir.
Yedeklemeler ne sıklıkla çalışmalı?
Ne kadar işi yeniden yapmaya razı olduğunuzu sorun. Çoğu sunucu için gecelik doğrudur: en fazla bir gün kaybedilir ve gece boyu tek bir çalıştırmayı akılda tutmak kolaydır. Meşgul bir veritabanı daha fazlasını ister — yalnızca veritabanının saatlik dökümleri, dosya geçişi ise gecelik kalır, bu genelde işleyen şekildir. Bu noktadan sonraki sıklık, aynı çabanın daha uzun saklama süresine ve gerçek riskin yattığı yer olan fiili bir geri yükleme tatbikatına harcanmasından daha azını verir.
Diski LUKS ile şifrelenmiş bir sunucuyu yedekleyebilir miyim?
Evet ve ikisi gereksiz tekrar değil, birbirini tamamlayıcıdır. LUKS, makine kapalıyken diski korur; yedek ise sizi silme, bozulma ve makineyi tamamen kaybetmeye karşı korur. Bağlı dosya sistemini, tam olarak şifrelenmemiş bir dosya sistemini yedekler gibi yedekleyin — restic çıkışta yeniden şifreler, bu yüzden depo güvenilmeyen bir depolamada bile güvenlidir. İki sırrı gerçekten ayrı yerlerde tutun: yalnızca restic deposunda saklanan bir LUKS parola öbeği, ya da yalnızca LUKS volume'ünün içinde saklanan bir restic parola öbeği, her iki tarafta da kapalı kalarak başarısız olan bir döngüdür.
Sunucum ele geçirilirse, yedekler güvende mi?
Bu tamamen aylar önce verdiğiniz bir karara bağlıdır. Üretim sunucusu, depo üzerinde silme hakkı olan bir kimlik bilgisi tutuyorsa, hayır — bir saldırgan önce yedekleri numaralandırıp yok eder, çünkü bir olayı bir pazarlığa çeviren şey budur. Depo append-only ise, ya da yedekleme sunucusu pull yapıyor ve üretim hiçbir yedekleme kimlik bilgisi tutmuyorsa, geçmiş hayatta kalır ve sızmadan önceki bir snapshot'a geri yüklersiniz. Pull tasarımının tüm argümanı budur ve ona ihtiyaç duymadan önce tercih etmenizin nedeni de budur.
Keep exploring
Kesintisiz VPS taşıma
Provası yapılmış bir geri yükleme, bir taşımanın zaten büyük bölümünü bitirmiştir — bu sayfa da gerisini, kesintinizi gerçekte belirleyen DNS zamanlamasıyla birlikte anlatır.
LUKS ile VPS diskini şifreleme
Bu sayfanın tamamlayıcısı: yedekler sizi veriyi kaybetmekten korur, LUKS ise onu artık fiziksel olarak elinizde tutmadığınız bir diskte korur.
Yeni bir VPS'i ilk saatte sertleştirme
Yedekleme hedefine güvenmeden önce bunu ona uygulayın — kabaca bir saatte sadece anahtarla SSH ve varsayılan reddet bir güvenlik duvarı.
Deploy your offshore server.
Bir bölge seçin. Bir plan seçin. Anahtar yapıştırın. Ödeyin. Sonraki 47 saniye bizden.