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