четверг, 6 ноября 2014 г.

Mikrotik. Запрещаем доступ к определенным сайтам по IP.

Собственно небольшая заметка, которая пригодится тем, кто хочет порезать рекламу на некоторых сайтах по IP на домашнем / офисном Mikrotik'е, ну и вообще, не только рекламу, а и доступ к любым сайтам из списка. Для начала нам необходимо уяснить, что в настройках Mikrotik в разделе IP -> Firewall -> Adress Lists есть списки адресов. Т.е. первое что нужно сделать - это добавить туда какие-то хосты, а потом уже писать соответствующие правила для firewall'а (например, разрешить, запретить и т.п.). Добавим туда три сайта с рекламой по IP:

/ip firewall address-list
add address=195.234.99.231 comment=rarenok.biz list="Blocked sites"
add address=193.105.200.13 comment=post.rmbn.net list="Blocked sites"
add address=195.234.99.4 comment=realer.info list="Blocked sites"

А теперь добавим правило для firewall'а:

/ip firewall filter
add action=reject chain=forward comment="Blocked sites" dst-address-list=\
    "Blocked sites" dst-port=80 protocol=tcp reject-with=tcp-reset

Тут все просто. Для всех сайтов из списка Blocked sites, т.е. где Dst IP совпадает с IP из списка у нас будет действовать action reject с reject-with = tcp-reset. Таким образом при обращении к ним. браузер будет просто считать что соединение было сброшено и не будет пытаться "достучаться" до них.

Теперь попробуем "расширить" данный пример для сайтов с мобильной рекламой. Скачиваем любой из представленных на различных "околомобильных" форумах файл hosts, в котором якобы прописаны баннерные сети и прочая гадость, с которых Android устройства тащат рекламу. Файл hosts надо как-то распарсить, для того чтобы добавить эти хосты в список Mikrotik'а. Это можно сделать к примеру, с помощью следующего PHP скрипта:

<?php

$f = file_get_contents("hosts");
$hosts = explode("\n",$f);
foreach ($hosts as $host) {
 if (preg_match("/^([0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3})\s(.*)/",$host,$res)) {
 $dns_record = dns_get_record($res[2], DNS_A);
 // var_dump($dns_record);
 if (!empty($dns_record[0])) {
 echo '/ip firewall address-list add address='.$dns_record[0]['ip'].' comment='.$res[2].' list=host_mikrotik'."\r\n";
 }
 }

}
?>

В результате в stdout у нас будут выведены соответствующие команды для Mikrotik'а. Пример:

/ip firewall address-list add address=68.170.148.7 comment=208.185.87.8.liveadvert.com list=host_mikrotik
/ip firewall address-list add address=64.151.102.166 comment=t2.leadlander.com list=host_mikrotik
/ip firewall address-list add address=38.113.1.80 comment=counter.bizland.com list=host_mikrotik
/ip firewall address-list add address=46.30.212.41 comment=adpop.theglobe.net list=host_mikrotik
/ip firewall address-list add address=217.163.21.34 comment=ad.bharatstudent.com list=host_mikrotik

Т.е. эти сайты будут добавлены в список host_mikrotik. Ну и на "закуску" самое интересное. Думаю, все мы понимаем что резать что-либо по IP не есть хорошая идея. Т.к. "под нож" могут попасть и вполне полезные сайты на том же IP. А можно ли использовать в правилах firewall'а имена хостов вместо IP?

Ответ на этот вопрос как раз дает статья - Use host names in firewall rules. Оставляю вам ее для самостоятельного изучения. Если вкратце - то все строится на динамическом резольвинге имен. Так, например, если вы введете в терминале Mikrotik'а put [:resolve vk.com], то увидите IP vk.com ... только в статье предлагается это делать с периодичностью 1 час. Т.е. раз в час в шедулере запускается скрипт updatehostnames, который обновляет адреса в заданном списке (изначально они задаются как 0.0.0.0). Ну и совсем напоследок - мануал по скриптовому языку в Mikrotik.

p.s. На всякий случай текст скрипта Mikrotik для обновления IP в списке:

 /system script add \
   name=resolvehostnames policy=write,read \
   source="# define variables\r\
   \n:local list\r\
   \n:local comment\r\
   \n:local newip\r\
   \n:local oldip\r\
   \n\r\
   \n# Loop through each entry in the address list.\r\
   \n:foreach i in=[/ip firewall address-list find] do={\r\
   \n\r\
   \n# Get the first five characters of the list name\r\
   \n  :set list [:pick [/ip firewall address-list get \$i list] 0 5]\r\
   \n\r\
   \n# If they're 'host_', then we've got a match - process it\r\
   \n  :if (\$list = \"host_\") do={\r\
   \n\r\
   \n# Get the comment for this address list item (this is the host name to u\
   se)\r\
   \n    :set comment [/ip firewall address-list get \$i comment]\r\
   \n    :set oldip [/ip firewall address-list get \$i address]\r\
   \n\r\
   \n# Resolve it and set the address list entry accordingly.\r\
   \n    : if (\$newip != \$oldip) do={:set newip [:resolve \$comment]\r\
   \n    /ip firewall address-list set \$i address=\$newip}\r\
   \n    }\r\
   \n  }"

Комментариев нет :

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