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 не был включен. Если вы хотите, чтобы это пошло быстрее, настройте вашу систему: примите фильтры, очередь сокетов и буферы и так далее.