Що означає ця помилка nginx "цикл перезапису чи внутрішнього перенаправлення"?


67
tail -f /var/log/nginx/error.log
2013/05/04 23:43:35 [error] 733#0: *3662 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 127.0.0.1, server: _, request: "GET /robots.txt HTTP/1.1", host: "kowol.mysite.net"
HTTP/1.1", host: "www.joesfitness.net"
2013/05/05 00:49:14 [error] 733#0: *3783 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 127.0.0.1, server: _, request: "GET / http://www.qq.com/ HTTP/1.1", host: "www.qq.com"
2013/05/05 03:12:33 [error] 733#0: *4232 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "joesfitness.net"

Я отримую це з журналу помилок nginx, у мене немає піддомену "kowol", на моєму веб-сайті немає посилань на qq.com або joesfitness.net. Що відбувається?

Редагувати: конфігурація за замовчуванням Nginx:

server {
    listen   8080; ## listen for ipv4; this line is default and implied
    listen   [::]:8080 default ipv6only=on; ## listen for ipv6

    root /usr/share/nginx/www;
    index index.php index.html index.htm;

    # Make site accessible from http://localhost/
    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.html
        try_files $uri $uri/ /index.html;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
    }

    location /doc/ {
        alias /usr/share/doc/;
        autoindex on;
        allow 127.0.0.1;
        deny all;
    }

    # Only for nginx-naxsi : process denied requests
    #location /RequestDenied {
        # For example, return an error code
        #return 418;
    #}

    #error_page 404 /404.html;

    # redirect server error pages to the static page /50x.html
    #
    #error_page 500 502 503 504 /50x.html;
    #location = /50x.html {
    #   root /usr/share/nginx/www;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

        # With php5-cgi alone:
        fastcgi_pass 127.0.0.1:9000;
        #With php5-fpm:
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
    }

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #   deny all;
    #}
}

Відповіді:


78

Це дивно, все гаразд, хоча я маю на те, що проблема полягає в:

        try_files $uri $uri/ /index.html;

Проблема тут полягає в тому, що другий параметр тут $uri/викликає indexспробу кожного з файлів у вашій директиві по черзі. Якщо жоден не знайдений, він переходить до /index.html, що призводить locationдо повторного введення того ж блоку, і оскільки він все ще не існує, ви отримуєте нескінченний цикл.

Я б переписав це як:

        try_files $uri $uri/ =404;

повернути помилку 404, якщо не існує жодного з файлів індексу, визначених вами в indexдирективі.


До речі, ці запити, які ви бачите, є фоновим шумом в Інтернеті . Зокрема, вони є зондами, щоб визначити, чи є ваш веб-сервер відкритим проксі-сервером і чи можна ним зловживати, щоб приховати зловмисне походження користувача, коли він переходить до зловмисної діяльності. Ваш сервер не є відкритим проксі-сервером у цій конфігурації, тому вам не потрібно про це хвилюватися.


Дякую за пояснення. Чи є якийсь спосіб заблокувати / заборонити подібні зонди?
pavs-maha

Насправді, просто нагодуй їх гарними 404, і вони з часом зрозуміють це.
Майкл Хемптон

2
Що смішно - це те, що конфігурація за замовчуванням на ubuntu 13.10 має try_files $uri $uri/ /index.html;та index index.php index.html index.htm;встановлює. що призводить до помилки у питанні. Не так для 12.04 та 14.04, так рідше трапляється на сервері.
leifcr

9

Ви також отримаєте це повідомлення про помилку, якщо index.phpвоно повністю відсутнє.


Так, у моєму випадку я помилився, поставивши шлях до кореневого параметра.
dlopezgonzalez

8

Це дратувало. Це працювало кілька тижнів тому, і це не вдалося мені, коли я спробував сьогодні.

Я вважав, що оновлення nginxпакета Ubuntu викликає каталог за замовчуванням, де Ubuntu зберігав стандартні файли індексів, змінив рядки:

root /usr/share/nginx/www;

Більше не працюватиме, оскільки розміщено файли /usr/share/nginx/html.

Для виправлення можна просто змінити кореневий вказівник на правильний каталог або створити посилання на новий каталог:

cd /usr/share/nginx
sudo ln -s html www

Працює для мене.


2

Я вчора зіткнувся з цією проблемою, тому що я тестував nginx на проксі-сервері, який кешував переспрямування, якого вже не було. Для мене рішенням було $ sudo service squid3 restartпроксі-сервер squid3, через який я підключався.


Зауважте, я поділився цією відповіддю з добрими намірами. Причин цієї помилки є декілька, і потрібно розглянути час кешування проксі.
Ninjaxor

2

Якщо ця помилка була сьогодні, витратьте кілька годин на з'ясування причини. Виявилося, хтось видалив усі файли сайту.


1

Просто додати ще один випадок, коли це станеться. Як і у прийнятій відповіді, в цілому це відбувається, коли створюється послідовність локацій, які пробуються, а потім створюється такий собі внутрішній цикл переспрямування (нескінченний).

Іноді це проявляється з поганою конфігурацією NGINX і навіть з обмежувальним chmod (у деяких конфігураціях блокування). Ось приклад.

Припустимо, у вас index.phpпередній контролер, як у звичайному:

location / {
    try_files $uri $uri/ /index.php?$args;
}
location ~\.php {
   ...
}

Ви в основному обслуговуєте URL-адреси SEO, як /some/thingчерез вашу index.php.

Але, як завжди, є деякі файли PHP, які потрібно експонувати безпосередньо (таким чином, location ~\.phpі ні location = /index.php.

Припустимо також, що для блокування безпеки index.phpбуло chmodдодано до 0400.

У цьому випадку все ще працює добре, доки файл належить "користувачеві PHP-FPM". NGINX не потребує читання файлу, оскільки він просто передає своє ім'я файлу PHP-FPM для виконання та отримує відповідь FastCGI.

Тоді ви хочете опрацювати випадок того, що відбувається, коли хтось відвідує, /non-existent.phpтому що за допомогою цієї досить стандартної конфігурації ви отримаєте No input file specified.для цього випадку.

Щоб вирішити це, деякі люди додають:

if (!-e $request_filename) { rewrite / /index.php last; } ## Catch 404s that try_files miss

Ну, звичайно, ifце зло, як за nginx, але це не про це. Тепер все порушиться з помилкою циклу перенаправлення. Чому?

Оскільки ця послідовність відбувається в циклі:

  • Коли /some/pageзапитується URL, nginx вводить location /, не знаходить справжній файл і перетворює його/index.php
  • Потім він входить до .phpблоку локації та намагається перевірити, чи може він читати index.php. Оскільки він не може , він переписує його на те саме, index.phpпісля чого повертається .phpзнову.

Дякую, Данила Вершинін ! Це допомогло мені: location / {try_files $ uri $ uri / /index.php?$args; }
Брабус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.