Рейтинг:0

Varnish иногда (до ~5% запросов) запускает err_too_many_redirects, работающий в докере в сочетании с plesk для wordpress

флаг tf

Мы следовали этим инструкциям https://support.plesk.com/hc/en-us/articles/115001888894-Does-Plesk-support-Varnish- и смогли заставить его работать «правильно», он обслуживает сайт wordpress через лак, и скорость потрясающая. Все хорошо, но наш робот, работающий безотказно, время от времени сообщает о коротких простоях (очень нерегулярно, но от 1 до 8 раз в день в течение <5 минут, в разное время в течение дня).

После нескольких различных тестов мы заметили проблему с URL-адресом wp-admin, мы пришли к выводу, что это происходит из-за нашего DirectoryIndex (по умолчанию это index.html), мы решили это, добавив «DirectoryIndex index.php к нашим «Дополнительным директивам Apache», которые решили эту проблему.

Одна вещь, которая показалась нам интересной, заключается в том, что когда мы меняем способ обслуживания PHP (FPM), это приводит к той же ошибке. Когда мы обслуживаем через NGINX, мы также получаем err_too_many_redirects, если мы обслуживаем его через Apache, он работает в 95% случаев.

Я добавил несколько журналов (varnishncsa) ниже, когда в ответе заголовка указано 301, когда мы находимся в цикле:

172.17.0.1 - - [11/Янв/2022:13:54:55 +0000] "HEAD http://[домен лака]/ HTTP/1.0" 200 0 "https://[домен лака]" " Mozilla/5.0+ (совместимо; UptimeRobot/2.0; http://www.[uptimerobot].com/)"

172.17.0.1 - - [11/янв/2022:13:56:51 +0000] "GET http://[домен лака]/ HTTP/1.0" 200 11184 "-" "-"

172.17.0.1 - - [11/янв/2022:13:58:31 +0000] "HEAD http://[домен лака]/ HTTP/1.0" 301 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/56.0.2924.76 Safari/537.36"

172.17.0.1 - - [11/Янв/2022:13:58:32 +0000] "HEAD http://[домен лака]/ HTTP/1.0" 301 0 "http://[домен лака]" " Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, например Gecko) Chrome/56.0.2924.76 Safari/537.36"

После этого мы делаем следующий лог 8 раз: 172.17.0.1 - - [11/янв/2022:13:58:32 +0000] "HEAD http://[домен лака]/ HTTP/1.0" 301 0 "https://[домен лака]/" «Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, например Gecko) Chrome/56.0.2924.76 Safari/537.36»

Затем один: 172.17.0.1 - - [11/янв/2022:13:58:34 +0000] "GET http://[домен лака]/ HTTP/1.0" 301 238 "-" "Mozilla/5.0 (X11; Linux x86_64) ) AppleWebKit/537.36 (KHTML, как Gecko) HeadlessChrome/96.0.4664.110 Safari/537.36"

Затем 7 раз: 172.17.0.1 - - [11/Янв/2022:13:59:55 +0000] "HEAD http://[домен лака]/ HTTP/1.0" 301 0 "https://[домен лака]" " Mozilla/5.0+ (совместимо; UptimeRobot/2.0; http://www.[uptimerobot].com/)"

Затем 22 раза: 172.17.0.1 - - [11/янв/2022:14:00:17 +0000] "GET http://[домен лака]/ HTTP/1.0" 301 238 "https://[домен лака]" " Mozilla/5.0+ (совместимо; UptimeRobot/2.0; http://www.[uptimerobot].com/)"

Потом сразу после этого вроде все снова нормально.

Обновление: проверка журналов

@thijs-feryn указал на кое-что интересное, что заставило нас сделать вывод, что мы слишком рано отвергли старую теорию. Поскольку мы были уверены, что X-Forwarded-Proto был передан, потому что он был в нашей «дополнительной конфигурации заголовка apache».

Однако, внимательно прочитав его ответ, мы узнали, что каким-то образом X-Forwarded-Proto не передает каждый запрос (по крайней мере, неработающие). Он указал, что [другой домен лака], похоже, отлично передал эту запись в аналогичном запросе.

После некоторого тщательного сравнения конфигураций мы выделили только одну вещь: предпочитаемый домен в plesk для [другого домена лака] был установлен на «Нет», а для [домен лака] был установлен на [домен лака]. домен].

Итак, мы зашли на www.[домен лака] в нашем браузере, и это, похоже, вызвало проблему. Мы также переключили «Предпочитаемый домен» на «Нет», и теперь www.[домен лака] перенаправляет на [домен лака] просто отлично.

гипотеза

Кажется, что собственное перенаправление plesk игнорирует «Дополнительные директивы для HTTP» и таким образом, «Vary: X-Forwarded-Proto» не был добавлен. Мы будем следить за этим и вскоре опубликуем обновление, когда будем полностью уверены, что это было причиной.

Рейтинг:0
флаг in

Проблема может быть связана с недостаточной осведомленностью о протоколе при кэшировании. Довольно типично, что HTTP-запрос, который должен быть перенаправлен на HTTPS-запрос, попадает в кеш, который безоговорочно перенаправляет пользователей на HTTPS-версию, даже если они действительно запрашивали HTTPS-версию.

Существуют различные способы исправить это в зависимости от типа используемого вами веб-сервера.

вывод лаклога

Но прежде чем мы сможем делать поспешные выводы, я хочу увидеть некоторые лаковое бревно вывод.

Я хотел бы увидеть вывод следующей команды, когда происходит цикл перенаправления:

лаклог -g запрос -q "ReqUrl eq '/'"

Предполагается, что проблема также возникает на домашней странице, которую мы добавили в качестве запроса VSL к лаковое бревно команда.

я заметил твой лакнкса вывод, но, к сожалению, он слишком ограничен с точки зрения вывода. лаковое бревно намного лучше для отладки, тогда как лакнкса просто.

Проверка гипотезы

Если петля перенаправления действительно вызвана отсутствием осведомленности о протоколе, мы можем вызвать проблему следующим образом:

  • Бег забанить лакадм obj.status "!=" 0 очистить кеш
  • Вызовите простой URL-адрес HTTP веб-сайта, чтобы убедиться, что эта версия кэширована.
  • Вызовите URL-адрес HTTPS веб-сайта, чтобы проверить, не застряли ли вы в цикле перенаправления.

Устранение проблемы

Если все тесты суммируются и гипотеза доказана, решение на самом деле довольно простое.

Если вы используете Apache в качестве веб-сервера, вы можете добавить следующее содержимое в свой .htaccess файл:

SetEnvIf X-Forwarded-Proto "https" HTTPS=on
Заголовок добавляется: X-Forwarded-Proto

В противном случае вы также можете добавить следующий код в свой файл VCL:

суб vcl_backend_response {
    if(beresp.http.Vary) {
        if(beresp.http.Vary !~ "X-Forwarded-Proto") {
            set beresp.http.Vary = set beresp.http.Vary + ",X-Forwarded-Proto";
        }
    } еще {
        установить beresp.http.Vary = "X-Forwarded-Proto";
    }
}

Добавление X-Forwarded-Proto к Отличаться заголовок гарантирует, что Varnish создаст отдельные объекты в кеше для HTTP и для HTTPS.

Я также предполагаю, что ваш прокси-сервер TLS фактически отправляет X-Forwarded-Proto заголовок.

Обновление: проверка журналов

После некоторого обмена комментариями я получил несколько проницательных журналов через https://pastebin.com/QzPh1r5R которые объясняют, что происходит.

В ** << БеРек >> 951078 вы можете увидеть X-Forwarded-Proto: http заголовок. Это означает, что запрос был отправлен через обычный HTTP-запрос. Этот тип запроса должен привести к перенаправлению 301, и это происходит в соответствии со следующими строками журнала:

-- БереспПротокол HTTP/1.1
-- BerespStatus 301
-- BerespReason перемещен навсегда
-- BerespHeader Дата: Чт, 13 января 2022 г., 08:55:17 GMT
-- Сервер BerespHeader: Apache
-- Расположение BerespHeader: https://[домен лака]/
-- BerespHeader Content-Length: 238
-- BerespHeader Content-Type: text/html; кодировка = iso-8859-1
-- TTL RFC 120 10 0 1642064118 1642064118 1642064117 0 0 кэшируемый

Мало того, что происходит перенаправление, оно еще и кешируется на 120 секунд. Также интересно видеть, что нет Вари: X-Forwarded-Proto заголовок.

В более позднее время, * << Запрос >> 951080 транзакция всплывает в журналах. Мы видим следующие заголовки запроса:

- ReqHeader X-Forwarded-Proto: https
- Хост ReqHeader: [другой лаковый домен]

Итак, это HTTPS-запрос для другого домена Varnish, и по какой-то причине он приводит к попаданию в кэш, который возвращает Отличаться заголовок:

- RespHeader варьируются: Accept-Encoding, Cookie, X-Forwarded-Proto
- VCL_вызов HIT
- Хит 886585 90003.966201 10.000000 0.000000

Мало того, что вы видите попадание, вы также можете сделать вывод, что объект был вставлен в кеш транзакцией 886585.

Хотя хорошо иметь Отличаться заголовок, этот содержит Куки значение, которое опасно.Это означает, что в кэше будет храниться отдельный объект для каждого возможного значения cookie, представленного Varnish. Это довольно опасно, поэтому, пожалуйста, удалите Куки от Отличаться заголовок и придерживаться Варьировать: Accept-Encoding, X-Forwarded-Proto.

Последняя транзакция, на которую я смотрел, * << Запрос >> 951082. Оно имеет X-Forwarded-Proto: https заголовок запроса и не должен приводить к перенаправлению 301, но, к сожалению, приводит.

Ударять тег предоставляет некоторую интересную информацию:

- Хит 951078 82.391648 10.000000 0.000000

Объект, в который попали, изначально был вставлен в кеш транзакцией. 951078. Если вы обратили пристальное внимание, это было первое, что мы рассмотрели. Эта транзакция была только транзакцией HTTP, которая привела к перенаправлению 301.

И это именно тот объект, который возвращается. Таким образом, даже если вы запрашиваете HTTPS-контент, вы все равно перенаправляетесь, и именно поэтому вы попадаете в бесконечный цикл.

Если вы посмотрите на ответ, возвращаемый транзакцией 951082, вы не видите Отличаться заголовок:

- Респпротокол HTTP/1.1
- RespStatus 301
- RespReason перемещен навсегда
- Дата RespHeader: четверг, 13 января 2022 г., 08:55:17 по Гринвичу
- Сервер RespHeader: Apache
- Расположение RespHeader: https://[домен лака]/
- RespHeader Content-Length: 238
- Тип содержимого RespHeader: text/html; кодировка = iso-8859-1
- RespHeader X-лак: 951082 951078
- RespHeader Возраст: 37
- RespHeader Через: 1.1 лак (Лак/7.0)

Заключение: Пожалуйста, убедитесь, что X-Forwarded-Proto добавляется к вашему Отличаться заголовок. Это предотвратит застревание в цикле перенаправления.

флаг tf
Прежде всего, спасибо за ваш подробный ответ. Я попытался выполнить шаги, описанные в разделе «Проверка гипотезы», и сделал журнал этого теста с помощью лаклога (я загрузил журнал https://pastebin.com/hxtp8gX9). Я постоянно регистрируюсь в журнале лака, как вы описали, и я опубликую журнал, когда возникнет проблема. >SetEnvIf X-Forwarded-Proto "https" HTTPS=on Заголовок добавляется: X-Forwarded-Proto Есть у меня в "дополнительной конфигурации апача", что по сути примерно то же самое, что добавить его в файл .htaccess.
Thijs Feryn avatar
флаг in
@RemcovanGrinsven Держи меня в курсе, Ремко. С нетерпением жду достойного ведения журнала, когда что-то пойдет не так.
флаг tf
Спасибо за ваш интерес.Мне удалось зафиксировать один момент простоя в лакологе, короткую версию лога можно найти здесь: https://pastebin.com/QzPh1r5R Я загрузил полный журнал https://we.tl/t-wDfhPo57in (если вы предпочитаете другой сайт, мы загрузим его туда), но это много логов. Ждем вашего мнения.
Thijs Feryn avatar
флаг in
@RemcovanGrinsven Думаю, я нашел это. Я обновил свой ответ и добавил свой вывод. Посмотри.
флаг tf
Большое спасибо за ваш вклад. Основываясь на ваших данных, мы смогли найти что-то подозрительное. В настоящее время мы тестируем возможное решение (я обновил наш исходный пост для получения более подробной информации).
флаг tf
Проблема не возникала в течение всех выходных, это либо огромное совпадение, либо можно с уверенностью сделать вывод, что проблема решена сейчас. Я приму ваш вклад как решение для других, у которых может быть что-то подобное. Ваш вклад был очень проницательным!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.