Дело было вечером, делать было нечего... © С. В. Михалков
Навеяно публикацией «Как я bind`ом вирусы искал…», а конкретно этой веткой комментариев. Надеюсь, не поздно размещаю.

Сидел я и думал, телевизор Samsung, WinPhone, (а впоследствии может кофеварка и пылесос) показывают суперназойливую рекламу, надо с этим чтото делать, и раз в WinPhone и телевизор(кофеварку, пылесос) плагина AdBlock нету, то он должен быть там где ходит их трафик, на роутере.

Оказалось ничего сложного тут нету, роутер у меня TP-Link 1043, с usb портом, флешка монтирована в /root, у кого флешки нет, можно использовать /tmp, замените пути.

Для начала научим стандартный dnsmasq работать с внешним host файлом.
В файле /etc/config/dhcp добавить строку:

в секции 
config dnsmasq
        list addnhosts '/root/hosts/adfree'
        list addnhosts '/root/hosts/unchanged'

Файл /root/hosts/unchanged я использую для добавления собственных hosts правил, или которых нет в adfree.
По пути /root/hosts/ создаем скриптик upd-adfree.sh который качает свежие списки adfree (ссылка которую использует android телефон) и модифицирует под вид hosts, затем перезагружает dnsmasq для того чтоб он прочитал новые файлы.

##adfree
wget http://winhelp2002.mvps.org/hosts.txt -O adfree-tmp
sed 's/^\(.*\).$/\1/' adfree-tmp > adfree

## dns restart to update
/etc/init.d/dnsmasq restart

И дать права на выполнение:

chmod +x /root/hosts/upd-adfree.sh

в файле /etc/crontabs/root добавить строку
0 0 * * * /root/hosts/upd-adfree.sh
Что означает запускать скрипт каждый день в 0:00.
Активировать cron:

/etc/init.d/cron enable

Собственно, всё. Конечно блокируется не всё, не сравнить с AdBlockPlus в десктопный браузерах, для этого надо проксю ставить, но и нагрузка небольшая идет.

Плюсы для меня: WinPhone не показывает рекламу в играх, девушке на компе не выскакивает видеореклама всяких 1000$ за сутки ничегонеделанья с какого то форума, который не работает если видит в плагинах adblock, ютуб на телевизоре не орет рекламу на весь дом.

Минусы, обнаруженные мною: Некоторые сайты умеют определять adblock по размеру рекламных окон, такие будут возмущаться.

Ну и по традиции ошибки прошу писать в личные сообщения, я их исправлю.

Комментарии (36)


  1. orosz
    20.07.2015 13:45

    Спасибо за пост.
    Буду пытаться сделать нечто подобное на моем старике Linksys wrt54gl.


  1. a553
    20.07.2015 14:20
    +3

    Для ddwrt:
    1. Включить dnsmasq, local dns в Services
    2. Сохранить в Administration/Commands/Firewall:

    if test -s /tmp/hosts0
    then
        rm /tmp/hosts0
    fi
    
    wget -O - http://someonewhocares.org/hosts/zero/hosts >/tmp/hosts0
    grep addn-hosts /tmp/dnsmasq.conf || echo "addn-hosts=/tmp/hosts0" >>/tmp/dnsmasq.conf
    killall dnsmasq
    dnsmasq --conf-file=/tmp/dnsmasq.conf
    
    


    1. Tonkonozhenko
      20.07.2015 15:07

      Ссылка выдает 403, так что берите ту, что указана в посте


      1. a553
        20.07.2015 15:09

        У меня работает


        1. Tonkonozhenko
          20.07.2015 15:11

          Действительно, с сервера проверил, все ок.
          Тогда это вероятно у меня что-то не так.


          1. a553
            20.07.2015 16:27

            Страничка проверяет Referer, надо пустой отправлять.


  1. ilyaplot
    20.07.2015 15:01

    Кому вообще лень заморачиваться, есть dns от яндекса. При чем, в нескольких вариантах.


    1. pavlo
      20.07.2015 15:47

      А там же по моему порезанные все IP заблокированные роскомнадзором не? ;)
      Еще бы решить как на rt-n16 с олеговской сделать подобное с автопополнением, идея конечно понятна, нужно вот раскопать где это там ;)


      1. 4aba Автор
        20.07.2015 16:47
        +1

        … или поставить openwrt :-)
        на dir320 и wl500V2 у меня олеговские прошивки не вытягивали то, с чем хорошо справлялся еще openwrt10. Вот только например на tplink1043 не работает апаратный nating что не дает толком большой скорости, может и у rt-n16 какие проблемы…


        1. pavlo
          20.07.2015 18:35

          хм, помню opewrt не все может, мне не удалось запустить например нормально на своем железе Multicast to HTTP Proxy, отключение вафли по времени и что то еще. Может конечно плохо искал или думал.


        1. 4mz
          21.07.2015 08:54

          Вот только например на tplink1043 не работает апаратный nating что не дает толком большой скорости

          А вот про это можете подробнее? Сам использую TPLink 1043nd v1 c OpenWrt BarrierBreaker 14.07, скорость закачки торрентов, к примеру, аналогична стандартной прошивке. Чем мне может грозить отсутствие аппаратного nating, есть ли какие-то сравнения, подробности?


    1. UksusoFF
      20.07.2015 18:26
      +1

      А как он поможет? Судя по описанию там только блокировка adult-рекламы.


  1. Keroro
    20.07.2015 16:24

    А какой формат у /root/hosts/unchanged? Вида: 0.0.0.0 s.adframesrc.com, я правильно понял?


    1. 4aba Автор
      20.07.2015 16:40
      +1

      да, собственно как файл hosts в системе.
      к этому виду приводу и списки adfree по ссылке


  1. maisvendoo
    20.07.2015 16:53

    Утащил в избранное. Попробую провернуть подобное. Реклама достала уже


  1. pdacity
    20.07.2015 17:20
    +2

    Еще несколько хостов со списком рекламы (выдрано из приложения adaway под андроид)

    hosts-file.net/ad_servers.txt
    adaway.org/hosts.txt
    pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext

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


  1. brabon
    20.07.2015 18:06
    +1

    Сам использую томато / на асус н16

    Проблема с хостс, то что нельзя применять wildcards и блокировать вес домейн.

    Например, analytics от Adobe: 2o7.net, у него куча саб-домейнов, и все их в hosts муторно писать

    Что нас спасёт? dnsmasq.conf

    address=/2o7.net/127.0.0.1

    с этих пор, любой DNS запрос с *.2о7.нет будет отдаваться как 127.0.0.1


    1. CRImier
      20.07.2015 18:20
      +1

      Удваиваю, особенно стоит учесть такую директорию, как /etc/dnsmasq.d, откуда dnsmasq при включённой соответствующей опции подтягивает конфиги, добавляя их к основному. Стоит создать там файл — будет фильтрация по * и возможность лёгкого обновления скриптом.


  1. solalex
    20.07.2015 20:05

    файлик adfree-tmp можно и удалять, зачем лишний мусор?


    1. 4aba Автор
      20.07.2015 23:12

      А еще лучше качать этот файлик на /tmp/ ;-)


      1. lexore
        21.07.2015 11:34

        Или так :)

        wget http://winhelp2002.mvps.org/hosts.txt -O - | sed 's/^\(.*\).$/\1/' adfree-tmp > /root/hosts/adfree
        


        1. solalex
          21.07.2015 18:07
          +1

          С учетом всего вышесказанного правим /etc/config/dhcp
          list addnhosts '/tmp/adfree'
          и правим /root/hosts/upd-adfree.sh

          ##adfree
          wget http://winhelp2002.mvps.org/hosts.txt -O - | sed 's/^\(.*\).$/\1/' adfree-tmp > /tmp/adfree
          ## dns restart to update
          /etc/init.d/dnsmasq restart
          


          А в кроне я сделал раз в неделю, чаще обновлять смысла не вижу
          0 1 * * 7 /root/hosts/upd-adfree.sh
          Кстати вариант автора сохраняет результат скрипта в /root/, а не там как задуманно в /root/hosts/


          1. solalex
            21.07.2015 18:15

            и еще не забыть скрип в автозагрузку сунуть, чтоб при ребуте все поднялось, иначе в /tmp/ не будет списка блокируемых доменов


          1. solalex
            21.07.2015 18:37
            +1

            вот это точно работает :)

            cd /tmp
            wget http://winhelp2002.mvps.org/hosts.txt -O adfree-tmp
            sed 's/^\(.*\).$/\1/' adfree-tmp > adfree
            rm -f adfree-tmp
            /etc/init.d/dnsmasq restart
            


            1. LexB
              22.07.2015 17:39

              Возможен ли сценарий что роутер повиснет если сервер вернет слишком большой файл?
              Жаль что у wget в openwrt нет флага ограничения на размер полученного файла.
              Кстати почему вы сразу не перенаправляете вывод wget на sed без использования промежуточного файла?


              1. solalex
                24.07.2015 18:02

                там файлик то всего чуть больше 500 кб, почему сервер должен возвратить большой файл? А по второму вопросу — работает и ладно, не жалко оперативки для временного файла.


  1. Alet
    21.07.2015 11:21
    +1

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

    random1000=`dd if=/dev/urandom count=1 2>/dev/null | uuencode -m - | head -n 2 | tail -n 1| tr -cd 0-9 | head -c 3`
    randomSec=`dc -e $random1000 -e '3600 * 1000/p'`
    
    sleep $randomSec
    


    1. lexore
      21.07.2015 18:09

      В зависимости, от урезанности шелла, может быть в наличии такая переменная

      echo $RANDOM


  1. loginsin
    21.07.2015 16:07

    Обратный вопрос: А есть список сайтов с большим количеством рекламы? Хочется списки проверить :)


    1. cmepthuk
      21.07.2015 22:36

      Вот пара примеров ad-помоек — zaycev.net да allday2.com


  1. cmepthuk
    21.07.2015 23:15
    +3

    Уважаемые %habrapeople%, после прочтения поста в голове возник вопрос:

    «А что если вместо хостов dnsmasq для достижения аналогичного результата использовать таблицу статических DNS маршрутов на Mikrotik hAP lite (650MHz @ RAM 32 Mb)?»

    Блочить на уровне файрвола железки — не всё так просто, а держать прозрачный web-прокси для этого — решение, но только для http трафика.
    Для решения в настройках dhcp первым dns был прописан адрес маршрутизатора, подготовлены списки и переведены политкорректный для импорта формат:

    # Скачиваем списки, и аккуратно складываем их под именами ./hosts_list.1 , ./hosts_list.2 и т.д.
    $ src=('http://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext' 'https://adaway.org/hosts.txt'); i=0; for file in ${src[*]}; do i=$((i+1)); wget --no-check-certificate -O "./hosts_list.$i" "$file"; done;
    

    # Грепаем всё что начинается на '127.0.0.1 ', удаляем комменты, оставляем только имена доменов,
    # убираем дубликаты, убираем пустые строки, и оформляем каждый домен в виде команды для импорта
    $ in="./hosts_list.*" && out="./adblock_dns.rsc" && host='127.0.0.1'; echo "/ip dns static" > $out && grep '127.0.0.1 ' $in | grep -v '^#' | cut -d' ' -f 2 | sort -u | grep . | sed "s/^/add address=$host name=/" >> $out && rm -f $in; wc -l $out;
    

    Полученный файл adblock_dns.rsc был залит по ftp на железку, в шеле выполнено:
    # грохаем все имеющиеся записи в таблице статических DNS маршрутов
    /ip dns static remove [/ip dns static find]
    # Импортируем загруженный файл
    /import adblock_dns.rsc
    # Убираем за собой
    /file remove adblock_dns.rsc
    

    Итого у нас 2802 статических маршрутов на loopback в таблице (эмпирически доказано что при импортировании ~5500 записей — железка встает почти колом), после ребута и тестового прогона на пару часов имеем Free Memory 6.0 MiB, CPU Load 0..2%. Как автоматически выполнять аналогичную по смыслу операцию без использования дополнительной машины (только средствами самого микротика) по расписанию — ещё не придумал.

    Очень хотелось бы услышать мнения более опытных товарищей — на сколько таковое решение пригодно к жизни? На данный момент железка стоит дома, трафика ходит не много, активный серфинг возможен лишь с 2х устройств в одну единицу времени


    1. vvzvlad
      24.07.2015 14:16
      +1

      Спасибо за скрипт. Автоматически — там же есть скрипты и расписание, правда переписать придется.
      Ну и /ip dns static remove делать тоже не очень хорошая идея — мало ли что у человека там может быть. У меня там немного, но важное.


      1. cmepthuk
        24.07.2015 15:52
        +1

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

        s1.2mdn.net
        pubads.g.doubleclick.net
        static.doubleclick.net
        devads.skypeassets.net
        devapps.skype.net
        qawww.skypeassets.net
        qaapi.skype.net
        preads.skypeassets.net
        preapps.skype.net
        static.skypeassets.com
        serving.plexop.net
        preg.bforex.com
        ads1.msads.net
        flex.msn.com
        apps.skype.com
        api.skype.com
        cdn.mbstatic.org
        marathonbet.com
        megogo.net
        adselector.ru
        pluso.ru
        flash.begun.ru
        ad.adriver.ru
        

        Сказав рекламе в скайпе, youtube.com (лишь через браузер), и паре назойливых сервисов — до свидания :)


      1. cmepthuk
        24.07.2015 16:41

        Кстати, по поводу скачивания файлов хостов — проблемы то нет:

        [admin@router] > /tool fetch url="https://adaway.org/hosts.txt" mode=https 
              status: finished
          downloaded: 13KiB-z pause]
               total: 13KiB
            duration: 0s
        
        [admin@router] > /file print                                              
         # NAME       TYPE       SIZE     CREATION-TIME       
         0 skins      directory           jan/01/1970 05:00:01
         1 hosts.txt  .txt file  13.2KiB  jul/24/2015 18:25:51
        

        Проблема в том, чтоб распарсить файл. Можно, конечно, если аппаратные средства позволяют — с помощью MetaRouter поднять хоть тот же dd-wrt и уже его средствами делать всю «магию». Но, как мне кажется, эффективнее бы для этих целей создать простенький веб-сервис для «нуждающихся», где в «личном кабинете» была бы возможность задать свои правила (которые необходимы в добавок к публичным) + некоторые подготовленные шаблоны (как со скайпом или рекламой на youtube, которые поддерживаются в актуальном виде).
        И формируя необходимого вида запрос — получать готовый скрипт импорта актуальных маршрутов, который бы обновлялся с заданной периодичностью. Делать для себя одного — слишком жирно будет, а для двух-трех гиков, которым данная идея покажется интересна — таки надо ли? :)


        1. vvzvlad
          24.07.2015 17:25

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


    1. av0000
      16.08.2015 17:24
      +1

      Ковыряясь в свежей прошивке своего 951-го обнаружил, что он вполне себе понимает регэкспы в именах!

      [sarcasm]Традиционно для RouterOS как-то всё не очевидно[/sarcasm], но, по крайней мере, «звёздочка» в начале доменного имени работает:

      add address=127.0.0.1 name=".*liveadvert\\.com"
      add address=127.0.0.1 name=".*top.*\\.mail\\.ru"
      


      А это уже сильно уменьшает требуемый список.
      Сколько при этом отъестся CPU не скажу — на фоне моих 3-6% загрузки разницы не заметил