SSL و امنیت

رفع خطای ERR_TOO_MANY_REDIRECTS بعد از نصب SSL و فعال کردن Cloudflare

خطای ERR_TOO_MANY_REDIRECTS یعنی مرورگر بین چند آدرس در رفت و برگشت افتاده و هیچ وقت به صفحه نمی رسد. بعد از نصب SSL معمولا دو قانون ریدایرکت با هم کار می کنند، و رایج ترین علت حالت Flexible در Cloudflare همراه با ریدایرکت HTTPS روی هاست است.

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

خطای ERR_TOO_MANY_REDIRECTS در کروم و مرورگرهای مشابه با عنوان «This page isn't working» و جمله «redirected you too many times» نمایش داده می شود. فایرفاکس همان را به شکل «The page isn't redirecting properly» نشان می دهد. معنی اش این است که آدرس A شما را به B می فرستد و B دوباره به A برمی گرداند. اگر این خطا درست بعد از فعال کردن Cloudflare آمد، اول حالت SSL/TLS را از Flexible به Full یا Full (strict) ببرید. اگر بدون Cloudflare بعد از نصب SSL آمد، قانون ریدایرکت در .htaccess را با آدرس سایت در وردپرس مقایسه کنید.

اول تکرار شدن ریدایرکت را ببینید

پیش از تغییر هر چیز، با curl زنجیره ریدایرکت را بخوانید. curl کوکی و کش مرورگر ندارد، پس نتیجه اش دقیق تر است:

curl -sIL --max-redirs 6 http://example.com/ | grep -iE "^(HTTP|location)"

خروجی یک حلقه معمولا شبیه این است:

HTTP/1.1 301 Moved Permanently
Location: https://example.com/
HTTP/2 301
Location: http://example.com/

یعنی نیمه اول به https می رود و نیمه دوم دوباره به http برمی گردد. با خواندن همین Locationها می فهمید کدام قانون آدرس را عوض می کند. اگر خروجی ریدایرکت اصلا نشان نداد و فقط مرورگر خطا می دهد، کوکی یا کش مرورگر مقصر است. پنجره ناشناس باز کنید یا کوکی های همان دامنه را پاک کنید.

علت ها به ترتیب شیوع

Cloudflare روی Flexible است و هاست هم به HTTPS ریدایرکت می کند

در حالت Flexible، بازدیدکننده با HTTPS به Cloudflare وصل می شود ولی Cloudflare با HTTP ساده به سرور شما می رسد. سرور (یا افزونه SSL وردپرس) می بیند درخواست HTTP است و آن را به HTTPS ریدایرکت می کند. Cloudflare دوباره با HTTP می رود و حلقه شروع می شود.

راه حل درست این است که گواهی روی هاست نصب باشد و Cloudflare با HTTPS به آن وصل شود:

  1. در cPanel بخش SSL/TLS Status مطمئن شوید دامنه گواهی معتبر دارد. اگر ندارد، رفع صادر نشدن AutoSSL را بخوانید.
  2. در داشبورد Cloudflare به SSL/TLS، بخش Overview بروید.
  3. حالت را روی Full (strict) بگذارید. این حالت گواهی معتبر روی هاست می خواهد. اگر گواهی هاست self-signed است، Full کار می کند ولی گواهی را اعتبارسنجی نمی کند.
  4. چند دقیقه صبر کنید و صفحه را در پنجره ناشناس باز کنید.

اگر نمی توانید گواهی روی هاست بگیرید و باید روی Flexible بمانید، ریدایرکت HTTPS را از سمت هاست بردارید و آن را فقط در Cloudflare، با گزینه Always Use HTTPS در Edge Certificates، انجام دهید. این وضعیت فقط موقت است، چون ترافیک بین Cloudflare و سرور رمزنگاری نمی شود.

قانون ریدایرکت در htaccess پشت پروکسی HTTPS را نمی بیند

وقتی ترافیک از Cloudflare یا هر reverse proxy دیگری می آید، سرور اتصال را HTTP می بیند، حتی وقتی کاربر HTTPS آمده است. قانون معمول %{HTTPS} off در این حالت همیشه درست است و ریدایرکت بی پایان می شود. اگر هاست پشت پروکسی است و Full نمی خواهید یا نمی توانید، قانون را با هدر X-Forwarded-Proto هم چک کنید:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [L,R=301]

قبل از تغییر .htaccess از آن یک نسخه پشتیبان بردارید، چون یک غلطی در این فایل کل سایت را با خطای 500 از کار می اندازد. در cPanel نسخه پشتیبان فایل را با File Manager و گزینه Copy بگیرید. اگر بعد از ویرایش خطای 500 دیدید، رفع خطای 500 در cPanel را ببینید.

آدرس وردپرس هنوز http است یا با قانون www فرق دارد

در وردپرس دو مقدار WordPress Address و Site Address مشخص می کنند آدرس اصلی چیست. اگر این دو http یا بدون www باشند ولی .htaccess یا Cloudflare به https و www ریدایرکت کنند، وردپرس دوباره خود را به آدرس تنظیم شده برمی گرداند و حلقه ایجاد می شود. هر دو مقدار را در Settings، General درست کنید. اگر وارد پیشخوان نمی شوید، دو خط زیر را بالای عبارت That's all, stop editing! در wp-config.php بگذارید:

define('WP_HOME', 'https://example.com');
define('WP_SITEURL', 'https://example.com');

این دو خط مقدار دیتابیس را نادیده می گیرند. بعد از ورود، مقدار را در General اصلاح کنید و خطوط را بردارید. اگر WP-CLI دارید، دستور wp option update siteurl 'https://example.com' و wp option update home 'https://example.com' هم همین کار را می کند.

وردپرس پشت پروکسی HTTPS را تشخیص نمی دهد

حتی وقتی Cloudflare روی Full است، بعضی تنظیمات وردپرس یا قالب ها با دیدن اتصال HTTP به https ریدایرکت می کنند. اگر با Full هم حلقه دارید، این چند خط را قبل از require_once ABSPATH . 'wp-settings.php'; در wp-config.php اضافه کنید:

if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

دو قانون ریدایرکت با هم کار می کنند

وقتی چند جا ریدایرکت HTTPS فعال است، هر کدام آدرس را به شکل دیگری عوض می کنند. جاهایی که باید بگردید:

  • بخش Domains در cPanel، گزینه Force HTTPS Redirect.
  • قانون در .htaccess هاست، و قانون های ریدایرکت دیگری که افزونه ها اضافه می کنند.
  • افزونه های SSL وردپرس مثل Really Simple SSL یا افزونه سئو که ریدایرکت دارند.
  • در Cloudflare: Always Use HTTPS، Redirect Rules و Page Rules قدیمی.
  • تنظیم www و بدون www هم می تواند در یکی از جاهای بالا جدا از بقیه باشد.

اصل ساده این است: یک جا ریدایرکت HTTPS را انجام دهید و بقیه را خاموش کنید. بعد از هر تغییر کش Cloudflare و افزونه کش وردپرس را پاک کنید، چون ریدایرکت 301 در مرورگر هم کش می شود.

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

سرورهای VPS با Nginx

اگر خودتان Nginx را به عنوان reverse proxy جلوی Apache یا PHP-FPM گذاشته اید و برنامه ریدایرکت می کند، باید پروتکل اصلی به backend برسد:

proxy_set_header X-Forwarded-Proto $scheme;

بعد از تغییر پیکربندی، قبل از reload دستور nginx -t را اجرا کنید و از فایل پیکربندی نسخه پشتیبان داشته باشید.

جدول عیب یابی سریع

نشانهعلت محتملراه حل
بعد از فعال کردن Cloudflare شروع شدحالت Flexible با ریدایرکت هاستFull (strict)
بدون Cloudflare و بعد از نصب افزونه SSLتعارض قانون htaccess و افزونهیک ریدایرکت را نگه دارید
حلقه بین www و بدون wwwآدرس وردپرس با قانون htaccess فرق داردآدرس و قانون را یکی کنید
فقط در یک مرورگرکش یا کوکیپنجره ناشناس
فقط روی صفحه ورود wp-adminآدرس سایت یا FORCE_SSL_ADMINتنظیم siteurl و home

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

دستور curl اول مقاله را دوباره بزنید. باید حداکثر یک ریدایرکت از http به https (و اگر قانون www دارید، یکی هم برای www) و بعد پاسخ 200 ببینید. در مرورگر هر چهار شکل آدرس را باز کنید: http با www، http بدون www، https با www و https بدون www. هر چهار باید به یک آدرس نهایی برسند.

اگر بعد از رفع حلقه هنوز قفل ناقص می بینید، منبع های http داخل صفحه علت اند. رفع Mixed Content در وردپرس را بخوانید. اگر مرورگر به جای حلقه، خطای گواهی می دهد، خطای your connection is not private را ببینید. برای نوشتن درست قانون ریدایرکت HTTPS و www در Apache هم راهنمای htaccess را بخوانید.

برای تنظیم حالت های SSL در Cloudflare می توانید مستندات Cloudflare درباره حالت های رمزنگاری را ببینید. هاست وردپرس پیکوهاست SSL رایگان دارد و AutoSSL آن روی cPanel فعال است.