Adblock w OpenWrt / Gargoyle / LEDE

Adblock w OpenWrt / Gargoyle / LEDE – tytuł wpisu sugeruje, że artykuł będzie o blokowaniu reklam na routerze z alternatywnym firmwarem OpenWrt / Gargoyle. Tak, owszem będzie o blokowaniu reklam, ale bezpośrednią inspiracją do jego powitania była lektura artykułu o nowych serwisach działających w pobieraczkowym stylu – Uwaga na internetowych oszustów!. Jako że dziecka w domu rosną, ani chybi w końcu któreś trafi na jeden z takich serwisów i się nieświadome konsekwencji zarejestruje. Kierując się przysłowiem, że lepiej jest zapobiegać niż leczyć, postanowiłem wyciąć te serwisy już na routerze. Takie rozwiązanie ma tą niezaprzeczalną zaletę, że dzięki temu strony te blokowane będą niezależnie od tego jakie urządzenie podłączymy do naszej sieci domowej, z jakim systemem operacyjnym czy z jaką przeglądarką WWW. W ten sposób powstał mój mały plik w formacie HOSTS dostępny pod adresem http://jazz.tvtom.pl/download/hosts. Z ostatnich ciekawych zmian dodałem serwery z którymi komunikuje się Windows 10 (i wcześniejsze też, choć w mniejszym stopniu) oraz na życzenie jednego z czytelników blokowanie reklam na stronie jasnet.pl. Dopiero potem przyszedł mi pomysł, żeby przy okazji blokowania pobieraczkowych serwisów zablokować także reklamy, serwisy śledzące, spyware czy wszystko inne znajdujące się na dostępnych w internecie czarnych listach. Skutkiem blokowania reklam uzyskanym niejako przy okazji, będzie przyśpieszenie wczytywania stron pozbawionych balastu reklam.

Realizacja tego pomysłu na routerze wyposażonym w alternatywny firmware OpenWrt / Gargoyle jest banalnie prosta. Właściwie wszystko, co potrzebujemy dostajemy out of the box, a naszą rzeczą jest jedynie dokonanie prostej konfiguracji.

Adblock (curl version) w LEDE / OpenWrt / Gargoyle

Do blokowania adresów wykorzystamy Dnsmasq – prosty serwer zabudowany w OpenWrt / Gargoyle służący do realizacji usług: DNS, DHCP i TFTP w małych sieciach. Wszystko co musimy zrobić to:

  • w pliku /etc/config/dhcp w sekcji config dnsmasq dopisać lokalizację pliku z adresami do zablokowania, np:. list addnhosts '/mnt/sda3/hosts/hosts.deny';
  • stworzyć ów plik /mnt/sda3/hosts/hosts.deny (ze względu na objętość tego pliku koniecznie na zewnętrznym nośniku USB);
  • zrestartować Dnsmasq.

Poniżej prezentuję mały skrypt, który zautomatyzuje powyższe 3 kroki. Skrypt do działania wymaga doinstalowania 2 pakiety: curl i ca-certificates:

Potrzebne są one do ściągania czarnych list. Skrypt aktualnie obsługuje czarne listy w 3 formatach:

  1. klasycznym formacie HOSTS – np. 127.0.0.1 090.waw.pl,
  2. formacie HOSTS ze zmodyfikowanym IP – np. 0.0.0.0 fr.a2dfp.net,
  3. czystej liście domen – np. arta.romail3arnest.info.

Skrypt przetworzy też pliki w formacie Adblocka / μBlocka, jednakże w tym przypadku zalecam BARDZO DALEKO IDĄCĄ OSTROŻNOŚĆ, np. taka sobie reguła ukrywająca reklamy google.pl##.ads-ad po przetworzeniu zablokuje całą google.pl. Jeśli więc komuś nie wystarczają listy z domyślnej wersji skryptu i ma nieodpartą potrzebę dodania listy Adblocka / μBlocka musi ją bardzo dokładnie przeanalizować i zdawać sobie sprawę, że może zablokować więcej niż by chciał.

Ja nie chcę, więc zdecydowałem usunąć z domyślnej wersji skryptu listy:

  1. http://hostsfile.mine.nu/Hosts,
  2. http://optimate.dl.sourceforge.net/project/adzhosts/HOSTS.txt,
  3. http://securemecca.com/Downloads/hosts.txt;

gdyż zawierały one zbyt dużo “dobrych” stron. Listy te były najobszerniejsze ze wszystkich testowanych przez mnie, wniosek z tego płynie dość oczywisty – trudno zapanować nad ogromną listą, lepiej więc skorzystać z wielu mniejszych list niż jednej obszernej

Data ostatniej modyfikacji skryptu adblock-curl to 08.04.2017

Działanie skryptu kontrolowane jest przez 4 parametry:

  • WORKDIR – wskazuje katalog, gdzie zapisywane są czarne listy, zarówno tymczasowe jak i ostatecznie wygenerowana;
  • BLACKLISTS – zawiera adresy URL list serwerów do zablokowania;
  • WHITELIST – to natomiast lista adresów, które z jakiś względów nie powinny być zablokowane, tworząc białą listę możemy posiłkować się wyrażeniami regularnymi. W chwili obecnej kod skryptu jest już dojrzały i nie przewiduję jakiś zmian. Aktualizacje, które ukazują się tu dość regularnie dotyczą jedynie rosnącej białej listy. Wychodzę bowiem z założenia, że lepiej zablokować mniej niż za dużo.
  • IP – domyślnie niebezpieczne serwery przekierowywane są na adres 127.0.0.1 czyli localhost, jeśli chcemy dokonać przekierowania pod inny adres IP podajemy go w tej zmiennej, jeśli nie – pozostawiamy pustą. Ciekawą propozycją jest podanie adresu IP pixelserv, o instalacji którego będzie pod koniec wpisu.

Adblock (wget version) w LEDE / OpenWrt / Gargoyle

Jeśli z jakiś względów wolisz starszą, oryginalną wersję skryptu opartą na wget poniżej ją prezentuję. Skrypt do działania wymaga doinstalowania 2 pakiety: wget i ca-certificates:

Jedyną różnicą w stosunku do wersji bazującej na curl jest to, że czarne listy są ścigane przy każdej aktualizacji, niezależenie czy na serwerach uległy zmianie czy nie.

Data ostatniej modyfikacji skryptu adblock-wget to 08.04.2017

Działanie skryptu kontrolowane jest przez 5 parametrów, 3 z nich BLACKLISTS, WHITELIST oraz IP zostały omówione powyżej, więc nie będę się powtarzał. Natomiast zamiast WORKDIR mamy:

  • HOSTSDENY – wskazuje lokalizację pliku z listą serwerów do zablokowania;
  • HOSTSTEMP – wskazuje tymczasową lokalizację pliku z listą serwerów do zablokowania;

Instalacja skryptu oraz aktualizacja

Niezależnie od wybranej wersji dalsze postępowanie będzie identyczne. Skrypt zapisujemy w wybranej przez nas lokalizacji np. /mnt/sda3/bin. Nadajemy mu prawa wykonywania:

Skrypt adblock wywołujemy z odpowiednim parametrem:

  • start lub enable – włącza blokowanie stron,
  • stop – zatrzymuje blokowanie stron,
  • reload – uaktualnia listę blokowanych stron,
  • restart – restartuje Dnsmasq,
  • disable – zatrzymuje blokowanie stron i usuwa wszystkie pliki stworzone przez skrypt.

Na koniec możemy zadbać o automatyczną aktualizację pliku hosts.deny, w tym celu posłużymy się oczywiście cron-em:

i dopisujemy na końcu linijkę:

Jak widać sugeruję aktualizację raz w tygodniu w godzinach nocnych.

Gotowy plik hosts.deny (oczywiście z domyślnym IP 127.0.0.1) dostępny jest na mojej stronie pod adresem http://jazz.tvtom.pl/download/hosts.deny. Aktualizowany jest zgodnie z powyższym harmonogramem. Plik ten możesz wykorzystać wprost w programach blokujących reklamy działających w oparciu o pliki HOSTS. Przykładem może tu być aplikacja AdAway działająca pod kontrolą systemu operacyjnego Android. AdAway nie jest dostępna w sklepie Google Play, ale możesz ją ściągnąć z repozytoriów F-Droid.

AdAway - Źródła hostów

AdAway – Źródła hostów

Pixelserv – eliminujemy komunikaty przeglądarek

Pixelserv do poprawnego działania Adblocka nie jest konieczny, jednakże jak słusznie zauważył w komentarzu kolega daro, niektóre strony z zablokowanymi reklamami nie wyglądają za dobrze – w miejscu reklamy pojawia się komunikat, że dana strona nie jest dostępna. Wygląd tego komunikatu zależy jest od przeglądarki. Jeśli nie chcesz ich oglądać, pomocny będzie pixelserv – czyli serwer WWW, którego jedynym zadaniem jest zaserwowanie jednopixelowego pliku GIF.

Konfigurację OpenWrt / Gargoyle zaczniemy od dodania aliasu adresu IP dla naszego routera, na który to adres przekierowywać będziemy żądania wyświetlania reklamy (parametr IP w skrypcie). Wybieramy zatem jakiś pierwszy, lepszy, nieużynany w naszej sieci lokalnej adres IP np. 192.168.1.2. W skrypcie ustawiamy ten adres w w parametrze IP.

W tej chwili nasz router powinien być widocznym pod dwoma adresami, sprawdzimy to wchodząc na stronę routera pod adresem http://192.168.1.2/.

Teraz zajmiemy się instalacją pixelserv, serwującego jednopixelowy plik GIF jako stronę komunikatu błędu, nasłuchującego na porcie 81. Do tego oczywiście potrzebujemy samego pliku GIF, który ściągnąć możemy z tego bloga. Mamy to do wyboru aż cztery propozycje. Ja wybrałem pierwszą, czyli przeźroczysty obrazek zgodny ze specyfikacją GIF89a. Plik ten umieściłem w katalogu /www_vargalex, gdyż używam OpenWrt vargalex build, Wy możecie go umieścić w katalogu /www lub utworzyć nowy np. /www_pixelserv, tak jak to zostało pokazane poniżej.

Drugim plikiem jaki powinniśmy utworzyć w katalogu naszego Pixelserv to plik index.html, który będzie informował użytkownika zablokowanej strony dlaczego jej nie widzi, przykładowa najprostsza strona:

Nasze dalsze postępowanie zależne będzie od tego jaki serwer WWW mamy już zainstalowany na routerze, i tak w przypadku OpenWrt z LuCI musimy skonfigurować nową instancję serwera uHTTPd:

Natomiast w przypadku Gargoyle, nową instancję serwera httpd_gargoyle uruchomimy komendą:

którą warto dopisać do pliku /etc/rc.local oczywiście przed ostatnią komendą exit 0, aby pixelserv startował automatycznie po restarcie routera.

Pora na kolejny test – pod adresem http://192.168.1.2:81/jakaś_nieistniejąca_podstrona (lub http://192.168.1.1:81/jakaś_nieistniejąca_podstrona powinien znajdować się nasz jednopixelowy GIF.

Na koniec musimy jeszcze dodać do naszego firewalla regułkę przekierowującą żądania wyświetlania reklamy z 192.168.1.2:80 na adres pixelserv 192.168.1.2:81 (lub 192.168.1.1:81).

Teraz jednopixelowy GIF powinien być już pod adresem http://192.168.1.2/jakaś_nieistniejąca_podstrona.

Na koniec nie pozostaje mi nic innego jak tylko przekonać nieprzekonanych poniższym zrzutem ekranu.

Adblock w OpenWrt / Gargoyle działa

Adblock w OpenWrt / Gargoyle działa

Skryptowi Adblock poświęcony jest wątek na polskim forum Gargoyle.

37 Comments

  1. No faktycznie sprytne rozwiązanie, pierwszy raz widziałem Internet Explorera bez reklam 🙂

  2. Fajny wpis. Mam pytanie do ciebie. Czy było by łatwo skonfigurować OpenWrt do działania w podobny sposób do AdTrapa https://www.youtube.com/user/getadtrap/videos czyli, praca bez natu, podpinamy między modemem i routerem, który nie ma możliwości pracy na alternatywnym firmware i jego zadaniem było by tylko blokowanie reklam, malware itp. z reguł. Zamiast wydawać 130$ można by było nabyć np. TL-WR740N. albo najtańszy router z USB na ar71xx, wgrać spreparowany obraz gargoyle i cieszyć się ze nie ma reklam na przeglądarce w SmartTV, telefonie itd.
    Widziałem ciekawy projekt http://eko.one.pl/?p=openwrt-dyskbezprzewodowy może ktoś mógłby rozważyć stworzenie AdTrapa.

  3. Moje 3gr: na openwrt raczej uci się powinno używać a nie sed do wpisywania opcji. Więc zamiast

    if ! grep -q “list addnhosts ‘$HOSTSDENY'” /etc/config/dhcp ; then
    sed -i -e “/config dnsmasq/{:a;n;/^$/!ba;i\ list addnhosts ‘$HOSTSDENY'” -e ‘}’ /etc/config/dhcp
    fi

    po prostu

    uci add_list dhcp.@dnsmasq[0].addnhost=$HOSTSDENY
    uci commit

    i analogicznie

    uci del_list dhcp.@dnsmasq[0].addnhost=$HOSTSDENY
    uci commit

    do usunięcia tego wpisu.

    • No faktycznie z tymi sedami i grepami ostro przekombinowałem, a to takie proste było. Chyba miałem pomroczność jasną. Dzięki.

  4. Great script, thanks for sharing!

    • You’re welcome. If You find any hosts that are incorrectly blocked by the script, please let me know. I will add them to the white list.

  5. Proponowałbym dodać pixelserv żeby zamiast http://i.imgur.com/CexPkSM.png wczytywał się 1 pixelowy przezroczysty obrazek. Do whitelisty mozna by było wpisać cdnapi.kaltura.com niektóre strony mają osadzone na tym player. Dodałbym jeszcze listę z Anti-PUPs/Adware = http://www.malekal.com/HOSTS_filtre/HOSTS.txt

    • Dzięki za wszystkie sugestie – białą i czarną listę uzupełniłem, a co do pixelserv to pomyślę w wolnym czasie.

  6. THX for perfect script. I’m using adblock plus w/ firefox(my primary browser) but sometimes, i need to use chrome or ie and i hate adds. Thx once more

  7. Dzięki wielkie! Działa i to sprawnie 🙂

  8. Witam,
    Testuje skrypt na AA12.09, router Tp-Link WR1043ND.
    Otrzymuje taki oto blad w logu:
    Oct 9 22:31:59 OpenWrt daemon.err dnsmasq[2362]: failed to load names from /data/adblock/hosts.deny: Permission denied
    Poprosze o wskazowki, jak sobie z nim poradzic.

    ^folder na zewnetrznym nosniku + extroot
    Pozdrawiam

    • Podaj uprawnienia do pliku hosts.deny oraz do katalogów nadrzędnych.

      • Uprawnienia pliku juz wczesniej ustawilem na 777, dla testow, nie zmienilem tylko uprawnien folderu nadrzednego. Dziala 🙂
        Mam jeszcze jedno pytanie, czy da sie w jakis sposob skopiowac same regulki z adblocka (chrome) ktore sam utworzylem podczas korzystania z niego? (sa to dodatkowe wszelkiego rodzaju przeszkadzajace mi ramki itp.) ? W jaki sposob to sformatowac? Rozumiem, ze jak do skryptu dodam linijke odwolujaca sie do dodatkowego pliku lokalnego, ktory bede sam sobie edytowal, poprzez wklejanie dodatkowych stron, to skrypt sam sie zajmie reszta -> sortowanie itp.?
        Dziekuje z wklad pracy, pozdrawiam C.

        • Nie używam Chrome’a, ale podejrzewam że format reguł jego adblocka znacznie odbiega od formatu plików HOSTS. Plikami HOSTS może zablokować tylko konkretne serwery np. ads.serwer.pl. Wszystko więc zależy od tego jakie reguły zdefiniowałeś – blokowanie konkretnych plików np. reklama.swf, serwerów z ads w nazwie itp. zatem odpada.

          Skrypt a obecnym kształcicie nie przewiduje dodawania lokalnych plików HOSTS – są one pobierane są wgetem z serwerów www.

          Mogę ewentualnie zaproponować dodanie serwerów z twojej listy reguł do pliku http://jazz.tvtom.pl/download/hosts

  9. Bardzo ciekawa metoda blokowania!
    Niedawno postawiłem router na gargoyle i nie mam żadnego doświadczenia z linkuksem. Twoja domyślna lokalizacja to /mnt/bin, nie mam takiej lokalizacji… powinienem? czy to tylko przykładowe miejsce?

    Mam zrobiony swap i exroot, to ma jakieś znaczenie dla lokalizacji skryptu?

    pozdrawiam

    • Tak, to przykładowa lokalizacja. Skoro masz extroot możesz zarówno skrypt jak i pliki na których działa umieścić gdziekolwiek.

      • Chyba udało mi się zastosować tą metodę ale mam wrażenie, że otwieranie stron zwolniło… muszę protestować.

        Nie umiem dopisać linijki w crontab -e http://scr.hu/1w5g/arx2m i nie moge ani w kleić ani dopisać nic na końcu…

        i jeszcze error tu:
        ~# uci add uhttpd uhttpd
        cfg0422fe
        ~# uci rename uhttpd.@uhttpd[-1]=pixelserv
        ~# uci add_list uhttpd.@uhttpd[-1].listen_http=0.0.0.0:81
        ~# uci set uhttpd.@uhttpd[-1].home=/www
        ~# uci set uhttpd.@uhttpd[-1].error_page=/blank.gif
        ~# uci commit uhttpd
        ~# /etc/init.d/uhttpd restart
        bind(): Address already in use
        Error: No sockets bound, unable to continue
        co tu jest nie tak?

        dodatkowo 192.168.1.2 jest u mnie niedostępna.

        • Ad 1. Jest to możliwe jeśli dokonałeś przekierowania na nieistniejący adres.
          Ad 2. Poczytaj o vi, zmień edytor lub skorzystaj z GUI (w LuCI jest taka możliwość, w Gargoyle nie pamiętam 🙂
          Ad 3. Widać jedna instancja uhttpd już nasłuchuje na porcie 81. Zobacz ps.

          • Mogę Ci tu tak spamować? Na niektórych stronach mam coś takiego http://screenshu.com/static/uploads/temporary/1o/yq/cc/1k84s9.jpg to z deviantart.com i jeszcze zauważyłem na liveleak.com
            Powtórzyłem wszystkie czynności związane z gifem i jest ten sam błąd co wcześniej
            ~# uci add uhttpd uhttpd
            cfg0422fe
            ~# uci rename uhttpd.@uhttpd[-1]=pixelserv
            ~# uci add_list uhttpd.@uhttpd[-1].listen_http=0.0.0.0:81
            ~# uci set uhttpd.@uhttpd[-1].home=/www
            ~# uci set uhttpd.@uhttpd[-1].error_page=/blank.gif
            ~# uci commit uhttpd
            ~# /etc/init.d/uhttpd restart
            bind(): Address already in use
            Error: No sockets bound, unable to continue

            i na 192.168.1.2 mam dostęp do gui routera, ale 192.168.1.1:81/byleco jest niedostępne. Włączyłem autostart uhttpd, ale po tym stracilem dostęp do GUI – miałem tylko katalog “index of”. więc to chyba nei jest rozwiązanie.

            Przesłać Ci gdzieś logi żeby tu nei śmiecić?

          • Najprawdopodobniej coś mi już słucha na tym porcie. Czy ma to związek z istniejącym już httpd_gargoyle?
            uci show httpd_gargoyle
            httpd_gargoyle.server=server
            httpd_gargoyle.server.web_protocol=both
            httpd_gargoyle.server.http_port=80
            httpd_gargoyle.server.https_port=443
            httpd_gargoyle.server.web_root=/www
            httpd_gargoyle.server.default_page_file=overview.sh
            httpd_gargoyle.server.page_not_found_file=login.sh
            httpd_gargoyle.server.no_password=1

            jak to przerobić żeby nie korzystać z uhttpd?

  10. Wybacz moją namolność…
    ad 1. Robinem wszystko korok w krok, jedyne co zmieniłem to ścieżka z mnt/bin na mnt/ i /www_vargalex na /www
    ad.2 Okazało się, że wystarczyło doinstalować crona do gargoyla:)
    ad.3 ps to znaczy? W gargulcu nie miałem uhttpd więc go donstalowalem…

  11. ad. 3 Mam przekierowanie portu z WAN do LAN: http://scr.hu/1w5g/c3md4

  12. Mam problem z aplikacją google maps na androida i iOSa (przez przeglądarkę maps.google.com działa bezproblemowo). Skrypt blokuje dostęp aplikacji do któregoś z serwisów google, który jest niezbędny do prawidłowego jej działania – np. przy próbie wyszukiwania pokazuje “No network connection”. Przypuszczam, że wystarczyłoby dopisać odpowiedni adres do Whitelist’y, ale za nie potrafię ustalić co to ma być za adres. Monitor sieci w Gargoyle nie daje żadnych wskazówek, po wyłączeniu adblocka też nie. Jak mogę sprawdzić do jakiego serwera próbuje się połączyć aplikacja?

  13. Jak napisać skrypt by adblock ładował się sam po uruchomieniu urządzenia?

  14. niestety u mnie to nie działa.

    Urządzenie TL-WR1043ND, Wersja Gargoyle:1.6.0.1

    Wpisuje adres onetu, zasypuje mnie reklamami
    Wpisuje adres phorm.kr wyciągnięty z pliku host.deny który miał być blokowany, strona się ładuje

    http://192.168.1.1:81/jakaś_nieistniejąca_podstrona – jest gif
    http://192.168.1.1:80/jakaś_nieistniejąca_podstrona – wyświetla dostęp do routera
    http://192.168.1.2:81/jakaś_nieistniejąca_podstrona – wyświetla dostęp zabroniony
    http://192.168.1.2:80/jakaś_nieistniejąca_podstrona – nie wyświetla strony

  15. Mam router TP-Linka TL-WR841ND ver 7.1 i tak myśle wgrać Gargoyle i ten skrypt. Starczy pamięci w tym routerze bo nie wiem czy się za to zabrać czy jest sens ?

    • Gargoyle warto wgrać nawet jeśli nie będziesz korzystać z adblocka. Sam skrypt jest malutki, ale plik przez niego generowany może być duży. Wypadałoby mieć extroota, a do tego potrzeba niestety USB.

      • Dzięki za info. Wgrałem właśnie gargoyle i ma wiele fajnych opcji. No szkoda tylko z tym adblockiem.

  16. Witam, przekierowanie z adresu 192.168.1.2:80 na 192.168.1.2:81 działa ok do momentu zalogowania się na router i zapisania czegokolwiek w zakładce firewall. Potem wejście na stronę 192.168.1.2 powoduje wyświetlenie strony logowana routera. Dokładnie tak jak pisze “jezy”
    Ale wystarczy Dodać do /etc/firewall.user wpis:
    config redirect
    option target ‘DNAT’
    option proto ‘tcp’
    option src ‘lan’
    option src_dip ‘192.168.1.2’
    option src_dport ’80’
    option dest ‘lan’
    option dest_ip ‘192.168.1.2’
    option dest_port ’81’
    option name ‘pixelserv’

    Domyślny skrypt firewalla ładuje ustawienia usera..
    Teraz już wszystko działa Ok, a przeżucenie blokowania reklam na satrym kompie bezcenne, poza tym dzięki za świetny pomysł na blokowanie reklam lokalnie jak korzystam z modemu 🙂
    Pozdro
    P.

  17. Czy jest jakieś rozwiązanie pod kątem pixelserv i https? Część reklam jest właśnie na https i wówczas dostaję info o błędnych certyfikatach w miejscach reklam.

  18. Proponuję jeszcze wywalić z http://jazz.tvtom.pl/download/hosts
    adres http://storeedgefd.dsx.mp.microsoft.com bo wyśledziłem, że blokuje to działanie Windows Store w Win10

Leave a Reply

Your email address will not be published. Required fields are marked *