Анализ логов Nginx: топ IP и URL по 404/500 ошибкам
Быстрый анализ логов nginx для поиска проблемных IP и URL по ошибкам 404/500 через awk, sort, uniq.
Как использовать
- Подставьте путь к access.log и при необходимости дату; формат даты в логах обычно %d/%b/%Y (например 20/Jan/2025).
- Топ IP по 404: grep дату access.log | awk '$9==404 {print $1}' | sort | uniq -c | sort -rn | head -10.
- Проверьте формат лога: head -1 /var/log/nginx/access.log (поля: IP, метод, URL, код ответа в $9).
По логам nginx нужно быстро выяснить, какие IP и URL дают больше всего 404 или 500 — чтобы найти сканеры, битые ссылки или сбойные страницы. Ручной просмотр access.log неудобен при больших объёмах. Проблема: нет готовых команд — непонятно, с чего начать анализ. Симптомы: подозрительная активность по логам, массовые 404 после смены URL, 500 на части страниц. Ниже — команды на awk/sort/uniq для топа IP и URL по коду ответа, по времени, по User-Agent и готовый скрипт для мониторинга; проверка формата лога и типичные ошибки.
Решение
Анализ логов nginx для поиска проблемных IP и URL по ошибкам 404/500. Используйте для выявления атак, битых ссылок и проблем на сайте.
# 1. Топ-10 IP по количеству 404 ошибок за сегодня
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 404 {print $1}' | \
sort | uniq -c | sort -rn | head -10
# 2. Топ-10 URL с 404 ошибками
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 404 {print $7}' | \
sort | uniq -c | sort -rn | head -10
# 3. Топ-10 IP по 500 ошибкам
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 500 {print $1}' | \
sort | uniq -c | sort -rn | head -10
# 4. Все 404 ошибки за последний час
grep "$(date -d '1 hour ago' +%d/%b/%Y:%H)" /var/log/nginx/access.log | \
awk '$9 == 404'
# 5. Топ-20 IP по общему количеству запросов (подозрительная активность)
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '{print $1}' | sort | uniq -c | sort -rn | head -20
# 6. IP с большим количеством разных 404 URL (возможный сканер)
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 404 {print $1, $7}' | sort -u | awk '{print $1}' | \
uniq -c | sort -rn | head -10
# 7. Все ошибки 4xx и 5xx с URL и IP
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 >= 400 && $9 < 600 {print $9, $1, $7}' | sort -rn
# 8. Топ User-Agent для 404 (поиск ботов/сканеров)
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 404 {print $NF}' | sort | uniq -c | sort -rn | head -10
# 9. Статистика по кодам ответов за сегодня
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '{print $9}' | sort | uniq -c | sort -rn
# 10. IP с запросами к несуществующим .php, .asp и т.д.
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | \
awk '$9 == 404 && ($7 ~ /\.php|\.asp|\.aspx|\.jsp/) {print $1, $7}' | \
sort | uniq -c | sort -rn | head -20
Скрипт для мониторинга:
#!/bin/bash
LOG_FILE="/var/log/nginx/access.log"
TODAY=$(date +%d/%b/%Y)
echo "=== Топ-10 IP по 404 ошибкам ==="
grep "$TODAY" "$LOG_FILE" | awk '$9 == 404 {print $1}' | sort | uniq -c | sort -rn | head -10
echo -e "\n=== Топ-10 проблемных URL (404) ==="
grep "$TODAY" "$LOG_FILE" | awk '$9 == 404 {print $7}' | sort | uniq -c | sort -rn | head -10
echo -e "\n=== Топ-10 IP по 500 ошибкам ==="
grep "$TODAY" "$LOG_FILE" | awk '$9 == 500 {print $1}' | sort | uniq -c | sort -rn | head -10
echo -e "\n=== Статистика кодов ответов ==="
grep "$TODAY" "$LOG_FILE" | awk '{print $9}' | sort | uniq -c | sort -rn
Формат даты в nginx обычно %d/%b/%Y (например 20/Jan/2025). Проверьте: head -1 /var/log/nginx/access.log. Для нескольких дней: grep -E "20/Jan/2025|21/Jan/2025".
Проверка
- Формат access.log — в стандартном формате nginx поля разделены пробелами; $1 — IP, $7 — URL, $9 — код ответа. Убедитесь:
head -1 /var/log/nginx/access.log
Подставьте путь к вашему логу (например /var/www/site.ru/logs/access.log при отдельных логах на сайт).
- Проверка одной команды — выполните топ URL по 404 за сегодня; путь к логу замените на свой:
grep $(date +%d/%b/%Y) /var/log/nginx/access.log | awk '$9 == 404 {print $7}' | sort | uniq -c | sort -rn | head -5
Если логов за сегодня нет, подставьте дату вручную: grep "21/Feb/2026" ....
- Права на лог — для чтения лога нужны права пользователя, от которого запускаете команду (часто root или пользователь с доступом в группу nginx). Иначе «Permission denied».
Типичные ошибки
- Формат даты не совпадает — в логах может быть другой формат (например с временем). Посмотрите первую строку лога и подстройте вывод
dateили шаблон grep (напримерgrep "21/Feb/2026:"для фильтра по дате и часу). - Код ответа в другом поле — при кастомном log_format номера полей ($7, $9) меняются. Проверьте директиву log_format в конфиге nginx и при необходимости поменяйте номера в awk.
- Лог в другом месте — путь к access.log задаётся в конфиге виртуального хоста (access_log). В BitrixVM и при структуре каталогов по сайтам логи часто лежат в /var/www/ДОМЕН/logs/ или /var/log/nginx/.
Где применять
- Prod / dev: сервер с nginx, разовый анализ или скрипт по cron для отчёта по 404/500. Логи — по пути из конфига nginx (access_log).
- Безопасность: выявление сканеров (много разных 404 с одного IP), подозрительных User-Agent, запросов к .php/.asp.
Связанные сниппеты: Структура каталогов nginx для сайтов (пути к логам), Nginx и SSL Let’s Encrypt в BitrixVM.