Парсер неудачных авторизаций nginx с хранением данных в MySQL

Задача состояла в том, что бы мониторить неудачные попытки авторизации на вебсервере Nginx и хранить эти данные для удобного просмотра в реляционной базе данных MySQL
Нас интересует когда, кто и с какого IP ввёл неверный пароль
в БД(допустим logs) создадим таблицу (к примеру fail_auth), в которой будут 5 столбцов: id, date, time, user, from_IP
Так же создадим отдельного пользователя с паролем именно для доступа к этой базе
Nginx записывает неудачные попытки в файл /var/log/nginx/error.log:

#cat /var/log/nginx/error.log | grep password
2015/05/11 14:41:15 [error] 29024#0: *24907 user "admin": password mismatch, client: 93.190.44.154, server: host.tradenark.com.ua, request: "GET /test/ HTTP/1.1", host: "host.tradenark.com.ua"

То что нужно! Теперь выделю только те данные, которые мне нужны:

# cat /var/log/nginx/error.log | grep password | awk '{print $1"|"$2"|"$7"|"$11}'
2015/05/11|14:41:15|"admin":|*.*.44.154,

Уже лучше. Вертикальный разделитель понадобится немного позже и будет видно для чего. Немного очистим от лишних символов:

# cat /var/log/nginx/error.log | grep password | awk '{print $1"|"$2"|"$7"|"$11}' | sed 's\,\\g' | sed 's\":\\g' | sed 's\"\\g'
2015/05/11|14:41:15|admin|*.*.44.154

Специально введу неправильный пароль для проверки, всё ли фиксируется как нужно:

# cat /var/log/nginx/error.log | grep password | awk '{print $1"|"$2"|"$7"|"$11}' | sed 's\,\\g' | sed 's\":\\g' | sed 's\"\\g'
2015/05/15|23:50:37|admin|*.*.24.138
2015/05/15|23:50:37|admin|*.*.24.138
2015/05/15|23:50:45|admin|*.*.24.138
2015/05/15|23:50:50|admin|*.*.24.138

Отлично! Все неудачные попытки фиксируются одинаково правильно
Далее собственно скрипт:

#!/bin/bash

#присваиваем переменной array те данные, которые отдаёт нам nginx для дальнейшей их обработки
array=$(cat /var/log/nginx/error.log | grep password | awk '{print $1"|"$2"|"$7"|"$11}' | sed 's\,\\g' | sed 's\":\\g' | sed 's\"\\g')

#построчно помещаем данные в файлик для удобства(можно было не присваивать переменную, а просто сделать перенаправление вывода прямиком в файл)
for i in ${array[@]}; do echo $i > /root/auth.txt; done

#Далее производим чтение из этого файла, параллельно разделяя строки на элементы, используя в качестве разделителя (-d\) ту самую вертикальную черту. значение каждого нового элемента присваиваем переменным, которые начинаются с _ (для удобства и отсутствия путаницы). И когда строка уже прочитана и разделена INSERT-им это в таблицу используя простую конструкцию
cat /root/auth.txt | while read F
 do
        _day=$(echo $F | cut -d\| -f1)
        _time=$(echo $F | cut -d\| -f2)
        _user=$(echo $F | cut -d\| -f3)
        _IP=$(echo $F | cut -d\| -f4)


echo "INSERT INTO fail_auth (date,time,user,from_ip) VALUES ('$_day','$_time','$_user','$_IP');" | mysql -uuser -ppassword logs
done

#Подчищаем за собой
cp /dev/null /root/auth.txt

Структура БД:

CREATE TABLE IF NOT EXISTS `fail_auth` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `date` date NOT NULL,
  `time` time NOT NULL,
  `user` varchar(64) NOT NULL,
  `from_ip` varchar(64) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

запускаем скрипт и смотрим в phpmyadmin

# sh /root/auth_fail.sh

Fail Auth

Добавить комментарий