تاحالا اون لحظهی ترسناک رو تجربه کردی که یههو حس کنی سایت وردپرست در معرض حملهست؟ لاگین مشکوک، ترافیک عجیب، یا پیامی از هاستینگ که «منابع غیرمعمول مصرف میکنی»؟ نفس عمیق بکش! قرار نیست با یک کوه از افزونهها خودتو دفن کنی. توی این راهنمای پروژهمحور، میخوایم هاردنینگ وردپرس رو بدون هیچ افزونهای انجام بدیم؛ با تکیه بر تنظیمات هسته، وبسرور و چندتا ترفند تمیز که بار امنیتی سایت رو حسابی بالا میبره.
قانون طلایی ما: هر تغییری میدی، اول بکاپ بگیر، بعد روی استیجینگ تست کن و در نهایت روی سایت اصلی اعمالش کن. امنیت یعنی نظم + استمرار، نه حرکتهای نمایشی.
نقشه راه ۱۲ گامی (بدون افزونه، ولی با آچارکشی حسابی)
قبل از اینکه بریم سراغ آچارکشی جدی، یک چارچوب ثابت داریم تا هر مرحله هم منطقی باشه هم اجرایی. هر گام سه بخش داره:
- «چرا مهمه؟» دقیقاً توضیح میده این کار جلوِ چه ریسکی رو میگیره و کجای زنجیره امنیتی رو محکم میکنه؛ یعنی اول بفهمیم داریم چه مشکلی رو خنثی میکنیم.
- «چطور انجامش بدم؟» دستورالعمل قدمبهقدم و بدون افزونهست؛ از تغییر فایلهای کلیدی تا نمونه تنظیمات Apache/Nginx و حتی چند خط WP-CLI یا کد لازم—همه چیز آماده اجرا.
- «نکته حرفهای» ریزهکاریها، دامهای احتمالی و جایگزینهای هوشمندانه رو میگه تا خروجیت تمیز، پایدار و سازگار با محیط میزبانیت باشه.
پس الگوی مطالعهت اینه: با «چرا» دید بگیر، با «چطور» اجرا کن، و با «نکته حرفهای» کار رو صیقل بده تا هر تغییر، هم امن باشه هم بیدردسر.
گام ۱: بهروزرسانیهای منظم هسته، پوسته و افزونههای موجود
چرا مهمه؟
بیشتر نفوذها از باگهای شناختهشده اتفاق میافتن. قدیمیبودن یعنی درهای باز.
چطور انجامش بدم؟
- پنل مدیریت → Updates رو مرتب چک کن.
- اگر دسترسی SSH داری، با WP-CLI:
- wp core update
- wp plugin update –all
- wp theme update –all
- اگر خیلی محتاطی، «بهروزرسانی خودکار جزئی» رو فقط برای سطوح امن فعال نگه دار (وردپرس بهصورت پیشفرض آپدیتهای امنیتی کوچک رو میگیره).
نکته حرفهای:
قبل از هر آپدیت، از فایلها و دیتابیس بکاپ کامل بگیر. یک ریکاوری تمیز نصف امنیت راهه.
گام ۲: سفتوسختکردن پسوردها و سیاست رمز (بدون افزونه)
چرا مهمه؟
Brute Force و Password Spraying هنوز محبوبترین حملهها هستن.
چطور انجامش بدم؟
- از پسوردهای طولانی (۱۶ کاراکتر به بالا) با کاراکترهای ترکیبی استفاده کن.
- برای «اجباریکردن» سیاست رمز قوی، یک قطعه کد داخل functions.php قالب فرزند بذار تا هنگام تغییر رمز، قاعده رو enforce کنه:
add_action('user_profile_update_errors', function($errors, $update, $user){
if ( isset($_POST['pass1']) && strlen($_POST['pass1']) < 16 ) {
$errors->add('pass_too_short', '<strong>خطا:</strong> رمز عبور باید حداقل ۱۶ کاراکتر باشد.');
}
}, 10, 3);
مدیرها و نویسندهها رو مجبور کن از Password Manager استفاده کنن.
نکته حرفهای:
از «Application Passwords» فقط در صورت نیازهای API و با دامنه دسترسی محدود استفاده کن و هر چیزی که لازم نداری رو Revoke کن.
گام ۳: قفلِ ورودی مدیریت با IP یا احراز هویت دومرحلهایِ وبسرور
چرا مهمه؟
بروتفورس روی wp-login.php و wp-admin/ بیرحمانهست.
چطور انجامش بدم؟
- Apache: محدودسازی IP برای wp-login.php و wp-admin/ (در .htaccess یا vhost):
<Files "wp-login.php">
Require ip 203.0.113.10
Require ip 203.0.113.11
</Files>
<Directory "/var/www/example.com/htdocs/wp-admin">
Require ip 203.0.113.10
Require ip 203.0.113.11
</Directory>
اگر IP ثابت نداری، از Basic Auth استفاده کن:
<Files "wp-login.php">
AuthType Basic
AuthName "Restricted"
AuthUserFile /path/to/.htpasswd
Require valid-user
</Files>
- Nginx: allow/deny یا auth_basic روی مسیرهای لاگین/ادمین.
نکته حرفهای:
Basic Auth یک دیوار دوم میسازه. قبل از رسیدن به فرم لاگین وردپرس، مهاجم گیر میکنه.
گام ۴: محکمکاری wp-config.php (جابهجایی، تنظیمات و کلیدهای محرمانه)
چرا مهمه؟
مغز تنظیمات و اطلاعات دیتابیس همینه. باید مثل گاوصندوق باشه.
چطور انجامش بدم؟
- فایل wp-config.php رو یک لِول بالاتر از وبروت منتقل کن.
- سطح دسترسی رو 600 تنظیم کن.
- در wp-config.php:
define('DISALLOW_FILE_EDIT', true); // ویرایشگر تم/افزونه داخل داشبورد غیرفعال
define('FORCE_SSL_ADMIN', true); // لاگین و مدیریت فقط روی HTTPS
کلیدها و Salts را با مقادیر قوی و جدید تنظیم کن (وقتی تغییرشون بدی، سشنهای قدیمی باطل میشن).
نکته حرفهای:
اگر مجبور نیستی، DISALLOW_FILE_MODS رو فعال نکن چون جلوی آپدیتها رو میگیره.
گام ۵: سطح دسترسی فایلها و فولدرها + مالکیت
چرا مهمه؟
دسترسیهای باز یعنی دعوتنامه رسمی برای شِلهای مخرب.
چطور انجامش بدم؟
- فولدرها: 755
- فایلها: 644
- wp-config.php: 600
- مالکیت با کاربر صحیح وبسرور (مثلاً www-data یا apache) طوری که هم امنیت حفظ بشه هم فرایندهای لازم دسترسی داشته باشن.
نکته حرفهای:
روی هاست اشتراکی، از پشتیبانی بخواه سطح دسترسیهای «امن پیشنهادی» رو اعمال کنه.
گام ۶: بستن اجرای PHP در uploads و پوشههای حساس
چرا مهمه؟
اکثر آپلودهای مخرب بهصورت PHP اجرا میشن تا دسترسی شِل بگیرن.
چطور انجامش بدم؟
- داخل wp-content/uploads/ یک .htaccess بساز:
<FilesMatch "\.php$">
Require all denied
</FilesMatch>
(برای Apache 2.2 قدیمی: Deny from all)
- برای wp-includes هم اجرای مستقیم بعضی فایلها رو ببند (با دقت و مطابق نسخه هسته).
نکته حرفهای:
اگر Nginx داری، معادلش رو با locationها انجام بده و اجرای PHP رو برای uploads ممنوع کن.
گام ۷: قطع دسترسیهای بیمصرف — XML-RPC، Directory Listing و غیره
چرا مهمه؟
هر سطح حملهی اضافه یعنی شانس بیشتر برای نفوذ.
چطور انجامش بدم؟
- بستن XML-RPC (اگر واقعاً لازم نداری):
<Files "xmlrpc.php">
Require all denied
</Files>
هشدار: اگر از Jetpack/اپهای موبایل خاص استفاده میکنی، قبلش تست کن.
- بستن Directory Listing:
- Options -Indexes
نکته حرفهای:
هر قابلیتی که استفاده نمیکنی، خاموشش کن. اصل «حداقل سطح دسترسی».
گام ۸: محدودسازی نرخ درخواست (Rate Limiting) برای لاگین
چرا مهمه؟
Brute Force با محدودسازی نرخ درخواست، خیلی بیاثر میشه.
چطور انجامش بدم؟
- Nginx (نمونه ساده):
limit_req_zone $binary_remote_addr zone=logins:10m rate=10r/m;
location = /wp-login.php {
limit_req zone=logins burst=20 nodelay;
include fastcgi_params;
# ... باقی تنظیمات PHP-FPM
}
Apache: با mod_ratelimit یا mod_evasive (در سطح سرور/vhost) الگوهای درخواست به wp-login.php و xmlrpc.php را محدود کن.
نکته حرفهای:
اگر SSH داری، fail2ban برای الگوهای ۴۰۱/۴۰۳ روی لاگین عالیه.
گام ۹: هدرهای امنیتی و HSTS + HTTPS اجباری
چرا مهمه؟
هدرها جلوی کلی سوءاستفاده سمتبروزر رو میگیرن و HTTPS اجباری از «شنود/دستکاری» جلوگیری میکنه.
چطور انجامش بدم؟
- Apache (در .htaccess یا vhost):
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
# HSTS (فقط وقتی ۱۰۰٪ همه زیر دامنهها HTTPS هستند!)
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
ریدایرکت دائمی به HTTPS:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
نکته حرفهای:
برای CSP محتاط باش؛ از حالت گزارشدهی شروع کن تا چیزی رو ناخواسته نشکنی.
گام ۱۰: بهداشت دیتابیس — دسترسی حداقلی و پیشوند جدول
چرا مهمه؟
کاهش سطح دسترسی کاربر دیتابیس و پیشوند غیرقابلحدس، سطح حمله را پایین میآورد.
چطور انجامش بدم؟
- برای وردپرس یک کاربر دیتابیس با حداقل دسترسی لازم بساز.
- اگر تازه نصب میکنی، پیشوند جداول را از wp_ به چیزی تصادفی تغییر بده (مثلاً wpx9a_). تغییر پیشوند روی سایتِ فعال کار حساسیست و نیاز به اسکریپت/آگاهی کامل دارد. اگر انجام میدی، بکاپ یادت نره.
نکته حرفهای:
دسترسی کاربر DB را دورهای بازبینی کن و هر دسترسی اضافه را قطع کن.
گام ۱۱: قفلکردن REST API و جلوگیری از User Enumeration
چرا مهمه؟
نمایش عمومی نویسندهها و بعضی اندپوینتها اطلاعات جذابی برای مهاجم فراهم میکنه.
چطور انجامش بدم؟
- جلوگیری از نمایش لیست نویسندهها از طریق پارامتر ?author=:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^author=\d+ [NC]
RewriteRule ^ - [F]
محدودکردن بعضی مسیرهای REST به کاربران لاگینکرده (کد در functions.php):
add_filter('rest_authentication_errors', function($result){
if ( ! empty($result) ) return $result;
if ( is_user_logged_in() ) return $result;
// مسیرهای عمومی لازم را اینجا «اجازه» بده و بقیه را ببند
return new WP_Error('rest_forbidden', 'دسترسی REST فقط برای کاربران احراز هویتشده است.', array('status' => 401));
});
(با دقت تنظیم کن که ویژگیهای لازم مثل سرچ یا سایدبار شکسته نشن.)
نکته حرفهای:
هر تم/قالب یا اسکریپتی ممکنه به REST نیاز داشته باشه. اول لیست وابستگیها رو مشخص کن، بعد محدود کن.
گام ۱۲: بکاپگیری، مانیتورینگ و لاگها (سیستماتیک و بدون افزونه)
چرا مهمه؟
امنیت بینسخهٔ پشتیبان یعنی سراب. و بدون مانیتورینگ، نفوذ را دیر میفهمی.
چطور انجامش بدم؟
- بکاپ فایلها + دیتابیس با اسکریپت کران:
#!/bin/bash
TS=$(date +%F-%H%M)
BACKUP_DIR=/backups/wp
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/files-$TS.tgz /var/www/example.com/htdocs
mysqldump -u dbuser -p'STRONGPASS' dbname | gzip > $BACKUP_DIR/db-$TS.sql.gz
find $BACKUP_DIR -type f -mtime +14 -delete
مانیتورینگ لاگها: لاگهای access/error وبسرور رو بهصورت دورهای نگاه کن. الگوهای ۴۰۱/۴۰۳/۴۰۴ غیرعادی را جدی بگیر.
- اعلان ایمیلی/سیگنال روی رخدادهای بحرانی وبسرور یا مصرف منابع تنظیم کن (در سطح سرور/هاست).
نکته حرفهای:
بکاپ را فقط نگیر، بازگردانی را هم تمرین کن. ریکاوری واقعی با تست معنا پیدا میکند.
چند ریزهکاری اضافه که ارزشش را دارند
- حذف حسابهای بلااستفاده و کاهش نقشها به حداقل لازم (اصل Least Privilege).
- غیرفعالکردن و سپس حذف افزونه/قالبهای بدون استفاده (فقط غیرفعال کافی نیست؛ فایلها همچنان وجود دارند).
- نشانی لاگین سفارشی از طریق وبسرور: با rewrite میشود مسیر wp-login.php را پشت یک آدرس داخلی نگه داشت؛ اما این کار حساس است و ممکن است با برخی سناریوها تداخل کند—فقط اگر دقیقاً میدانی چه میکنی.
- محیط اجرا: نسخهی PHP پشتیبانیشده، ماژولهای غیرضروری خاموش، و حداقل سرویسهای فعال.
دانلود چکلیست سریع اجرایی امنیت سایت
میخوای همین ۱۲ گام رو بدون حاشیه و دقیق اجرا کنی؟ این چکلیست اجرایی هاردنینگ وردپرس (قابل چاپ) رو بردار و مرحلهبهمرحله جلو برو. طوری طراحی شده که هم تو کار انفرادی جواب بده، هم وقتی میخوای وظایف رو بین اعضای تیم تقسیم کنی.
سوالات واقعی که باید از خودت بپرسی
- اگر امروز دسترسیت به هاست قطع بشه، آخرین بکاپ سالمت چند ساعت/روز قبله؟
- آیا ریکاوری رو تمرین کردی یا فقط «فکر میکنی» بلدی؟
- چند نفر به ادمین دسترسی دارن و کِی آخرین بار نقشها را بازبینی کردی؟
- آیا روی wp-login.php شواهد تلاش ناموفق زیاد داری؟ (لاگها رو ببین!)
جمعبندی: قفلِ مطمئن، خوابِ راحت
دیدی که هاردنینگ وردپرس بدون افزونه کاملاً شدنیه؛ فقط به یک رویکرد منظم، کمی حوصله و چند خط تنظیمات نیاز داری. ما با ۱۲ گام عملی، از درِ ورودی (لاگین) تا اعماق هسته (wp-config، دیتابیس، هدرها و سرور) رو سفتوسخت کردیم. این کار یک «پروژه یکروزه» نیست؛ یک چرخهی مداومه: بررسی → تقویت → مانیتور → تکرار.
اگر میخوای همین مسیر رو هدفمند، سریع و پروژهمحور یاد بگیری و زیرساخت امنیتی سایتت رو ظرف چند جلسه فشرده محکم کنی، پیشنهاد میکنم همین حالا یک قدم حرفهای برداری: در دوره افزایش امنیت وردپرس ثبتنام کن؛ جایی که با چکلیستهای عملی، سناریوهای واقعی و تمرینهای مرحلهبهمرحله، امنیت سایتت رو از «امیدوارم امن باشه» به «خیالم راحته» ارتقا میدیم.
