Adblock via DNS - Frust, Bugs und Lösungen

Pummeluff

Lt. Commander
Registriert
März 2021
Beiträge
1.053
Ich muss erst mal etwas Frust ablassen. Aber vielleicht/hoffentlich entwickelt sich hier auch was Konstruktives.

Auf meinem NAS hatte (hab ich noch) ich die letzten Jahre immer ein DNSMasq laufen. Einsatzzweck: DHCP, DNS, Adblock-Listen

Ab und zu kam mal Einiges durch. Aber im Grunde genommen hat das Ganze relativ brauchbar funktioniert. Dazu finde ich eigentlich dnsmasq im heimischen Netz ganz gut, da es die Funktionalität von Authoritative-DNS-Servers mit der eine DHCP-Servers vereint und zusätzlich einen TFTP-Server beinhaltet, den ich allerdings nicht eingerichtet hatte.

Jetzt hab ich mein NAS von Debian 11 auf Debian 12 upgraded. Und seitdem flutet die Werbung mein "Interneterlebnis". Der Grund dafür ist, dass aus irgendeinem Grund neben den A- und AAAA-Records auch noch die MX-Records abgefragt werden. Und viele Ad-Server sind CNames, die dann trotz meiner Tausenden von Adblock-Einträgen einfach mal so aufgelöst werden. Beschrieben ist das Problem hier. Ich konnte dnsmasq bisher nicht dazu bewegen, die MX-Queries zurückzuweisen, wenn ein A-Record auf den lokalen Server zeigt.

Das Problem scheint auch in der unterschiedlichen Abfragemethodik der Tools begründet zu sein. dig zeigt brav nur den abgefragten Records (A, AAAA) an, während host gleich alle 3 Einträge (A, AAAA, MX) abfragt.

Ich hab dann mal auf meinem Notebook dasselbe Verhalten getestet. Da das Notebook auch im mobilen Einsatz ist, betreibe ich da einen Unbound. Der funktioniert korrekt, auch host erhält hier nur den A-Record.

Gut, dann versuchen wir einfach mal Alternativen. Von PowerDNS hab ich schon viel gehört, also probier ich den mal aus. Die Idee ist durchaus reizvoll, den DNS-Server vom Recursor (Caching, Forward-only) zu trennen. Auch das DB-Backend sollte sich eigentlich positiv auf große Eintragsmengen auswirken. Und dazu hab ich noch überlegt, die Einträge per PHPIPAM zu verwalten, was allerdings etwas überdimensioniert für 30 Einträge wäre, aber aufgrund der PowerDNS Integration reizvoll ist.

Jetzt kommt der Frust:
  • Tutorials sind Mangelware
  • PowerDNS erschlägt einen mit Optionen
  • Will man eine Zone oder überhaupt Einträge anlegen, landet man schnell bei:
  • PowerDNS Admin: Docker will ich nicht. Und die manuelle Installation hat sehr viele Freunde, die dann als verwaiste Leichen auf dem System enden. Wieso können die kein DEB-Paket bereitstellen? Also hab ich stattdessen:
  • PDNS-Manager installiert. Das hat mich auch erst mal Nerven gekostet, bis ich rausgefunden hatte, dass der Pfad in der NGINX-Config nicht ganz korrekt ist und sich deshalb das Setup nicht ausführen lässt. Als nächstes muss man die Tabellen der PDNS-Datenbank wieder löschen, da der PDNS-Manager eine leere Datenbank will. Gut damit hab ich meine Zone und die ersten Einträge angelegt und konnte die auch per host und dig abfragen.

Unverständlich war mir dann der PDNS-Recursor:
Die Komponente soll eigentlich der 1. Ansprechpunkt sein. Interne Adressen sollen an den PDNS-Server, externe Adressen an öffentliche DNS-Server forwared werden. Soweit die Theorie. Meine Config
Code:
local-address=192.168.109.50
local-port=5353
allow-from=192.168.0.0/16, 127.0.0.1
forward-zones-recurse=mylocaldomain.=127.0.0.1:5300
Erwartung:
  • Meine internen Adressen werden an den PDNS-Server (127.0.0.1:5300) weitergeleitet.
  • Externe werden verworfen, da ich keinen Forward-Eintrag dafür hab.

Realität:
  • Interne Adressen werden nicht aufgelöst. Der DNS-Server (sowohl pdns als auch dnsmasq) werden noch nicht mal angefragt. Eine Fehlermeldung kommt nicht.
  • Externe Adressen werden aufgelöst. Über welchen öffentlichen DNS-Server der PDNS-Recursor geht, ist mir vollkommen unklar. Eine oder mehrere IPs oder Namen öffentlicher DNS-Server konnte ich nicht finden in der Config.

Vermutlich bin ich einfach zu blöd für PowerDNS. Aber soviel Komplexität und Blackboxverhalten hab ich selten erlebt.

Ich bin jetzt an dem Punkt, dass ich reumütig den Bind, gegen den ich mich im privaten Bereich jahrelang gewehrt hatte, und den ISC-DHCP-Server installieren werd. Ich geb dann mal Rückmeldung, wenn ich soweit bin.
 
pihole als docker war zu einfach? :)
 
  • Gefällt mir
Reaktionen: Bob.Dig, dewa, azereus und 5 andere
Ich tue mal meinen Senf dazu. Ich war mehrere Jahre mit Pi-hole unterwegs. Das war aber vor allem in der älteren Version etwas buggy. Aber auch bei aktuellen Versionen gibt es hin und wieder größere Probleme.
Seit einem Jahr nutze ich Adguard Home. Läuft genauso wie Pi-hole auf meinem Raspberry Pi 3 absolut ohne Probleme. Alles lässt sich sehr simpel einrichten und funktioniert tadellos.
 
  • Gefällt mir
Reaktionen: dewa
0x8100 schrieb:
pihole als docker war zu einfach? :)
Als ich ungefähr 4 Sätze gelesen habe kam mir auch die Frage: Warum nutzt er denn kein PiHole?

Und am Ende der WoT denke ich mir immer noch: Warum kein PiHole?
 
  • Gefällt mir
Reaktionen: Bob.Dig, azereus und acidarchangel
War irgendwie ab dem Part mit den DNS-Einträgen raus, hab keine Ahnung was damit erklärt werden sollte und ergibt für mich null Sinn und ich habe in meinem Alltag schon des Öfteren mit DNS zu tun.

Wenn es nur um Adblock und DHCP geht, dann kann das Adguard Home wunderbar abbilden, habe ich seit drei Jahren null Probleme mit.
Man kann es sich auch wirklich absichtlich schwer machen.
 
  • Gefällt mir
Reaktionen: JumpingCat
Ich habe früher PiHole genutzt und bin dann irgendwann auf Adguard Home umgestiegen. Ganz genau weiß ich gar nicht mehr warum. Später habe ich noch Technitium DNS ausprobiert. Das hat nochmal einiges mehr an Optionen, die ich aber nicht wirklich gebraucht habe. Für mich hat da Adguard völlig ausgereicht.

Was ist denn der Grund, dass du es so kompliziert machen möchtest?
 
  • Gefällt mir
Reaktionen: Paxter
Pummeluff schrieb:
Auf meinem NAS hatte (hab ich noch) ich die letzten Jahre immer ein DNSMasq laufen. Einsatzzweck: DHCP, DNS, Adblock-Listen
Vielleicht beschreibst du einmal deinen Netzwerk-Aufbau. Macht der Router in dem Netzwerk also kein DHCP?
Der DHCP auf dem NAS verteilt seine eigene IP als DNS-Server? Hast du IPv6 und wenn ja ist sicher dass die Endgeräte über SLAAC auch nichts anderes als den NAS als DNS bekommen?

Pummeluff schrieb:
Ab und zu kam mal Einiges durch. Aber im Grunde genommen hat das Ganze relativ brauchbar funktioniert.
Das wird auch nie besser werden denn Selektion nur Anhand des Domainnamens ist einfach nicht mächtig genug.

Pummeluff schrieb:
Jetzt hab ich mein NAS von Debian 11 auf Debian 12 upgraded. Und seitdem flutet die Werbung mein "Interneterlebnis". Der Grund dafür ist, dass aus irgendeinem Grund neben den A- und AAAA-Records auch noch die MX-Records abgefragt werden. Und viele Ad-Server sind CNames, die dann trotz meiner Tausenden von Adblock-Einträgen einfach mal so aufgelöst werden. Beschrieben ist das Problem hier.
Glaub ich nicht. MX records spielen für Browser keine Rolle. Bzgl. CNAMEs siehe CNAME Uncloaking. Ich bin aber nicht sicher ob das für DNS-Adblocker überhaupt ein Problem ist, wenn das Ziel des CNAME am Ende doch auch auf der Blockliste steht.

Recht neu sind außerdem die SVCB/HTTPS records die Browser bevorzugt nehmen und ebenfalls als CNAME fungieren können:
Code:
$ dig +noall +answer computerbase.de HTTPS
computerbase.de.        3600    IN      HTTPS   1 . alpn="h2" ipv4hint=212.83.33.137 ipv6hint=2a00:f48:2000:1::137

Pummeluff schrieb:
Das Problem scheint auch in der unterschiedlichen Abfragemethodik der Tools begründet zu sein. dig zeigt brav nur den abgefragten Records (A, AAAA) an, während host gleich alle 3 Einträge (A, AAAA, MX) abfragt.
Das sind doch beides Diagnosetools, warum sollte das ein Problem sein was die machen? Auf welchem System testest du denn überhaupt? Auf dem gleichen NAS? Bekommt host denn die originalen A/AAAA records, dig aber nicht? In dem Fall könnte es daran liegen dass host über glibc auflöst, welches die /etc/nsswitch.conf befolgt. In dieser könnte z.B. systemd-resolved über dns (/etc/resolv.conf) priorisiert sein. Während dig die DNS-Auflösung selber implementiert hat und direkt die Server aus der /etc/resolv.conf liest.

Pummeluff schrieb:
Ich konnte dnsmasq bisher nicht dazu bewegen, die MX-Queries zurückzuweisen, wenn ein A-Record auf den lokalen Server zeigt.
Pummeluff schrieb:
Ich hab dann mal auf meinem Notebook dasselbe Verhalten getestet. Da das Notebook auch im mobilen Einsatz ist, betreibe ich da einen Unbound. Der funktioniert korrekt, auch host erhält hier nur den A-Record.
Das hängt auch ganz davon ab wie du die Adblock-Listen in unbound reinkriegst! Wenn du eine local-zone vom Typ transparent nutzt dann beantwortet unbound alle queries für diese domain nur aus den lokalen Daten. Wenn deine Konfiguration für eine Domain also einen A/AAAA aber keinen MX Record listet dann sagt unbound: Für diese Domain gibt es keinen MX. Mit Typ typetransparent werden Query-Typen die nicht lokal überschrieben wurden regulär vom upstream beantwortet. Also wenn du nur A/AAAA stehen hast würden MX & Co. normal an den forwarder/recursor weitergehen.

Pummeluff schrieb:
Externe Adressen werden aufgelöst. Über welchen öffentlichen DNS-Server der PDNS-Recursor geht, ist mir vollkommen unklar. Eine oder mehrere IPs oder Namen öffentlicher DNS-Server konnte ich nicht finden in der Config.
Die sind so zentral und bekannt die brauchen nicht in einer Config stehen :evillol: Es handelt sich um /die/ DNS Server: https://www.iana.org/domains/root/servers Du machst volle Rekursion vom DNS Root aus, also so richtiges DNS wie es im Buche steht :cheerlead: (mit allen Nachteilen bei der Privatsphäre die das mit sich bringt).

Der Rest war mir grad zu viel des Guten und ohnehin keine Erfahrung mit PowerDNS. Du hast doch schon unbound erfolgreich auf dem Laptop laufen, warum nicht wieder dazu greifen?
dnsmasq laufen lassen, nur DNS Port auf 5300 legen. Dann unbound auf Port 53 und für mylocaldomain. eine forward-zone auf localhost:5300. Und wenn du nicht volle Rekursion willst dann noch eine forward-zone für . auf Quad9, Cloudflare, oder was auch immer du nutzt.
 
  • Gefällt mir
Reaktionen: Pummeluff
Danke, Dein Beitrag war lesenswert. Ich hab jetzt mal Pihole installiert. War auch nicht so trivial. Mehr schreib ich dazu morgen. Die erste Werbung ist aber auch bei Pihole durchgekommen.

Und im Endeffekt nutzt Pihole auch nur dnsmasq.
 
Marco01_809 schrieb:
Vielleicht beschreibst du einmal deinen Netzwerk-Aufbau.
  • Fritzbox: Internetzugang per Deutsche Glasfaser, d.h. CGNAT, d.h. Konfiguration IPv6 + IPv4. DHCP+DNS sind deaktiviert, Konfiguration IPv6-Adressen im heimischen Netz per SLAAC, da ich im LAN für die Kommunikation zwischen den Geräten nur IPv4 nutz. Außerdem ist noch eine LAN-LAN-Wireguard-Verbindung zu meinem V-Server eingerichtet.
  • NAS: Auf dem lief bisher DNSMasq als DNS- und DHCP-Server für das LAN. Konfiguriert waren 3 Zonen (LAN, V-Server, LAN meiner Eltern über VPN).
  • V-Server: per Wireguard verbunden. Ist meine Schnittstelle, um von IPv4-only-Netzen ins heimische LAN zu kommen. Z.B. liefert der Internet-Provider meiner Eltern nur IPv4.
  • Ca. 20 Clients: Desktoprechner, Notebook, RPi, Ubiquiti-Switch + -APs, AVR, TV, Nvidia-Shield, TV-Karte

Marco01_809 schrieb:
Das wird auch nie besser werden denn Selektion nur Anhand des Domainnamens ist einfach nicht mächtig genug.
Naja, in meinem alten DNS-Masq hab ich ebenfalls die Steven-Black-Adblockliste verwendet. Was anderes macht Pihole auch nicht. Aber ein paar deutsche Ad-Server stehen da auch nicht mit drin. Hab jetzt schon wieder im Pihole eine eigene Liste hinzugefügt.

Marco01_809 schrieb:
Das sind doch beides Diagnosetools, warum sollte das ein Problem sein was die machen? Auf welchem System testest du denn überhaupt?
Auf einem Desktop-PC im LAN. Firefox bietet dazu eine ziemlich gute Grundlage. Wenn man im Firefox auf about:networking → DNS geht, kann man den DNS-Cache löschen. Öffnet man dann eine Seite, z.B. www.n-tv.de, kann man im Networking ganz hübsch sehen, welche Flut an DNS-Abfragen auftaucht. Bei den geblockten Server steht halt als IP dort: 0.0.0.0.

Gleichzeitig läuft in der Konsole das Log vom dnsmasq. Und da taucht dann eben sowas auf:
Code:
Aug 19 18:49:45 dnsmasq[54635]: query[A] secure.adnxs.com from 192.168.109.21
Aug 19 18:49:45 dnsmasq[54635]: config secure.adnxs.com is 192.168.109.10
Aug 19 18:49:45 dnsmasq[54635]: query[AAAA] secure.adnxs.com from 192.168.109.21
Aug 19 18:49:45 dnsmasq[54635]: forwarded secure.adnxs.com to 208.67.222.222
In den Filterlisten stehen gewöhnlich nur die IPv4-Adressen:
Code:
address=/secure.adnxs.com/192.168.109.10

dig und host hab ich nur zu Analyse genutzt, um das Verhalten des dnsmasq zumindesst nachvollziehen zu können. Und zumindest bei host wurde erst der IPv4-, dann der IPv6- und anschließend noch der MX-Record abgefragt, wenn ich das dnsmasq-Log richtig interpretiert hab. Hab auch testweise mal IPv6 mit aufgenommen in die Liste:
Code:
address=/secure.adnxs.com/192.168.109.10
address=/secure.adnxs.com/::
Und trotzdem kam die reale IP durch, da der Eintrag ein CName auf irgendeinen Cloudserver war.
Ergänzung ()

Ok, mal ein paar Punkte zu Pihole. Docker mag ich nicht. Deswegen hab ich die normale Installation gewählt. Ein paar Anpassungen:

Da ich Nginx verwende und keine Bedarf hab, einen 2. Webserver laufen zu lassen (nein, erst recht nicht per Reverse Proxy den 2. Server durch den ersten durchzuschleusen), hab die Nginx-Konfiguration etwas anpassen müssen.

NGINX:
server {
    listen 80;
    listen [::]:80;

    root /var/www/pihole;
    server_name pihole.mld;
    server_name pihole;
    autoindex off;

    index pihole/index.php index.php index.html index.htm;

    access_log off;
#    access_log /var/log/nginx/pihole.access_log main;
    error_log /var/log/nginx/pihole.error_log notice;

    location / {
        expires max;
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        fastcgi_pass unix:/run/php/pihole.sock;
        fastcgi_param FQDN true;
        #auth_basic "Restricted"; # For Basic Auth
        #auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location /*.js {
        index pihole/index.js;
        #    auth_basic "Restricted"; # For Basic Auth
        #    auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location /admin {
        root /var/www/pihole;
        index index.php index.html index.htm;
        #auth_basic "Restricted"; # For Basic Auth
        #auth_basic_user_file /etc/nginx/.htpasswd; # For Basic Auth
    }

    location ~ /\.ht {
        deny all;
    }
}
Änderungen meinerseits:
  • Pihole ist bei mir ein Vhost und liegt nicht einfach im Default-Pfad.
  • Da der Installer durcheinanderkommt, wenn man das admin-Verzeichnis im Pfad ändert, hab ich einfach einen Symlink gesetzt:
    Code:
    cd /var/www
    ln -s html/admin pihole
Das nächste Problem ist PHP bzw. die Rechte des PHP-FPM-Sockets.
  • Nginx verwendet www-data als User/Gruppe.
  • Pihole "korrigiert" bei jedem Update alle Zugehörigkeiten wieder zurück zu pihole : pihole
Also erstellen wir einen eigenen Pihole-PHP-Pool:

Code:
[pihole]
user = pihole
group = pihole
listen = /run/php/pihole.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

Eingepflegt hab ich als zusätzliche Listen:

Letztere enthält bisher die folgenden Einträge, die ich in den vorgefertigten Liste nicht finden konnte, die aber auf GMX und n-tv.de für einges an unerwünschtem Inhalt sorgen:

Code:
0.0.0.0 ad4m.at
0.0.0.0 ad4m.ax
0.0.0.0 opecloud.com
0.0.0.0 adtrafficquality.google
0.0.0.0 adwords.l.google.com
0.0.0.0 agma-analytics.de
0.0.0.0 api.lotto24.de
0.0.0.0 buyer.dspx.tv
0.0.0.0 cdn-1239.privacy-mgmt.com
0.0.0.0 exitbee.com
0.0.0.0 feed.solads.media
0.0.0.0 hirsung.de
0.0.0.0 jubbie.de
0.0.0.0 medialead.de
0.0.0.0 orbidder.otto.de
0.0.0.0 viralize.tv
0.0.0.0 yieldlove.com
0.0.0.0 adalliance.profiles.tagger.opecloud.com
Außerdem hab ich noch eine Liste zum Sperren von Youtube, wenn der Sohnemann sich mal wieder zulange zuviel Müll von Youtube auf dem TV reinziehen will:
Code:
0.0.0.0 youtube.de
0.0.0.0 youtube.com
0.0.0.0 youtube-nocookie.com
0.0.0.0 youtu.be
0.0.0.0 ytimg.com
0.0.0.0 ggpht.com
# wird für Google Playstore benötigt
#0.0.0.0 googleapis.com
0.0.0.0 googlevideo.com
# App
0.0.0.0 youtube-ui.l.google.com
0.0.0.0 youtube.googleapis.com
0.0.0.0 youtube.l.google.com
0.0.0.0 youtubei.googleapis.com
0.0.0.0 appspot.l.google.com

Schön find ich an Pihole, dass man die Listen per Schalter einfach deaktivieren kann.

Was stört mich an Pihole (ein bisschen):
  • Im DNSMasq hatte ich bisher lokale 3 Zonen (SOA: mein LAN, LAN meiner Eltern, VPN-Zone) eingerichtet. Pihole bietet nur die Einrichtung einer Zone an.
  • Ich hatte im DNSMasq meine Infrastruktur (DHCP+DNS) schön übersichtlich in einer Datei. Pihole verteilt die Einträge sogar auf verschiedene Verzeichnisse.

Aber so als Fazit:
Es funktioniert erst mal alles soweit mit Pihole, und ist auch weniger aufgeblasen, als ich anfangs vermutet hatte. Ich beobachte das mal. Im Grunde genommen macht Pihole nicht soviel anders als ich vorher mit meiner DNSMasq-Konfiguration. Ist halt noch ein hübsches Frontend dazu. Aber sogar die Filterlisten sind gleich. Und auch die DNSMasq-Konfiguration ist ziemlich ähnlich zu der, die ich vorher schon hatte.
 
Zuletzt bearbeitet:
Hab grad eine Antwort auf meinen Bugreport bekommen:

Debian 11 contains dnsmasq 2.85-1, Debian 12 brings dnsmasq 2.89-1.

With version 2.86 dnsmasq changed its behaviour regarding the --address
option. Here's an excerpt from the manual page explaining the change:

-A, --address=/<domain>[/<domain>...]/[<ipaddr>]
[...]
Note that the behaviour for queries which don't match the speci‐
fied address literal changed in version 2.86. Previous versions,
configured with (eg) --address=/example.com/1.2.3.4 and then
queried for a RR type other than A would return a NoData answer.
From 2.86, the query is sent upstream. To restore the pre-2.86
behaviour, use the configuration --address=/example.com/1.2.3.4
--local=/example.com/

Das wäre dann auch die Erklärung dafür, dass mein DNSMasq nach dem Update ausgestiegen ist.

Jetzt muss ich überlegen, ob ich den Pihole behalte oder irgendwann mal wieder auf DNSMasq ohne Webfrontend zurückgeh.
 
Hab mal etwas weiter recherchiert und 2 neue Erkenntnisse erlangt:

1. Plain dnsmasq
Wie man hier schön entnehmen kann, ändert sich jetzt das Format der Adblock-Listen aufgrund der Verhaltensänderung von dnsmasq ab 2.86.

alt: address=/böser.server.com/0.0.0.0
neu: local=/böser.server.com/

Damit einher geht allerdings auch der Rückgabewert. Bei address wird die angegebene IP zurückgegeben. Bei local liefert dnsmasq allerdings ein NXDomain.

Ausprobiert in Vivaldi. Da funktioniert es wunderprächtig. Leider nicht so bei Firefox. Der hängt. Beide beschriebene Workarounds lösen das Problem bei mir allerdings nicht.

2. Pihole
Leider bietet die Oberfläche nicht alle benötigten Optionen. Allerdings ist hier ganz hübsch beschrieben, wie man das umgehen kann. Pihole nutzt die Konfigurationsdateien für dnsmasq mit den Präfixen 01..06 mit Ausnahme der 03. Und in die kann man dann die benötigten Einstellungen packen, ohne dass Pihole die wieder überschreibt.

Code:
############### DNS - Authoritative #############
auth-server=dns.mld
listen-address=192.168.109.50,127.0.0.1,fd00::6662:66ff:fed0:5ac,::1
auth-zone=mld,192.168.109.0/24
#- Serial,Hostmaster,Refresh,Retry,Expiry -#
auth-soa=42,admin@mld.de,86400,900,86400                                                                                                          
domain=mld,192.168.109.0/24,local                        
domain=mld2,192.168.108.0/24,local                        
domain=mld3,192.168.110.0/24,local                        
 
############### DHCP #############                      
dhcp-option=3,192.168.109.1                 # Default-GW via Fritzbox
dhcp-option=6,192.168.109.50                # DNS,systemd-resolved workaround
#dhcp-option=6,192.168.109.50,192.168.109.1  # DNS      
dhcp-option=15,mld                          # Domain (wird ignoriert)
dhcp-option=42,192.168.109.1                # NTP        
dhcp-option=119,mld,mld2,mld3                 # Search Domain

Langsam wird's brauchbar.
 
Zurück
Oben