بکاپ و امنیت

آموزش بکاپ‌گیری از سرور لینوکس — اسکریپت، زمان‌بندی و ریستور

هارددیسک‌ها بدون اطلاع قبلی می‌میرند، یک rm اشتباه در سه ثانیه حاصل سه ماه کار را پاک می‌کند و باج‌افزارها همیشه نیمه‌شب می‌رسند. تنها چیزی که بین شما و فاجعه می‌ایستد، بکاپ است — آن هم بکاپی که واقعاً ریستور می‌شود. در این راهنما بکاپ گیری از سرور لینوکس را قدم‌به‌قدم جلو می‌بریم: قانون ۳-۲-۱، اسکریپت بکاپ شبانه با tar و cron، بکاپ دیتابیس MySQL، انتقال نسخه‌ها با rsync به سرور دوم و مهم‌ترین قدمی که بیشتر مدیرها فراموشش می‌کنند: تست ریستور.

قانون ۳-۲-۱ به زبان آدمیزاد

هر استراتژی بکاپ جدی روی یک قانون ساده سوار است:

  • ۳ نسخه از هر داده‌ی مهم داشته باشید (نسخه‌ی اصلی + دو کپی).
  • کپی‌ها روی ۲ سیستم متفاوت باشند — نه دو پوشه روی همان دیسک.
  • ۱ نسخه کاملاً بیرون از سرور اصلی نگه‌داری شود.

منطقش ساده است: هر لایه یک سناریوی خرابی متفاوت را پوشش می‌دهد. بکاپِ روی خودِ سرور در برابر حذف اشتباهی نجات‌تان می‌دهد و سریع‌ترین ریستور را دارد؛ اما اگر دیسک بسوزد یا باج‌افزار کل سرور را قفل کند، همان بکاپ هم با بقیه‌ی داده‌ها می‌رود. نسخه‌ی خارج از سرور دقیقاً برای همان روز است. به عددها هم وسواس بی‌جا نداشته باشید — اگر امروز فقط یک نسخه‌ی شبانه روی سرور دوم دارید، از ۹۰٪ سرورهای دنیا جلوترید. مهم این است که از جایی شروع کنید و روال خودکار باشد.

لایه‌ی صفر و بی‌زحمتِ این معماری، بکاپ خودِ ارائه‌دهنده است: افزونه‌ی بکاپ که در سطح دیسک و به‌صورت خودکار نسخه برمی‌دارد و با چند کلیک فعال می‌شود — در مهران هاست هم از پنل قابل فعال‌سازی است. اما به یک لایه اکتفا نکنید؛ بکاپ ارائه‌دهنده داخل همان زیرساخت است و جای بکاپ فایلی و دیتابیسیِ خودتان را نمی‌گیرد. لایه‌ی دوم را خودتان بسازید — بقیه‌ی این مقاله همین است.

💡 نکته: لازم نیست از کل سیستم‌عامل بکاپ بگیرید. سیستم‌عامل قابل بازسازی است؛ چیزی که قابل بازسازی نیست، داده‌ی شماست: کانفیگ‌ها، فایل‌های سایت و دیتابیس.

اسکریپت بکاپ گیری از سرور لینوکس با tar و cron

ساده‌ترین شکل قابل‌اتکای بکاپ، یک آرشیو فشرده‌ی شبانه از مسیرهای مهم است. قبل از نوشتن اسکریپت، پنج دقیقه فکر کنید دقیقاً چه چیزهایی «داده‌ی شما» هستند. فهرست معمول: /etc (تمام کانفیگ‌ها، از Nginx تا فایروال)، /var/www (فایل‌های سایت)، /home (فایل‌های کاربران) و اگر اسکریپت یا کرانتب سفارشی دارید، مسیر آن‌ها. در عوض چیزهایی مثل کش، فایل‌های موقت و لاگ‌های حجیم را داخل آرشیو نبرید — هم فضا می‌خورند و هم زمان بکاپ را چند برابر می‌کنند. حالا این اسکریپت بکاپ را در /root/backup.sh بسازید:

#!/bin/bash
set -euo pipefail

DATE=$(date +%F)
DEST=/var/backups/files
mkdir -p "$DEST"

# paths worth keeping: configs, web files, home dirs
tar -czpf "$DEST/backup-$DATE.tar.gz" \
    /etc /var/www /home

# retention: delete archives older than 14 days
find "$DEST" -name "backup-*.tar.gz" -mtime +14 -delete

سوییچ‌ها: -c ساخت آرشیو، -z فشرده‌سازی gzip، -p حفظ مالکیت و سطح دسترسی فایل‌ها (برای ریستور حیاتی است) و -f نام فایل خروجی. خط set -euo pipefail هم باعث می‌شود اسکریپت با اولین خطا متوقف شود، نه این‌که بی‌سروصدا یک آرشیو ناقص بسازد. با chmod +x /root/backup.sh قابل‌اجرایش کنید و یک بار دستی اجرا کنید تا مطمئن شوید خطا نمی‌دهد؛ بعد با gzip -t سلامت فایل خروجی را هم چک کنید.

زمان‌بندی: بکاپ خودکار سرور با cron

بکاپی که به حافظه‌ی انسان وابسته باشد، دیر یا زود فراموش می‌شود. با crontab -e این خط را اضافه کنید تا هر شب ساعت ۳:۳۰ بامداد اجرا شود:

30 3 * * * /root/backup.sh >> /var/log/backup.log 2>&1

خروجی و خطاها در /var/log/backup.log ثبت می‌شود؛ هفته‌ای یک بار نگاهی به آن بیندازید. بکاپ خودکار سرور یعنی همین: یک بار تنظیم می‌کنید و بعد فقط بر کارکردش نظارت می‌کنید.

سیاست نگهداری (Retention)

خط find در انتهای اسکریپت، آرشیوهای قدیمی‌تر از ۱۴ روز را پاک می‌کند تا دیسک پر نشود. عدد را با حجم داده و فضای دیسک‌تان تنظیم کنید؛ یک الگوی رایج و منطقی: ۷ نسخه‌ی روزانه + ۴ نسخه‌ی هفتگی + ۳ نسخه‌ی ماهانه. حساب سرانگشتی‌اش هم ساده است: اگر هر آرشیو ۲ گیگابایت باشد، نگهداری ۱۴ نسخه یعنی ۲۸ گیگابایت — قبل از انتخاب عدد، با df -h ببینید چقدر جا دارید. نگه‌داشتن فقط «آخرین بکاپ» خطرناک است — اگر خرابی داده چند روز دیرتر کشف شود، آخرین بکاپ هم خراب است و شما یک نسخه‌ی سالمِ قدیمی‌تر لازم دارید.

بکاپ دیتابیس MySQL با mysqldump

کپی مستقیم پوشه‌ی /var/lib/mysql در حالی که سرویس در حال کار است، تقریباً همیشه یک بکاپ ناسازگار و غیرقابل‌ریستور تحویل می‌دهد. راه درست بکاپ دیتابیس mysql، ابزار mysqldump است. اول اطلاعات ورود را در /root/.my.cnf بگذارید تا رمز در تاریخچه‌ی شل و خروجی ps دیده نشود:

[client]
user=root
password=YourStrongPassword

و فقط root بتواند بخواندش: chmod 600 /root/.my.cnf. حالا خودِ بکاپ:

mkdir -p /var/backups/db
mysqldump --all-databases --single-transaction --quick \
    --routines --events | gzip > /var/backups/db/all-db-$(date +%F).sql.gz

سوییچ --single-transaction برای جدول‌های InnoDB یک نمای سازگار می‌گیرد بدون این‌که جدول‌ها قفل شوند — یعنی سایت هنگام بکاپ کُند یا قطع نمی‌شود. سوییچ --quick هم ردیف‌ها را جریانی می‌خواند تا مصرف حافظه در جدول‌های بزرگ بالا نرود. این دستور را به انتهای همان backup.sh اضافه کنید (به‌همراه یک خط find مشابه برای پاک‌سازی دامپ‌های قدیمی) تا فایل و دیتابیس با هم و هم‌زمان بکاپ شوند.

اگر چند سایت با چند دیتابیس روی سرور دارید، به‌جای یک دامپ غول‌پیکر از همه‌چیز، برای هر دیتابیس یک فایل جداگانه بگیرید (mysqldump myshop_db به‌جای --all-databases). موقع ریستور فرقش را می‌فهمید: برگرداندن دیتابیس یک سایت خراب، نباید مستلزم دست‌کاری دیتابیس نُه سایت سالم باشد.

نسخه‌ی دوم: rsync بکاپ‌ها به سرور دیگر

تا این‌جا بکاپ‌ها هنوز روی همان سرورند؛ قانون ۳-۲-۱ می‌گوید باید یک نسخه بیرون برود. یک سرور دوم (حتی کوچک و ارزان) آماده کنید، طبق آموزش SSH ورود با کلید را بین دو سرور برقرار کنید و بعد:

rsync -az /var/backups/ [email protected]:/srv/backup/web1/

زیبایی rsync در افزایشی‌بودن آن است: فقط فایل‌های جدید یا تغییرکرده منتقل می‌شوند، پس بعد از اولین انتقال، شب‌های بعد چند ثانیه بیشتر طول نمی‌کشد. سوییچ -a مالکیت، دسترسی و تاریخ فایل‌ها را حفظ می‌کند و -z داده را حین انتقال فشرده می‌کند تا پهنای باند کمتری مصرف شود. این خط را هم به cron اضافه کنید (مثلاً ساعت ۴ بامداد، بعد از اتمام بکاپ‌ها). به این ترتیب rsync بکاپ هر شب به مقصد دوم می‌رسد بی‌آن‌که شما کاری کنید.

یک عادت خوب: هفته‌ای یک بار روی سرور مقصد ls -lh بزنید و تاریخ و حجم آخرین فایل‌ها را چک کنید. بکاپی که سه هفته پیش بی‌سروصدا از کار افتاده و کسی نفهمیده، از نداشتن بکاپ هم خطرناک‌تر است — چون به شما احساس امنیت دروغین می‌دهد.

⚠️ سوییچ --delete را برای مقصد بکاپ به‌کار نبرید مگر دقیقاً بدانید چه می‌کنید: این سوییچ مقصد را آینه‌ی مبدأ می‌کند، یعنی اگر بکاپی در مبدأ پاک شود (مثلاً توسط باج‌افزار)، از مقصد هم پاک می‌شود.

restic؛ بکاپ رمزنگاری‌شده و افزایشی

روش tar یک ضعف آشکار دارد: هر شب یک آرشیو کاملِ جدید می‌سازد، حتی اگر فقط دو فایل عوض شده باشد. تا وقتی حجم داده چند گیگابایت است مشکلی نیست، اما با رشد داده هم فضای دیسک هدر می‌رود و هم زمان بکاپ طولانی می‌شود. این‌جاست که سراغ restic بروید: رمزنگاری سمت مبدأ (مقصد فقط داده‌ی رمزشده می‌بیند)، حذف داده‌ی تکراری (deduplication) و اسنپ‌شات‌های افزایشی — یعنی هر شب فقط تغییرات ذخیره می‌شود، اما هر اسنپ‌شات مثل یک بکاپ کامل و مستقل قابل ریستور است.

apt install restic -y
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic
restic init
restic backup /etc /var/www
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic snapshots

دستور init مخزن را یک بار می‌سازد و از شما رمز می‌خواهد، backup هر بار فقط تغییرات را می‌فرستد، و forget --prune همان سیاست نگهداری است، این بار داخل خود ابزار: ۷ نسخه‌ی روزانه، ۴ هفتگی و ۶ ماهانه نگه می‌دارد و بقیه را واقعاً از دیسک پاک می‌کند. فقط یک هشدار جدی: رمز مخزن restic را جایی امن و خارج از سرور نگه دارید؛ بدون آن رمز، هیچ‌کس — از جمله خودتان — به بکاپ‌ها دسترسی نخواهد داشت.

تست ریستور: بکاپی که هرگز ریستور نشده، امید است نه بکاپ

تلخ‌ترین جمله‌ای که یک مدیر سرور می‌تواند بگوید این است: «بکاپ داشتیم، ولی ریستور نشد.» فایل خراب، آرشیو ناقص، دامپی که وسطش قطع شده، رمزی که گم شده — همه‌ی این‌ها فقط موقع ریستور خودشان را نشان می‌دهند، یعنی دقیقاً بدترین لحظه‌ی ممکن. تمرین ریستور باید مثل خودِ بکاپ گیری از سرور لینوکس، بخشی از روال ثابت‌تان باشد. ماهی یک بار این سه قدم را انجام دهید:

# list the archive contents
tar -tzf /var/backups/files/backup-2026-07-17.tar.gz | head

# extract into a test dir, never into /
mkdir -p /tmp/restore-test
tar -xzpf /var/backups/files/backup-2026-07-17.tar.gz -C /tmp/restore-test

# restore the DB dump into MySQL
gunzip -c /var/backups/db/all-db-2026-07-17.sql.gz | mysql

بعد از استخراج، فقط به «خطا نداد» راضی نشوید: چند فایل مهم را باز کنید، تعداد ردیف چند جدول کلیدی را با SELECT COUNT(*) مقایسه کنید و مطمئن شوید تاریخ آرشیو همانی است که انتظار دارید. تست واقعی اما یک قدم جلوتر است: یک سرور موقت بالا بیاورید، بکاپ را رویش ریستور کنید و ببینید سایت واقعاً بالا می‌آید یا نه. این‌جا مدل ساعتی طلاست — از مهران هاست یک سرور ابری ساعتی بسازید، دو سه ساعت تمرین ریستور کنید و سرور را حذف کنید؛ کل هزینه‌ی این تمرینِ حیاتی به اندازه‌ی یک لیوان چای است. اگر ریستور کامل جواب داد، آن‌وقت می‌توانید بگویید بکاپ گیری از سرور لینوکس‌تان واقعاً کار می‌کند.

💡 نکته: تاریخ آخرین تست ریستور موفق را یادداشت کنید. اگر بیش از یک ماه گذشته، بکاپ‌تان رسماً در وضعیت «امیدواریم» است.

قدم بعدی

بکاپ فقط یک ضلع نگه‌داری سرور است؛ ضلع دیگر جلوگیری از خودِ حادثه است — راهنمای امنیت سرور لینوکس را بخوانید تا احتمال نیاز به بکاپ را هم پایین بیاورید. و اگر هنوز سروری برای تمرین ندارید، همین حالا ثبت‌نام کنید و با یک سرور ساعتی ارزان، همین امشب اولین اسکریپت بکاپ‌تان را راه بیندازید.

آموزش‌های مرتبط

آماده‌ی تمرین عملی هستی؟

سرور ابری ساعتی مهران هاست در ۶۰ ثانیه تحویل می‌شود — تمرین کن، و فقط بابت همان ساعت‌ها پرداخت کن.