Иногда нужно не просто писать общий access log, а отдельно сохранять конкретные типы запросов. Например: все 404, все 5xx, запросы от конкретных ботов, отдельные URI, нестандартные методы, трафик из определенных стран. Можно потом парсить общий лог через grep, awk или SIEM. Но в Nginx часто есть более аккуратный способ - использовать map.
map позволяет создать переменную на основе другой переменной Nginx. А потом использовать эту переменную в логах, блокировках, редиректах и другой логике.
▪️ Пример: пишем 404 и 5xx в отдельные файлы. В секции http добавляем:
map $status $to404log {
404 1;
default 0;
}
map $status $to5xxlog {
~^5 1;
default 0;
}
Теперь в нужном виртуальном хосте:
access_log /var/log/nginx/404.log combined if=$to404log;
access_log /var/log/nginx/5xx.log combined if=$to5xxlog;
▪️ Что получится:
• запросы со статусом 404 попадут в /var/log/nginx/404.log
• ответы 500, 502, 503, 504 и другие 5xx попадут в /var/log/nginx/5xx.log
• при этом общий access log можно оставить как есть
Например:
access_log /var/log/nginx/access.log combined;
▪️ Как это работает:
• Nginx смотрит на встроенную переменную $status
• если статус 404, переменная $to404log получает значение 1
• если статус начинается с 5, переменная $to5xxlog получает значение 1
• директива access_log ... if= пишет запись только если переменная не равна 0
Так можно быстро отделить интересные события без внешней обработки логов.
▪️ map полезен не только для логов. Например, можно помечать нежелательные User-Agent:
map $http_user_agent $block_useragent {
default 0;
~*semrushbot 1;
~*ahrefs 1;
~*rss2tg 1;
~*seznambot 1;
~*AspiegelBot 1;
~*BLEXBot 1;
~*MASHIAH 1;
}
А в виртуальном хосте вернуть 403:
if ($block_useragent) {
return 403;
}
Да, if в Nginx часто ругают, но для простого return внутри server это нормальный и распространенный сценарий. По такой же логике можно делать условия по другим переменным:
$request_method
$request_uri
$remote_addr
$host
$geoip_country_code
$http_referer
Например:
• отдельно логировать POST-запросы
• блокировать конкретные URI для некоторых User-Agent
• писать подозрительные запросы в отдельный лог
• ограничивать доступ по стране через GeoIP
• включать разные upstream’ы по признакам запроса
#nginx #linux
🧑💻 NetworkAdmin