BASH
#bash#nginx#logs#analysis#security#monitoring#awk

Анализ логов Nginx: топ IP и URL по 404/500 ошибкам

Быстрый анализ логов nginx для поиска проблемных IP и URL по ошибкам 404/500 через awk, sort, uniq.

Как использовать

  1. Подставьте путь к access.log и при необходимости дату; формат даты в логах обычно %d/%b/%Y (например 20/Jan/2025).
  2. Топ IP по 404: grep дату access.log | awk '$9==404 {print $1}' | sort | uniq -c | sort -rn | head -10.
  3. Проверьте формат лога: 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".

Проверка

  1. Формат access.log — в стандартном формате nginx поля разделены пробелами; $1 — IP, $7 — URL, $9 — код ответа. Убедитесь:
head -1 /var/log/nginx/access.log

Подставьте путь к вашему логу (например /var/www/site.ru/logs/access.log при отдельных логах на сайт).

  1. Проверка одной команды — выполните топ 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" ....

  1. Права на лог — для чтения лога нужны права пользователя, от которого запускаете команду (часто 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.