Apache و Nginx

رفع خطای 403 Forbidden در Apache و cPanel

خطای 403 Forbidden یعنی وب سرور درخواست شما را فهمیده، ولی اجازه نمی دهد آن فایل یا پوشه را ببینید. در اغلب سایت های cPanel علت یکی از این چهار مورد است: پرمیشن یا مالکیت فایل، یک قانون در htaccess، نبودن فایل index یا بسته شدن درخواست توسط ModSecurity و فایروال.

نوشته تیم فنی پیکوهاستبه روزرسانی: ۲۱ مهر ۱۴۰۵۱۰ دقیقه مطالعه

وقتی سایت به جای صفحه اصلی عبارت Forbidden یا You don't have permission to access this resource نشان می دهد، با خطای 403 Forbidden روبرو هستید. سریع ترین راه این است که اول پرمیشن فایل ها را درست کنید (پوشه ها 755 و فایل ها 644) و بعد فایل .htaccess را موقتا تغییر نام بدهید تا ببینید خطا از آن می آید یا نه. اگر هیچ کدام جواب نداد، لاگ خطا دقیقا می گوید Apache چه چیزی را رد کرده است.

خطای 403 چه معنی دارد

کد 403 یعنی وب سرور کار می کند و درخواست را دریافت کرده، ولی به دلیلی اجازه نمی دهد. این با 404 فرق دارد که یعنی فایل پیدا نشده، و با 500 هم فرق دارد که یعنی کد یا کانفیگ خطا داده است. اگر 500 می بینید، رفع خطای 500 در cPanel را بخوانید.

403 دو شکل دارد. در شکل اول فقط یک مسیر خاص بسته است، مثلا یک پوشه یا فایل. در شکل دوم کل سایت برای شما یا برای همه بازدیدکننده ها 403 می دهد. شکل دوم معمولا به .htaccess، پرمیشن پوشه اصلی سایت یا فایروال مربوط است و شکل اول به پرمیشن یا نبودن فایل index.

اول لاگ را بخوانید

حدس زدن وقت می گیرد. در cPanel بخش Metrics و بعد Errors آخرین خطاهای Apache را برای دامنه های حساب شما نشان می دهد. متن همان خطا علت را مشخص می کند. اگر Terminal دارید، همین خطاها در فایل error_log کنار فایل های سایت هم ثبت می شوند. روی هاست هایی که LiteSpeed دارند، قالب صفحه خطا فرق می کند ولی لاگ و علت ها همان اند.

متن در لاگمعنیعلت محتمل
AH01630: client denied by server configurationیک قانون دسترسی درخواست را رد کردهRequire all denied یا Deny from all در htaccess، یا بلاک IP
AH00529: ... pcfg_openfile: unable to check htaccess fileApache نمی تواند مسیر یا فایل htaccess را بخواندپرمیشن پوشه ها یا مالکیت اشتباه
AH01276: Cannot serve directory ... No matching DirectoryIndexپوشه فایل index ندارد و لیست کردن پوشه بسته استنبودن index.php یا index.html
ModSecurity: Access denied with code 403یک قانون ModSecurity درخواست را مشکوک دانستهقانون فایروال وب، معمولا روی فرم یا آدرس با پارامتر

اگر در لاگ هیچ خطایی برای آن آدرس نیست ولی 403 می بینید، درخواست پیش از Apache بسته شده است. فایروال سرور، CDN یا پلاگین امنیتی وردپرس محتمل ترین علت اند و در بخش های بعد آمده اند.

علت اول: پرمیشن و مالکیت فایل ها

شایع ترین علت 403 بعد از آپلود فایل، انتقال سایت یا باز کردن زیپ است. روی هاست cPanel معمولا پوشه ها باید 755 و فایل ها 644 باشند. پوشه ای با 700 یا فایلی با 600 که مالک دیگری دارد، برای وب سرور قابل خواندن نیست. پرمیشن 777 هم مشکل ساز است: سرور هایی که با suEXEC یا PHP-FPM کار می کنند، برای امنیت اسکریپت و پوشه ای را که برای همه قابل نوشتن است اجرا نمی کنند و 403 یا 500 می دهند.

مالکیت هم مهم است. فایل هایی که با کاربر دیگری ساخته یا استخراج شده اند، ممکن است مالک اشتباه داشته باشند. روی هاست اشتراکی خودتان مالک را تغییر نمی دهید، ولی اگر فایل ها را با File Manager یا FTP همان حساب آپلود کرده اید معمولا مالک درست است.

برای اصلاح دسته جمعی، در Terminal cPanel یا با SSH این دو دستور را اجرا کنید. دستورها فقط محتوای public_html را عوض می کنند و خود پوشه public_html را دست نمی زنند، چون cPanel پرمیشن آن را خودش تنظیم می کند:

cd ~/public_html
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;

اگر Terminal ندارید، در File Manager روی پوشه کلیک راست کنید و Change Permissions را بزنید. این روش برای پوشه های پر از فایل کند است و بهتر است فقط برای چند مسیر مشخص استفاده شود.

پیش از تغییر دسته جمعی پرمیشن، از سایت بک آپ بگیرید. بعضی اسکریپت ها فایل هایی دارند که عمدا پرمیشن دیگری دارند، مثلا wp-config.php که 600 یا 640 است. دستور بالا این فایل را هم 644 می کند. پرمیشن آن را پس از اجرا دوباره بررسی کنید. برای راهنمای بک آپ بک آپ و ریستور در cPanel را ببینید.

علت دوم: فایل .htaccess

اگر کل سایت 403 می دهد و پرمیشن ها درست اند، .htaccess را بررسی کنید. این فایل در پوشه سایت قرار دارد و نام آن با نقطه شروع می شود، پس در File Manager باید گزینه Settings را باز کنید و Show Hidden Files را بزنید.

آزمایش سریع این است که فایل را با نام .htaccess-old ذخیره کنید و صفحه را دوباره باز کنید. اگر سایت بالا آمد، مشکل از یکی از خط های آن بوده است. فایل را از نسخه اصلی برگردانید و خط ها را یکی یکی فعال کنید. این ها خط های مشکل ساز رایج اند:

  • Require all denied یا Deny from all که کل پوشه را می بندد. این خط برای پوشه های داخلی مثل wp-content/uploads/ برای جلوگیری از اجرای PHP درست است، ولی در پوشه اصلی سایت 403 می سازد.
  • Order allow,deny و Allow from که در Apache 2.4 فقط با ماژول سازگاری کار می کنند. در نسخه های جدید نگارش درست Require all granted یا Require ip است. اگر سرور این ماژول را نداشته باشد، به جای 403 ممکن است 500 ببینید.
  • قانون بلاک کردن IP یا User-Agent که دامنه یا IP خودتان را هم می گیرد.
  • Hotlink Protection در cPanel که تصویر ها را برای دامنه های دیگر می بندد و اگر فهرست دامنه ها ناقص باشد، سایت خودتان هم تصویر را نمی بیند.

برای قانون های ریدایرکت و HTTPS که اغلب در همین فایل نوشته می شوند، راهنمای ریدایرکت HTTPS و www با htaccess نگارش های درست را نشان می دهد.

اگر فایل .htaccess را حذف کردید و وردپرس دارید، بعد از بالا آمدن سایت از Settings و Permalinks فقط دکمه Save را بزنید تا وردپرس فایل را دوباره بسازد.

علت سوم: نبودن فایل index

اگر آدرس یک پوشه، مثل example.com/files/، را باز می کنید و 403 می بینید، شاید در آن پوشه index.php یا index.html نباشد. Apache در این حالت می خواهد فهرست فایل ها را نشان بدهد، ولی Options -Indexes این کار را ممنوع کرده است. لاگ در این حالت خط AH01276 دارد.

در دو حالت این رفتار درست است. اگر نمی خواهید فهرست فایل ها دیده شود، فقط یک فایل خالی با نام index.html در آن پوشه بسازید. اگر می خواهید فهرست دیده شود، در cPanel در بخش Advanced و Indexes برای آن پوشه حالت Standard را انتخاب کنید یا در htaccess خط زیر را بگذارید:

Options +Indexes

برای سایت اصلی، خود فایل index باید در پوشه ریشه دامنه باشد، نه یک پوشه پایین تر. این اتفاق بعد از استخراج زیپ ای که پوشه ای با نام سایت داخلش بوده است زیاد می افتد و فایل ها یک سطح پایین تر قرار می گیرند. مسیر Document Root هر دامنه را در بخش Domains می بینید.

علت چهارم: ModSecurity و فایروال

ModSecurity یک فایروال برنامه وب است که روی خیلی از هاست ها فعال است. اگر فرم، آپلود یا آدرسی با پارامتر طولانی 403 می دهد و لاگ عبارت ModSecurity: Access denied with code 403 دارد، یکی از قانون های آن فعال شده است. در لاگ، فیلد id شناسه قانون را نشان می دهد.

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

علت پنجم: بلاک شدن IP

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

  1. در cPanel بخش Security و IP Blocker را باز کنید و ببینید IP یا بازه ای که شامل IP شماست در فهرست هست یا نه. IP خودتان را از سایت های نمایش IP بگیرید.
  2. بعد از چند بار رمز اشتباه در cPanel یا ایمیل، فایروال سرور (مثل CSF یا cPHulk) ممکن است IP را موقتا ببندد. روی هاست اشتراکی این بخش را فقط ادمین سرور می بیند. IP خود را در تیکت بفرستید.
  3. اگر دامنه پشت Cloudflare یا CDN دیگری است، فایروال آن هم 403 می فرستد. صفحه خطا در این حالت معمولا نام CDN را دارد و در لاگ Apache اثری از آن نیست.

آزمایش ساده این است که با اینترنت موبایل یا IP دیگر سایت را باز کنید. اگر باز شد، مشکل بلاک IP است و نه فایل ها.

چک لیست قدم به قدم

اگر ترتیب را نمی دانید، این را دنبال کنید:

  1. در Errors در cPanel آخرین خطای آن آدرس را بخوانید و با جدول بالا مقایسه کنید.
  2. پوشه ها را 755 و فایل ها را 644 کنید و مالک فایل ها را همان حساب cPanel نگه دارید.
  3. .htaccess را با نام دیگر ذخیره کنید و دوباره آزمایش کنید.
  4. وجود index.php یا index.html را در Document Root بررسی کنید.
  5. اگر درخواست مشخصی بسته می شود، لاگ را برای ModSecurity ببینید.
  6. با IP دیگری سایت را باز کنید تا بلاک IP را رد یا تایید کنید.
  7. در وردپرس پوشه wp-content/plugins را موقتا به plugins-old تغییر نام بدهید تا پلاگین های امنیتی غیرفعال شوند. بعد از بازگشت سایت، پلاگین ها را یکی یکی فعال کنید.

اگر سایت را تازه منتقل کرده اید

بعد از انتقال سایت از هاست قبلی، 403 معمولا از مالکیت و پرمیشن یا از یک قانون ریدایرکت در .htaccess می آید که به دامنه یا مسیر هاست قدیمی اشاره می کند. خط هایی که مسیر مطلق مثل /home/olduser/ دارند، روی هاست جدید معتبر نیستند. نکته های بیشتر در راهنمای انتقال سایت وردپرس آمده است.

اگر سایت بعد از انتقال خطای دیگری هم می دهد، پر بودن فضا یا inode حساب را با رفع پر شدن فضا و inode در cPanel بررسی کنید. وب سرور را هم می توانید با مقایسه LiteSpeed و Apache برای وردپرس مقایسه کنید، چون رفتار htaccess روی هر کدام کمی فرق دارد.

چطور مطمئن شویم حل شده

بعد از اصلاح، کش مرورگر را دور بزنید و صفحه را در یک پنجره ناشناس باز کنید. از Terminal یا سیستم خودتان کد پاسخ را ببینید:

curl -I https://example.com/

خط اول خروجی باید HTTP/2 200 یا HTTP/1.1 200 OK باشد. اگر 301 یا 302 می بینید، ریدایرکت فعال است و باید آدرس نهایی را هم با curl امتحان کنید. بعد از آن چند دقیقه خطاهای جدید در Errors را زیر نظر بگیرید تا مطمئن شوید خط تازه ای اضافه نمی شود.

اگر لاگ هیچ دلیلی نشان نمی دهد و همه موارد بالا را امتحان کرده اید، متن دقیق خطا، آدرس، ساعت و IP خودتان را در تیکت پشتیبانی هاست بفرستید. لاگ سطح سرور را فقط ادمین سرور می بیند و با آن علت را سریع پیدا می کند. اگر هاست شما cPanel دارد، هاست لینوکس ایران پیکوهاست پشتیبانی تیکتی هم دارد. برای دستورهای Apache، مستندات رسمی در httpd.apache.org و برای پنل در docs.cpanel.net قرار دارد.