در یکی از پروژه‌های پشتیبانی، سایتی که روزی سه بازدید داشت، در Search Console با هشدار عجیبی مواجه شد: «تلاش‌های مشکوک به ورود». لاگ سرور را باز کردیم و دیدیم یک IP در سه ساعت، ۱۲٬۰۰۰ تلاش برای ورود به wp-login.php کرده. سایت نه هک شده بود و نه کند، ولی حجم حمله به قدری بود که مصرف CPU هاست را بالا برده بود. آن پرونده یادآوری شد که حمله brute force در وردپرس، همیشه به هک موفق منجر نمی‌شود، ولی هزینه‌های پنهان زیادی دارد. در این راهنما، همان چارچوب دفاعی چهارلایه‌ای را می‌گویم که در همه پروژه‌ها استفاده می‌کنم.

اگر با مفاهیم پایه امنیت وردپرس آشنا نیستید، ابتدا راهنمای امنیت وردپرس برای مبتدیان را بخوانید. برای درک کلی چارچوب دفاعی، بهترین افزونه‌های امنیتی وردپرس پیش‌نیاز خوبی است.

حمله brute force دقیقاً چیست؟

حمله brute force یا «حدس زورآمیز»، روشی است که در آن مهاجم با تلاش‌های پیاپی، رمز عبور را حدس می‌زند. سه نوع اصلی:

  1. حمله ساده (Simple Brute Force): امتحان کردن ترکیب‌های رایج مثل admin/admin، password/123456.
  2. حمله دیکشنری (Dictionary Attack): استفاده از فهرست کلمات پرکاربرد.
  3. حمله اعتبارنامه‌ای (Credential Stuffing): استفاده از رمزهای لو رفته از سایت‌های دیگر.

دلیل اصلی که وردپرس هدف این حمله است، معماری wp-login.php است. یک نقطه پایانی مشخص که به‌طور پیش‌فرض به همه پاسخ می‌دهد. اگر سایت نام کاربری‌های قابل‌حدس (مثل admin) داشته باشد، حمله سریع‌تر موفق می‌شود.

حمله brute force، فرض نمی‌کند که شما رمز ضعیف دارید؛ فرض می‌کند که شما اجازه می‌دهید هزاران تلاش انجام شود.

سه شکل اصلی این حمله

در لاگ‌های سرور، این سه الگو را زیاد دیده‌ام:

شکل اول: حمله تک‌منبع

یک IP، تلاش‌های سریع پیاپی. ساده‌ترین شکل و قابل‌مسدودسازی با محدودسازی نرخ.

# الگوی حمله تک‌منبع در access.log
1.2.3.4 - - [15/Sep/2026:10:00:01] "POST /wp-login.php HTTP/1.1" 200
1.2.3.4 - - [15/Sep/2026:10:00:02] "POST /wp-login.php HTTP/1.1" 200
1.2.3.4 - - [15/Sep/2026:10:00:03] "POST /wp-login.php HTTP/1.1" 200
...

شکل دوم: حمله توزیع‌شده (Distributed Brute Force)

چندین IP، هرکدام تعداد کم تلاش. این شکل، از محدودسازی تک‌IP عبور می‌کند و نیازمند تحلیل در سطح شبکه است. مقایسه تفصیلی در حمله DDoS و راه دفاع.

شکل سوم: حمله XML-RPC

استفاده از قابلیت xmlrpc.php برای ارسال چندین نام کاربری و رمز در یک درخواست. این روش، تعداد درخواست‌های HTTP را کاهش می‌دهد ولی سرعت حمله را بالا می‌برد. راهنمای مسدودسازی:

# در .htaccess
<Files xmlrpc.php>
    Order Deny,Allow
    Deny from all
</Files>

اگر به دلایلی به XML-RPC نیاز دارید (مثلاً اپلیکیشن موبایل وردپرس)، به‌جای مسدودسازی کامل، از فیلتر بر اساس IP استفاده کنید.

نشانه‌های حمله در حال اجرا

پیش از هر اقدامی، باید بدانید که سایت شما هدف این حمله هست یا نه. پنج نشانه:

  1. کندی ناگهانی سایت در ساعات خاص: معمولاً وقتی حمله در جریان است.
  2. مصرف CPU بالا در پنل هاست: حمله، منابع سرور را می‌خورد. راهنمای تحلیل در رفع مصرف بالای CPU.
  3. ایمیل‌های هشدار ورود ناموفق: اگر از افزونه‌ای استفاده می‌کنید که هشدار می‌دهد.
  4. ریست شدن رمز کاربران: یکی از نشانه‌های حمله موفق که به ریست رمز منجر می‌شود.
  5. لاگ‌های بزرگ در کوتاه‌مدت: در access.log، تعداد بالای درخواست به wp-login.php.
# بررسی حمله با ابزارهای خط فرمان
grep "wp-login.php" /var/log/apache2/access.log | \
    awk '{print $1}' | sort | uniq -c | sort -rn | head -20

خروجی این دستور، IPهایی که بیشترین درخواست به wp-login.php را داشته‌اند نشان می‌دهد. IPهایی با تعداد بالا (بیش از ۱۰۰ در ساعت)، مشکوک‌اند.

لایه اول: محدودسازی تلاش ورود

اولین لایه دفاع، محدودسازی تعداد تلاش‌های ناموفق ورود است. سه روش:

روش اول: با افزونه امنیتی

افزونه‌های امنیتی مثل Wordfence، Solid Security و Limit Login Attempts Reloaded این قابلیت را دارند. مقایسه تفصیلی در افزونه‌های امنیت ورود.

پیکربندی توصیه‌شده:

حداکثر تلاش قبل از قفل: 5
زمان قفل: 30 دقیقه
زمان ریست شمارنده: 24 ساعت
نوع قفل: بر اساس IP + نام کاربری

روش دوم: کد سفارشی در چایلد تم

اگر به‌دلایلی نمی‌خواهید افزونه نصب کنید، این کد در functions.php چایلد تم کار می‌کند:

add_action( 'wp_login_failed', function( $username ) {
    $ip       = $_SERVER['REMOTE_ADDR'];
    $key      = 'login_fail_' . md5( $ip );
    $attempts = (int) get_transient( $key );

    if ( $attempts >= 5 ) {
        wp_die( 'حساب موقتاً قفل شده است. لطفاً بعداً تلاش کنید.' );
    }

    set_transient( $key, $attempts + 1, HOUR_IN_SECONDS * 6 );
} );

روش سوم: محدودسازی سروری

در سطح سرور (Nginx یا Apache)، می‌توان محدودیت سخت‌گیرانه‌تری اعمال کرد:

# در Nginx
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

location = /wp-login.php {
    limit_req zone=login burst=3 nodelay;
    # ...بقیه تنظیمات
}

این تنظیم، بیش از ۵ درخواست در دقیقه از هر IP را مسدود می‌کند. قوی‌ترین لایه دفاعی است ولی نیاز به دسترسی سرور دارد.

لایه دوم: تأخیر و تأخیر تصاعدی

لایه دوم، تأخیر عمدی در پاسخ به تلاش‌های ناموفق. چرا؟ چون حمله brute force در سرعت است. اگر هر تلاش، دو ثانیه کند شود، تعداد تلاش‌ها به‌طور چشمگیر کاهش می‌یابد.

پیاده‌سازی تأخیر تصاعدی

تأخیر تصاعدی یعنی: بعد از اولین تلاش ناموفق، صفر ثانیه؛ بعد از دوم، یک ثانیه؛ بعد از سوم، دو ثانیه؛ بعد از چهارم، چهار ثانیه و... این روش، حمله را غیراقتصادی می‌کند.

add_action( 'wp_login_failed', function( $username ) {
    $ip       = $_SERVER['REMOTE_ADDR'];
    $key      = 'login_delay_' . md5( $ip );
    $attempts = (int) get_transient( $key );

    if ( $attempts > 0 ) {
        $delay = min( pow( 2, $attempts - 1 ), 30 );
        sleep( $delay );
    }

    set_transient( $key, $attempts + 1, HOUR_IN_SECONDS );
} );

نکته مهم: تابع sleep در PHP، منبع سرور را اشغال می‌کند. در سایت‌های پربازدید، استفاده از این روش باید با احتیاط و با سقف حداکثری (مثلاً ۳۰ ثانیه) باشد.

لایه سوم: احراز هویت دوعاملی (2FA)

2FA (Two-Factor Authentication — احراز هویت دوعاملی)، قوی‌ترین لایه دفاعی است. حتی اگر مهاجم رمز عبور شما را حدس بزند، بدون کد دوم نمی‌تواند وارد شود.

روش‌های پیاده‌سازی 2FA

  1. اپلیکیشن‌های Authenticator: Google Authenticator، Authy، Microsoft Authenticator.
  2. SMS: کد از طریق پیامک. کمتر امن، ولی در ایران راحت‌تر.
  3. سخت‌افزار امنیتی: YubiKey و مشابه. امن‌ترین، ولی گران.
  4. ایمیل: کد از طریق ایمیل. کم‌امن‌ترین، ولی از هیچ بهتر است.

پیکربندی 2FA در وردپرس

سه افزونه معتبر برای 2FA:

  • Wordfence Login Security: رایگان، سبک.
  • Solid Security: شامل 2FA و ویژگی‌های سخت‌سازی.
  • WP 2FA: مخصوص 2FA، ساده.

راهنمای تفصیلی در فعال‌سازی 2FA برای کاربران وردپرس و چگونه 2FA امنیت را بالا می‌برد.

نکته عملی که در پروژه‌ها رعایت می‌کنم: پیش از فعال‌سازی 2FA برای همه کاربران، روش بازیابی (recovery code) را به همه آموزش بدهید. وگرنه صبح دوشنبه، هیچ‌کس نمی‌تواند وارد پیشخوان شود.

2FA تنها لایه‌ای است که به‌تنهایی می‌تواند حمله brute force را ناکام بگذارد، حتی اگر رمز عبور در دست مهاجم باشد.

لایه چهارم: فایروال و محدودسازی IP

لایه چهارم، فیلترینگ در سطح شبکه است. سه رویکرد:

رویکرد اول: فایروال ابری

فایروال ابری (مثل Cloudflare)، ترافیک را پیش از رسیدن به سرور فیلتر می‌کند. مزیت اصلی: بار فیلترینگ از سرور شما برداشته می‌شود. در پروژه‌های پربازدید، این رویکرد را ترجیح می‌دهم. مقایسه تفصیلی در فایروال ابری در برابر سنتی.

رویکرد دوم: فایروال سروری

فایروال روی خود سرور (UFW، iptables، CSF). کنترل کامل، ولی مصرف منابع سرور. راهنمای تفصیلی در فایروال نرم‌افزاری در سرور.

رویکرد سوم: IP allowlist

اگر تیم شما کوچک است و IP ثابت دارد، محدود کردن wp-login.php به همان IPها، مؤثرترین راه است:

<Files wp-login.php>
    Order Deny,Allow
    Deny from all
    Allow from 1.2.3.4
    Allow from 5.6.7.8
</Files>

عیب این روش: اعضای تیم که از اینترنت خانگی وصل می‌شوند، IP متغیر دارند و باید مدام به‌روزرسانی شود. برای تیم‌های کوچک با IP ثابت اداری، بهترین گزینه است.

تغییر مسیر ورود: راه‌حل امن یا فریبنده؟

تغییر مسیر wp-login.php به یک مسیر ناشناس، یکی از رایج‌ترین توصیه‌ها در مقالات امنیتی است. تجربه من می‌گوید این راه‌حل، هم مزیت دارد و هم معایب:

مزایا

  • ربات‌های ساده که به wp-login.php حمله می‌کنند، مسدود می‌شوند.
  • حجم درخواست‌های حمله کاهش می‌یابد.

معایب

  • امنیت از طریق تاریکی: مهاجم حرفه‌ای می‌تواند مسیر جدید را کشف کند.
  • برخی از افزونه‌ها با تغییر مسیر سازگار نیستند.
  • اپلیکیشن‌های موبایل وردپرس کار نمی‌کنند.
  • ممکن است در به‌روزرسانی‌های وردپرس به مشکل بخورد.

توصیه من: اگر می‌خواهید مسیر ورود را تغییر دهید، از افزونه‌های معتبر استفاده کنید و مطمئن شوید با 2FA و سایر لایه‌های دفاعی ترکیب شده. تغییر مسیر را به‌تنهایی، راه‌حل امنیتی نمی‌بینم.

رمز عبور قوی و مدیریت رمز

پایه‌ای‌ترین لایه دفاعی: رمز عبور قوی. سه قاعده که در همه پروژه‌ها رعایت می‌کنم:

  1. حداقل ۱۶ کاراکتر: ترکیب حروف بزرگ، کوچک، اعداد و نمادها.
  2. رمز یکتا برای هر سایت: هرگز از یک رمز در چند سایت استفاده نکنید.
  3. مدیریت رمز با ابزار: Bitwarden، 1Password، یا KeePass.

یک نکته مهم که در پروژه‌ها زیاد می‌بینم: کارمندی که از شرکت خارج می‌شود، رمز عبورهای مشترک را با خودش می‌برد. این ریسک را با دو کار کاهش دهید:

  • هر کاربر، حساب جداگانه داشته باشد. حساب مشترک، ممنوع.
  • پس از خروج هر کارمند، رمزهای مشترک (اگر وجود دارند) را تغییر دهید.

پایش و لاگ‌گیری

پایش، لایه ششم دفاع است. سه ابزار پایش:

ابزار اول: افزونه لاگ فعالیت

افزونه‌هایی مثل WP Activity Log، تمام فعالیت‌های کاربران را ثبت می‌کنند. ورودهای ناموفق، تغییرات در تنظیمات، نصب افزونه و... .

ابزار دوم: پایش لاگ سرور

ابزارهای تحلیل لاگ (مثل GoAccess یا Awstats)، الگوهای حمله را نشان می‌دهند. مسیر تفصیلی در بررسی لاگ حملات سایت.

ابزار سوم: هشدار خودکار

افزونه‌های امنیتی می‌توانند در صورت ورود از IP ناشناس یا تعداد بالای تلاش ناموفق، به شما ایمیل هشدار بفرستند. پیکربندی هشدار در پست امن‌سازی دیتابیس وردپرس.

اشتباهات رایج در مقابله

  1. تکیه بر یک لایه: فقط محدودسازی بدون 2FA، در برابر حمله توزیع‌شده شکست می‌خورد.
  2. مسدودسازی IP بدون تحلیل: مسدود کردن IPهای ایران، خودتان را هم مسدود می‌کند.
  3. تغییر مسیر ورود به‌تنهایی: به‌تنهایی امنیت نمی‌آورد.
  4. نادیده گرفتن XML-RPC: نقطه ضعف کلاسیک که اکثر افراد فراموش می‌کنند.
  5. خاموش کردن لاگ‌ها: بدون لاگ، تشخیص حمله و تحلیل آن ممکن نیست.
  6. استفاده از رمز مشترک: یکی از دلایل اصلی هک موفق.
  7. بی‌توجهی به ایمیل هشدار: بعضی افراد ایمیل هشدار را در پوشه spam دارند.
  8. نادیده گرفتن کاربران غیرفعال: کاربرانی که دیگر استفاده نمی‌شوند، باید حذف شوند.

خط پایان

مقابله با حمله brute force در وردپرس، یک استراتژی چندلایه است: محدودسازی، تأخیر، 2FA، فایروال و پایش. هر لایه، یک نوع حمله را سد می‌کند و ترکیب آن‌ها، دفاعی جامع می‌سازد. توصیه عملی من: از همان روز اول، چهار لایه را فعال کنید. هزینه راه‌اندازی چند ساعت است، ولی از دست دادن یک فروشگاه یا سایت با ترافیک بالا، به‌مراتب پرهزینه‌تر است.

سه تجربه شخصی از پرونده‌های مختلف: اول، در ۹۰٪ پرونده‌های هک موفق، ورود از brute force موفق به‌خاطر نبود 2FA بوده. دوم، تغییر مسیر ورود به‌تنهایی، امنیت نمی‌آورد. سوم، پایش روزانه، حمله را زودتر از هر ابزار خودکار آشکار می‌کند.

اگر در پروژه خود با شکل خاصی از این حمله روبرو شده‌اید که در این چارچوب نمی‌گنجد، در دیدگاه‌ها بنویسید. تجربه‌های واقعی هر پرونده، این راهنما را دقیق‌تر می‌کند. 🔒