فایلها با پسوند .locked بالا آمدهاند، یک README.txt روی دسکتاپ است و اولین کاری که ذهنت میکند این است: «بروم از بکاپ برگردانم.» همان لحظه است که میفهمی درایو بکاپ هم به همان سرور mount بوده و رمز شده. این مقاله دربارهٔ همان لحظه است؛ نه دربارهٔ اینکه بکاپ مهم است.
سه چیز باید همزمان درست باشند تا بکاپ امن باشد: یک نسخه خارج از دسترس شبکه، یک نسخه که حتی با دسترسی root هم در بازهٔ نگهداری قابل تغییر نیست، و یک بازیابی که در ۹۰ روز گذشته واقعاً اجرا شده. اگر یکی از این سه نباشد، بقیه تزئینی است.
چرا بکاپ روی همان شبکه، بکاپ نیست
باجافزارهای امروزی قبل از رمز کردن، اول دنبال مقصد بکاپ میگردند. اسکریپتهایشان mount pointها، اعتبارنامههای ذخیرهشده در ~/.aws/credentials، کانفیگ restic، و پسوردهای داخل فایلهای .env را میخوانند. اگر سرور بکاپ با همان کلید SSH یا همان توکن S3 در دسترس باشد، مهاجم دقیقاً همان کاری را میکند که اسکریپت تو میکند: نسخهٔ قبلی را حذف، نسخهٔ جدید را رمز.
علامتش همیشه دیر پیدا میشود. لاگ سرور بکاپ پر است از jobهای موفق، داشبورد سبز است، و فقط وقتی میفهمی که میخواهی restore کنی و میبینی snapshotهای هفت روز گذشته همه صفر بایت یا رمز شدهاند. اینجا اشتباه میکنند: فرض میکنند «job موفق» یعنی «بکاپ سالم». job موفق یعنی فایل منتقل شد؛ دربارهٔ محتوایش هیچ نمیگوید.
تست واقعی، نه چکلیست
یک بار در ماه، روی یک ماشین جدا، آخرین snapshot را restore کن و یک فایل مشخص را باز کن. عددی که باید یادداشت کنی دو چیز است: زمان تا اولین بایت سالم، و تعداد فایلهایی که checksumشان با مبدأ نمیخورد. اگر این کار را نکردهای، بکاپ تستنشده داری و بکاپ تستنشده بکاپ نیست.
restic -r s3:s3.example.com/bucket restore latest \
--target /tmp/restore-test --include /var/www/html/index.php
sha256sum /tmp/restore-test/var/www/html/index.php
نسخهٔ تغییرناپذیر: چطور immutability را واقعاً پیاده کنیم
«تغییرناپذیر» یعنی در بازهٔ نگهداری، هیچکس — از جمله خودت با کلید ادمین — نتواند آبجکت را حذف یا بازنویسی کند. سه راه عملی وجود دارد و انتخاب بینشان به بودجه و سطح تحمل درد برمیگردد.
| روش | چطور کار میکند | هزینهٔ واقعی |
|---|---|---|
| Object Lock در S3 | حالت Compliance با retention مثلاً 30 روز | تا پایان دوره حتی ادمین هم نمیتواند پاک کند؛ فضا آزاد نمیشود |
| درایو آفلاین چرخشی | دیسک هفتگی وصل، sync، جدا، در گاوصندوق | دستی است و فراموش میشود |
| سرور بکاپ pull-only | سرور بکاپ به مبدأ وصل میشود، نه برعکس | نیاز به پیکربندی SSH و کلید جداگانه |
اگر مجبورم یکی را انتخاب کنم، برای سایتهای تولیدی Object Lock در حالت Compliance را برمیدارم، چون خودکار است و به حافظهٔ انسان وابسته نیست. حالت Governance را انتخاب نمیکنم؛ در آن حالت هر کسی با مجوز s3:BypassGovernanceRetention میتواند قفل را باز کند و همان دسترسی، دقیقاً همان چیزی است که مهاجم دنبالش میگردد.
الگوی pull-only با SSH
در این الگو، سرور بکاپ کلید دارد و به سرور تولید وصل میشود. سرور تولید هیچ کلیدی برای نوشتن روی بکاپ ندارد. اگر مهاجم روی سرور تولید root شود، مقصد بکاپ را نمیبیند.
# روی سرور بکاپ، در /etc/ssh/sshd_config مبدأ:
Match User backupuser
AllowTcpForwarding no
PermitOpen none
# روی سرور بکاپ، cron روزانه:
rsync -a --delete --link-dest=/backup/current \
backupuser@prod:/var/www/html/ /backup/$(date +\%F)/
نکتهٔ ریز: --link-dest فضا را کم میکند ولی اگر مبدأ فایل را بازنویسی کند، نسخهٔ قدیمی دستنخورده میماند. این همان چیزی است که در حملهٔ رمزنگاری نجاتت میدهد.
بکاپ دیتابیس: جایی که بیشترین خرابی رخ میدهد
کپی کردن فایلهای /var/lib/mysql روی یک دیتابیس در حال کار، یک بکاپ خراب تولید میکند که تا لحظهٔ restore سالم به نظر میرسد. برای MySQL باید dump منطقی بگیری و آن را با checksum تأیید کنی.
mysqldump --single-transaction --quick --routines --triggers \
--all-databases | gzip > /backup/db-$(date +\%F).sql.gz
gzip -t /backup/db-$(date +\%F).sql.gz && echo OK
فلگ --single-transaction فقط روی InnoDB معنا دارد. اگر جدول MyISAM داری، این فلگ قفل نمیگیرد و dump ناسازگار میشود؛ آنجا باید --lock-tables بگذاری و پنجرهٔ نگهداریات را کوتاه کنی. این همان trade-offی است که در مستندات کم دیده میشود.
رمزنگاری بکاپ و مدیریت کلید
بکاپ رمز نشده روی فضای ابری، یعنی اگر باکت لو برود همهچیز لو رفته. اما رمزنگاری هم تله دارد: کلید را کجا نگه میداری؟ اگر کلید کنار بکاپ باشد، رمزنگاری فقط یک لایهٔ تزئینی است. کلید باید جای دیگری باشد، در یک password manager تیمی یا KMS، و در دسترس حداقل دو نفر.
برای restic و borg، پسورد را از فایل جدا بخوان و آن فایل را در بکاپ نگذار:
export RESTIC_PASSWORD_FILE=/etc/restic/pass
restic -r s3:... backup /var/www --exclude-caches
اگر کلید را گم کنی، بکاپ برای همیشه غیرقابل بازیابی است. این را در runbook بنویس، نه در ذهنت.
قاعدهٔ 3-2-1 و نسخهٔ آفلاین
سه نسخه، دو رسانهٔ متفاوت، یک نسخه خارج از سایت. نسخهٔ آفلاین همان چیزی است که در بدترین سناریو نجاتت میدهد: وقتی مهاجم هم روی سرور تولید و هم روی حساب ابری دسترسی گرفته. یک دیسک NVMe یا HDD که هفتهای یک بار وصل میشود و بعد فیزیکی جدا میشود، از هر تنظیم نرمافزاری قویتر است، چون حملهٔ شبکهای به دیسکی که وصل نیست ممکن نیست.
هزینهاش را هم بگویم: این روش دستی است و در عمل فراموش میشود. راهحل من این است که آن را به یک نفر با reminder تقویمی بسپارم و نتیجهٔ هر بار را در یک فایل log با تاریخ ثبت کنم. اگر کسی ثبت نکرد، آن هفته بکاپ آفلاین وجود ندارد.
پایش: چطور بفهمی بکاپ شکسته است، قبل از حادثه
سه سیگنال را پایش کن. اول، سن آخرین snapshot موفق؛ اگر از ۲۶ ساعت گذشت، هشدار. دوم، حجم snapshot؛ افت ناگهانی مثلاً از ۴۰ گیگابایت به ۲ گیگابایت یعنی چیزی در مبدأ خراب است. سوم، نتیجهٔ restore آزمایشی ماهانه.
یک اسکریپت کوچک کافی است:
restic snapshots --json | jq -r '.[-1].time'
اگر خروجی از ۲۴ ساعت پیش قدیمیتر بود، در cron هشدار بفرست. برای بررسی مسیر شبکه و دسترسیها هم میتوانی از ابزارهای بررسی DNS و شبکه استفاده کنی تا مطمئن شوی مقصد بکاپ از بیرون قابل دسترسی نیست.
دسترسیها: بکاپ فقط با کمترین مجوز
حسابی که بکاپ میگیرد نباید بتواند حذف کند. در S3، policy را طوری بنویس که فقط PutObject و ListBucket مجاز باشد و DeleteObject صریحاً رد شود. روی سرور، کاربر بکاپ نباید عضو گروه sudo باشد و بهتر است در chroot یا کانتینر جدا اجرا شود.
اگر روی زیرساخت خودت کار میکنی، جدا کردن شبکهٔ بکاپ از شبکهٔ تولید یکی از مؤثرترین کارهاست. برای لایهٔ شبکه و مقابله با ترافیک مخرب روی سرور بکاپ هم محافظت در برابر DDoS را جدی بگیر؛ سرور بکاپی که از بیرون دیده شود، هدف خوبی است.
در کنارش، لاگ ممیزی را دستنخورده نگه دار. اگر روزی بفهمی snapshotها پاک شدهاند، اولین سؤالت این است: «کی و از کجا؟» بدون لاگ، جواب نداری. دربارهٔ نگهداری درست آن در لاگ ممیزی و روش دستنخورده نگه داشتن آن نوشتهایم.
بازیابی: تمرینی که واقعاً جواب میدهد
بازیابی را روی محیطی اجرا کن که هیچ ارتباطی با تولید ندارد. ترتیب کار: اول دیتابیس، بعد فایلها، بعد کانفیگها و کلیدها. اگر ترتیب را برعکس کنی، سایت بالا میآید ولی داده ندارد و این بدترین حالت است، چون فکر میکنی موفق شدی.
- یک ماشین تازه با همان نسخهٔ OS و همان نسخهٔ MySQL بالا بیاور.
- dump را restore کن و تعداد رکوردهای سه جدول اصلی را با تولید مقایسه کن.
- فایلها را restore کن و checksum ده فایل تصادفی را بگیر.
- سایت را با DNS موقت بالا بیاور و یک تراکنش واقعی تست کن.
- زمان کل را ثبت کن؛ این عدد همان RTO واقعی توست، نه عددی که در سند نوشتهای.
اگر زمان بازیابی از تحمل کسبوکار بیشتر است، مشکل بکاپ نیست، مشکل معماری است. آنجا باید به replica آماده یا snapshotهای سریعتر فکر کنی.
اشتباههایی که مرتب تکرار میشوند
- نگهداشتن پسورد بکاپ داخل همان اسکریپتی که روی سرور تولید است.
- retention کوتاهتر از زمان تشخیص نفوذ؛ اگر ۷ روز نگه داری و حمله ۲۰ روز پیش شروع شده باشد، نسخهٔ سالم نداری.
- بکاپ گرفتن از مسیری که خودش symlink به جای دیگری است و restore شدن فایلهای اشتباه.
- تکیه بر snapshotهای provider بهعنوان تنها نسخه؛ snapshot هم با حذف حساب از بین میرود.
اگر روی وردپرس کار میکنی، بخشی از سطح حمله خودِ اپلیکیشن است. بستن راههای نشت کاربران در امنسازی REST API وردپرس و سختکردن کلی در امنیت وردپرس از wp-config تا افزونهها را جدا بخوان؛ بکاپ خوب روی سایتی که از قبل باز است، فقط تاریخ حادثه را عقب میاندازد.
و اگر دسترسی مدیریتی سرورت از بیرون باز است، قبل از هر چیز آن را ببند: امنیت SSH از تغییر پورت تا fail2ban و کلید عمومی.
پرسشهای پرتکرار
آیا snapshot ابری برای بکاپ امن کافی است؟
نه، اگر تنها نسخه باشد. snapshot معمولاً در همان حساب و همان کنترلپلین است؛ مهاجمی که به حساب دسترسی بگیرد میتواند آن را حذف کند. snapshot را بهعنوان لایهٔ سرعت نگه دار، ولی حداقل یک نسخهٔ تغییرناپذیر یا آفلاین جدا داشته باش.
immutable backup یعنی چه و چطور فعال میشود؟
یعنی در بازهٔ نگهداری، حذف یا بازنویسی آبجکت ممکن نیست. در S3 با Object Lock و تعیین retention mode فعال میشود. حالت Compliance را انتخاب کن، چون در حالت Governance هر کسی با مجوز bypass میتواند قفل را باز کند.
هر چند وقت باید بازیابی را تست کنم؟
حداقل ماهی یک بار برای یک فایل و هر سه ماه یک بار برای بازیابی کامل روی محیط جدا. تست ماهانه سریع است و شکستهای زودهنگام را نشان میدهد؛ تست فصلی زمان واقعی RTO را مشخص میکند.
بکاپ رمزنگاریشده اگر کلید گم شود چه میشود؟
برای همیشه غیرقابل بازیابی میشود؛ راه دور زدنی وجود ندارد. پس کلید را در جای جدا از بکاپ، در دسترس حداقل دو نفر، و با یک نسخهٔ چاپی در گاوصندوق نگه دار.
کاری که همین امروز میتوانی بکنی این است: یک snapshot را روی ماشین جدا restore کن و زمانش را بنویس. اگر جواب نداشت، بقیهٔ بحثها بیفایده است.
دیدگاهها ۰
هنوز دیدگاهی ثبت نشده؛ اولین نفر باشید!