[HowTo] Running Adguard Home on OpenWrt

Hello everybody,

this is a small guide for Adguard Home, an equivalent alternative to Pi-Hole.
To use Adguard Home on an OpenWrt router you need at least 20 MB free storage and about 100 MB free RAM (it can be started from a USB stick; the more RAM, the better). I‘m running Adguard Home on a Netgear R7800.

Ads/trackers/malware etc. are blocked by DNS. The DNS lists can be copied 1:1 from Pi-Hole or equivalent sources. Regex is also supported.

  • The big advantage over Pi-Hole is that Adguard Home does not need any dependencies and can be started from a single binary file.
  • Adguard Home comes with its own web interface, which can be accessed on a self-selected port.
  • The DNS server can be operated in parallel to dnsmasq.
  • DNS over TLS and HTTPS are supported by default.
  • Adguard Home can be started automatically via /etc/rc.local by simply executing the binary

Since it is programmed in Go, many architectures are already supported:
https://github.com/AdguardTeam/AdGuardHome/releases

1. Installation

The installation is relatively simple. The corresponding release must be downloaded and unpacked.
The application starts via ./AdguardHome and all necessary settings can be made via the web interface.

ssh root@192.168.1.1
opkg update && opkg install wget
mkdir /opt/ && cd /opt
wget -c https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.101.0/AdGuardHome_linux_armv5.tar.gz
tar xfvz AdGuardHome_linux_armv5.tar.gz
rm AdGuardHome_linux_armv5.tar.gz
Either just run it:
/opt/AdGuardHome/AdGuardHome 

or install it directly with:
/opt/AdGuardHome/AdGuardHome -s install

It is also possible to run it in the background (manually started):
opkg update && opkg install coreutils-nohup
nohup /mnt/usb/AdGuardHome/AdGuardHome > /dev/null 2>&1&

1.1. Attention

!!!! It is possible to install AdguardHome under /opt/, but this directory can grow. Old binaries are moved as backup after an update. blocklists can become relatively large. it is better to move AdGuardHome to a USB stick. So it will survive future OpenWRT updates !!!!

2. Configuration

After AdguardHome is started on the router, open the browser and start the AdGuard Home web interface

2.1 DNS Port
I have the Adguard Home DNS server running at 192.168.1.1:5353

2.1 HTTP Port
web interface at 192.168.1.1:8080.

2.2 /etc/conf/dhcp
Accordingly, the /etc/conf/dhcp config must be adjusted and the new DNS server must be defined:

config dnsmasq 
       option domainneeded '1' 
       option localise_queries '1' 
       option rebind_protection '1' 
       option rebind_localhost '1' 
       option local '/lan/' 
       option domain 'lan' 
       option expandhosts '1' 
       option authoritative '1' 
       option readethers '1' 
       option leasefile '/tmp/dhcp.leases' 
       option localservice '1' 
       list server '192.168.1.1#5353

2.3 /etc/firewall.user
Prevent DNS leaks and force all connected devices to use the new DNS port:

iptables -t nat -A PREROUTING -i br-lan -p udp --dport 53 -j DNAT --to 192.168.1.1:5353
iptables -t nat -A PREROUTING -i br-lan -p tcp --dport 53 -j DNAT --to 192.168.1.1:5353

Good Blocklists:
https://firebog.net/
https://dbl.oisd.nl/

Adguard Home Regex:
https://github.com/mmotti/adguard-home-filters/blob/master/regex.txt

DNS over TLS Upstream Server:
https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers#DNSPrivacyTestServers-DoTservers

DNS Leak Test:
https://www.dnsleaktest.com/results.html

Recommended modifications:

DNS over TLS

Good no-logging-policy DNS Server:

tls://dot.securedns.eu
tls://fdns1.dismail.de
tls://dns.neutopia.org
tls://dns.digitale-gesellschaft.ch

For me it is a super easy alternative to Pi-Hole, without installation effort and many dependencies.
Have fun with it!

8 Likes

Thank you for this guide. I had been curious about Adguard Home for quite some time now but had no idea that it could run on OpenWrt. This is great. Excellent tutorial too.

What exact package did you download for your Netgear R7800?

Also, which package would I download for my Linksys WRT3200ACM?

Thank you for sharing this info. Cheers!

Or just install https-dns-proxy with the Web UI app and configure it to use AdGuard DNS server. That's it, no downloading/unpacking needed.

2 Likes

Thanks for your reply! The R7800 and the WRT3200ACM are using both an ARM-CPU. You will probably need this package:

https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.100.8/AdGuardHome_linux_arm.tar.gz

The standard AdGuard DNS servers "only" provide standard filtering. You can't configure the filters/blocklists/whitelists/web services (Facebook, WhatsApp, Amazon, ...) that are to be blocked. Furthermore you have to use an adguard server as dns server. with the home variant you can use secure dns over tls servers which do not log.

1 Like

There're settings for AdGuard Standard and AdGuard Family Protection DNS servers in the package I referenced.

But yes, you can't configure additional blocklists without additional packages (like adblock or simple-adblock).

I haven't checked, but I'm pretty sure that the DNS servers the "AdGuard Home" uses are exactly the same as https-dns-proxy can use.

1 Like

I am quite impressed with this AdGuard Home after trying it out (mostly) successfully on my WRT3200ACM. Wickedly thorough with regex filtering, parental control, and so much more. It's got a very responsive and well designed web UI as well.

The only issue that I have right now with AdGuard Home on my WRT3200ACM is that AdGaurd Home itself does not seem to get network access and therefore continues to fail at any kind of network connectivity such as checking for updates, filter updates, etc. All network connectivity of AdGaurd Home itself seems to fail with certificate related issues. I'm not referring to devices connecting to network, but simply AdGaurd Home itself. Any ideas what would cause this?

AdGuard Home is open source, as far as I understand. Hopefully somebody, maybe even AdGuard Team themselves, can create these as individual .ipk releases at some point in the future. It will get more users testing their program as well.

1 Like

Nice to hear :slight_smile:

Are ca-certificates or ca-bundle installed?

No, I don't have either of those packages installed. I run mostly default OpenWrt settings so I usually don't stray too far from defaults. I am running 19.07 RC2 right now. I just went ahead and updated lists, installed those packages that you suggested. Now that I have those installed, I will try AdGuard Home again in the next hour or so. Thank you for your help.

1 Like

I have confirmed just now that this suggestion has fixed my problem regarding AdGuard Home network issues. It is able to download filter lists and check for updates now. Thank you again.

So far, so good. Everything appears to be working great, although I do have one error message still showing up in the console still:

2020/01/04 16:02:24 [error] command systemctl has failed: exec: "systemctl": executable file not found in $PATH code:-1

I am not as familiar with Linux in general and therefore don't understand the error. Are you familiar with this error message?

Also, just a couple of questions if you have a moment:

Where is the best location within the file system to store the AdGuardHome binary so that it is appropriate for execution and for storing it's configuration file? (currently just executing from Tmp just during my testing phase before I decide to implement fully)

Is it absolutely required to run AdGuardHome via sudo ./AdGuardHome everytime or is sudo just required for the initial launch? (I saw that command on it's wiki documentation site)

Thank you for your time, I do appreciate it.

2 Likes

I'm glad it fixed this certificate issue! Currently, I've put the folder into the /-folder and automatically start it with rc.local each reboot (no issues so far):

root@OpenWrt:~# cat /etc/rc.local

/AdGuardHome/AdGuardHome

I can imagine that Adguard Home wants to use systemctl when sudo ./AdGuardHome -s install is called. systemd or systemctl is responsible for starting and running all services under Linux. OpenWrt is init based and does not use SystemD

I've been thoroughly testing AdGuardHome since you created this fantastic HowTo post and I am glad that you posted this because I had been curious about AdGuardHome for a while.

I found a nice, functional luci-app-adguardhome (https://github.com/rufengsuixing/luci-app-adguardhome). The development appears to be in Chinese, however, the web UI itself shows in English on my device and works great for configuring many options for AdGuardHome. After you install it, you just have to change the luci-app-adguardhome to match the settings that you have for AdGuardHome (binary locations, work dir, port, etc.) and it will recognize everything from that point and you can make changes as needed.

@brokenpipe Have you played around with the experimental DHCP functionality of AdGuardHome yet?

I tried (and failed) today because I was curious about per-device AdGuardHome settings based on MAC addresses but it requires that you use the DHCP functionality. I will try again tomorrow and see where I went wrong. Likely due to odhcp already listening on port 67, but will dig in more when I have more time.

2 Likes

I am really pleased that it works so well! I have not done anything with the dhcp setting yet. I think this will break some openwrt settings. Thanks for the tip with the luci app. Is it possible to change more settings there? Probably it reads the Adguard Home config!?

I have been running AdGuaradHome successfully on my network of approx. 9-10 devices for a little bit over a week now and figured I would provide some feedback in case it may be beneficial to others here.

Adblock syntax:
AdGuardHome is, at the moment, is only a little bit more than just a DNS sinkhole system like many others at the moment. Although the AdGuard Team does have big aspirations to continue making it do much more.

There is a nice feature comparison chart comparing AGH to Pi-Hole: https://github.com/AdguardTeam/AdGuardHome#comparison-pi-hole

There is an underlying component of AdGuardHome called urlfilter which does much of the filtering and Adblock syntax parsing. They have a TODO list that is interesting and shows features that are complete and also upcoming features that relate to Adblock syntax. See urlfilter TODO list here: https://github.com/AdguardTeam/urlfilter#todo

For example, it is easy to add domain whitelists that follow Adblock syntax such as Ebates/Rakuten domain whitelist filter. See list here: https://www.rakuten.com/whitelist/ebates-cash-back-shopping.txt

DHCP server and MAC filtering:
AdGuardHome has it's own built in DHCP server. I was interesting in MAC address filtering for the 9-10 devices on my network and wanted more granular control. Initially, I could not initiate AGH's built in DHCP server because it could not bind to port 67 because dnsmasq had access.

The dnsmasq option dhcp-alternate-port solved my issue. Setting that option, rebooting the router or restarting dnsmasq, switched dnsmasq to bind to ports 1067 and 1068 thus freeing up port 67. AGH's DHCP server is now able to initiate and bind to port 67 and working flawlessly.

I now have per-client (per-MAC) address filtering, without the need for static IP addresses, with the most granular control that I have had from a router device. I am quite impressed thus far.

Now, dhcp-alternate-port was tricky to get working correctly. I tried every possible way within etc/config/dhcp to get it working such as adding option dhcp-alternate-port or option dhcp-alternate-port '1067 1068' to in various sections within the etc/config/dhcp file but every attempt failed. The only way that was successful for me was to add one single line dhcp-alternate-port to the etc/dnsmasq.conf file.

luci-app-adguardhome:
I had mentioned this in my most recent post. I used it briefly but have since removed it. It is quite complex but I prefer simplicity myself. Anyway, it used an init.d script to facilitate in being able to change the work-dir, bin path, config path, etc. Much of these can be changed with command line arguments anyway. It can also compress the AdGuardHome binary as well. So while it is quite neat and comprehensive, I prefer to do many things manually myself and keep things simple.

Bug Fixes & Development:
The last thing that I wanted to touch on was that the development on Github seems quite active and the developers follow up on reported bugs and suggestions quite quickly. I reported one minor bug and it was fixed within a couple of days.

1 Like

I would not be so enthusiastic about this one. As it will need a proxy, with some (serious) performance impact. Especially, in case it should also work for https, which then will need installation of special cert on client device. And, even then, it will not always work, because of HSTS. So, for me it sounds more like "marketing hype".
Different story for well established browser plugins, though.

1 Like

I actually run adguard on port 53 and dnsmasq on 5300, this way i can have all the client statistics on AdGuard and have the 'home' domain resolved.

1 Like

Thanks for your tips. I've managed to have AdGuardHome starting on my router after the rc.local command included 'start-stop-daemon -S -b -x /pathtoAGH/AdGuardHome'. It was previously hanging the boot process as there are other init.d processes after rc.local.

I've a question though. I've disabled DHCP in OpenWrt to use the DHCP capability of AGH. My expectation was that this would lead to client identification. However, all my DNS queries are labelled with the rourter's IP address. I can't seem to be able to have per client/MAC address filtering even with DHCP leases attributed to clients in AGH's DHCP section.

Is there any flag or option in dnsmasq that sends DNS queries with a header or additional client information that AGH can read? I've tried all options within luci but no luck. I've spent a large amount of time by trial and error and failed.

Thanks

2 Likes

Try remove dnsmasq, and use full odhcpd as DHCP server.
Run AdGuard Home on port 53.

Your /etc/config/dhcp like this :

config dhcp 'lan'
option dhcpv4 'server'
option dhcpv6 'server'
option interface 'lan'
option leasetime '12h'
option ra 'server'
option ra_management '1'
...

config odhcpd 'odhcpd'
option maindhcp '1'

It works perfectly for me.

rc.local is called after all init.d scripts got called.

Thanks for your comment. Can you give a short explanation how to better start/stop agh? I also experienced that it kills cron and sysntpd when I call it via rc.local