Автоматизация проверки своего IP по спам базам. Вершин ту.


angel2s2 аватар

angel2s2 - Posted on 20 Ноябрь 2008

Не так давно я выкладывал собственноручный скрипт для автоматической проверки своего IP по спам базам. Там было всего 11 баз. Да и работал он через http, что естественно не очень хорошо...
Но есть способ получше =)

И заключается он в том, чтобы обращаться к DNSBL напрямую. =)

Делается это просто, вот пример:

$ host -t TXT 4.3.2.1.xbl.spamhaus.org

тут 4.3.2.1 - это IP адрес задом наперед, а xbl.spamhaus.org - один из многочисленных DNSBL =)

В результате получим ответ:

Host 4.3.2.1.xbl.spamhaus.org not found: 3(NXDOMAIN)

что говорит о том, что хост с IP адресом 1.2.3.4 в этой базе не числится.

А если сделаем такой запрос:

$ host -t TXT 79.35.217.90.xbl.spamhaus.org

то получит ответ:

79.35.217.90.xbl.spamhaus.org descriptive text "http://www.spamhaus.org/query/bl?ip=90.217.35.79"

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

Человек по "имени" darkk (http://darkk.net.ru/) поделился со мной замечательной ссылкой http://www.robtex.com/. Замечательна она тем, что этот сайт знает более 100 DNSBL и, естественно, позволяет проверить свой IP. Но кому будет оходта заходить каждый день на этот сайт, вбивать свой IP и ждать результатов? Естественно хочется этот процесс как можно лучше автоматизировать и забыть про это дело. А вспоминать, только тогда, когда IP, какого-то фига, попал в какую-то спам базу.
Вот для этого я и написал этот скрипт.

Вот что он умеет:

Использование:
        spam-check [[-e] [-g] [-s]] | [-v] | [-q] -p IP [IP2 [... [IPn]]]
        spam-check -i input_file [[-e] [-g] [-s]] | [-v] | [-q] -p IP [IP2 [... [IPn]]]
        spam-check -a dnsbl [[-e] [-g] [-s]] | [-v] | [-q] -p IP [IP2 [... [IPn]]]
        spam-check -d
 
         -e     - Показывать сообщения об ошибках
         -g     - Показывать успешные проверки (НЕ СПАМ)
         -s     - Не показывать не успешные проверки (СПАМ)
         -v     - Выводить все
         -q     - Ничего не выводить
         -p     - IP адрес (можно указывать несколько IP, через пробел)
         -i     - Файл со списком dnsbl-серверов
         -a     - Проверить по указанному dnsbl
         -d     - Вывести список всех dnsbl-серверов
         -V     - Вывести версию
         -h     - Показать справку
 
Особенности:
1. По умолчанию выводятся только не успешные проверки (СПАМ)
2. -g, -e и -s можно комбинировать.
3. -g, -e и -s нельзя использовать одновременно с -v и -q.
4. -v и -q одновременно использовать нельзя.
5. -p IP [IP2 [... [IPn]]] должен быть последним параметром.
6. -q абсолютно ничего не выводит.
7. Скрипт всегда возвращает следующие коды звершения:
        0   - данного IP в спам базе нет;
        1   - данный IP присутствует в спам базе;
        255 - ошибка в параметре, запрошена справка/версия;
              ошибки ответов от серверов не влияют на код завершения.
8. Если задано несколько IP и хоть один из них окажется хоть в кой-то спам базе, то код завершения будет равен 1.

В общем думаю тут и так все понятно. Скажу только, что ключ "-i" сделал на случай, если сервер http://www.robtex.com/ по какой-то причине откажется отдавать скрипту список DNSBL-серверов. А сохранить этот список предварительно можно так:spam-check -d > dnsbl.list или взять тут. А скрипт можно взять тут.

Если будут просьбы, сделаю порт для винды.

ЗЫ: Хочу выразить благодарность:
slash- указал на досадную ошибку с psbl.surriel.com (0.1.x)
Tenno Seremel - помог с правильным запросом для wget (0.1.x)
ramok - помог многими советами (wget, sed, dnsbl, printf) (0.1.x & 0.2.x)
darkk - помог с документацией по dnsbl и поделился ссылкой на сайт http://www.robtex.com/ (0.2.x)

5
Ваша оценка: Ничего Рейтинг: 5 (2 голоса)

UPD: Источник: мой блог

ЗЫ: Если кто найдет ошибки, прошу меня уведомить, в комментах (лучше в блоге) или по мылу на saimon.ghost [гав-гав] Гмыл0 [тут_точка] ком (защита от спама :-Р ).

UPD2: Добавил mktemp и защиту от запуска под рутом, а т.ж. опцию -u для разрешения запуска под рутом.

А еще этот скрипт нельзя запускать под рутом — иначе можно потерять любой существующий файл в системе если, например, перед запуском скрипта злоумышленник создаст симлинк /tmp/spam-check.tmp -> /etc/passwd.

mktemp призван решать эту проблему.

Я не уверен, что все dnsbl поддержикают TXT-записи, возможно, кто-то отдаёт только A или, к примеру, CNAME. В википедии вообще утверждалось, что спрашивать сто´ит -t ANY, но я не знаю, насколько это так. Пожалуй, в качестве авторитетного источника я бы посмотрел код postfix-а. :)

Ключ «-e» ужасен, сообщения об __ошибках__ должны показываться всегда, при том, наверное, в stderr, ключ «-s» довольно странен, кто не хочет вывода — пусть сделает &>/dev/null, после удаления «-s» можно, наверное, приравнять -v и -g.

«-p» тоже не несёт никакой нагрузки, если он должен быть последним — может быть проще начинать список IP с первой опции, которая начинается с цифры? А тогда, когда потребуется добавить домены — с первой опции, которая начинается с буквы, а тогда, когда захочется проверять домены вида -foo-.-bar-.com — отделять список доменов двумя минусами (опциональными, естественно, если домены не начинаются с знака минуса).

Всё это должно несколько упростить код и сделать интерфейс командной строки более «классическим».

Надеюсь, меня еще не ненавидят за эти пометки на полях. :)

// darkk, который ненавидит кривой ЖЖ-шный openid и всё никак не соберется настроить byteflow :(

За mktemp огромное спасибо, не знал про него. Хотя скрипт я не планировал для запуска под рутом.
Добавил mktemp и защиту от запуска под рутом, а т.ж. опцию -u для разрешения запуска под рутом.

На счет TXT, A, CNAME и ANY записей я тоже не уверен. Некоторые сервера возвращают ошибки.
Например (для TXT):

$ spam-check -s -e -p 90.217.35.79
Результат       Сервер                             Ответ сервера
--------------------------------------------------------------------------------------90.217.35.79------------
[ERROR]       - c10.rbl.hk                       - 79.35.217.90.c10.rbl.hk has no TXT record
[ERROR]       - images.rbl.msrbl.net             - ;; connection timed out; no servers could be reached
[ERROR]       - rbl.snark.net                    - 79.35.217.90.rbl.snark.net has no TXT record
[ERROR]       - rot.blackhole.cantv.net          - 79.35.217.90.rot.blackhole.cantv.net has no TXT record

Точно так же было и с ANY (я вначале его использовал, а потом решил сделать TXT). Проверял еще и с A и CNAME, но и тут были ошибки.

Под ошибками подразумевается, что сервер не ответил (time out) или не реагирует на TXT запись, т.е. основываясь на ответе сервера. А не ошибка в скрипте. Поэтому я и сделал ключ -e.
-s - для того чтобы не выводить сообщения о наличии IP в спам базе. Полезен он может быть тогда, когда ты хочешь узнать какие сервера не отвечают нормально (например, чтобы удалить их из файла, который можно подключать по ключу -i).
Все сообщения скрипт выводит в стандартный поток. Я не знаю как разделить вывод на потоки stderr и stdout. Если расскажешь как, сделаю.
С доменными именами скрипт не работает. Если указать после -p доменное имя, то скрипт будет пытаться сделать свою работу, но будут сыпаться ошибки сплошь и только. Так что ж правильное задание IP я оставляю тому кто будет задавать эти IP =)))))))))))))

А вот ключ -р я убирать не хочу. Мне он нравится. :)))
К тому же как я их тебе отловлю?

# Настройка заданных параметров
((i = 1))
while (( i <= $param_count )) ; do
	case "$1" in
	        "-u"	) IS_NO_ROOT='no' ; shift ; ((i += 1)) ;;
           ( cut ..................................................................... )
		"-p"	) shift ; while (( $# > 0 )) ; do PAR=$1 ; IP_LIST+=("$PAR") ; shift ; done ; break ;;
           ( cut ..................................................................... )
		*	) bad_param $1;;
	esac
done

-p повесить на * и там уже проверять параметры по шаблону для ИП?

Или так?

# Настройка заданных параметров
((i = 1))
while (( i <= $param_count )) ; do
	case "$1" in
           ( cut ..................................................................... )
                "[0..9]{1,3}\.[0..9]{1,3}\.[0..9]{1,3}\.[0..9]{1,3}" ) IP_LIST+=("$1") ; shift ;;
           ( cut ..................................................................... )
	esac
done

Но я не уверен, что это сработает... Позже потестю, подумаю, посмотрю, может придумаю чего.

> Надеюсь, меня еще не ненавидят за эти пометки на полях. :)
Ну что за детский сад, а? Конечно НЕТ! Наоборот, спасибо тебе за эти пометки, буду знать, чего людям не хватает, чего добавить/убавить! =)))))))))))

Про запуск под рутом это была шутка как раз на тему того, что надо код писать аккуратнее — а то могут систему поломать сильно. А вообще, идея запрещать что-то запускать под рутом не очень хороша, она как бы говорит "я очень сильно не уверен в том, что я пишу программы хорошо". :-)

А еще в новом скрипте нет проверки на то, что mktemp действительно что-то создал.
E.g. export TMPDIR=/dev/null; mktemp — и всё поломалось.
Ну и можно подумать о использовании set -e (оно же set -o errexit) — для того, чтоб быть уверенным, что никакая ошибка не останется незамеченной.

Для разделения stdout и stderr надо использовать перенаправления. Например, чтоб перенаправить stdout в stderr: 1>&2, подробнее в advanced bash scripting guide (на мой взгляд — продвинутые перенаправления это одна из самых сложных частей bash-а).

А про -p ramok ниже написал.

// darkk, который писал не про то, чего людям не хватает, а исключительно про стиль :)

Ну да, запрет запуска чего-либо под рутом, это не гуд. Но все же я еще новичек в мире пингвинов, поэтому и не очень то уверен в своем коде :))))) Да и правило у меня такое есть: "Перестраховаться никогда не вредно" =))

Хм... На счет mktemp... Очень, хм... Я думал он всегда и по любэ создает временный файлик... Спасибо, что носом ткнул, буду думать на эту тему :))

stdout и stderr... Но то, что ты говоришь, это же вывод программы/скрипта. Получается в самом скрипте тоже можно использовать такой подход? Классно, а мне что-то в голову не пришло, когда писал.
Про перенаправление вывода я знаю и гуид этот читал, правда не весь, все времени не хватает :( .

-р - ага, прочитал, изучил. Теперь надо время найти чтобы переделать :))) В общем все обновления 100% будут в моем блоге, буду в комментах там писать.

Ну как же он создаст временный файл на, например, переполненной ФС? Ошибки есть всегда и, к сожалению, зачастую половина кода — обработка возможных ошибок. Немного исправляют ситуацию исключения (в том же python и C++), но не принципиально, т.к. тогда приходится exception-safe код, который несколько (хоть и не всегда значительно) сложнее обычного. :)

bash скрипт не более чем последовательность команд оболочки, естественно можно использовать и все перенаправления, и пайпы и прочие счастия командной строки =)

// darkk, который зачем-то пишет комментарии в блоги вместо подготовки лекции по спецкурсу ОС Linux

Да, ты полностью прав.
Я когда пересел с винды на пингвина и начал учить его консоль (bash) просто офигевал от возможностей. А теперь я просто в недоумении как же я раньше жил под виндой?.. :)))))))))))))

традиционно используют -q для того что бы заглушить вывод. на вскидку grep
ps
скрипт сам не смотрел, но подозреваю что там не getopts?

ramok, сорри, но я что-то не понял о чем ты. :)))

примеры разбора параметров в шел скриптах с помощью getopts
http://linsovet.com/sh-getopts
http://linsovet.com/node/205
http://linsovet.com/x11-screenshot-script

Спасибо, идея хорошая. =)
Но не пойму, как к одному ключу несколько параметров задавать? Т.е. для ключа -p может быть n IP'шников. Как тут быть?

Такого обычно не делают.

Делают обычно так:
1. Не делают вообще ключа, а "после разбора всех ключей должны остаться список параметров" (как darkk выше и советовал)

$ ckspam -qab 1.2.3.4 2.2.2.2 3.3.3.3

где -qab это разные ключики -q -a -b

В примере из http://linsovet.com/sh-getopts после

shift $(($OPTIND-1))

в $1 $2 $3 и так делее как раз IP и останутся

Этот случай конечно самый правильный, так все утилиты работают куда ни плюнь Ж:-)

2. Или разрешают ключ повторять много раз

$ ckspam -qabp 1.2.3.4 -p 2.2.2.2 -p 3.3.3.3

Второй случай активно использует curl например.

$ curl --progress-bar --ftp-create-dirs -u root:root -T ./www/cgi-bin/atconf ftp://192.168.0.126//flash/www/cgi-bin/ -T ./www/data/header.gif ftp:/192.168.0.126/flash/www/data/

Можно повторять много раз ключик -T

3. Или перечисляют параметры через запятую и парсят дополнительно (это если первый случай использовать нельзя, нужно например несколько списков перечислить)

$ ckspam -qabp 1.2.3.4,2.2.2.2,3.3.3.3

Так делает gcc для всяких флажков которые нужно передавать программам, которые он сам в свою очередь вызывает.
Например:

-Wl,-elf2flt

Этот параметр говорит gcc вызвать линковщик с параметром -elf2flt

ООООО... Спасибо! Понял теперь, как с этим чудом возиться :). Попробую, повожусь. :))))
Хотя в принципе это, думаю, и не так то уж важно, главное, что работает. ;)
Но как будет время сделаю по новой :)))

Отправить комментарий

Google Friend Connect (leave a quick comment)
loading...
Содержание этого поля является приватным и не предназначено к показу.