Задача состояла в том, что бы мониторить неудачные попытки авторизации на вебсервере 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