<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBS: мониторинг попаданий в DNSBL]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=5661&amp;type=atom" />
	<updated>2011-03-28T12:31:57Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=5661</id>
		<entry>
			<title type="html"><![CDATA[VBS: мониторинг попаданий в DNSBL]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=46981#p46981" />
			<content type="html"><![CDATA[<p>Приветствую!</p><p>Ситуация - есть у нас один большой клиент. Можно сказать ключевой. И есть у него неприятная черта - его почтовый сервер на DNSBL прямо-таки молится. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /><br />В общем стоит попасть в блэклист баракуды и начинается коллапс с недоходящей до них почтой(ибо баллами они не пользуются, а блокируют безоговорочно). Т.к. в нескольких случаях ситуация возникала в пятницу под вечер, то наши сотрудники следуя традиции (&quot;само исправится&quot; - ведь даже менеджеры, свободно общающиеся на английском с клиентами, оказываются неспособны прочитать банальное уведомление о блокировке) сообщали о проблеме только в понедельник. А т.к. удаление из списка процесс не быстрый, то пол дня без возможности связаться с клиентом. Момент крайне неприятный.</p><p>Собственно для того чтобы оперативно отслеживать данную ситуацию и решил написать скриптик(в бою пока не был, но на IP из серверных логов потестировал). Надеюсь будет полезен не только мне.</p><div class="codebox"><pre><code>
&#039; VB Script Document
Option Explicit

&#039; http://www.barracudacentral.org/rbl/how-to-use
&#039; http://ru.wikipedia.org/wiki/DNSBL
&#039; если IP есть в блоклисте, то будет резолвиться хостнейм вида IP_наоборот.black.list.hostname
&#039; например, для 192.149.23.63 на баракуде нужно проверять 63.23.149.192.b.barracudacentral.org
&#039; резолвиться будет в адрес 127.0.0.x (обычно, но не обязательно)
&#039; X - в зависимости от причины попадания в список(хотя официального документа на этот счёт видимо нет)
&#039; http://www.spamhaus.org/faq/answers.lasso?section=DNSBL%20Usage#202 - расшифровка X для SPAMHOUSE

Dim RegPath, Write2Reg
RegPath = &quot;HKLM\Software\VBS Scripts Settings\DNSBL_Monitoring&quot; &#039; Храним тут
Write2Reg = true &#039; false - отключает запись в реестр(а вдруг будет нужно?)

&#039; Параметры отправки почты
Dim smtp_host, smtp_auth, smtp_port, smtp_user, smtp_pass, from_email, to_email
smtp_host = &quot;mail.mydomen.com&quot;
smtp_auth = 0 &#039; если 1(т.е. с авторизацией), то пароль нужен обязательно
smtp_port = 25
smtp_user = &quot;myusername&quot;
smtp_pass = &quot;mypassword&quot;
from_email = &quot;dnsbl.monitoring@ru.mydomen.com&quot;
to_email = &quot;my.name@ru.mydomen.com&quot;

Dim DNSBL, Hosts, TestHost
TestHost = &quot;8.8.8.8&quot; &#039; &quot;неумерающий&quot; хост для проверки доступности интернета, например публичный ДНС гугла

Set DNSBL = CreateObject(&quot;Scripting.Dictionary&quot;) &#039;список блэклистов
DNSBL.Add &quot;b.barracudacentral.org&quot;, &quot;Вражина №1&quot;
DNSBL.Add &quot;sbl.spamhaus.org&quot;, &quot;SBL Spamhaus&quot;
DNSBL.Add &quot;xbl.spamhaus.org&quot;, &quot;XBL Spamhaus&quot;
DNSBL.Add &quot;pbl.spamhaus.org&quot;, &quot;PBL Spamhaus&quot;
&#039;DNSBL.Add &quot;zen.spamhaus.org&quot;, &quot;ZEN Spamhaus&quot;
&#039; OFF потому что объединяет ответ не только с SBL, XBL, PBL, но и с cbl.abuseat.org
&#039; к тому-же если IP числится только в cbl.abuseat.org(а не в SBL, XBL or PBL),
&#039; то сайт выдаёт &quot;LISTED&quot;, а по лукапу выходит NOTLISTED
&#039; подробности - http://www.spamhaus.org/faq/answers.lasso?section=DNSBL%20Usage#252
DNSBL.Add &quot;cbl.abuseat.org&quot;, &quot;cbl.abuseat.org&quot;
DNSBL.Add &quot;bl.spamcop.net&quot;, &quot;bl.spamcop.net&quot;
DNSBL.Add &quot;dnsbl.sorbs.net&quot;, &quot;dnsbl.sorbs.net&quot;
DNSBL.Add &quot;web.dnsbl.sorbs.net&quot;, &quot;web.dnsbl.sorbs.net&quot;
DNSBL.Add &quot;bl.tiopan.com&quot;, &quot;bl.tiopan.com&quot;

Set Hosts = CreateObject(&quot;Scripting.Dictionary&quot;) &#039;список проверяемых IP-адресов
Hosts.Add &quot;94.100.177.6&quot;, &quot;pop3.mail.ru&quot;
Hosts.Add &quot;74.125.39.109&quot;, &quot;pop.gmail.com&quot;
Hosts.Add &quot;87.250.250.124&quot;, &quot;imap.yandex.ru&quot;
Hosts.Add &quot;86.35.249.224&quot;, &quot;Blocked IP2&quot;
Hosts.Add &quot;194.250.63.103&quot;, &quot;Blocked IP&quot;

&#039;##############################################################################
&#039;######                      все настройки выше                          ######
&#039;##############################################################################
Dim TotalTimer
TotalTimer = Timer

&#039; объекты:
Dim WshShell
Set WshShell = WScript.CreateObject(&quot;WScript.Shell&quot;)

Dim Key &#039; для возврата значений ключа реестра
Dim arrDNSBL, arrHosts
arrDNSBL = DNSBL.Keys
arrHosts = Hosts.Keys

Dim BBody, Need2Report
BBody = &quot;&lt;HTML&gt; &lt;meta http-equiv=&quot;&quot;Content-Type&quot;&quot; content=&quot;&quot;text/html; charset=windows-1251&quot;&quot; /&gt; &lt;b&gt;DNSBL_Monitoring&lt;/b&gt;&lt;br&gt;начало работы скрипта: &quot; &amp; Now &amp; &quot;&lt;hr&gt;&quot; &#039; &quot;начинаем&quot; тело
Need2Report = false &#039; если появятся новые данные по блокировкам, станет true


Dim i, j
For i = LBound(arrDNSBL) To UBound(arrDNSBL) &#039;пинганём список...
 DNSBL.Item(arrDNSBL(i)) = vbNullstring &#039; очистка перед заполнением
 For j = LBound(arrHosts) To UBound(arrHosts) &#039;пинганём список...
  &#039;читаем соотв. ключ в реестре и проверяем что IP ещё не там
&#039; ##############################################################################
  if Ping(TestHost) then &#039; инет есть, можно проверять BL
    Key = DoTheKey(RegPath, arrDNSBL(i), false, vbNullstring)
    &#039;wscript.echo &quot;Key = &quot; &amp; Key
&#039;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
    if StrComp(Key, vbNullstring, vbTextCompare) &lt;&gt; 0 then &#039; если ключ непустой - проверяем есть ли в нём IP, иначе переход на проверку хоста

      if InStr(1, Key, arrHosts(j), vbTextCompare) &gt; 0 then &#039;если IP уже блокировался
        if not IsInBL(arrDNSBL(i), arrHosts(j)) then &#039; если более не в списке - уведомляем что IP удалён из BL
          BBody = BBody &amp; &quot;IP-адрес &quot; &amp; arrHosts(j) &amp; &quot;(&quot; &amp; Hosts.Item(arrHosts(j)) &amp; &quot;) был удалён из DNSBL: &quot; &amp; arrDNSBL(i) &amp; &quot;&lt;br&gt;&quot;
          Need2Report = true
        end if
       else &#039;&lt;&lt;2&gt;&gt; ранее IP в BL не числился
        if IsInBL(arrDNSBL(i), arrHosts(j)) then &#039; попал в список - уведомляем
          BBody = BBody &amp; &quot;IP-адрес &quot; &amp; arrHosts(j) &amp; &quot;(&quot; &amp; Hosts.Item(arrHosts(j)) &amp; &quot;) был занесён в DNSBL: &quot; &amp; arrDNSBL(i) &amp; &quot;&lt;br&gt;&quot;
          Need2Report = true
        end if
      end if &#039; IP в списке?
       
    else &#039;&lt;1&gt; если Key пустой =&gt; блоклист ранее не проверялся

     if IsInBL(arrDNSBL(i), arrHosts(j)) then &#039; попал в список - уведомляем
       BBody = BBody &amp; &quot;IP-адрес &quot; &amp; arrHosts(j) &amp; &quot;(&quot; &amp; Hosts.Item(arrHosts(j)) &amp; &quot;) был занесён в DNSBL: &quot; &amp; arrDNSBL(i) &amp; &quot;&lt;br&gt;&quot;
       Need2Report = true
     end if

   end if
&#039;                                      &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;

     else &#039; или инета нет, или гугл накрылся :)

&#039;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
      wscript.echo &quot;Паночка померла :)&quot;
&#039;                                      &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;
  end if &#039; жив ли гугл?
 Next &#039;j
 Key = DoTheKey(RegPath, arrDNSBL(i), true, DNSBL.Item(arrDNSBL(i)))
Next &#039;i
BBody = BBody &amp; &quot;&lt;hr&gt;&quot; &amp; Now &amp; &quot; =&gt; Проверка завершена. Продолжительность проверки: &quot; &amp; Timer - TotalTimer &amp; &quot; сек.&quot;
BBody = BBody &amp; &quot;&lt;/HTML&gt;&quot;

if Need2Report then call SendMail(&quot;DNSBL Monitoring Report&quot;, BBody) &#039; если были подвижки в списках, надо уведомить

&#039;###############################################################################
function IsInBL(DNSBL_name, HOST2Chk) &#039;Оцениваем результаты пинга
 if Ping(RevIP(HOST2Chk) &amp; &quot;.&quot; &amp; DNSBL_name)  then &#039;если до сих пор в BL то...
   &#039; переформируем список заблокированных хостов для этого BL
   IsInBL = true
   if DNSBL.Item(DNSBL_name) = vbNullstring then
     DNSBL.Item(DNSBL_name) = HOST2Chk
    else
     DNSBL.Item(DNSBL_name) = DNSBL.Item(DNSBL_name) &amp; &quot;|&quot; &amp; HOST2Chk
   end if
  else
   IsInBL = false
 end if
end function
&#039;###############################################################################
Function Ping(Ip2Ping) &#039;пингуем хост
 Dim Hosts(), strComputer, objWMIService, colPings, objStatus
 Set objWMIService = GetObject(&quot;winmgmts:\\.\root\cimv2&quot;)
 Set colPings = objWMIService.ExecQuery _
    (&quot;Select * From Win32_PingStatus where Address = &#039;&quot; &amp; Ip2Ping &amp; &quot;&#039;&quot;)
 For Each objStatus In colPings
  If IsNull(objStatus.StatusCode) Or objStatus.StatusCode&lt;&gt;0 Then
    &#039;в принципе, уже не пингуется... но дополнительно проверим и IP(зарезолвился или нет)
    If objStatus.ProtocolAddress = vbNullstring Then Ping = False
   Else
    if StrComp(TestHost, Ip2Ping, vbTextcompare) &lt;&gt; 0 then
     WScript.Echo &quot;ping host &quot; &amp; Ip2Ping &amp; &quot; .... LISTED&quot;
     wscript.echo &quot;Return IP: &quot; &amp; objStatus.ProtocolAddress
    end if
    Ping = True
  End If
 Next
End Function
&#039;###############################################################################
Function RevIP(IP) &#039; &quot;переворачиваем&quot; IP-адрес
 Dim arrIPs, i
 RevIP = vbNullString
 arrIPs = Split(IP, &quot;.&quot;, -1, vbTextCompare)
 If UBound(arrIPs) &gt; 3 Then wscript.echo &quot;Неверный IP! &quot; &amp; IP : wscript.quit
 For i = UBound(arrIPs) To LBound(arrIPs) step -1
  If arrIPs(i) &gt; 254 Then wscript.echo &quot;Неверный IP! &quot; &amp; IP : wscript.quit
  If i = 3 Then RevIP = arrIPs(i) Else RevIP = RevIP &amp; &quot;.&quot; &amp; arrIPs(i)
 Next
End Function
&#039;###############################################################################
&#039; чтение-создание ключей в реестре
&#039; если Make = true, то записываем значение KeyValue в ключ
&#039; если Make = false, то пытаемся считать ключ и при его отсутствии создаём с значением KeyValue
Function DoTheKey(RegPath, RegKey, Make, KeyValue)
If Make and not Write2Reg Then &#039; Есди писАть в реестр запрещено, то писАть в реестр нельзя
  Exit Function
End If
If Make Then &#039; если задача записать, то:
  WshShell.RegWrite RegPath &amp; &quot;\&quot; &amp; RegKey, KeyValue, &quot;REG_SZ&quot;
 Else &#039; если только прочесть, то всё немного сложнее :)
  On Error Resume Next &#039; половим ошибки при отсутствии ключа(вариант что прав на чтения не хватает не рассматривается)
  DoTheKey = WshShell.RegRead(RegPath &amp; &quot;\&quot; &amp; RegKey)
  If Err.Number &lt;&gt; 0 Then
    wscript.echo &quot;не найден ключ или раздел в реестре: &quot; &amp; RegPath &amp; &quot;\&quot; &amp; RegKey
    Err.Clear   &#039; Clear the error.
    WshShell.RegWrite RegPath &amp; &quot;\&quot; &amp; RegKey, KeyValue, &quot;REG_SZ&quot; &#039; если ключа нет, то создаём его и заносим в него переданное значение(KeyValue)
      If Err.Number = 0 Then
        wscript.echo &quot;в реестре создан ключ: [&quot; &amp; RegPath &amp; &quot;\&quot; &amp; RegKey &amp; &quot;] со значением [&quot; &amp; KeyValue &amp; &quot;].&quot;
        DoTheKey = WshShell.RegRead(RegPath &amp; &quot;\&quot; &amp; RegKey)
      End If
    Else
&#039;    wscript.echo &quot;Значение ключа &quot; &amp; RegKey &amp; &quot; = [&quot; &amp; WshShell.RegRead(RegPath &amp; &quot;\&quot; &amp; RegKey) &amp; &quot;]&quot;
    DoTheKey = WshShell.RegRead(RegPath &amp; &quot;\&quot; &amp; RegKey)
  End If
  Err.Clear   &#039; Clear the error.
  On Error Goto 0
End If
End Function
&#039;###############################################################################
Sub SendMail(Subject, Body)&#039; отправка уведомления через CDO
Dim iMsg, iConf, Flds
  Set iMsg=CreateObject(&quot;CDO.Message&quot;)
  Set iConf=CreateObject(&quot;CDO.Configuration&quot;)
  Set Flds=iConf.Fields
&#039;http://msdn.microsoft.com/en-us/library/ms873037(EXCHG.65).aspx
&#039;The mechanism to use to send messages.
&#039; cdoSendUsingPort (2)
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendusing&quot;) = 2
&#039;The authentication mechanism to use when authenticating to a SMTP service over the network.
&#039;This field is relevant only if the http://schemas.microsoft.com/cdo/configuration/sendusing field is set to cdoSendUsingPort.
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout&quot;) = 10
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpauthenticate&quot;) = smtp_auth
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserver&quot;) = smtp_host
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/smtpserverport&quot;) = smtp_port
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendusername&quot;) = smtp_user
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/sendpassword&quot;) = smtp_pass
  Flds.Item(&quot;http://schemas.microsoft.com/cdo/configuration/languagecode&quot;) = &quot;ru&quot; &#039;?
  Flds.Update
  iMsg.Configuration = iConf
  iMsg.To = to_email
  iMsg.From = from_email
  iMsg.Subject = Subject
  iMsg.BodyPart.Charset = &quot;windows-1251&quot;
  iMsg.HtmlBody =  Body
  iMsg.Send

Set iMsg=Nothing
Set iConf=Nothing
Set Flds=Nothing
End Sub</code></pre></div><p>Принцип работы простой: два словаря(блэклисты и IP офисов и сервера), проверяем присутствие IP в чёрном списке(или исчезновение оттуда) и уведомляем об этом на почту. Список текущих блокировок хранится в реестре(я сохраняю в HKLM, чтобы можно было в любой момент без выкрутасов посмотреть что там <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />). Если IP уже числится в реестре, то по нему повторных отчётов не шлётся. Ну и чтобы для проверки наличия интернета пингуем гугл.<br /><span class="bbu">При отсутсвии ветки/параметра в реестре они создаются автоматически, в процессе работы параметры из этой ветки могут перезаписываться</span> - несмотря на п.6.5 отключать запись в реестр по умолчанию не стал(переменная Write2Reg - рудимент, присутствующий у меня везде где есть зработа с реестром <img src="//forum.script-coding.com/img/smilies/wink.png" width="15" height="15" />). Во-первых, данная ветка по умолчанию отсутствует, во-вторых, без неё полноценно скрипт функционировать не будет.</p><p>Метод проверки есть в скрипте, на википедии, в FAQ спамхауса(ссылки в коментариях скрипта), поэтому дублировать не буду.</p><p>Единственное что не протестировал - ситуацию с удалением IP из DNSBL - своих IP в блоках не имею(ттт), а чужие разблокировать не буду(ибо скорее всего спамерские - из логов сервера брал) - если кто-то может протестировать, буду рад. Или буду ждать попадания наших IP в BL. <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p><p>Список DNSBL можно посмотреть <a href="http://whatismyipaddress.com/blacklist-check">здесь</a>(кстати, удобный инструмент для ручной проверки попадания в BL).</p><p>P.S. Остался правда один момент - команда вроде такой &quot;nslookup -type=ANY 103.63.250.194.b.barracudacentral.org&quot; даёт больше информации, и если в случае с баракудой пользы от ней немного(выдаёт только ссылку на проверку IP), то для спамхауза это не так. У спамхауза в возвращаемом адресе &quot;закодирован&quot; как минимум список в который IP попал - но это в теории. В практике в спамхаузом пока не срабатывает&nbsp; (для IP из PBL-списка), впрочем я так до конца не понял систему взаимодействия их BL. Отсюда вопрос: есть ли под VBScript класс позволяющий выполнять запросы к DNS-серверу? В MSDN пока наткнулся на <strong>DNS WMI Provider</strong>, но беглый осмотр навёл на мысль что он предназначен для управления MS DNS-сервером. Глубже пока не копал - текущего скрипта мне достаточно(подробности через nslookup узнаю)... В идеале обойтись без сторонних контролов <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" /></p>]]></content>
			<author>
				<name><![CDATA[BeS Yara]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=25643</uri>
			</author>
			<updated>2011-03-28T12:31:57Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=46981#p46981</id>
		</entry>
</feed>
