Jon Brookes
2025-01-03
I’m looking at creating a containerised solution that offers customisable block / allow lists using DNS for small networks.
Having worked in this zone before my interest was piqued when a friend a colleague cam to me with an idea for a home / small office system to filter internet traffic for all the devices on the network.
Pi-Hole and AdGuard are possible candidates to assist in some of these requirements. So first off, I set up a lab to see how AdGuard works and if it can do what we need of it.
docker-compose.yml :
name: adguard-v1
services:
adguardhome:
container_name: adguardhome
restart: unless-stopped
volumes:
- ./workdir:/opt/adguardhome/work
- ./confdir:/opt/adguardhome/conf
ports:
- 53:53/tcp
- 53:53/udp
- 67:67/udp
#- 68:68/udp
- 80:80/tcp
- 443:443/tcp
- 443:443/udp
- 3000:3000/tcp
- 853:853/tcp
- 784:784/udp
- 853:853/udp
- 8853:8853/udp
- 5443:5443/tcp
- 5443:5443/udp
image: adguard/adguardhome
I needed to comment out port 68 used for DHCP clients, as this is not required and clashes what that already running on this VM.
Likely many more of these port exposures may be removed and more over the rmaining ones bound to a specific interfaces if not disabled in some way entirely.
Digging deeper, in confdir/AdGuardHome.yaml
of the container config there is to found the following :
dns:
bind_hosts:
- 0.0.0.0
port: 53
where dns is set to listen on all interfaces and port 53, so as others on reddit report that other ports for https and http can be changed this is possibly how adguard could be changed for this to work for port mappings to its DNS daemon.
However, lets not get too far ahead of ourselves. Running this on a simple docker host in a test lab, this is me testing AdGuard with all its default settings - first I dig cloudflare, unfiltered dns for youtube, which works
dig @1.1.1.1 www.youtube.com
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> @1.1.1.1 www.youtube.com
.....
;; Query time: 15 msec
;; SERVER: 1.1.1.1#53(1.1.1.1) (UDP)
;; WHEN: Fri Jan 03 15:11:49 GMT 2025
;; MSG SIZE rcvd: 318
which is first to prove I have DNS resolution working so next I try it with my local adguard on a client that is super restricted :
dig @192.168.88.10 www.youtube.com
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> @192.168.88.10 www.youtube.com
.......
;; QUESTION SECTION:
;www.youtube.com. IN A
;; ANSWER SECTION:
www.youtube.com. 10 IN A 0.0.0.0
so this would not be able to get to YouTube and would return the address of 0.0.00
to the user
then I change my AdGuard client config to allow this user to get to youtube :
dig @192.168.88.10 www.youtube.com
; <<>> DiG 9.18.28-0ubuntu0.24.04.1-Ubuntu <<>> @192.168.88.10 www.youtube.com
.....
;www.youtube.com. IN A
;; ANSWER SECTION:
www.youtube.com. 300 IN CNAME youtube-ui.l.google.com.
youtube-ui.l.google.com. 282 IN A 142.250.180.14
....
so adguard is relatively easy to get running in docker, easy to add / edit clients easy to block a whole array of services like youtube, betfair, amazon
AdGuard there for looks like a good candidate for us.
There is an api for adguard at its git repo so in theory it is programable which is what we need where it suggest running the OpenAPI specification from this directory using yarn
which I did and can browse the JSON spec more conffortably that grokking its JSON.
I confirmed also checked if openwrt is in theory capable of capturing DNS from specific IP or MAC addresses and sending these to a custom DNS server. As I’ve done this and similar with IPTables in the past it would be highly unlikely not to be the case in Netfilter.
OpenWRT however uses its own Unified Configuration Interface UCI for most if not all of tis configuration through this command line interface. So I was hoping to use something like
uci set firewall.@rule[-1].name="Redirect DNS for $SPECIFIC_MAC"
uci set firewall.@rule[-1].src="*"
uci set firewall.@rule[-1].proto="tcp udp"
uci set firewall.@rule[-1].dest_port="53"
uci set firewall.@rule[-1].target="DNAT"
uci set firewall.@rule[-1].dest_ip="$CUSTOM_DNS"
uci set firewall.@rule[-1].extra="--mac-source $SPECIFIC_MAC"
**# Commit and restart firewall**
uci commit firewall
/etc/init.d/firewall restart
Which will need tested in my lab a this has come fresh from an AI served to me by copilot so it could be hallucination.
So, pending more tests to prove the above we could have a working prototype.
🚀