در یکی از پرونده‌های پاکسازی که چند سال پیش بررسی کردم، مهاجم به‌جای حمله به وردپرس، از یک پورت باز روی سرور استفاده کرده بود که هیچ‌کس نمی‌دانست چرا فعال است. ورود از همان پورت، دسترسی به سیستم‌عامل را فراهم کرده و بعد، همه‌چیز از آنجا آغاز شده بود. آن روز فهمیدم امنیت سرور، فقط به‌روزرسانی وردپرس و افزونه‌های امنیتی نیست؛ یک لایه‌بندی چندسطحی است که هر سطح، باید جداگانه محافظت شود. از آن پروژه تا امروز، چک‌لیست امنیت سرور به یکی از بخش‌های ثابت پروژه‌های وردپرسی من تبدیل شده است. این مقاله، همان چک‌لیست در نه گام عملی است.

امنیت سرور در چند لایه معنا پیدا می‌کند

امنیت سرور، مثل ساختمان چند طبقه است: هر طبقه، نقاط ورود خودش را دارد و همه باید جداگانه محافظت شوند. چهار لایهٔ اصلی که در پروژه‌های خودم به آن‌ها می‌پردازم: لایهٔ کاربری (حساب‌های SSH، رمزها، کلیدها)، لایهٔ شبکه (فایروال، پورت‌ها، ترافیک ورودی)، لایهٔ سیستم‌عامل (پچ‌ها، سرویس‌ها، مجوزها) و لایهٔ اپلیکیشن (وب‌سرور، PHP، دیتابیس). ضعف در هر یک از این چهار لایه، کل ساختمان را آسیب‌پذیر می‌کند. به همین دلیل، امنیت سرور را نمی‌توان با یک ابزار یا یک تنظیم به دست آورد. اگر با مفهوم لایه‌بندی زیرساخت وردپرس آشنا نیستید، مقالهٔ سرور چیست و چگونه کار می‌کند؟ نقطهٔ شروع خوبی است.

امنیت سرور یک تنظیم نیست؛ یک عادت است — چیزی که هر هفته یک بار باید بازبینی شود، نه یک دکمه که یک بار فشار داده شود.

گام ۱: مدیریت کاربران و کلیدهای SSH

اولین گام، بازبینی حساب‌های کاربری سرور است. سه اقدام: یک، حذف حساب‌های اضافی. در بسیاری از سرورها، حساب‌هایی از پروژه‌های قدیمی باقی مانده که از آن‌ها استفاده نمی‌شود. هر حساب، یک نقطهٔ ورود بالقوه است. دو، استفاده از کلیدهای SSH (Secure Shell — پوستهٔ امن) به‌جای رمز عبور. ورود با کلید، عملاً غیرقابل حدس است. در پروژه‌های حرفه‌ای، این گام اولین قدم پس از راه‌اندازی سرور است. سه، غیرفعال‌کردن ورود مستقیم root. کاربر root نباید از راه دور قابل دسترسی باشد. به‌جای آن، یک کاربر با دسترسی sudo بسازید. مسیر کامل مدیریت کاربران در چگونه سرور را مدیریت و نگهداری کنیم؟.

گام ۲: فایروال و بستن پورت‌های اضافه

فایروال، مرز اولیهٔ شبکه است. سه سطح فایروال که در پروژه‌های خودم تنظیم می‌کنم: یک، فایروال سمت سیستم‌عامل مثل UFW یا firewalld. مسیرش در فایروال نرم‌افزاری در سرور: راهنمای عملی. دو، فایروال سمت ابر در سرویس‌های ارائه‌دهنده (Security Groups در AWS، Firewall در DigitalOcean). سه، فایروال ابری بیرونی مثل Cloudflare که ترافیک را قبل از رسیدن به سرور فیلتر می‌کند — مقایسه‌اش در فایروال ابری در مقابل فایروال سنتی. نکتهٔ کلیدی: هر پورت باز، یک در ورودی است. پورت‌های ضروری محدود به ۲۲ (SSH)، ۸۰ و ۴۴۳ (وب) و در صورت نیاز ۳۳۰۶ (MySQL که فقط از localhost). پورت‌های دیگر باید بسته باشند. در پروژه‌ای، همین یک اقدام ساده باعث شد یک اسکنر خودکار که روزانه هزاران سرور را بررسی می‌کرد، سرور ما را رد کند.

گام ۳: به‌روزرسانی و پچ امنیتی

هر پکیج نصب‌شده روی سرور، یک سطح حمله بالقوه است. به‌روزرسانی منظم، تفاوت بین سرور امن و سرور آسیب‌پذیر است. سه رویکرد: یک، به‌روزرسانی خودکار پکیج‌های امنیتی با unattended-upgrades در اوبونتو یا معادل آن. دو، به‌روزرسانی دستی دوره‌ای با بررسی changelog و رفع ریسک‌های احتمالی. سه، استفاده از ابزارهایی مثل apt list --upgradable برای مشاهدهٔ پکیج‌های نیازمند به‌روزرسانی. توصیهٔ عملی: به‌روزرسانی امنیتی را هرگز به تأخیر نیندازید، حتی اگر به‌نظر می‌رسد پکیج مربوط به سرویس غیرفعال است. تجربه‌ام می‌گوید اکثر سرورهایی که مورد حمله قرار می‌گیرند، توسط آسیب‌پذیری‌هایی قربانی می‌شوند که پچ آن‌ها هفته‌ها یا ماه‌ها قبل منتشر شده بوده است.

گام ۴: Fail2ban و محدودسازی Brute Force

Brute Force (حملهٔ حدس زدن سیستماتیک رمز عبور) روی SSH و پنل‌های مدیریت، یکی از شایع‌ترین حملات خودکار است. ابزار استاندارد مقابله: Fail2ban. این ابزار، لاگ‌ها را پایش می‌کند و در صورت تلاش ناموفق مکرر، IP مهاجم را برای مدتی مسدود می‌کند. سه تنظیم مهم: یک، حداکثر تعداد تلاش قبل از مسدودسازی (معمولاً ۳ تا ۵). دو، مدت زمان مسدودسازی (بین ۱۰ دقیقه تا ۱ ساعت، بسته به میزان ریسک). سه، سفیدکردن IP‌های خودی (مثل IP دفتر یا ابزارهای مانیتورینگ)، تا خودتان مسدود نشوید. برای سایت‌های وردپرسی، بالاتر از Fail2ban، محدودسازی ورود در لایهٔ اپلیکیشن هم ضروری است — مسیرش در چگونه ورود ادمین وردپرس را امن کنیم؟ و بهترین افزونه‌های وردپرس برای افزایش امنیت ورود.

گام ۵: مجوزهای فایل و پوشه

مجوزهای فایل، یکی از پنهان‌ترین حفره‌های امنیتی است. سه قاعدهٔ طلایی: یک، پوشه‌ها با مجوز 755، فایل‌ها با 644. این پیش‌فرض درست است. مجوز 777 برای پوشه یا فایل، خطرناک است، چون هر کاربری روی سرور می‌تواند آن را تغییر دهد. دو، فایل wp-config.php با مجوز 600 یا 640. این فایل حاوی رمزهای دیتابیس است و باید فقط برای کاربر و گروه مورد نظر قابل خواندن باشد. سه، پوشهٔ wp-content/uploads نباید اجازهٔ اجرای PHP داشته باشد. اگر مهاجم بتواند یک فایل PHP در این پوشه آپلود کند و آن را اجرا کند، سایت در دست اوست. مسیر مقابلهٔ دقیق در چگونه فایل wp-config را امن کنیم؟ آمده است.

گام ۶: SSH و دسترسی از راه دور

SSH، دروازهٔ اصلی مدیریت سرور است و باید با بیشترین دقت محافظت شود. چهار تنظیم کلیدی: یک، تغییر پورت پیش‌فرض SSH از 22 به یک پورت دلخواه. اگرچه این کار امنیت واقعی را زیاد نمی‌کند، اما حجم حملات خودکار را کاهش می‌دهد. دو، غیرفعال‌کردن احراز هویت با رمز عبور و اجبار به کلید SSH. سه، فعال‌سازی احراز هویت دو مرحله‌ای برای SSH در صورت پشتیبانی. چهار، محدودسازی IPهایی که می‌توانند به SSH وصل شوند — این کار در سرورهای با IP ثابت، یکی از مؤثرترین اقدام‌ها است.

گام ۷: امنیت وب‌سرور و PHP

وب‌سرور و PHP، لایهٔ تماس با اینترنت هستند و بیشترین حجم حملات را دریافت می‌کنند. سه تنظیم حیاتی: یک، غیرفعال‌کردن نمایش خطاهای PHP در محیط تولید (display_errors = Off). نمایش خطا به کاربر، اطلاعات حساسی مثل مسیر فایل و نسخهٔ PHP را افشا می‌کند. دو، محدودسازی اجرای توابع خطرناک PHP مثل exec، shell_exec و system از طریق disable_functions. سه، فعال‌کردن OPcache و تنظیم open_basedir برای محدودسازی دسترسی PHP به مسیرهای مشخص. برای اجرای این تنظیمات در سطح اپلیکیشن وردپرس، مطالعهٔ نوشتن کد PHP امن برای وردپرس هم ضروری است.

گام ۸: دیتابیس و شبکه

دیتابیس، قلب داده‌هاست و باید آخرین لایهٔ دفاعی باشد. سه تنظیم ضروری: یک، دیتابیس MySQL فقط از localhost قابل دسترسی باشد. دسترسی از راه دور، فقط در صورت نیاز واقعی و با محدودسازی IP. دو، کاربر دیتابیس با حداقل دسترسی. کاربر وردپرس نباید دسترسی DROP یا GRANT داشته باشد. سه، رمز عبور دیتابیس با پیچیدگی بالا و یکتا. مسیر کامل‌ترش در بهترین روش‌های امنیت MySQL کدامند؟. اگر از Redis برای کش آبجکت استفاده می‌کنید، آن هم باید از localhost فقط قابل دسترسی باشد و پورت 6379 از بیرون بسته باشد.

گام ۹: پایش و لاگ‌گیری

پایش و لاگ‌گیری، تفاوت بین کشف زودهنگام و کشف دیرهنگام یک حادثه است. سه سطح: یک، لاگ‌گیری سیستم‌عامل: auth.log، syslog و journald. دو، لاگ‌گیری وب‌سرور: access.log و error.log که الگوهای حمله را نشان می‌دهد. سه، پایش مستقیم: ابزارهایی مثل netstat، lsof و top برای دیدن ناهنجاری‌های لحظه‌ای. توصیهٔ عملی من: یک بار در ماه، لاگ‌های اخیر را دستی بررسی کنید — تعداد تلاش‌های ناموفق SSH، درخواست‌های مشکوک به وب‌سرور و ناهنجاری در مصرف CPU. این بررسی چند دقیقه‌ای، چندین بار در پروژه‌های واقعی جانِ سرور را نجات داده. مسیر تکمیلی در چگونه خطاهای سرور را در لاگ‌ها بررسی کنیم؟ و این مقاله.

جدول چک‌لیست امنیت سرور

گاماقدامفرکانس
۱بازبینی کاربران و کلیدهای SSHفصلی
۲بررسی فایروال و پورت‌های بازفصلی
۳به‌روزرسانی پکیج‌های امنیتیهفتگی
۴بررسی تنظیمات Fail2banماهانه
۵بررسی مجوزهای فایل و پوشهفصلی
۶بازبینی تنظیمات SSHسالانه
۷بررسی تنظیمات PHP و وب‌سرورسالانه
۸بازبینی دسترسی دیتابیس و Redisفصلی
۹پایش لاگ‌هاماهانه

نگاه لایه‌ای: سرور به‌عنوان مرز نهایی زیرساخت

برای توسعه‌دهندهٔ ارشد و معمار زیرساخت، سرور در وردپرس یک «مرز نهایی زیرساخت» است: هر چیزی که تا این لایه برسد، در واقع از تمام لایه‌های اپلیکیشن عبور کرده و کاربر یا سرویس فرض می‌شود معتبر است. اگر این مرز شکسته شود، هیچ لایهٔ اپلیکیشنی نمی‌تواند به‌تنهایی نجات‌دهنده باشد. سه اصل معماری که این مرز را تقویت می‌کند:

اصل اول — جداسازی لایه‌ها. سرور نباید همه‌چیز را در یک لایه داشته باشد. اگر دیتابیس روی سرور جداگانه باشد و از لایهٔ وب، دسترسی محدود داشته باشد، نفوذ به وب‌سرور به‌معنای نفوذ به دیتابیس نیست. این جداسازی، در سطح زیرساخت، اثر پیشگیرانهٔ چشمگیری دارد. اصل دوم — کمترین امتیاز (Least Privilege). این اصل را در همهٔ سطوح اعمال کنید: کاربران سیستم‌عامل، سرویس‌های وب، دیتابیس، PHP و حتی افزونه‌های وردپرس. هر سطح، باید فقط همان دسترسی‌هایی را داشته باشد که برای انجام کارش لازم است. سرویس وب‌سرور نباید به فایل‌های کاربران دسترسی مستقیم داشته باشد، PHP نباید به دیتابیس‌های غیرضروری دسترسی داشته باشد، و دیتابیس نباید به فایل‌سیستم دسترسی گسترده داشته باشد. اصل سوم — قابل بازیابی بودن. هر تغییری در سرور، باید قابل بازگشت باشد. این شامل تغییرات در پیکربندی، نصب پکیج و حتی حذف داده است. بکاپ سرور، بخشی از معماری امنیتی است، نه یک دکمهٔ اضطراری. در پروژه‌هایی که این سه اصل رعایت شده، حتی وقتی یک افزونهٔ ضعیف روی سایت نصب شد، سرور به‌دلیل جداسازی لایه‌ها مقاومت کرد و مهاجم نتوانست از آن عبور کند.

نکتهٔ تکمیلی که در پروژه‌های چندساله‌ام ارزشش را ثابت کرده: هر بار که یک سرویس یا پورت جدید روی سرور باز می‌کنید، باید در همان لحظه سه سؤال را بپرسید: چرا این سرویس لازم است؟ چه کسی باید به آن دسترسی داشته باشد؟ اگر این سرویس از بیرون قابل دسترسی نباشد، چه اتفاقی می‌افتد؟ پاسخ این سه سؤال، تصمیم نهایی در باز کردن یا بستن سرویس است. تجربه‌ام می‌گوید بیشتر سرورهایی که در حملات واقعی قربانی شدند، از سرویسی استفاده می‌کردند که هیچ‌کسی نمی‌دانست چرا فعال است. برای مطالعهٔ تکمیلی، مسیر امنیت سرور چه اصولی دارد؟ و بررسی لاگ‌های سرور و برای سایت‌های وردپرسی، راهنمای امنیت وردپرس برای مبتدیان و بهترین افزونه‌های امنیتی وردپرس را پیشنهاد می‌کنم. قاعدهٔ پایانی: امنیت سرور، یک حالت نیست؛ یک فرآیند مداوم است که هر هفته یک بازبینی کوچک می‌طلبد، نه یک پروژهٔ یک‌بار که بعد از آن خیال راحت شود.

اگر در پروژه‌ای یک اقدام امنیتی در سطح سرور را اجرا کرده‌اید که در یک حادثهٔ واقعی نجاتتان داد — مثل بستن یک پورت یا فعال‌سازی یک تنظیم — سناریو را در دیدگاه بنویسید. همین جزئیات، برای دیگران از هر راهنمای عمومی ارزشمندتر است. 🛡️