AdGuard Home

AdGuard Home (AGH) is a free and open source network-wide advertising and trackers blocking DNS server. It operates as a DNS server that re-routes tracking domains to a “black hole”, thus preventing your devices from connecting to those servers. It is based on software used with public AdGuard DNS servers.

In addition, AdGuard Home also offers DNS encryption features such as DNS over TLS (DoT) and DNS over HTTPS (DoH) built-in without any additional packages needed.

Routers with low RAM, flash/storage space or slower processors will potentially not be suitable to run AdGuard Home. You may want to run AdGuard Home on another client instead if you have any of the mentioned system resource limitations with your router. The following requirements below are provided as general guidance.

  • Minimum of 50 MB free RAM.
  • Minimum of 100 MB free flash/storage space (see flash/storage space requirements).
  • Higher performance routers i.e. dual-core with higher processor clock speeds are recommended.

The amount of RAM required will also be relative to the filter lists you use.

Routers with less than 128 MB of RAM or only having a single core processor will tend to perform poorly. The homehub_v5a was used for testing the 0.107.0 edge and release builds.

An alternative option could be to use a Raspberry Pi Zero plugged into your routers' USB port to run AdGuard Home: Using a Pi Zero for AdGuard Home

For the best performance and lowest latency on DNS requests, AdGuard Home should be your primary DNS resolver in your DNS chain. If you currently have dnsmasq or unbound installed, you should move these services to an alternative port and have AdGuard Home use DNS port 53 with upstream DNS resolvers of your choice configured. We recommend keeping dnsmasq/unbound as your local/PTR resolver for Reverse DNS.

The rationale for this is due to resolvers like dnsmasq forking each DNS request when AdGuard Home is set as an upstream. This will have an impact on DNS latency, which can be viewed in the AdGuard Home Dashboard. You will also not benefit from being able to see the DNS requests made by each client if AdGuard Home is not your primary DNS resolver, as all traffic will appear from your router.

The install script in the setup section will move dnsmasq to port 54 and set it for AdGuard Home to use as your local/PTR resolver for Reverse DNS.

The compiled AdGuardHome binary has grown since the 0.107.0 release. For many routers this will be quite a significant amount of storage taken up in the overlay filesystem. In addition, features like statistics and query logging will also require further storage space when being written to the working directory. For routers with less flash space, it is highly recommended to use USB or an external storage path to avoid filling up your overlay filesystem. If you have low flash space, you may want to use the custom installation method and have all of the AdGuard Home installation stored outside of your flash storage. Alternatively, you can also perform an exroot configuration.

Currently, a full install requires about 100 MB of space.

  • 35 MB for the AdGuardHome binary.
  • 10 MB for filters, but this will depend on what filter lists you use. This was calculated with AdGuard DNS Filter, HaGeZi's Pro Blocklist, and OISD Blocklist Small being used.
  • 2 MB for 90 days of statistics.
  • 53 MB for 7 days of query logs.

You can tweak your logs rotation to keep things smaller if required.

One of the main benefits of AdGuard Home is the detailed query and statistics data provided. For many routers, however, having long retention periods for this data can cause issues (see flash/storage space requirements). If you are using the default storage location (/var/lib/adguardhome/data), you should set a relatively short retention period or disable logging altogether. If you want to have longer retention periods for query/statistics data, consider moving the storage directory to outside your routers flash space.

Since OpenWrt 21.02, there is an official AdGuard Home package which can be installed through apk (since 25.12) and opkg (21.02 to 24.10).

Required dependencies (ca-bundle) are automatically resolved and installed when using the official package.

For OpenWrt 25.12 and above, the package manager switched from opkg to apk (opkg-to-apk-cheatsheet).

apk update
apk add adguardhome

For OpenWrt 21.02 to 24.10, opkg is used.

opkg update
opkg install adguardhome

The opkg package for 21.02 has also been confirmed to work on 19.07, but will require transferring the correct ipk through SSH or SCP and installing with opkg manually due to not being present in the 19.07 package repository.

The official OpenWrt package uses the following paths and directories by default:

  • The AdGuardHome binary will be installed to /usr/bin/AdGuardHome.
  • The main adguardhome.yaml configuration file is stored at /etc/adguardhome/adguardhome.yaml.
  • The default working directory is /var/lib/adguardhome. By default, /var is a symlink to /tmp.
  • The working directory can be configured in /etc/config/adguardhome
  • An init.d script is provided at /etc/init.d/adguardhome.

Query logs and statistics will be lost on a reboot using the default working directory. To avoid this, you should configure a persistent storage path such as /opt or /mnt with external storage and update the working directory accordingly.

To have AdGuard Home automatically start on boot and to start the service:

service adguardhome enable
service adguardhome start

After installing the package, run the following commands through SSH to prepare for making AdGuard Home the primary DNS resolver. These instructions assume you are using dnsmasq. This will demote dnsmasq to an internal DNS resolver only.

The ports chosen are either well known alternate ports or reasonable compromises. You are free to edit the scripts to use your own ports but you should check with List_of_TCP_and_UDP_port_numbers for reserved ports.

# Get the first IPv4 and IPv6 Address of the router LAN interface and store them in following variables for use during the script.
dev=$(ifstatus lan | grep \"device | awk '{ print $2 }' | sed 's/[",]//g')
NET_ADDR=$(/sbin/ip -o -4 addr list $dev | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1]; exit }')
NET_ADDR6=$(/sbin/ip -o -6 addr list $dev scope global | awk '$4 ~ /^fd|^fc/ { split($4, ip_addr, "/"); print ip_addr[1]; exit }')
echo "Router IPv4 : ""${NET_ADDR}"
echo "Router IPv6 : ""${NET_ADDR6}"
 
# 1. Move dnsmasq to port 54.
# 2. Set local domain to "lan".
# 3. Add local '/lan/' to make sure all queries *.lan are resolved in dnsmasq;
# 4. Add expandhosts '1' to make sure non-expanded hosts are expanded to ".lan";
# 5. Disable dnsmasq cache size as it will only provide PTR/rDNS info, making sure queries are always up to date (even if a device internal IP change after a DHCP lease renew).
# 6. Disable reading /tmp/resolv.conf.d/resolv.conf.auto file (which are your ISP nameservers by default), you don't want to leak any queries to your ISP.
# 7. Delete all forwarding servers from dnsmasq config.
uci set dhcp.@dnsmasq[0].port="54"
uci set dhcp.@dnsmasq[0].domain="lan"
uci set dhcp.@dnsmasq[0].local="/lan/"
uci set dhcp.@dnsmasq[0].expandhosts="1"
uci set dhcp.@dnsmasq[0].cachesize="0"
uci set dhcp.@dnsmasq[0].noresolv="1"
uci -q del dhcp.@dnsmasq[0].server
 
# Delete existing config ready to install new options.
uci -q del dhcp.lan.dhcp_option
uci -q del dhcp.lan.dns
 
# DHCP option 3: Specifies the gateway the DHCP server should send to DHCP clients.
uci add_list dhcp.lan.dhcp_option='3,'"${NET_ADDR}"
 
# DHCP option 6: Specifies the DNS server the DHCP server should send to DHCP clients.
uci add_list dhcp.lan.dhcp_option='6,'"${NET_ADDR}" 
 
# DHCP option 15: Specifies the domain suffix the DHCP server should send to DHCP clients.
uci add_list dhcp.lan.dhcp_option='15,'"lan"
 
# Set IPv6 Announced DNS
uci add_list dhcp.lan.dns="$NET_ADDR6"
 
uci commit dhcp
service dnsmasq restart
service odhcpd restart
exit 0

The script makes the necessary settings only for the LAN interface. Since it changes the dnsmasq default listening port, the router address will no longer be advertised via DHCP as a DNS server. If you have multiple interfaces, you will need to specify the required DNS server IP address using DHCP Option 6.

Setup AdGuard Home through the web interface

On first time setup the default web interface port is TCP 3000.

  1. Go to http://192.168.1.1:3000/ (if your router IP is not 192.168.1.1, replace this accordingly).
  2. Set the Admin Web Interface to listen on 192.168.1.1 at port 8080 (or any other port you wish to use).
  3. Set DNS server to listen on “All interfaces” at port 53.
  4. Create a username and choose a strong password.

Login to AdGuard Home

AdGuard Home has its own web interface for configuration and management and is not managed through LuCI. There is no official LuCI application for managing AdGuard Home.

By default, LuCI will be configured to use standard ports TCP 80 and 443, so AdGuard Home will need to use an alternative port for the web interface. The setup guide above uses port 8080.

Visit http://192.168.1.1:8080/ (or whatever listening port you set), follow the official AdGuard Home wiki instructions to configure upstreams and filters. A list of known DNS providers and settings are provided by AdGuard.

Some advanced settings may not be editable via the web interface and instead will need to be changed by editing the adguardhome.yaml configuration file.

Bypassing encrypted DNS for NTP

In order for SSL to work and to use an upstream DNS setup that utilises DNS encryption e.g. DoT or DoH, the correct time must be set on the device. You may come across a race condition on startup where communication to such DNS resolvers are not possible, due to the NTP service not being able to establish a connection to a network time source (and then set the correct time on your router). To prevent this, you must allow NTP DNS requests to use plain DNS, regardless of the upstream DNS resolvers set.

From the AdGuard Home web interface: SettingsDNS SettingsUpstream DNS Servers

Add the following to ensure any DNS request for NTP uses plain DNS. In this example, Cloudflare resolvers have been used. However, you can use any plain resolvers you like.

[/pool.ntp.org/]1.1.1.1
[/pool.ntp.org/]1.0.0.1
[/pool.ntp.org/]2606:4700:4700::1111
[/pool.ntp.org/]2606:4700:4700::1001

Click apply to enable these specific DNS rules.

For older builds, a custom installation, or running the latest edge builds, you can follow several well written guides by members of the community:

Below are recommendations and best configuration practices for using AdGuard Home on OpenWrt.

You might notice quite a large number of PTR records appearing in the query log and in statistics. These are useful to have in the first few minutes of your brand new setup to see DNS working, but they aren't the most helpful afterwards.

To exclude them from appearing in the query log and statistics:

  1. From the AdGuard Home web interface SettingsGeneral settings,
  2. Enable “Ignore domains” for both Query Log and Statistics,
  3. Enter *.arpa in the domain list for both Query Log and Statistics, and save changes.

You'll now have a cleaner experience.

To enable rDNS so AdGuard Home picks up your DHCP assignments from OpenWrt:

  1. From the AdGuard Home web interface SettingsDNS settings,
  2. Scroll to Private reverse DNS servers,
  3. Add 127.0.0.1:54 or 192.168.1.1:54 (using loopback interface [127.0.0.1] is recommended whenever applicable to avoid network overhead and increase performance for rDNS queries),
  4. Tick both “Use private reverse DNS resolvers” and “Enable reverse resolving of clients' IP addresses” boxes and click apply.

Adding the following to the Upstream DNS Server configuration will intercept any LAN domain request or requests without a FQDN and pass those requests to the appropriate resolver, which is mostly like your OpenWrt router (but it doesn't have to be).

SettingsDNS SettingsUpstream Servers

[/lan/]127.0.0.1:54
[//]127.0.0.1:54

Setting [//]127.0.0.1:54 will prevent Spotify from connecting to its servers, so leave this out if you use it.

The default LAN domain configured by OpenWrt is “lan”, but if you have configured your own domain, replace lan with your own.

Some devices will bypass DHCP provided DNS servers e.g. Google TV.

In order to make sure all DNS traffic goes through your primary DNS resolver, you can enforce this through firewall rules.

Please note this only enforces plain DNS enquiries from your LAN to be redirected through your DNS. To block DoH or other encrypted DNS requires further rules. You also might like to add the HaGeZi's Encrypted DNS/VPN/TOR/Proxy Bypass filter to your AdGuard Home blocklist.

Add a new rule to Network → Firewall → Port Forwards, setting “Protocol” as “UDP”, “Source zone” as “lan”, “External port” to 53, “Destination zone” as “unspecified” and “Internal IP Address” your router address (usually 192.168.1.1) and “Internal port” still 53. When saving and applying the rule, all UDP 53 traffic will redirected to your router.

Alternately, a custom rule can be added:

nft add rule nat pre udp dport 53 ip saddr 192.168.1.0/24 dnat 192.168.1.1:53

This will redirect all DNS traffic from 192.168.1.0/24 to the 192.168.1.1 server.

Copy and paste these iptables rules in Network → Firewall → Custom Rules Tab or directly to /etc/firewall.user.

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

You can also implement this via a fw3 rule within /etc/config/firewall:

config redirect 'adguardhome_dns_53'
        option src 'lan'
        option proto 'tcp udp'
        option src_dport '53'
        option target 'DNAT'
        option name 'Adguard Home'
        option dest 'lan'
        option dest_port '53'

These examples are for IPv4 DNS traffic only, as they use DNAT.

Further information on DNS interception (fw3)

AdGuard Home is recommended to be used with filtering disabled as a NextDNS client. See: Using AGH as a NextDNS Client

If you already use Nginx with LuCI rather than uHTTPd, you can reverse proxy the AdGuard Home interface. This can simplify accessing the AdGuard Home interface and not having to worry about URLs with non standard HTTP ports. Using a reverse proxy also means you don't have to specifically configure HTTPS access through AdGuard Home, and can instead utilise the HTTPS configuration of LuCI.

The following example will allow accessing the AdGuard Home interface as a sub directory path of /adguard-home. If your router IP or AdGuard Home http_port value is different, change it accordingly.

location /adguard-home/ {
    proxy_pass http://192.168.1.1:8080/;
    proxy_redirect / /adguard-home/;
    proxy_cookie_path / /adguard-home/;
}

You can then access it using http://192.168.1.1/adguard-home in your browser.

Read more reverse proxy configurations from the Nginx docs.

Disable DoH encryption on AdGuard Home

If you have configured TLS on LuCI, there's no need to use TLS on AdGuard Home. Set allow_unencrypted_doh to false in adguardhome.yaml to allow AdGuard Home respond to DoH requests without TLS encryption.

For users using ipset policies for purposes such as VPN split tunnelling, AdGuard Home provides ipset functionality similar to dnsmasq. The configuration/syntax is slightly different - you will need to migrate any existing dnsmasq ipset policies to the AdGuard Home format and apply these to AdGuard Home instead.

An ipset policy is defined in the adguardhome.yaml file. There is currently no web interface available to add these policies, therefore you must add these to the yaml config manually.

If ipset is not already installed, install it:

apk update
apk install ipset

Example dnsmasq syntax

Using the following example ipset rules in dnsmasq as a reference, the AdGuard Home equivalent is demonstrated.

ipset=/domain.com/ipset_name
ipset=/domain1.com/domain2.com/ipset_name,ipset_name2

Example AdGuard Home syntax

dns:
 ipset:
 - domain.com/ipset_name
 - domain1.com,domain2.com/ipset_name,ipset_name2
...

The main syntax differences is each domain is separated using a comma (,) not a forward slash (/). A forward slash denotes the end of a domain rule with AdGuard Home. When specifying the ipset chain, a comma is used in both examples to denote multiple chains if required.

Like dnsmasq, an ipset policy in AdGuard Home can have one or more domains as well as be assigned to multiple ipset chains. Further information on ipset functionality can be found on the official AdGuard Home wiki under “Other Settings”.

The ipset chains must exist before being used or referenced as AdGuard Home does not initialise them. It is possible to potentially encounter a race condition on startup if the ipset chains are not created in time when AdGuard Home attempts to start. An alternative is creating a custom init script that runs the ipset create command earlier than the START value of AdGuard Home.

If AdGuard Home won't start, you will want to view error logs to understand why.

If using the apk package you can view syslog for errors using logread.

logread -e AdGuardHome

You can also run AdGuardHome from command line and see the output directly.

AdGuardHome -v -c /etc/adguardhome.yaml -w /var/lib/adguardhome --no-check-update

This example uses the defaults set in the init script with the extra addition of the verbose flag.

  • -v --verbose - Enables verbose output (useful for debugging).
  • -c --config - Path to the AdGuard Home YAML config.
  • -w --work-dir - Path to the set working directory where data such as logs and statistics are stored.
  • --no-check-update - Disables the built in update checker.

The most common reason for AdGuard Home not starting is due to syntax errors in the adguardhome.yaml config.

This script uninstalls AdGuard Home and resets your router DNS to Google DNS. This is a known good default and should always work, but you can change it to something else. If your router is not at 192.168.1.1 then replace the router IP address used in the commands below accordingly.

#!/bin/sh
apk update
service adguardhome stop
service adguardhome disable
apk del adguardhome
 
# 1. Reverts AdGuard Home configuration and resets settings to default.
# 2. Enable rebind protection.
# 3. Remove DHCP options for IPv4 and IPv6 
uci -q delete dhcp.@dnsmasq[0].noresolv
uci -q delete dhcp.@dnsmasq[0].cachesize
uci set dhcp.@dnsmasq[0].rebind_protection='1'
uci -q delete dhcp.@dnsmasq[0].server
uci -q delete dhcp.@dnsmasq[0].port
uci -q delete dhcp.lan.dhcp_option
uci -q delete dhcp.lan.dns
 
# Network Configuration
# Disable peer/ISP DNS
uci set network.wan.peerdns="0"
uci set network.wan6.peerdns="0"
 
# Configure DNS provider to Google DNS
uci -q delete network.wan.dns
uci add_list network.wan.dns="8.8.8.8"
uci add_list network.wan.dns="8.8.4.4"
 
# Configure IPv6 DNS provider to Google DNS
uci -q delete network.wan6.dns
uci add_list network.wan6.dns="2001:4860:4860::8888"
uci add_list network.wan6.dns="2001:4860:4860::8844"
 
# Save and apply
uci commit dhcp
uci commit network
/etc/init.d/network restart
/etc/init.d/dnsmasq restart
/etc/init.d/odhcpd restart

Reconnect your clients to apply the changes.

The adguardhome/data folder contains the following.

root@OpenWrt:/var/lib/adguardhome/data# ll -h
drwxr-xr-x    3 root     root         512 Oct 29 09:42 ./
drwxrwxrwx    4 root     root         736 Oct 30 09:06 ../
drwxr-xr-x    2 root     root         800 Nov  2 09:52 filters/
-rw-r--r--    1 root     root       45.4M Nov  2 20:42 querylog.json
-rw-r--r--    1 root     root       32.0K Oct 30 05:28 sessions.db
-rw-r--r--    1 root     root        4.0M Nov  2 21:00 stats.db
  • querylog.json: This is a log of DNS queries shown in the Query Log. Can be deleted, but you will lose your query data.
  • sessions.db: Active logins to AdGuard Home. Can be deleted, but you will need to log back in.
  • stats.db: This is a database of statistics shown in the Dashboard. Can be deleted, but you will lose your statistics data.

The filters folder contains all your filter downloads. Can be deleted, but AdGuard Home will re-download your filters.

If your filters are too large for your disk space, you will need to disable large filters and restrict their usage.

The more blocklists enabled in AdGuard Home, the more memory the service will consume. This matters especially on devices with less than 1 GB of RAM. This python script analyzes block activity (querylog.json) and checks each entry against the configured blocklists.

The script expects a directory named 'data' in the current working directory. Obtain this by copying the adguardhome data folder from the router, for example:

scp -O -r root@192.168.1.1:/var/lib/adguardhome/data .

Example output:

% python blocklist_analyzer.py
AdGuard Home Blocklist Usage Analyzer
============================================================
Data directory: ./data
Filters directory: ./data/filters
Query log: ./data/querylog.json
 
Loading 16 blocklists...
  1769441304.txt (ID: 1769441304)
  1769441877.txt (ID: 1769441877)
  1769458714.txt (ID: 1769458714)
  1769441872.txt (ID: 1769441872)
  1.txt (ID: 1)
  1769458716.txt (ID: 1769458716)
  1769441302.txt (ID: 1769441302)
  1769441876.txt (ID: 1769441876)
  1770030832.txt (ID: 1770030832)
  1769458712.txt (ID: 1769458712)
  1769441874.txt (ID: 1769441874)
  1769458713.txt (ID: 1769458713)
  1769441303.txt (ID: 1769441303)
  1769441875.txt (ID: 1769441875)
  1770030833.txt (ID: 1770030833)
  1769441301.txt (ID: 1769441301)
 
Analyzing query log: ./data/querylog.json
  Processed 100000 entries...
  Processed 200000 entries...
  Processed 300000 entries...
  Processed 400000 entries...
  Processed 500000 entries...
  Processed 600000 entries...
  Processed 700000 entries...
  Processed 800000 entries...
  Processed 900000 entries...
  Total entries processed: 923,715
  Total blocked queries: 16,637
 
============================================================
BLOCKLIST USAGE REPORT
============================================================
 
USED BLOCKLISTS (10):
------------------------------------------------------------
  1.txt: 11,156 blocks
  1770030832.txt: 1,936 blocks
  1769441872.txt: 1,209 blocks
  1769441301.txt: 1,166 blocks
  1769458712.txt: 1,092 blocks
  1769441875.txt: 294 blocks
  1769458716.txt: 55 blocks
  1769441303.txt: 49 blocks
  1769458714.txt: 21 blocks
  1769458717: 2 blocks
 
UNUSED BLOCKLISTS (7):
------------------------------------------------------------
  1769441304.txt
  1769441877.txt
  1769441302.txt
  1769441876.txt
  1769441874.txt
  1769458713.txt
  1770030833.txt
 
============================================================

Manually inspect blocklists called out as unused. All are listed in /etc/adguardhome/adguardhome.yaml As an example, 1769441874 from the output above:

...
  - enabled: true
    url: https://phishing.army/download/phishing_army_blocklist_extended.txt
    name: phishing army
    id: 1769441874
...
This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
  • Last modified: 2026/03/30 04:23
  • by owlsy