Блокировщик рекламы для дома на коленке

Предыстория


Прожорливый Bind9


Пришлось мне пару лет назад покинуть свой родной дом и переехать в другой город. В результате свой самосборный медиа-центр пришлось оставить, а на новом месте купить телеприставку AuraHD Plus. Весьма не плохой девайс за свои деньги, особенно если учесть, что в нем встроены приложения для доступа к сервисам с фильмами и т.п.


Все бы ничего, но реклама там крутится на каждый чих. Пришлось изобретать, как же ее "порезать". Первая мысль была — поднять свой DNS сервер и отправлять все неугодные домены в /dev/null на 127.0.0.1. К этому моменту мой домашний серверок вернулся ко мне и занял свое почетное место на шкафу в качестве NAS сервера.


Сказано — сделано. Поднят Bind9, прописаны конфиги для нескольких доменов, все отлично. Летим.


Спустя пару недель пришла мысль в голову, а почему бы не использовать этот метод для фильтрации рекламы для всех устройств дома? Дело не хитрое же.


Поиск списков с рекламными доменами привел меня к нескольким урлам и я взялся их парсить. Где-то на просторах Хабра была статья, которая помогла мне с парсингом и написанием скриптов для генерации конфигов для Bind9 (спасибо автору, но я не смог найти ссылку, пусть меня простит).


Все сделано и пришло время запускать Bind9. Старт и все отлично. Кроме одного. Этот прожорливый монстр съел всю оперативку и попросил своп. 5 гигабайт памяти на 400 тысяч доменов!


По-мучая таким образом свой бедный сервер на Intel Atom я решил, что это не дело.


Миграция на PowerDNS


Погуглив и поизучав другие варианты, я пришел к выводу, что Bind9 не совсем то, что нужно. Нужен более легкий по ресурсам DNS сервер, который смог бы лопатить такое количество доменов.


PowerDNS подошел как нельзя к стати, т.к. он умеет сам читать конфиги Bind9 и использовать их в работе. Поставил, настроил (собственно в этом нет никакой сложности) backend Bind9 запустил.


Результат превзошел все ожидания — 700 MB потребляемой памяти после 5 гигабайт! Это ли не мечта? Особенно при наличии всего 4 GB в сервере. :)


Несколько месяцев так все и проработало, пока я не задумался, что конфиги Bind9 это конечно хорошо, но старт PowerDNS какой-то ну совсем медленный. Время на "всасывание" всех доменов до неприличия большое и стоит как-то оптимизировать этот процесс.


Из оптимизации оставалось влить только все эти домены с рекламой в MySQL. Это дало бы возможность более гибко управлять списком доменов, добавлять, удалять, поддерживать свои внутренние домены.


Закатали рукава и приступили. Оказалось все довольно просто — zone2sql решает все проблемы :) Оставалось завернуть все это в доккер и поднять. Сделал довольно быстро и без особых проблем.


Так оно летит уже с полгода дома и радует. Но сегодня вышла статья на Хабре о блокировщике рекламы для смартфонов Samsung и мне предложили в комментариях выдать мое поделие в открытый доступ.


Что ж, делюсь.


Зависимости


docker


Поскольку все это крутится внутри контейнеров docker, то эта штука нам 100% понадобится. Все действия относятся к Ubuntu Linux, т.к. именно его я использую дома и в работе.


Устанавливается она согласно документации достаточно просто:


curl -sSL https://get.docker.com/ | sh

После завершения работы скрипта docker будет готов и им можно пользоваться.


Если вы предпочитаете другой метод установки, то всегда можно обратиться к документации и выбрать то, что вам будет по душе.


docker-compose


Docker Compose предназначен для планирования и организации процессов в контейнерах Docker (запуска, отключения, создания межконтейнерных соединений и томов, и т.п.).


Установка не сложнее самого докера:


curl -L "https://github.com/docker/compose/releases/download/1.8.1/docker-compose-$(uname -s)-$(uname -m)" > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Запуск собственного фильтра рекламы


Клонируем репозиторий


Логичное действие и не нуждается, наверное, в пояснениях, зачем это делать. :)


sudo mkdir /opt/docker
sudo chown <user> /opt/docker
git clone https://github.com/DmitriyLyalyuev/powerdns-no-ads /opt/docker/pdns
cd /opt/docker/pdns

Создаем базу данных


docker-compose up -d mysql

Пользователь базы данных


Для доступа к консоли MySQL сервера нужно выполнить:


docker exec -ti pdns_mysql_1 mysql -u root -p

Пароль по умолчанию для пользователя root — 12345.


Создаем пользователя и базу:


CREATE USER 'powerdns_user'@'%' IDENTIFIED BY 'powerdns';
GRANT ALL PRIVILEGES ON powerdns.* TO 'powerdns_user'@'%';
CREATE DATABASE powerdns;
exit

Стартуем DNS сервер


docker-compose up -d

Обновление списков рекламных доменов


Для обновления списков запускаем:


docker exec -ti pdns_pdns_1 bash
cd /etc/powerdns/bind
./getnewlist.sh && ./import.sh && ./clean.sh
exit

White listing


Список для исключения доменов содержится в начале файла /opt/docker/pdns/powerdns-server/bind/getnewlist.sh.


Пользуйтесь, экспериментируйте и давайте сделаем интернет чище. Хотя бы у себя дома. ;)

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 34

    +1

    Спасибо!


    Создание базы можно подсунуть в скрипт


        volumes:
          - /opt/docker/mysql/data:/var/lib/mysql
          - /opt/docker/mysql/structure/:/docker-entrypoint-initdb.d

    тогда база будет создаваться сама.


    UPD: а, у вас maria, надо посмотреть, умеет ли их image такую штуку
    UPD2: да, умеет, тут у них с mysql совместимость

      0
      Спасибо, посмотрю в эту сторону. :)
      –4
      когда вы повыедетесь уже! :) ©
        +2
        Глупость, повторенная дважды, не становиться шуткой.
          –1
          Блокировка рекламы — это вам не шутки.
            +6
            Да, это вынужденная необходимость.
              –1
              Не думаю, что это вынужденная необходимость: блокировать всю рекламу скопом.
                0
                Поскольку в настоящее время, это решение работает лучше, чем решение с «приемлемой» рекламой, мы вынуждены блокировать всю рекламу.
                Пока нет возможности отфильтровать только порнуху, мошенников и неприемлемые форматы, блокироваться будет всё.
            0
            Она становится мемом, судя по тому, что творится в интернетиках на этот счет.
              +1
              Даже если её форсят, не всякая глупость может стать мемом.
          +1
          dnsmasq потребляет память в килобайтах, делает всё то же самое, работает даже на роутерах с 16мб оперативки.
          зачем этот велосипед было городить — непонятно.
            +2
            Вы в него пробовали запихнуть 400 тысяч доменов?
            Пробовали управлять всем этим делом?
            Как быстро он стартует с таким багажом?

            Сомневаюсь, что он сможет это все адекватно переваривать.
              0
              root@router:/etc/dnsmasq.d# cat ad* | wc -l
              635317
              стартует минуту на слабом железе.
                +1
                Рад, что он так отлично работает. Надо будет посмотреть в его сторону.
                  0
                  На самом деле причина такой колосальной разницы между «настоящими» DNS и dnsmaq в том, что большие DNS сделаны для того, чтобы обслуживать крупные авторитативные DNS в интернете. Поэтому они сразу тащат все в память, предполагая, что производительность важнее и хостер с 400к доменов уж может себе позволить 5G памяти.

                  А dnsmasq сделан именно как прокладка между локальным компом или максимум локальной сеткой и большим миром, поэтому логика его работы совсем другая. Если не пытаться разом обратится ко все 600К доменам, то и память он не должен так кушать.
                    0
                    там вроде как хэш-таблица используется.
                  0
                  поделитесь роскошным файликом)
                    +1
                    Тоже использую dnsmasq для блокировки рекламы.
                    # cat /etc/dnsmasq.hosts | wc -l
                    48306

                    Базы обновляю при помощи скрипта в cron.
                    #!/bin/bash
                    #
                    if test -s /tmp/hosts_list.*
                    then
                        rm -f /tmp/hosts_list.*
                    fi
                    wget --no-check-certificate -O /tmp/hosts_list.1 http://hosts-file.net/ad_servers.txt &&
                    wget --no-check-certificate -O /tmp/hosts_list.2 https://adaway.org/hosts.txt &&
                    cat /tmp/hosts_list.* | grep -v ^# | sort -u > /etc/dnsmasq.hosts &&
                    rm -f /tmp/hosts_list.* &&
                    /bin/systemctl reload dnsmasq
                    
                0
                так же быстр nsd, хотя да, dnsmasq есть во всех роутерах,
                А уж цеплять скуль к днс — сильное снижение времени ответа
                  –1
                  $ dig @127.0.0.1 ya.ru
                  
                  ; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @127.0.0.1 ya.ru
                  ; (1 server found)
                  ;; global options: +cmd
                  ;; Got answer:
                  ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30975
                  ;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
                  
                  ;; OPT PSEUDOSECTION:
                  ; EDNS: version: 0, flags:; udp: 512
                  ;; QUESTION SECTION:
                  ;ya.ru.             IN  A
                  
                  ;; ANSWER SECTION:
                  ya.ru.          6685    IN  A   213.180.193.3
                  ya.ru.          6685    IN  A   93.158.134.3
                  ya.ru.          6685    IN  A   213.180.204.3
                  
                  ;; Query time: 44 msec
                  ;; SERVER: 127.0.0.1#53(127.0.0.1)
                  ;; WHEN: Wed Nov 02 15:46:33 EET 2016
                  ;; MSG SIZE  rcvd: 82

                  Да вроде не сильно снижает время ответа. ;)

                    0
                    Это, прошу прощения, в сравнении с чем?
                    у меня вафлероутер (на атоме вроде) говорит за 1(кеш) и 4 (not cached) msec, т.е. в 11 раз быстрее, что всё-таки является показателем, имхо.
                    Про unbound забыл, тоже очень быстрое/простое поделие, но сие для диких нагрузок
                      +1

                      Вот и я говорю — в сравнении с чем… Меня это время ответа устраивает. Я из дома не устраиваю гонки на бирже. Меня больше волнует отсутствие рекламы дома.


                      На работе я не использую PowerDNS, само собой. Там все по другому.

                        0

                        Сделал вот на dnsmasq — https://github.com/DmitriyLyalyuev/dnsmasq-no-ads
                        Но статью писать по этому делу, думаю, не стоит. :)

                  +1
                  Вроде бы squid для этого раньше применяли.
                    +1
                    Прокси мне дома только и не хватало.
                      0
                      Зато он не только просто DNS, а по URL блокировать может.
                  • UFO just landed and posted this here
                      0
                      Проще чем bind, ни вьюх, ни плагинов, бэкенд не поменяешь для зон.
                      Из исходников? я подобным только на проектах с BSD занимаюсь, а там j4, минимум.
                        0
                        Поделитесь полным списком доменов?
                        0
                        Снизойдите ко мне, если я совсем в танке…
                        Я, в общем знаю, что такое DNS, а вот Bind и прочее — не сильно.

                        Из статьи я понял, как настроить сёрвис, нокак вот сделать так, чтобы мои устройства дома использовали этот сёрвис?
                        — нужно ли будет в каждом устройстве прописывать DNS server, указывая на мой?
                        — или это каким-то образом надо будет сделать на роутере, чтобы он всем раздавал это в настройках сети через DHCP?
                          0
                          dhcp в стандартных прошивках роутеров обычно указывает себя в качестве днс-сервера, всё зависит от модели
                            0
                            Ну да. Поэтому я и спрашиваю — как заставить это всё работать?
                            Нужно чтобы роутер умел указывать на нужный DNS? Или он указывает на себя, а сам смотрит на поставленный PowerDNS вместо провайдера?
                            Или надо на конечных устройствах указывать на свой PowerDNS сервер?
                              0
                              В роутере указать свой DNS в настройках WAN.
                          0
                          Есть ещё вариант из коробки, на малинке — pi-hole.net

                          Only users with full accounts can post comments. Log in, please.