رفع خطای Wordfence WAF بعد از انتقال هاست در cPanel و LiteSpeed
بعد از انتقال یک سایت وردپرسی از یک سرور یا هاست به سرور دیگر، ممکن است سایت با خطایی مشابه زیر مواجه شود:
Warning: Unknown: Failed to open stream: No such file or directory in Unknown on line 0
Fatal error: Failed opening required '/home1/USERNAME/public_html/wordfence-waf.php'
(include_path='.:/opt/cpanel/ea-php82/root/usr/share/pear')
in Unknown on line 0
این خطا معمولاً زمانی اتفاق میافتد که سایت روی سرور قبلی در مسیری مانند:
/home1/USERNAME/public_html
قرار داشته، اما روی سرور جدید مسیر Home تغییر کرده و مثلاً به این تبدیل شده باشد:
/home/USERNAME/public_html
Wordfence برای فعالکردن Web Application Firewall یا WAF از تنظیم PHP به نام auto_prepend_file استفاده میکند. اگر بعد از انتقال، مسیر قدیمی در تنظیمات باقی مانده باشد، PHP قبل از اجرای WordPress تلاش میکند فایل Wordfence را از مسیر قبلی باز کند و چون آن مسیر دیگر وجود ندارد، سایت با Fatal Error متوقف میشود.
بررسی مسیر واقعی سایت
ابتدا مسیر فعلی سایت را بررسی کنید:
cd /home/USERNAME/public_html
pwd
خروجی باید مشابه این باشد:
/home/USERNAME/public_html
سپس مطمئن شوید فایل Wordfence وجود دارد:
ls -lah /home/USERNAME/public_html/wordfence-waf.php
اگر فایل موجود باشد، خروجی مشابه زیر خواهید داشت:
-rw-r--r-- 1 USERNAME USERNAME 325 Aug 17 wordfence-waf.php
پیدا کردن مسیر قدیمی Wordfence
مهمترین مرحله، پیدا کردن تمام محلهایی است که مسیر قدیمی در آنها باقی مانده است.
برای مثال اگر مسیر قدیمی این بوده:
/home1/USERNAME/public_html
این دستور را اجرا کنید:
grep -Rns "/home1/USERNAME" /home/USERNAME 2>/dev/null
همچنین فایلهای مهم PHP و Apache را جداگانه بررسی کنید:
grep -nEi \
'home1|auto_prepend_file|wordfence|php_value|php_flag' \
/home/USERNAME/public_html/.htaccess \
/home/USERNAME/public_html/.user.ini \
/home/USERNAME/public_html/php.ini \
2>/dev/null
مشکل اصلی در سرورهای LiteSpeed
در سرورهایی که LiteSpeed یا LSAPI استفاده میکنند، ممکن است .user.ini کاملاً درست باشد اما سایت همچنان مسیر قدیمی را استفاده کند.
برای مثال .user.ini ممکن است صحیح باشد:
auto_prepend_file = '/home/USERNAME/public_html/wordfence-waf.php'
اما داخل .htaccess هنوز این مقدار وجود داشته باشد:
<IfModule LiteSpeed>
php_value auto_prepend_file '/home1/USERNAME/public_html/wordfence-waf.php'
</IfModule>
<IfModule lsapi_module>
php_value auto_prepend_file '/home1/USERNAME/public_html/wordfence-waf.php'
</IfModule>
در این حالت LiteSpeed مقدار .htaccess را اعمال میکند و اصلاح .user.ini به تنهایی مشکل را حل نمیکند.
برای بررسی:
grep -nA20 -B5 -Ei \
'lsapi_module|auto_prepend_file|Wordfence|cPanel-generated php' \
/home/USERNAME/public_html/.htaccess
تهیه Backup از .htaccess
قبل از هرگونه تغییر:
cd /home/USERNAME/public_html
cp -a .htaccess \
.htaccess.bak-$(date +%F-%H%M%S)
با این کار در صورت بروز مشکل میتوان فایل قبلی را Restore کرد.
اصلاح مسیر Wordfence
اگر مسیر قدیمی:
/home1/USERNAME/public_html/wordfence-waf.php
و مسیر جدید:
/home/USERNAME/public_html/wordfence-waf.php
است، دستور زیر را اجرا کنید:
sed -i \
's#/home1/USERNAME/public_html/wordfence-waf.php#/home/USERNAME/public_html/wordfence-waf.php#g' \
/home/USERNAME/public_html/.htaccess
سپس بررسی کنید:
grep -nEi \
'home1|auto_prepend_file|wordfence' \
/home/USERNAME/public_html/.htaccess
نباید دیگر مسیر:
/home1/USERNAME
در تنظیمات فعال Wordfence مشاهده شود.
مقدار صحیح باید مشابه این باشد:
# Wordfence WAF
<IfModule LiteSpeed>
php_value auto_prepend_file '/home/USERNAME/public_html/wordfence-waf.php'
</IfModule>
<IfModule lsapi_module>
php_value auto_prepend_file '/home/USERNAME/public_html/wordfence-waf.php'
</IfModule>
# END Wordfence WAF
بررسی .user.ini
فایل زیر را بررسی کنید:
cat /home/USERNAME/public_html/.user.ini
بخش Wordfence باید مشابه این باشد:
; Wordfence WAF
auto_prepend_file = '/home/USERNAME/public_html/wordfence-waf.php'
; END Wordfence WAF
اگر هنوز مسیر قدیمی وجود دارد، آن را اصلاح کنید:
sed -i \
's#/home1/USERNAME/public_html/wordfence-waf.php#/home/USERNAME/public_html/wordfence-waf.php#g' \
/home/USERNAME/public_html/.user.ini
بررسی نسخه PHP و session.save_path
بعد از انتقال ممکن است سایت از PHP 8.2 استفاده کند ولی تنظیمات قدیمی PHP 7.4 هنوز باقی مانده باشند.
برای مثال:
session.save_path = "/var/cpanel/php/sessions/ea-php74"
در حالی که سایت با PHP 8.2 اجرا میشود.
در این شرایط مقدار صحیح باید این باشد:
session.save_path = "/var/cpanel/php/sessions/ea-php82"
برای پیدا کردن مقادیر قدیمی:
grep -nEi \
'session.save_path|ea-php7|ea-php8' \
/home/USERNAME/public_html/.htaccess \
/home/USERNAME/public_html/.user.ini \
/home/USERNAME/public_html/php.ini
برای تغییر PHP 7.4 به PHP 8.2:
sed -i \
's#/var/cpanel/php/sessions/ea-php74#/var/cpanel/php/sessions/ea-php82#g' \
/home/USERNAME/public_html/.htaccess
sed -i \
's#/var/cpanel/php/sessions/ea-php74#/var/cpanel/php/sessions/ea-php82#g' \
/home/USERNAME/public_html/.user.ini
sed -i \
's#/var/cpanel/php/sessions/ea-php74#/var/cpanel/php/sessions/ea-php82#g' \
/home/USERNAME/public_html/php.ini
اگر سایت از نسخه دیگری مانند PHP 8.1 یا PHP 8.3 استفاده میکند، مقدار باید متناسب با همان نسخه اصلاح شود.
بررسی PHP واقعی سایت
برای اطمینان میتوان یک فایل موقت ایجاد کرد:
cat > /home/USERNAME/public_html/__phpcheck.php <<'PHP'
<?php
header('Content-Type: text/plain');
echo "PHP=" . PHP_VERSION . "\n";
echo "SAPI=" . PHP_SAPI . "\n";
echo "auto_prepend_file=" . ini_get('auto_prepend_file') . "\n";
echo "session.save_path=" . ini_get('session.save_path') . "\n";
PHP
مالک فایل را اصلاح کنید:
chown USERNAME:USERNAME \
/home/USERNAME/public_html/__phpcheck.php
سپس سایت را بررسی کنید:
curl -ksS https://DOMAIN.COM/__phpcheck.php
در صورت نیاز میتوان مستقیماً Origin Server را تست کرد:
curl -ksS \
--resolve DOMAIN.COM:443:SERVER_IP \
https://DOMAIN.COM/__phpcheck.php
خروجی صحیح باید مشابه این باشد:
PHP=8.2.x
SAPI=litespeed
auto_prepend_file=/home/USERNAME/public_html/wordfence-waf.php
session.save_path=/var/cpanel/php/sessions/ea-php82
اگر همچنان مسیر قدیمی نمایش داده شود:
/home1/USERNAME/public_html/wordfence-waf.php
یعنی هنوز یک تنظیم قدیمی در .htaccess، PHP configuration یا LiteSpeed وجود دارد.
Restart کردن PHP مربوط به LiteSpeed
بعد از اصلاح تنظیمات، در LiteSpeed میتوان PHP همان اکانت را Restart کرد:
touch /home/USERNAME/.lsphp_restart.txt
در صورت وجود process مربوط به همان user:
ps -fu USERNAME | grep -E 'lsphp|php'
و در صورت نیاز:
pkill -u USERNAME lsphp
در Request بعدی LiteSpeed یک PHP Worker جدید ایجاد میکند.
در صورت نیاز میتوان LiteSpeed را نیز Restart کرد:
service lsws restart
اما توجه داشته باشید که اگر مسیر اشتباه همچنان در .htaccess وجود داشته باشد، Restart هیچ مشکلی را حل نمیکند؛ PHP Worker جدید دوباره همان تنظیم اشتباه را Load خواهد کرد.
تست نهایی سایت
پس از انجام اصلاحات:
curl -ksSI https://DOMAIN.COM/
یا مستقیم روی Origin:
curl -ksSI \
--resolve DOMAIN.COM:443:SERVER_IP \
https://DOMAIN.COM/
برای سایت سالم باید Response قابل قبول مانند زیر دریافت شود:
HTTP/2 200
همچنین فایل PHP Test باید مقدار صحیح Wordfence را نمایش دهد:
auto_prepend_file=/home/USERNAME/public_html/wordfence-waf.php
پس از اتمام بررسی، حتماً فایل تست را حذف کنید:
rm -f /home/USERNAME/public_html/__phpcheck.php
بررسی کلی مسیرهای قدیمی پس از Migration
برای سایتهایی که از سرور دیگری منتقل شدهاند، بهتر است به صورت کلی تمام مسیرهای قدیمی بررسی شوند.
برای مثال:
grep -Rns "/home1/USERNAME" \
/home/USERNAME/public_html \
--include=".htaccess" \
--include=".user.ini" \
--include="php.ini" \
--include="wp-config.php" \
2>/dev/null
اگر هدف فقط پیدا کردن فایلهایی است که مسیر قدیمی داخل آنها وجود دارد:
grep -RIl "/home1/USERNAME" \
/home/USERNAME/public_html \
2>/dev/null
توجه کنید که error_log، فایلهای AWStats و Logهای قدیمی ممکن است همچنان مسیر قدیمی را نمایش دهند. وجود مسیر قدیمی در Logهای تاریخی به تنهایی مشکل محسوب نمیشود.
آنچه اهمیت دارد، وجود مسیر قدیمی در فایلهای تنظیمات فعال مانند موارد زیر است:
.htaccess
.user.ini
php.ini
wp-config.php
PHP-FPM configuration
LiteSpeed configuration
خطاهای قدیمی را با مشکل فعلی اشتباه نگیرید
ممکن است هنگام grep خطاهایی مربوط به چند ماه یا چند سال قبل مشاهده شوند، مانند:
PHP Fatal error
Use of undefined constant ABSPATH
Use of undefined constant WPINC
یا مسیرهایی مانند:
/home1/USERNAME/...
در فایلهای:
error_log
awstats
analog
razor-agent.log
این موارد ممکن است صرفاً Log تاریخی باشند و ارتباطی با خطای فعلی نداشته باشند.
برای تشخیص مشکل فعلی باید تاریخ و ساعت Log را نیز بررسی کنید.
علت فنی مشکل
Wordfence Extended Protection از PHP directive زیر استفاده میکند:
auto_prepend_file
این directive باعث میشود PHP قبل از اجرای index.php وردپرس، فایل Wordfence WAF را اجرا کند.
برای مثال:
Request
↓
PHP
↓
auto_prepend_file
↓
wordfence-waf.php
↓
WordPress index.php
اگر مسیر auto_prepend_file اشتباه باشد:
/home1/USERNAME/public_html/wordfence-waf.php
اما مسیر واقعی:
/home/USERNAME/public_html/wordfence-waf.php
باشد، PHP حتی به مرحله اجرای WordPress نمیرسد.
به همین دلیل خطا به شکل زیر مشاهده میشود:
Unknown on line 0
و معمولاً تغییر قالب، افزونهها، Database یا WordPress Core هیچ تأثیری در حل این مشکل ندارد.
روش سریع برای رفع چند سایت مشابه
برای هر سایت مراحل زیر را انجام دهید:
cd /home/USERNAME/public_html
Backup:
cp -a .htaccess \
.htaccess.bak-$(date +%F-%H%M%S)
اصلاح Wordfence:
sed -i \
's#/home1/USERNAME/public_html/wordfence-waf.php#/home/USERNAME/public_html/wordfence-waf.php#g' \
.htaccess
اصلاح .user.ini:
sed -i \
's#/home1/USERNAME/public_html/wordfence-waf.php#/home/USERNAME/public_html/wordfence-waf.php#g' \
.user.ini
اصلاح PHP session در صورت تغییر PHP 7.4 به PHP 8.2:
sed -i \
's#/var/cpanel/php/sessions/ea-php74#/var/cpanel/php/sessions/ea-php82#g' \
.htaccess .user.ini php.ini
Restart PHP:
pkill -u USERNAME lsphp 2>/dev/null
touch /home/USERNAME/.lsphp_restart.txt
بررسی:
grep -nEi \
'home1|auto_prepend_file|session.save_path' \
.htaccess .user.ini php.ini
در نهایت نباید هیچ مسیر فعال Wordfence به /home1/USERNAME اشاره کند.
جمعبندی
اگر بعد از انتقال هاست با خطای زیر مواجه شدید:
Fatal error: Failed opening required
'/home1/USERNAME/public_html/wordfence-waf.php'
در اکثر موارد مشکل از خود WordPress یا PHP version نیست.
علت اصلی این است که Wordfence WAF هنوز مسیر Absolute هاست قبلی را در تنظیمات PHP یا .htaccess نگه داشته است.
در سرورهای LiteSpeed مهمترین فایل برای بررسی:
/home/USERNAME/public_html/.htaccess
است.
بهخصوص این بخش:
<IfModule LiteSpeed>
php_value auto_prepend_file '...'
</IfModule>
<IfModule lsapi_module>
php_value auto_prepend_file '...'
</IfModule>
مسیر auto_prepend_file باید دقیقاً مطابق مسیر جدید سایت باشد.
همچنین پس از Migration باید تنظیمات PHP قدیمی مانند:
ea-php74
با نسخه PHP فعلی سایت هماهنگ شوند.
با اصلاح این موارد، Wordfence WAF مجدداً قبل از WordPress Load شده و سایت بدون نیاز به حذف Wordfence یا غیرفعالکردن Firewall قابل استفاده خواهد بود.

ارسال نظر