Ilija Matoski

    ← Articles

    My Pi-hole had not been blocking ads for most of the network

    An adlist with no group assignment applies to no client. Mine had 93,516 domains in it and had been doing nothing for as long as it had been there.

    I’ve been running Pi-hole for years and I’d have told you it was blocking ads for everything on the network.

    It wasn’t, and I only found out because I was copying its configuration into something else.

    The blocklists and the client groups live in gravity.db, so you can ask it directly:

    sqlite3 /etc/pihole/gravity.db 'select id, address, enabled from adlist;'
    sqlite3 /etc/pihole/gravity.db 'select adlist_id, group_id from adlist_by_group;'

    The big list, StevenBlack at 93,516 domains, had no row in adlist_by_group at all.

    A list with no group assignment applies to no client, because Pi-hole’s own vw_gravity view joins through that table.

    So the domains were sitting in the database and in no client’s view of it.

    The schema is one thing, so in my case I checked it with the following query as well:

    dig +short ad-assets.futurecdn.net @192.168.178.5

    That name is a StevenBlack entry and it came back with a real address.

    So every device outside the six clients I’d configured by hand had no ad blocking at all, and hadn’t had any for as long as that list had been there.

    The second list was a web page

    The next one down pointed at github.com/.../blob/main/...txt, which is the HTML page GitHub renders around a file, and not the file itself.

    Pi-hole downloaded it and parsed it as a domain list, so its 2,061 entries include things like 0-1.123.404-2.336 scraped out of the surrounding markup.

    Point it at the raw.githubusercontent.com URL instead.

    Two more that nothing complained about

    One CNAME had a stray tab inside the value, which dnsmasq took without a word.

    And home had both an A record and a CNAME, which isn’t legal, because a CNAME has to be the only record for a name. dnsmasq silently picked one, and a live query showed the CNAME winning, so the dead A record went away.

    Technitium rejects both of those outright, which is how I found them.

    MAC is the part that doesn’t move

    Pi-hole keys clients by MAC address, while Technitium matches on IP, subnet or DNS endpoint, and there’s no MAC option at all, because a DNS server never sees a MAC.

    So we need to identify those six devices some other way, and there are three ways to do it, none of which is a straight copy:

    • DHCP reservations plus a per IP mapping, which is the least disruption since four of the six already have reservations
    • a VLAN per policy group, and map the subnet instead of the address
    • per device DoT or DoH endpoints, which is the most precise and means configuring every device by hand

    That part of the migration needs a decision, and there is no script for it.

    What did map

    Pi-hole Technitium
    25 dns.hosts A records a primary zone with A records
    29 dns.cnameRecords CNAMEs in the same zone
    revServers reverse half a conditional forwarder for 178.168.192.in-addr.arpa
    revServers forward half gone, the zone is authoritative now
    dnscrypt-proxy on 127.0.0.1:5054 built in, DoH and DoT are native
    adlists and regexes per group the Advanced Blocking app
    the 2.9 GB pihole-FTL.db left behind

    dnscrypt-proxy is the one I’m happiest to stop running, because it was a second daemon on the Pi whose entire job was being the upstream for the first one:

    technitium_forwarders:
    - https://cloudflare-dns.com/dns-query
    - https://dns.quad9.net/dns-query
    technitium_forwarder_protocol: Https