Echo 404 напрямую из nginx для улучшения производительности

Я отвечаю за производственные серверы, обслуживающие статический контент для веб-сайта. Эти серверы постоянно просматриваются ботами, которые ищут потенциальные эксплойты (что не является большой проблемой с точки зрения безопасности, поскольку ни одно приложение не может быть доступно за веб-сервером), но генерирует тысячи 404 в день, иногда в час. Я ищу способы блокировать эти запросы, но это сложно (вы хотите убедиться, что вы не блокируете законный трафик, и эти боты становятся все более и более умными в том, чтобы выглядеть так, как будто они законны), и это займет у меня некоторое время найти приемлемое решение.

В то же время я хотел бы уменьшить влияние производительности 404 страницы. На самом деле мы используем nginx который по умолчанию настроен на обслуживание это 404 страницы с диска (это можно изменить с помощью error_page директива, но в конце концов 404 нужно будет либо обслуживать с диска, либо из другого внешнего источника (например, из вышестоящего приложения, что было бы хуже), что не идеально.

Я провел тест с ab на моей локальной машине с базовой конфигурацией: в одном случае я echo сообщение непосредственно от nginx так что диск вообще не трогается, в другом случае я попал на недостающую страницу и nginx служит своим 404 с диска.

server {
  # [...] the default nginx stuff
  location / {

  }
  location /this_page_exists {
     echo "this page was found";
  }
}

Вот результаты теста (на моем ноутбуке установлен Intel(R) Core(TM) i7-2670QM + SSD на случай, если вам интересно, почему они такие высокие):

$ ab -n 500000 -c 1000 http://localhost/this_page_exists
Requests per second:    25609.16 [#/sec] (mean)

$ ab -n 500000 -c 1000 http://localhost/this_page_doesnt_exists
Requests per second:    22905.72 [#/sec] (mean)

Как видите, возвращая значение с echo является 11% ((25609−22905)÷22905×100) быстрее, чем обслуживать 404 страница с диска. Соответственно хотелось бы echo просто 404 Page not Found строка из nginx,

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

location / {
  try_files $uri @not_found;
}
location @not_found {
  echo "404 - Page not found";
}

Проблема в том, что как только echo директива используется, http response code установлен в 200, Я пытался изменить это, делая error_page 200 = 400 но это нарушает конфигурацию.

Как я могу служить 404 страница прямо из nginx? (без взлома источника, который может быть следующим шагом)

2 ответа

Решение

На самом деле, по умолчанию nginx генерирует ответ 404 внутри. Он подает файл с диска только в том случае, если вы указали это с помощью директивы error_page. Если вы хотите контролировать формат страницы 404, а не echo "404 - page not found";, ты можешь использовать return 404 "404 - page not found"; (Предполагается, что вы используете несколько новую версию nginx, я считаю, что вам нужно 0.9 или новее)

Nginx echo module is what you need. But you should use it with error_page:

error_page 404 @echo_404;
location @echo_404 { echo "Not found"; }

Вы можете заставить nginx закрыть активное соединение, вернув 444:

return 444;

Это немедленно закроет сокет, ничего не записав в сеть.

Разница в ваших вычислениях заключается только в том, что open_file_cache не был включен. Если вы хотите, чтобы это пошло быстрее, настройте вашу систему: примите фильтры, очередь сокетов и буферы и так далее.

Другие вопросы по тегам