Найти в Дзене
Talibanich

Скрипт анализа логов Angie/Nginx и вывода списка наиболее встречающихся IP-адресов

Заметки по системному администрированию в основном пишу для себя, в интернете как говорится целее будет. Но вдруг кому-то пригодится. Данный скрипт я запускаю для анализа логов веб-сервера Angie, чтобы быстро оценить аномальные всплески обращений и при необходимости добавить новое правило фильтрации в fail2ban, о котором я писал здесь: https://dzen.ru/a/Z0W9rGxYTnfTW47S Сам скрипт, анализирует логи access_* и error_* и выводить ТОП-25 наиболее встречающихся IP. В настройках можно задать диапазон IP для исключения в формате CIDR (например yandex/google bot, свои IP и т.д.) #!/bin/bash # Скрипт анализа логов Angie/Nginx и вывода списка наиболее встречающихся IP-адресов # Настройки TOP_COUNT=25 MIN_ACCESS_COUNT=10 MIN_ERROR_COUNT=10 # Список игнорируемых CIDR IGNORE_CIDRS=( "155.55.128.0/20" "166.66.144.0/20" ) # Функция для проверки IP check_ip() { local check_ip=$1 local ip_long=$(ip2long "$check_ip") for cidr in "${IGNORE_CIDRS[@]}"; do local net=${cidr%/*} local bits=${cidr#*/} local

Заметки по системному администрированию в основном пишу для себя, в интернете как говорится целее будет. Но вдруг кому-то пригодится.

Данный скрипт я запускаю для анализа логов веб-сервера Angie, чтобы быстро оценить аномальные всплески обращений и при необходимости добавить новое правило фильтрации в fail2ban, о котором я писал здесь: https://dzen.ru/a/Z0W9rGxYTnfTW47S

Сам скрипт, анализирует логи access_* и error_* и выводить ТОП-25 наиболее встречающихся IP.

В настройках можно задать диапазон IP для исключения в формате CIDR (например yandex/google bot, свои IP и т.д.)

#!/bin/bash
# Скрипт анализа логов Angie/Nginx и вывода списка наиболее встречающихся IP-адресов
# Настройки
TOP_COUNT=25
MIN_ACCESS_COUNT=10
MIN_ERROR_COUNT=10
# Список игнорируемых CIDR
IGNORE_CIDRS=(
"155.55.128.0/20"
"166.66.144.0/20"
)
# Функция для проверки IP
check_ip() {
local check_ip=$1
local ip_long=$(ip2long "$check_ip")
for cidr in "${IGNORE_CIDRS[@]}"; do
local net=${cidr%/*}
local bits=${cidr#*/}
local net_long=$(ip2long "$net")
local mask=$((0xffffffff << (32 - bits)))
if [ $((ip_long & mask)) -eq $((net_long & mask)) ]; then
return 1
fi
done
return 0
}
# Функция конвертации IP в число
ip2long() {
local IFS='.'
read -r i1 i2 i3 i4 <<< "$1"
echo -n $((i1 * 256 ** 3 + i2 * 256 ** 2 + i3 * 256 + i4))
}
echo "=== TOP $TOP_COUNT IPs from access logs (min count: $MIN_ACCESS_COUNT) ==="
cat access_*.log* 2>/dev/null | \
awk '{print $1}' | \
sort | \
uniq -c | \
awk -v min="$MIN_ACCESS_COUNT" '$1 >= min' | \
sort -rn | \
while read count ip; do
if check_ip "$ip"; then
echo "$count $ip"
fi
done | \
head -n $TOP_COUNT
echo -e "\n=== TOP $TOP_COUNT IPs from error logs (min count: $MIN_ERROR_COUNT) ==="
cat error_*.log* 2>/dev/null | \
grep "client:" | \
sed 's/.*client: \([^,]*\).*/\1/' | \
sort | \
uniq -c | \
awk -v min="$MIN_ERROR_COUNT" '$1 >= min' | \
sort -rn | \
while read count ip; do
if check_ip "$ip"; then
echo "$count $ip"
fi
done | \
head -n $TOP_COUNT

Пример вывода:

Далее вручную пробегаюсь по логам и смотрю что это за IP, бот или просто какие-то кулхакеры. Смотрю информацию в сервисах WHOIS. И в зависимости от этого уже прнимаю решение - или добавляю новое правило в fail2ban или просто жестко блокирую в iptables:

Блокировка одного IP адреса:
iptables -A INPUT -s 176.32.158.46 -j DROP

Блокировка CIDR диапазона:
iptables -A INPUT -s 176.32.144.0/20 -j DROP

Сохранение правил после перезагрузки:
iptables-save > /etc/iptables/rules.v4 # для Debian/Ubuntu