URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8546
[ Назад ]

Исходное сообщение
"Освоение скриптописания под shell"

Отправлено Vadim_nsk , 11-Дек-09 06:23 
#!/bin/sh
cat /var/log/auth.log | grep "Invalid user" | expand | tr -s ' ' | cut -d' ' -f8 -f10 > /tmp/block_users_ip_list.txt
cat /var/log/auth.log | grep "authentication error" | expand | tr -s ' ' | cut -d' ' -f13 -f15 >> /tmp/block_users_ip_list
.txt
cat /tmp/block_users_ip_list.txt | cut -d' ' -f1 | sort | uniq -c > /tmp/block_users_list.txt
cat /tmp/block_users_ip_list.txt | cut -d' ' -f2 | sort | uniq -c | sort -n > /tmp/block_ip_list.txt
rm -rf /tmp/block1.txt
cat /tmp/block_users_list.txt /tmp/block_ip_list.txt | while read cnt text; do
    if [ $cnt -ge 3 ]; then
        cat /tmp/block_users_ip_list.txt | grep $text | cut -d' ' -f2 | while read ip; do
            case $ip in
                *[!01-9.]*|"");;
                *) echo $ip >> /tmp/block1.txt;;
            esac
        done
    fi
done
cat /tmp/block1.txt /etc/block_list_ip.txt | sort -n | uniq > /tmp/block2.txt
cp /tmp/block2.txt /etc/block_list_ip.txt

Задача простая. Например, раз в час, анализируем файл /var/log/auth.log, ищем в нем подстроки "Invalid user" и "authentication error", создаем список имен и адресов. и если, имя или адрес встретились более 3-х раз, пишем адрес в файл /etc/block_list_ip.txt.
Но уж сильно топорно и ресурсоемко у меня все это получилось...
Попытался переписать:
bunzip2 -kcf /var/log/auth.log.0.bz2 | cat - /var/log/auth.log | grep "Invalid user\|authentication error" | while read str; do
    echo $str > /tmp/block1.txt
done

И на этом застрял...
Задача: в найденных строках выделить слово, следующее за "user" и слово, следующее за "from". Т.е. username и ip-address. Далее, хочу пока сформировать также два файла или массива имен и адресов. подсчитать количество повторений и вторым проходом уже вычленить адреса. Может кто подскажет как выделить слово в строке, следующее за искомым? При этом, чтобы это работало в потоке.
В идеале конечно, хотелось бы сформировать файл из двух столбцов: "username ip-addreess". И считать повторы по первому и второму столбцу. Но на это у меня нет даже идей...
Моя задача сейчас, изучить получше работу с shell, потом уже перейду к Perl. Поэтому примеры на Perl это хорошо, но не то, что нужно мне сейчас...

Содержание

Сообщения в этом обсуждении
"Освоение скриптописания под shell"
Отправлено phpcoder , 11-Дек-09 07:08 
>Задача простая.

Я бы её на awk сделал. (К сожалению, у меня нет под рукой файла с тестовыми данными, чтобы написать и опробовать такой скрипт.)

>Может кто подскажет как выделить слово в строке, следующее за искомым?

Как вариант использовать регулярные выражения.


"Освоение скриптописания под shell"
Отправлено Vadim_nsk , 11-Дек-09 08:06 
>>Задача простая.
>Я бы её на awk сделал. (К сожалению, у меня нет под
>рукой файла с тестовыми данными, чтобы написать и опробовать такой скрипт.)

Dec 10 05:43:08 gw sshd[1157]: error: PAM: authentication error for illegal user acosta from 92.79.128.167
Dec 10 06:05:31 gw sshd[2005]: Invalid user oracle from 218.76.193.140
Dec 10 06:05:35 gw sshd[2007]: Invalid user test from 218.76.193.140
Dec 10 06:05:38 gw sshd[2011]: Invalid user test from 218.76.193.140
Dec 10 06:05:42 gw sshd[2013]: Invalid user test from 218.76.193.140
Dec 10 06:05:45 gw sshd[2015]: Invalid user user from 218.76.193.140
Dec 10 06:05:49 gw sshd[2017]: Invalid user apache from 218.76.193.140
Dec 10 06:17:15 gw sshd[2485]: Invalid user hesse from 217.136.232.11
Dec 10 06:17:15 gw sshd[2485]: error: PAM: authentication error for illegal user hesse from 217.136.232.11
Dec 10 06:24:51 gw sshd[2730]: Invalid user hh from 99.234.5.98
Dec 10 06:24:51 gw sshd[2730]: error: PAM: authentication error for illegal user hh from 99.234.5.98
Dec 10 07:48:53 gw sshd[5621]: Invalid user hr from 211.143.78.2
Dec 10 07:48:54 gw sshd[5621]: error: PAM: authentication error for illegal user hr from 211.143.78.2
Dec 10 08:03:26 gw sshd[6134]: Invalid user http from 99.234.5.98
Dec 10 08:03:27 gw sshd[6134]: error: PAM: authentication error for illegal user http from 99.234.5.98
Dec 10 08:53:29 gw sshd[8092]: error: PAM: authentication error for vadim from 192.168.114.26
Dec 10 08:53:36 gw sshd[8092]: error: PAM: authentication error for vadim from 192.168.114.26
Dec 10 10:18:57 gw sshd[11523]: Invalid user info from 81.189.96.100
Dec 10 10:18:57 gw sshd[11523]: error: PAM: authentication error for illegal user info from 81.189.96.100
Dec 10 11:13:41 gw sshd[13447]: Invalid user internet from 80.169.105.159
Dec 10 11:13:41 gw sshd[13447]: error: PAM: authentication error for illegal user internet from 80.169.105.159
Dec 10 11:55:05 gw sshd[14823]: Invalid user irina from 85.70.129.57
Dec 10 11:55:07 gw sshd[14823]: error: PAM: authentication error for illegal user irina from 85.70.129.57
Dec 10 12:16:26 gw sshd[15777]: Invalid user is from 209.203.56.150
Dec 10 12:16:27 gw sshd[15777]: error: PAM: authentication error for illegal user is from 209.203.56.150
Dec 10 12:19:46 gw sshd[15984]: Invalid user istvan from 200.75.72.185
Dec 10 12:19:46 gw sshd[15984]: error: PAM: authentication error for illegal user istvan from 200.75.72.185
Dec 10 12:20:14 gw sshd[16030]: Invalid user roto from 121.52.214.105
Dec 10 12:20:55 gw sshd[16058]: Invalid user thx1138 from 121.52.214.105
Dec 10 12:20:58 gw sshd[16060]: Invalid user 0123456789 from 121.52.214.105
Dec 10 12:21:02 gw sshd[16064]: Invalid user root123 from 121.52.214.105
Dec 10 12:21:06 gw sshd[16090]: Invalid user r00t from 121.52.214.105
Dec 10 12:21:13 gw sshd[16094]: Invalid user toor123 from 121.52.214.105
Dec 10 12:21:17 gw sshd[16096]: Invalid user t00r from 121.52.214.105
Dec 10 12:21:21 gw sshd[16100]: Invalid user acces from 121.52.214.105
Dec 10 12:21:24 gw sshd[16102]: Invalid user access from 121.52.214.105
Dec 10 12:21:28 gw sshd[16104]: Invalid user acc3ss from 121.52.214.105
Dec 10 12:21:32 gw sshd[16106]: Invalid user acc3s from 121.52.214.105
Dec 10 12:21:36 gw sshd[16110]: Invalid user acce$$ from 121.52.214.105
Dec 10 12:21:39 gw sshd[16112]: Invalid user acce55 from 121.52.214.105
Dec 10 12:21:43 gw sshd[16114]: Invalid user tomcat from 121.52.214.105
Dec 10 12:21:47 gw sshd[16116]: Invalid user tomcat1 from 121.52.214.105

С тестовыми данными у меня проблем нет, у меня со знаниями проблемы...
Это после:
bunzip2 -kcf /var/log/auth.log.0.bz2 | cat - /var/log/auth.log | grep "Invalid user\|authentication error" > /tmp/block1.txt

Никак не могу понять как записать в sed следующее: удалить начало строки до "user" (а лучше включая). sed 's/^ * user//g' нужного эффекта не дает. Тут главное понять механизм работы sed, чего у меня не получается...

"Освоение скриптописания под shell"
Отправлено Pahanivo , 11-Дек-09 08:13 
это все уже реализовано, если не ошибаюсь называется sshit

"Освоение скриптописания под shell"
Отправлено Vadim_nsk , 11-Дек-09 09:23 
>это все уже реализовано, если не ошибаюсь называется sshit

Спасибо, нашел, установил. Можно сказать задача решена. Но подобных задач масса, надо научиться, поэтому sshit лишь добавил к "своей" борьбе. Будет на чем тренироваться...


"Освоение скриптописания под shell"
Отправлено ACCA , 11-Дек-09 08:41 
>до "user" (а лучше включая). sed 's/^ * user//g' нужного эффекта
>не дает. Тут главное понять механизм работы sed, чего у меня
>не получается...

sed 's/^.\+user //'


"Освоение скриптописания под shell"
Отправлено phpcoder , 11-Дек-09 08:42 
>Никак не могу понять как записать в sed следующее: удалить начало строки
>до "user" (а лучше включая). sed 's/^ * user//g' нужного эффекта
>не дает. Тут главное понять механизм работы sed, чего у меня
>не получается...

Попробуй так: sed 's/^.* user//g'
Точка это любой символ, * это значит повторяется ноль и более раз.



"Освоение скриптописания под shell"
Отправлено phpcoder , 11-Дек-09 08:47 
>С тестовыми данными у меня проблем нет, у меня со знаниями проблемы...

Если я правильно понял задание, то вот мой вариант:


coder@proger-ub5 ~ $ awk '{if(/Invalid user/){print $8, $10;}else if(/authentication error for illegal user/){print $13, $15;}else if(/authentication error for/){print $11, $13;}}' auth.log | sort -k1 | uniq -c | awk '{if($1 >= 3){print $3;}}'
218.76.193.140

Это на приведённый данных. С IP 218.76.193.140 три раза безуспешно пытались зайти под логином test.


"Освоение скриптописания под shell"
Отправлено Vadim_nsk , 13-Дек-09 09:41 
Как заставить awk читать входной поток вместо файла?

"Освоение скриптописания под shell"
Отправлено phpcoder , 13-Дек-09 19:52 
>Как заставить awk читать входной поток вместо файла?

Просто не указывать файл :)

Пример: cat /etc/passwd | awk -F: '{print $1}'



"Освоение скриптописания под shell"
Отправлено ACCA , 11-Дек-09 08:31 
[...]
>Но уж сильно топорно и ресурсоемко у меня все это получилось...

Ты хотел на shell или изящно?

Правило #1 - не нужно чинить исправную вещь. Работает правильно?
Правило #2 - не оптимизируй. Трассируй. Что-нибудь работает долго и требует улучшения?


В качестве игрушки на bash:


TMPFILE=/tmp/toy.$(basename $0)

expand /var/log/auth.log | tr -s ' ' | tee >(grep "Invalid user" | cut -d' ' -f8 -f10 >$TMPFILE.e1) | grep "authentication error" | cut -d' ' -f13 -f15 >$TMPFILE.e2

exec 4> >(sort | uniq -c | sort -n > $TMPFILE.usr)
exec 5> >(sort | uniq -c | sort -n > $TMPFILE.ip)
while read f1 f2 rest
do
    echo $f1 >&4
    echo $f2 >&5
done < <(cat $TMPFILE.e{1,2})

4>&-
5>&-

exec 5> >(sort | uniq > /tmp/block.lst)

grep -f <(while read n data ; do [ $n -lt 3 ] && continue ; echo $data ; done < $TMPFILE.usr) $TMPFILE.e{1,2} | while read f1 f2 rest
do
    echo $f2 >&5
done

while read n data
do
    [ $n -lt 3 ] && continue
    echo $data >&5
done < $TMPFILE.ip

5>&-
rm $TMPFILE.*
cat /tmp/block.lst



"Освоение скриптописания под shell"
Отправлено vg , 11-Дек-09 10:31 
когда-то и создали Perl для быстрой обработки текста
и думаю что использование Perl  оправданно до сих пор

"Освоение скриптописания под shell"
Отправлено L0n3R4ng3r , 11-Дек-09 12:08 
можно так на перле:
#!/usr/bin/perl

open(LOG,"<auth.log");
my %ip;
while(<LOG>){
        if( $_ =~ /Invalid user|authentication error/ ){
                if ($_ =~ /(\d+\.\d+\.\d+\.\d+)/) {
                        $ip{$1}++;
                }
        }
}
close(LOG);

foreach my $key (sort keys %ip) {
        if ( $ip{$key} >= 3 ) {
                print "Block ip $key. There were made $ip{$key} unsuccessful attempts\n";
        }
}