Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Операционные системы » UNIX » UNIX Shell: sh, bash, zsh; Coreutils и ко.; sed, awk, perl;

Модерирует : ShriEkeR

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

Открыть новую тему     Написать ответ в эту тему

digital422

Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Товарищи вопрошающие! Если ваша система отлична от ГНУ, и в то же время вы желаете обойтись только дефолтными средствами, указывайте и то и другое сразу, пожалуйста.


UNIX Shell

 
   Это глобальная тема по юниксовой командной оболочке, как по интерактивной работе в командной строке, так и по шелл-скриптам. Ключевые слова: sh, bash, zsh, tcsh, busybox, readline, coreutils, cp, mv, ln, rm, ls, readlink, mkdir, touch, stat, date, test, sleep, chown, chmod, chattr, dd, df, du, env, echo, cat, less, man, grep, sort, findutils, find, locate, xargs, md5sum, cmp, diff, patch, ps, kill, killall, tar, gzip, bzip2, xz, mount, fdisk, parted, mkfs, fsck, e2fsprogs, mtools, ss, netcat, netstat, rsync, ssh, scp, sftp, lftp, ncftp, time, strace.
   Неинтерактивная обработка текста (sed, awk, perl) пока тоже здесь.
   Смотри в других ветках: wget, convert, montage, mogrify и др., gs, git, 7z, p7zip, soffice, mplayer, mencoder, vlc, vim, mc, mcedit, kioclient.
 
 

Hint! Русские маны (подустаревшие, не всегда полные и не всегда для вашей системы) можно попытаться найти на Опеннете, к примеру: bash, tar, grep.

 
Готовые решения:
  • commandlinefu.com
    Крупнейшая база полезных однострочников на командной оболочке с ранжированием на основе пользовательского голосования.
     
  • shell-fu.org
    Аналогично, но поменьше и формат записей более свободный, поэтому встречаются и однострочники, и развернутые скрипты, и просто советы.
     
  • Useful one-line scripts for sed
    Почти исчерпывающий список решений для тех случаев, когда sed незаменим. Более сложные скрипты с sed.sf.net — только для тех, кто знает толк... :)

 
Учебная литература:
  • Greg’s Wiki (http://mywiki.wooledge.org)
    Наиболее обширный авторский сборник постоянно обновляющихся материалов по Башу.

    1. Bash Pitfalls
      (Частые ошибки программирования на Баше: [1], [2], [3], [4], [5] — пер. на русский по сост. на дек. 2008 г.).
      Рассмотрены преимущественно ошибки, возникающие из-за непонимания отличия шелла от «нормальных» скриптовых языков. Если вы уже владеете, например, Перлом, то это вполне может быть ваше первое руководство для ознакомления с Башем.
    2. Bash FAQ
    3. Bash Guide
    4. Bash Reference Sheet
      Шпаргалка по частым синтаксическим оборотам.

 
Классическая учебная литература:
С одной стороны не упомянуть эти издания нельзя, с другой — они настолько устарели, что едва ли их можно рекомендовать в роли учебника.

 

Смело правьте и дополняйте шапку, однако не забывайте отписываться об исправлениях и сохранять исходный вариант под #.
Первый пост темы имел вид...

Всего записей: 360 | Зарегистр. 19-04-2003 | Отправлено: 18:51 16-05-2008 | Исправлено: qw12, 09:42 24-03-2020
ndch

Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
.

Всего записей: 7010 | Зарегистр. 31-08-2008 | Отправлено: 09:20 05-02-2015 | Исправлено: ndch, 09:27 05-02-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
> Но вот вопрос какого файла? Который на выходе или как?
 
Что значит «какого»? Того, который вы указали под ключом -zzzz то бишь. Ясно же написано: «it is taken as a filename».
 
Чего вы хотите-то?

----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 09:21 05-02-2015 | Исправлено: ASE_DAG, 09:22 05-02-2015
ndch

Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Что значит «какого»? Того, который под ключом -z — zzz то бишь.

О! Теперь понял. Теперь получилось. Спасибо.

Всего записей: 7010 | Зарегистр. 31-08-2008 | Отправлено: 09:27 05-02-2015
Alukardd



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
ndch
Главное вдумчиво читать!

----------
Microsoft gives you windows, linuх gives you the whole house...
I've been using Vim for about 4 years now, mostly because I can't figure out how to exit it.

Всего записей: 6571 | Зарегистр. 28-08-2008 | Отправлено: 12:25 05-02-2015
mithridat1



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Существует ли средство для парсинга json из командной строки,не требующее дополнительных зависимостей ?
 
Добавлено:
Вроде нашел http://xmodulo.com/how-to-parse-json-string-via-command-line-on-linux.html

Всего записей: 5025 | Зарегистр. 05-01-2006 | Отправлено: 17:36 13-02-2015 | Исправлено: mithridat1, 17:41 13-02-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Уважаемые Гуру.
Помогите написать скрипт, который обрабатывал бы лог rinetd и выполнял бы такие действия:
1. Берем строку лога и смотрим нет ли в 9-ом столбце слова "denied", если есть - переходим к следующей строке лога и снова проверяем на наличие "denied".
 
2. Если "denied" отсутствует, то берем из этой строчки IP из 2-го столбца, проверяем нет ли данного IP в массиве deny_ip и если уж есть, то переходим к п.1.
 
3. Берем следующую строчку и сравниваем IP из 2-го столбца с IP из п.2
 
4. Проверяем так еще 5 строчек после строчки из п.2 и если все IP совпадают переходим к п.5, в противном случаем берем строчку на которой прервалось совпадения и возвращаемся к п.1
 
5. Заносим IP из п.2 в массив deny_ip, а значение времени из 1 столбца в массив deny_time, с таким же ключем массива как и IP.
 
6.По окончанию лога данные массивов deny_ip и deny_time вставляем в конфигурационный файл rinetd
echo deny $deny_ip[key]    #$deny_time[key] >> /usr/local/etc/rinetd.conf
 
7. Перегружаем rinetd с применением нового конфига
 
cat /var/run/rinetd.pid | xargs kill -1
 
 
Запуск скрипта предполагается выполняться каждые 5 минут посредством крона.
 
Смысл назначения скрипта думаю понятен.
Занести IP адрес "переборщика доступа", после 5 попытки, в конфиг rinetd
 
P.S. Скрипт собираюсь использовать на FreeBSD 10. Гуи нет. Из оболочек имеется sh и csh, поэтому скрипт желательно чтобы работал из-под них, без установки дополнительных пакетов.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 14:49 23-03-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
CKOPnuOH
 
> в массиве deny_ip
 
Что это за массив? Где образец журнала?
 
> Из оболочек имеется sh и csh, поэтому скрипт желательно чтобы работал из-под них
 
sh Алмквиста вовсе не умеет массивы, csh умеет (тем более, что у вас там tcsh), но лично я писать на нем не буду. awk у вас там есть?

----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 20:00 23-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
> Что это за массив?
 
Собственный, который собирает IP, которые в последствии нужно будет выгрузить в конфиг rinetd.conf
 
> Где образец журнала?
 
Образец
 
Добавлено:
> awk у вас там есть?
Есть, работает.
 
 
Добавлено:
в образце <-> означает табуляцию.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 20:15 23-03-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
CKOPnuOH> собственный, который собирает IP, которые в последствии нужно будет выгрузить в конфиг rinetd.conf
 
То есть при каждом запуске парсим еще и rinetd.conf?
 
> в образце <-> означает табуляцию.
 
Не надо так больше делать. Если вы считаете, что про табуляцию не достаточно только сказать, но и важно сохранить ее (в данном случае это не так), то используйте какой-нибудь файлообменник или «pastebin» с неограниченным сроком хранения и/или прилагайте прямо к форумному письму в base64: вот так.
 
> 2. Если "denied" отсутствует, то берем из этой строчки IP из 2-го столбца, проверяем нет ли данного IP в массиве deny_ip и если уж есть, то переходим к п.1.
 
Здесь у вас что-то не то написано. Вероятно, имеется в виду «если присутствует».
 
> 3. Берем следующую строчку и сравниваем IP из 2-го столбца с IP из п.2
 
Я нахожу этот подход зело странным — у вас решение о блокировке брутфорсера зависит от активности других клиентов — если кто-то успел вклинится меж соседних попыток перебора, то блокировка откладывается.
 
По-хорошему надо бы либо считать количество отказов за период, либо количество отказов одному адресу подряд вне зависимости от остальных. Пойдем по второму пути — он примитивнее и ближе к тому, что предлагали вы.
 
В общем, как-то так:
 

Код:
#!/usr/bin/awk -f
 
BEGIN {
    ATTEMPTS_ALLOWED = 5;
    LOG = "rinetd.log";
    CONF = "rinetd.conf";
    PIDFILE = "rinetd.pid";
    CONF_FIELD_ACTION = 1;
    CONF_FIELD_IP = 2;
    LOG_FIELD_TIME = 1;
    LOG_FIELD_IP = 2;
    LOG_FIELD_ACTION = 9;
 
    while (getline < CONF)  
        if ($CONF_FIELD_ACTION == "deny")  
            deny_ip_conf[$CONF_FIELD_IP]++;
    close(CONF);
 
    while (getline < LOG) {
        if (!deny_ip_conf[$LOG_FIELD_IP]) {
            if ($LOG_FIELD_ACTION == "denied") {
                denied_ip_log[$LOG_FIELD_IP]++;
                if (denied_ip_log[$LOG_FIELD_IP] >= ATTEMPTS_ALLOWED) {  
                    print "deny", $LOG_FIELD_IP, "#"$LOG_FIELD_TIME >> CONF;
                    do_reload_conf++;
                }
            } else  
                delete denied_ip_log[$LOG_FIELD_IP];
        }
    }
    close(LOG);
 
    if (do_reload_conf) {
        getline pid < PIDFILE;
        if ( pid > 0 )
            system("kill -HUP" pid);
        else
            print "E: rinetd is not running" > "/dev/stderr";
    }
}

 
Не проверял, ибо не на чем — вы же не дали актуальных примеров, но должно, вроде бы, работать. Пути к файлам прописать не забудьте.

----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 00:28 24-03-2015 | Исправлено: ASE_DAG, 00:35 24-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
ASE_DAG
>> собственный, который собирает IP, которые в последствии нужно будет выгрузить в конфиг rinetd.conf
>То есть при каждом запуске парсим еще и rinetd.conf?
Нет, его парсить не надо. Для того чтобы не получилось так что мы снова добавляем IP адрес, который уже был добавлен ранее и существует проверка на наличие в логе надписи "denied". То есть эта запись в логе появляется если IP ( который во втором столбце лога) уже имеется в конфигурационном файле и он снова пытается зайти.
 
>Не надо так больше делать.
Не совсем понял упреков, но вот эта самая <-> сохраняется при копировании текста при помощи Shift+мышь в MC. И вот чтобы не вводить заблуждение что эти черточки-стреки якобы имеют место быть в реальном логе я и пояснил по поводу табуляции (ведь в MC по умолчанию она именно так и обозначается)
На счет выложить файлом ступил, извиняюсь, спешил быстрее донести инфу.
 
>Здесь у вас что-то не то написано. Вероятно, имеется в виду «если присутствует».
Выше я уже объяснил зачем эта проверка. Если присутствует в логе "denied", то данный IP уже присутствует в конфиге и он нам не интересен.
 
>если кто-то успел вклинится
Тут Вы абсолютно правы . Но такое ложное срабатывание будет крайне редко. Да и переборщик все равно спалиться если будет долбиться дальше. А считать общее количество попыток входа не вариант, так как не совсем понятно вход был законным или это была попытка перебора. В логах rinetd это к сожалению не указывается.
 
Чтобы было видно более ясную картину прикладываю более полный лог, в котором есть и переборщики и вполне законные входы и те кто уже забанены.
http://sderni.ru/266912
 
>В общем, как-то так:  
 
Спасибо огромное, буду разбираться.
 
Добавлено:
P.S. Небольшое пояснение к выложенному логу.
вот например 97.78.241.227, 5.200.52.203, 213.138.82.85 явные перебощики и именно их IP Необходимо занести в конфиг. (Счас я это делаю руками)
 
а например 212.7.209.11 и 116.236.243.50 уже когда-то  пытались переберать и были занесены мною в конфиг. Такие обычно еще пару раз "постучаться" и уходят восвояси, понимая что им там уже не чего не светит.
 
 
Добавлено:
Ну а если сменять адрес (а настырные сменять полюбому) то через 5 минут они снова будут вычислены скриптом и снова заблокированы.
Просто ну устал я это все ручками делать.
 
Добавлено:
кстати еще одно дополнение
Я обратил вниманием что у перебощиков никогда не бывает в 9 столбце done-local-closed, всегда только done-remote-closed. Можно еще сделать проверку на это значение. Но не забывать что и у законных пользователей тоже не всегда присутствует -local-.
Как я понимаю -remote- это если соединение с клиентом разорвал компьютер к которому он подключается, а -local- это если клиент сам разорвал соединение.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 07:05 24-03-2015 | Исправлено: CKOPnuOH, 07:06 24-03-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
CKOPnuOH
 
> Не совсем понял упреков
 
Задачу тем, кто вам, возможно, вызовется помогать, стоит не усложнять, а облегчать.
 
> Но такое ложное срабатывание будет крайне редко. Да и переборщик все равно спалиться если будет долбиться дальше.
 
Допустим, но помимо ложно-отрицательных это также приведет и к ложно-положительным срабатываниям:

12/Mar/2015:10:10:13     182.160.81.13    ...  done-remote-closed
12/Mar/2015:12:30:51     213.138.82.12    ...  done-remote-closed
12/Mar/2015:13:12:02     213.138.82.12    ...  done-remote-closed
12/Mar/2015:14:47:14     213.138.82.12    ...  done-remote-closed
12/Mar/2015:15:32:13     213.138.82.12    ...  done-remote-closed
12/Mar/2015:16:54:42     213.138.82.12    ...  done-remote-closed
12/Mar/2015:17:18:20     182.160.81.13    ...  done-remote-closed

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

Код:
#!/usr/bin/awk -f
 
BEGIN {
    ATTEMPTS_ALLOWED = 5;
    LOG = "rinetd.log";
    CONF = "rinetd.conf";
    PIDFILE = "rinetd.pid";
    LOG_FIELD_TIME = 1;
    LOG_FIELD_IP = 2;
    LOG_FIELD_ACTION = 9;
 
    while (getline < LOG) {
        if ($LOG_FIELD_ACTION == "done-remote-closed" &&
                !ip_for_denying[$LOG_FIELD_IP]) {
            if ($LOG_FIELD_IP == prev_ip) {
                if (++attempts >= ATTEMPTS_ALLOWED) {  
                    ip_for_denying[$LOG_FIELD_IP]++;  
                    print "deny", $LOG_FIELD_IP, "#"$LOG_FIELD_TIME >> CONF;
                }
            } else {
                prev_ip = $LOG_FIELD_IP;
                attempts = 1;
            }
        }
    }
    close(LOG);
 
    if (length(ip_for_denying) > 0) {
        getline pid < PIDFILE;
        if ( pid > 0 )
            system("kill -HUP" pid);
        else
            print "E: rinetd is not running" > "/dev/stderr";
    }
}

 
А по-хорошему, очевидно, нужно анализировать период времени, но для этого средства искоробчной Фри-БСД представляются мне скудноватыми (хотя можно и извернуться).


----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 19:51 24-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
После долгих проб и ошибок, вот что у меня получилось:

Код:
#!/usr/bin/awk -f
BEGIN {
LOG = "rinetd.log";
CONF = "rinetd.conf";
LOG_FIELD_TIME = 1;
LOG_FIELD_IP = 2;
LOG_FIELD_ACTION = 9;
CONT = 0;
 
    while ( getline < LOG ) {
        if ( $LOG_FIELD_ACTION != "denied" ) {
           if ( CONT == 0 ) {
               CONT++;
               check_ip = $LOG_FIELD_IP;
           } else  {
               if ( check_ip == $LOG_FIELD_IP ) {
                   CONT++;
                   if ( CONT == 5 ) {
                      CHECK_KEY = 0;
                      for ( ip_check in denied_ip_base ) {
                           if  ( ip_check == $LOG_FIELD_IP ) {
                               CHECK_KEY++;
                           }
                      }
                      if ( CHECK_KEY == 0 ) {
                           denied_ip_base[$LOG_FIELD_IP]++;
                           print "deny", $LOG_FIELD_IP, "#" ,$LOG_FIELD_TIME >> CONF;
                      }
                   }
               } else {
                   CONT = 0;
              }
           }
        }
    }
    close(LOG);
}

 
 
Добавлено:
ASE_DAG
Не дождался я Вас :))))
 
> Задачу тем, кто вам, возможно, вызовется помогать, стоит не усложнять, а облегчать.
Косяк понял и принял во внимание, причины я объяснил - торопился :)
 
>А по-хорошему, очевидно, нужно анализировать период времени
После сегодняшнего погружения с головой в изучения Вашего скрипта и тестов, полностью с Вами согласен. Необходимо еще проверять на сколько время из первой проверяемой строчки отличается от следующей проверяемой, и если разрыв во времени меньше минуты - то это "переборщик", а если нет то считать что запись принадлежит "своим", которые по стечению обстоятельства зашли 5 раз в течении часа.
 
Вот счас пытаюсь сообразить как сравнить $LOG_FIELD_TIME двух соседних строчек и вычислить разницу во времени.
Есть советы куда глянуть?

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 19:58 24-03-2015 | Исправлено: CKOPnuOH, 23:07 24-03-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
CKOPnuOH
 
> Не дождался я Вас :))))  
 
Не-не, скорее я не вытерпел ждать пока вы начнете что-нибудь сами делать и опубликовал кусочек кода :-)
 
> получилось
 
Ага! Сначала по форме: у вас все отступы раз’ехалися. Если это они у вас оригинале такие, то поаккуратнее будьте — сами же потом запутаетесь. А если это при копировании сбилось, то это от неправильного соответствия табуляции пробелам — надо, наверное, выяснить где именно несоответствие и исправить.
 
Плюс, что за точки в конце 25 и 26 строк? Если бы они были в оригинале, то программа бы просто не работала, значит опять ошибка копирования?
 
Кстати, что вообще делает 26 строка? Если выводит что-то человекочитаемое для оператора, то писать надо не на STDOUT, а на STDERR (> "/dev/stderr").
 
По-моему, вы забыли про перезагрузку конфига.
 
И да, конфиг все-таки надо парсить на предмет уже запрещенных адресов, если не хотите получать в нем дубликаты — вы же это собираетесь каждые N минут по одному и тому же месту прогонять.
 
> сообразить, как сравнить $LOG_FIELD_TIME двух соседних строчек и вычислить разницу во времени
 
Вам точно нельзя что-нибудь из сверхискоробочного попользовать? Ну то есть установить из пакетов или портов? Как я уже говорил, доступные в минимальной Фре средства мне видятся скудноватыми. Хорошо бы, конечно, сразу Perl, но раз если начали с AWK’ом, то пока GNU AWK (gawk) — там тоже функции для работы с датами найдутся.
 


----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 22:09 24-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
ASE_DAG

Цитата:
Сначала по форме:

Разъехались скорее всего. Так как скрипт отрабатывается без ошибок. И точки тоже из-за переноса. В самом скрипте их нет, я уже на это нарывался.
 
Чет у меня не получилось красиво, как у Вас, разместить тут, на форуме, листинг кода. Чтобы и подсветка была и чтобы отступы соответствовали. Как Вы это делаете?
 

Цитата:
Кстати, что вообще делает 26 строка

Забыл убрать, для тестов использовал. Мэтод тЫка ......он такой
 

Цитата:
по одному и тому же месту прогонять.

Ну я хотел после парсинга "сливать" (с удалением из /var/log ) лог в архив, так как после перезагрузки rinetd создаст его заново, освободив меня от парсинга уже добавленных в конфиг IP адресов.
 

Цитата:
По-моему, вы забыли про перезагрузку конфига.  

Как сделать перезагрузку вопрсов нет, поэтому пока этот кусочек кода я убрал на время отладки скрипта.
 

Цитата:
Вам точно нельзя что-нибудь из сверхискоробочного попользовать?

Ругаться будете? Вообще то пакеты Perl-а установлен, не знаю на сколько полно и готово к использованию, но они есть.
 
P.S. Не думал что будет сложно решить эту задачу с ипользованием исключительно шеловского языка. На виндовском cmd я бы его написал менее чем за полчаса-час.
 
 
 
 
 
 
Добавлено:
ASE_DAG
Убрал точки, лишнюю строчку и подправил отступы в листинге.
 
Добавлено:
Ну и последняя ремарка на сегодня.
Попробовал Ваш скрипт и в итоге он "поймал" на один больше IP чем мой на томже логе.
Беглый взгляд причины не выяснил, но помоему я догадываюсь почему так произошло, но это уже не сегодня. На сегодня с меня хватит этих условий, переборов, сравнений и выводов в файл Пора и отдохнуть. Так что завтра продолжу.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 22:54 24-03-2015 | Исправлено: CKOPnuOH, 23:08 24-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Попробовал с утра на свежую голову.
Моя идея не подтвердилась.
Идея заключалась в том, что я не правильно обрабатывал условие сравнения проверяемого IP и следующего за ним.
В строчке 31  

Код:
 
CONT = 0
 

Необходимо заменить на:

Код:
 
CONT = 1;
check_ip = $LOG_FIELD_IP;
 

 
В Вашем коде кстати этот момент учтен верно.
 
Но все равно, при парсинге вот этого лога - http://sderni.ru/267040
у Вас происходит на одно больше срабатывание чем у меня.
При этом этот IP не подходит под заданные мною условия и в тоже время, если более детально рассматривать лог, можно сказать что это все таки "переборщик".
 
Результат моего скрипта
 
Результат Вашего скрипта
 
Разница в IP 78.189.234.222
 
Что скажете по этому поводу?
 
 
 
Добавлено:
Нашел я в чем причина разницы результата :))))))
Так как в строчке 14 проверяете на наличие проверяемого IP во временной базе уже найденных за этот сеанс "нехороших" IP и если он там есть то данная строка пропускается.
А так как 78.189.234.222 как раз идет в перемешку с уже имеющимся IP который занесен в ip_for_denying вот и получается что 78.189.234.22 с учетом исключения строк с забанным уже ранее IP идет 5 раз подряд.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 07:05 25-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
По поводу проверки времени.
Я вижу это так.
Во время присвоения prev_ip, определяем еще одну переменную

Код:
 
prev_time = prev_h+prev_m*60+prev_s*60
 

где prev_h, prev_m, prev_s вычлененные значения из $LOG_FIELD_TIME, те что в конце и разделенные двоеточием:

Код:
 
12/Mar/2015:17:18:20
                          ^    ^   ^
                          h   m  s
 

 
Далее, после положительной проверки prev_ip и $LOG_FIELD_TIME проверяем разницу во времени и если она менее минуты продолжаем дальнейший код:

Код:
 
 
if (next_h < prev_h) { next_h = next_h+24};
 
next_time = next_h+next_m*60+next_s*60;
 
   if (next_time-prev_time < 60) {
 
   # продолжение кода
 
  }
 
 

где next_h, next_m, next_s вычлененные текущие значения из $LOG_FIELD_TIME  
 
Но на данный момент мне моих знаний не хватает на вычленение значений из  $LOG_FIELD_TIME :) , в остальном я думаю все логично.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 12:20 25-03-2015 | Исправлено: CKOPnuOH, 07:47 26-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Хех. split наше все

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 19:13 25-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Ну что же.
Вот итог нескольких дней "мучений"

Код:

#!/usr/bin/awk -f
BEGIN {
ATTEMPTS_ALLOWED = 5;
TIME_PERIOD = 60;
LOG = "/var/log/rinetd.log";
ARCH = "/var/log/rinetd.old";
CONF = "/usr/local/etc/rinetd.conf";
PIDFILE = "/var/run/rinetd.pid";
LOG_FIELD_TIME = 1;
LOG_FIELD_IP = 2;
LOG_FIELD_ACTION = 9;
getline pid < PIDFILE;
    if ( pid > 0 ) {
        system("kill -1 " pid);
        while ( getline < LOG ) {
            if ($LOG_FIELD_ACTION != "denied" && $LOG_FIELD_IP == prev_ip) {
                if (!ip_for_denying[$LOG_FIELD_IP]) {
                    split($LOG_FIELD_TIME, next_time, ":");
                    if (next_time[2] < prev_time[2]) { next_time[2]=next_time[2]+24 ; }
                    if ( next_time[2]*3600+next_time[3]*60+next_time[4]-priv_time[2]*3600-priv_time[3]*60-priv_time[4] < TIME_PERIOD ) {
                        if (++attempts >= ATTEMPTS_ALLOWED) {
                            ip_for_denying[key]++;
                            ip_for_denying[$LOG_FIELD_IP]++;
                            print "deny", $LOG_FIELD_IP, "\t\t#"$LOG_FIELD_TIME >> CONF;
                        }
                    }
                }
            } else {
                prev_ip = $LOG_FIELD_IP;
                attempts = 1;
                split($LOG_FIELD_TIME, priv_time, ":");
            }
        }
        close(LOG);
        if (ip_for_denying[key] != 0){
            system("cat " LOG " >> " ARCH);
            system("rm  " LOG);
            system("kill -1 " pid);
        }
    }
}

 
Добавлено:
Скрипт проверен на реальном сервере - все ок. Может кому пригодиться
 
Возможно есть моменты которые можно оптимизировать, но моих скудных знаний awk хватило только на это
 
ASE_DAG
Большое спасибо за помощь.

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 22:27 25-03-2015 | Исправлено: CKOPnuOH, 11:25 26-03-2015
CKOPnuOH



Member
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
После ночи работы скрипта была обнаружена ошибка
 
Странно, почему не вылезла сразу.
 
20-ую строку

Код:
 
if ( next_time[2]+next_time[3]*60+next_time[4]*60-priv_time[2]-priv_time[3]*60-priv_time[4]*60 < TIME_PERIOD ) {
 

 
необходимо привести к такому виду:
 

Код:
 
if ( next_time[2]+next_time[3]*60+next_time[4]-priv_time[2]-priv_time[3]*60-priv_time[4] < TIME_PERIOD ) {
 

 
То есть убрать умножение секунд на 60.
 
 
 
 
Добавлено:
P.S. Итоговый скрипт в предыдущем сообщении я исправил.
 
Добавлено:
Вот смотрю-смотрю на скрипт и понимаю что что-то не так
И вот БАЦ! А часы в секунды кто переводить то будет?
Вообще не понятно, как этот "кривой" скрипт срабатывает
 
Вообщем поправил итоговый скрипт Добавил умножение часов на 3600
Блин математик хренов ))

Всего записей: 339 | Зарегистр. 28-05-2004 | Отправлено: 09:42 26-03-2015
ASE_DAG



Gold Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
> system("cat " LOG " >> " ARCH);
> system("rm  " LOG);
> system("kill -1 " pid);
 
Ужас какой. :-) Можно не дергать все это безобразие по крону, а просто запустить скрипт-анализатор демоном — он будет сам отмерять интервалы и считывать только свежезаписанное в лог.
 
Плюс, я тогда не понимаю. Если вы, получается, обрабатываете только участок лога за некий период небольшой (5 минут, да?), то к чему вовсе было разбирать дату и анализировать интервалы? Считаете сколько было подключений с адреса за эти пять минут и все.
 
Короче, вот:

Код:
#!/usr/bin/perl
 
use Fcntl qw(SEEK_SET SEEK_END);
 
$attempts_allowed = 5;
$period           = 5 * 60;
$log              = "rinetd.log";
$conf             = "rinetd.conf";
$pidfile          = "rinetd.pid";
 
sub flush {
    my $h = select($_[0]); my $af=$|; $|=1; $|=$af; select($h);
}
 
open $pidfilefh, '<',  $pidfile  
    or die "rinetd is not running\n";
$pid = readline $pidfilefh;
close $pidfilefh;
 
until (open $logfh, '<', $log) {
    print STDERR "$log is not created yet, repeating...\n";
    sleep 3;
}
 
$SIG{HUP} = sub {
    seek $logfh, 0, SEEK_SET;
};
 
open my $conffh, '>>', $conf;
 
seek $logfh, 0, SEEK_END;
while (1) {
    my %attemts;
    my $denied;
    while (<$logfh>) {
        my ($time, $ip, $action) = (split)[0, 1, 8];
        if (++$attemts{$ip} == $attempts_allowed) {
            print STDERR "Banning $ip\n";
            print $conffh "deny $ip #$time\n";
            $denied++;
        }
    }
    if ($denied > 0) {
        flush $conffh;
        system "kill -HUP $pid"
    }
    sleep $period;
}

 
Повторяю: запускать демоном. И одна очевидная проблемка: когда ротатор журналов очистит rinetd.log, сей скрипт сам об этом не узнает и будет пытаться считать что-то далеко за его новым концом, поэтому настройте logrotate(8) пинать этот скрипт после ротации SIGHUP’ом.


----------
Dmitry Alexandrov <321942@gmail.com> [PGP] [BTC]

Всего записей: 9272 | Зарегистр. 12-05-2005 | Отправлено: 08:46 27-03-2015 | Исправлено: ASE_DAG, 08:47 27-03-2015
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154

Компьютерный форум Ru.Board » Операционные системы » UNIX » UNIX Shell: sh, bash, zsh; Coreutils и ко.; sed, awk, perl;


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru