Tutorial AdGuard Home - adblocker - Clean install on Asus Merlin (No 3rd party scripts !!!)

gspannu

Regular Contributor
I have finally managed to install AdGuard Home on an Asus Router.... this is without using any special scripts.

There was a previous forum post (here) on the same, but that involved installing using a custom script (that asked for your ssh login credentials, installed its own version of Samba, etc... and a lot of people (here, here, here, here, here) including myself were very nervous to use it for the same reasons)

My tutorial below has none of the above.... you can install it yourself by following the instructions below. No 3rd party scripts, no login creds needed... it is almost like any other addon.

UPFRONT DECLARATION
- Asus Routers run great with Diversion AdBlocker, it is one of the best add-ons for Asus Routers
- This article is not to undermine Diversion or contest the pros/ cons of Diversion or AdGuard Home.
- This article is not promoting AdGuard as a replacement to Diversion. It is NOT and I WILL NEVER even remotely suggest this. The contribution by lonelycoder is beyond comparison.
- This post is in in academic interest for anyone who wants to install AdGuard Home (on the router itself) and play with it.

My setup:
Asus RT-AX88U running 386.3.2
Attached USB drive

Pre-requisites
Asus Merlin firmware
USB attached
Entware installed on Asus Router

Some basic knowledge about ssh, scripts, editing files on the router
Some working knowledge of AdGuard Home (as a product)


TUTORIAL

1. Download AdGuard Home on your USB drive

ssh to your router
navigate to the root of your attached USB drive (in my case, it is cd /tmp/mnt/USB-ASUS
download a version of AdGuard from Github
You can use either a stable release version or the beta version
wget https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz (for a stable release)
wget https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz (for a beta release)
Or get whatever you wish from the Github page

2. Extract AdGuard to your USB root folder
tar -xvzf AdGuardHome_linux_arm64.tar.gz

3. You should now have a folder called AdGuardHome in your attached USB root folder.

4. Create a AdGuard startup script

nano /opt/etc/init.d/S99adguardhome

Your script needs to look like below...
Change the PATH statement to reflect your USB drive path (where you installed AdGuard). This is important else your script won't work.
Code:
#!/bin/sh
ENABLED=yes
PROCS=AdGuardHome
ARGS="$OPTIONS"
PREARGS=""
DESC=$PROCS
PATH=$PATH:/tmp/mnt/USB-ASUS/AdGuardHome
. /opt/etc/init.d/rc.func
The above script will cause your AdGuard Home to auto startup on router reboot

5. Make sure your script is executable
chmod 755 /opt/etc/init.d/S99adguardhome

6. Now it is time to start AdGuard...
execute the following line
/opt/etc/init.d/S99adguardhome start

You can check if AdGuard Home is running or not..
/opt/etc/init.d/S99adguardhome check
[email protected]:/tmp/home/root# /opt/etc/init.d/S99adguardhome check
Checking AdGuardHome... alive.

or it may look like
Checking AdGuardHome... dead.

{And if you need to stop AdGuard Home, execute /opt/etc/init.d/S99adguardhome stop]

7. Now it is time to Configure AdGuard Home
In your internet browser, navigate to your router address:3000
e.g. something like 192.168.1.1:3000 or 192.168.50.1:3000

8. This should open up a familiar AdGuard Home Setup Wizard page...
Choose a Web Interface address and a port number.
I choose the router IP address (in my case it is 192.168.1.1) and port number as 30000
The default is port 80, make sure you change it to some thing else that is unused, I chose 30000

9. Choose the DNS Listener address and port
I choose the router IP address (in my case it is 192.168.1.1) and port number as 53535
The default is port 53, make sure you change it to some thing else that is unused, I chose 53535

AdGuard shows an error on both steps 8 and 9, if not configured properly.

10. Setup your username/ password as convenient.
Log into the AdGuard Home, navigate to the Query Log page
At this stage, you will notice that there are no queries in the Query Log.
This is because our DNS server is set for port 53535 and default port on the router is 53

11. Test that AdGuard is resolving queries...
ssh into your router and keep your AdGuard Home Webpage on the Query Log page
execute the below command
nslookup google.com 192.168.1.1 (or whatever your router IP address)
Refresh your AdGuard Home portal - AdGuard Query Log, but you should not see any query

now execute the below command
nslookup google.com 192.168.1.1:53535 (or whatever IP address/ port you specified above in Step 9)
Refresh your AdGuard Home portal - AdGuard Query Log, but you should now see the query

If all this works as above, then we do have AdGuard working properly...

12. Now it is time to redirect your default queries from Port 53 to Port 53553
(or whatever port you choose in Step 9)
Create a firewall-start script to set some IPTables
nano /jffs/scripts/firewall-start
Code:
iptables -t nat -I PREROUTING -i br0 -p udp -m udp --dport 53 -j REDIRECT --to-port 53535
iptables -t nat -I PREROUTING -i br0 -p tcp -m tcp --dport 53 -j REDIRECT --to-port 53535
Change the port number 53535 to whatever you choose in Step 9
Save the file..

13. Check that the firewall-start script is executable
ls -l ls -l /jffs/scripts
if not executable.... execute chmod 755 /jffs/scripts/firewall-start

[OPTIONAL]
14. AdGuard Home can identify the connected clients and resolve their DHCP names
Configure the AdGuard.yaml file to ensure that all our connected clients are identified by their names rather than IP addresses.
First, stop AdGuard Home
/opt/etc/init.d/S99adguardhome stop

Now edit the AdGuard Home config file.
nano /tmp/mnt/USB-ASUS/AdGuardHome/AdGuardHome.yaml (or wherever you installed AdGuard in Step 3.

Look for the line
local_domain_name: lan
Change it whatever you have defined your domain name in your Router Settings (on the LAN -> LAN IP page, domain name)
My domain name is home so the line should look like
local_domain_name: home

Save the yaml file.
Restart AdGuard
/opt/etc/init.d/S99adguardhome start

The above has to be done by editing the yaml file as there is no GUI option in AdGuard Home portal to do this..

15. Configure some other parameters in AdGuard Home web portal
Navigate to AdGuard Home portal
http://192.168.1.1:30000 (or whatever you chose in Step 8)
Login using your defined username/ password (as in Step 10)

Goto Settings -> DNS Settings
Upstream servers:
Add the below 2 lines to your upstream servers section..
[/in-addr.arpa/]127.0.0.1
[/ip6.arpa/]127.0.0.1

As an example... mine looks like this
1.1.1.1
8.8.8.8
[/in-addr.arpa/]127.0.0.1
[/ip6.arpa/]127.0.0.1

Private reverse DNS servers
Add the below line
127.0.0.1

Hit Test Upstreams and if all OK, hit Apply.

Enable both the checkboxes for
User Private Reverse DNS Servers
Enable Reverse Resolving of clients IP addresses
-------------------------------------------------------------------------------------------------------

15. Reboot Router

Navigate to AdGuard Home portal and check query page...
It should be showing your queries from the clients.
And if you followed step 14..
After a little while.... AdGuard should also be showing client names along with IP addresses.

Good luck... and thank you for reading.

And last but not the least, the above would not have been possible without the help of lbtboy ([email protected])
————————————————————————————————


2021-12-08 Update:
I highly recommend the slightly alternate method mentioned in Post 3 below by @SomeWhereOverTheRainBow
 
Last edited:

SomeWhereOverTheRainBow

Part of the Furniture
--Here is my method--

Prerequisites are:
Entware must be installed. ( Can be done using Amtm.)
A Usb drive or an external storage device must be used to store Adguardhome.( preferably on the same device that houses Entware which these instructions are based on. )
Disclaimer: Instructions are given as is. Any speculations on different methods or guidance for different methods will not be provided, but do feel free to share any new methods or findings you discover that work. No guidance will be given on installing Entware as that is outside the scope of this guide.

1. Download Instructions:

In my version, I use the edge version. You are welcome to change it to match your setup. I run this on an RT-AX88U, so I chose linux_arm64 branch.
Using ssh terminal
Code:
cd /opt/etc
wget -c https://static.adguard.com/adguardhome/edge/AdGuardHome_linux_arm64.tar.gz
tar -xvzf AdGuardHome_linux_arm64.tar.gz
rm -rf AdGuardHome_linux_arm64.tar.gz
cd AdGuardHome

2. First time run:
Here is where I run it for the first time to do the initial setup. This will allow us to generate our .yaml file. It will ask what listen addresses you want and what port. I chose 53 for DNS. I also set adguardhome gui port to 8081 -you can choose whatever port you want for the GUI, but DNS needs to run on 53 for this method to work.
Code:
killall -9 dnsmasq
nohup /opt/etc/AdGuardHome/AdGuardHome
The use of nohup allows it to run in the background.
minimize ssh terminal.
Initial setup is done from the browser at your routersaddress:3000

3.Place Adguard home in a path directory on entware installation:
Do this in the SSH terminal after initial setup.
Code:
killall -9 AdGuardHome
mv /opt/etc/AdGuardHome/AdGuardHome /opt/sbin/AdGuardHome

4. Make init.d file:
Code:
nano /opt/etc/init.d/S61AdGuardHome
Then paste this below script into the terminal.
Code:
#!/bin/sh
ENABLED=yes
WORK_DIR=/opt/etc/AdGuardHome
PROCS=AdGuardHome
ARGS="-c $WORK_DIR/AdGuardHome.yaml -w "$WORK_DIR" --no-check-update -l syslog"
PREARGS="nohup"
PRECMD="killall -9 dnsmasq"
POSTCMD="service restart_dnsmasq"
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export TZ=$(cat /etc/TZ)
. /opt/etc/init.d/rc.func
Save it and make it executable
Code:
chmod 755 /opt/etc/init.d/S61AdGuardHome

5. Make dnsmasq.postconf:
Code:
nano /jffs/scripts/dnsmasq.postconf
Then paste this below script into the terminal.
Code:
#!/bin/sh
CONFIG=$1
source /usr/sbin/helper.sh
[ "$(pidof AdGuardHome)" ] && pc_append "port=553" $CONFIG && pc_append "local=/1.168.192.in-addr.arpa/" $CONFIG
Save it and make it executable
Code:
chmod 755 /jffs/scripts/dnsmasq.postconf
The addresses in the above script need to match your router address and network.

6. Start AdGuardHome:
Code:
/opt/etc/init.d/S61AdGuardHome start

7. Setup Private reverse dns servers for private addresses:
The addresses need to match your router address. And the domain needs to match the Domain you have defined on the lan dhcp page of your router.
Code:
[/1.168.192.in-addr.arpa/]192.168.1.1:553
[/Some-Domain/]192.168.1.1:553

1637641961827.png


You will need to check box enable-
User Private Reverse DNS Servers
Enable Reverse Resolving of clients IP addresses

8. Set upstream DNS servers:
Code:
1.1.1.1
1.0.0.1
You can set these to whatever you like. Adguard home supports plain text, DoT, DoH, QUIC, and Dnscrypt.
1637642035696.png

Here is the wiki on configuration


Edits
  • Add support for dnsmasq at port 553 to run only when adguardhome is enabled, other wise use regular DNS.
  • Added pictures
  • Added Killall -9 dnsmasq to install instructions and to preargs of init.d script.
 
Last edited:

gspannu

Regular Contributor
--Here is my method--

First time run:


Here is where I run it for the first time to do the initial setup. This will allow us to generate our .yaml file. It will ask what listen addresses you want and what port. I chose 53 for DNS. I also set adguardhome gui port to 8081 -you can choose whatever port you want for the GUI, but DNS needs to run on 53 for this method to work.

Thanks for the detailed setup instructions...

- What address did you choose for the DNS listener? All Interfaces or 192.168.1.1 or 127.0.0.1?
- Also, wouldn't the initial setup throw an error because 53 is already in use?
(Bind: address already in use)
 

SomeWhereOverTheRainBow

Part of the Furniture
Thanks for the detailed setup instructions...

- What address did you choose for the DNS listener? All Interfaces or 192.168.1.1 or 127.0.0.1?
- Also, wouldn't the initial setup throw an error because 53 is already in use?
(Bind: address already in use)
You can use All interfaces or 192.168.1.1(your router's IP), and you can killall -9 dnsmasq which i forgot to mention in the guide
 

SomeWhereOverTheRainBow

Part of the Furniture
The one thing that I will mention, those who are using ipv6 (dual-stack), if you want true control over ipv6 clients, you have to either use stateful only ipv6 which android or smart devices does not support, or you need to use ipv4 only. Adguard home is not friendly with slaac ipv6 addressing.
 

SomeWhereOverTheRainBow

Part of the Furniture
How much RAM is used by AdGuard?
Well not a whole lot. If you use default settings and are not trying to use a giant block list, then the ram usage is not much more than using diversion. (not trying to compare the quality to diversion, just using it for memory reference). I am sure if one were to lower the cache size, and keep an average size block list, then the ram usage would stay pretty minimal. The main draw back to adguardhome can be seen with response times at loading web pages. (not really too noticeable for someone who hasn't been blessed by using Diversion or a Pihole.)
 

SomeWhereOverTheRainBow

Part of the Furniture
Also, it is important to make sure all parts of Adguardhome point back to the USB storage because the storage space it occupies can grow really quick making it less than ideal to have rooted in JFFS.
 

yababom

New Around Here
First, thanks to all for documenting your install processes!

For anyone using a AC68U or AC1750 B1 (functionally identical to an AC68U), I had to use the 'armv5' version of AdGuardHome
even though running "uname -m" returns "armv7l"... The 'ARM64' and 'armv7' versions would give mysterious errors when trying to run the binary file.

@gspannu Are there any advantages you see to your method of redirecting DNS queries to AdGuardHome via iptable entries (as your instructions do) VS moving dnsmasq to another port and running AdGuardHome on port 53 as @SomeWhereOverTheRainBow does.

@SomeWhereOverTheRainBow I experimented with your install process, but I ran into a snag when running "killall -9 dnsmasq" returned:
killall: can't kill pid 28987: No such process

Running "netstat -tunelp" after that shows port 53 is still in use by dnsmasq under a different PID, so it seems like it might be getting restarted instantly by another process?
 
Last edited:

SomeWhereOverTheRainBow

Part of the Furniture
First, thanks to all for documenting your install processes!

For anyone using a AC68U or AC1750 B1 (functionally identical to an AC68U), I had to use the 'armv5' version of AdGuardHome
even though running "uname -m" returns "armv7l"... The 'ARM64' and 'armv7' versions would give mysterious errors when trying to run the binary file.

@gspannu Are there any advantages you see to your method of redirecting DNS queries to AdGuardHome via iptable entries (as your instructions do) VS moving dnsmasq to another port and running AdGuardHome on port 53 as @SomeWhereOverTheRainBow does.

@SomeWhereOverTheRainBow I experimented with your install process, but I ran into a snag when running "killall -9 dnsmasq" returned:
killall: can't kill pid 28987: No such process

Running "netstat -tunelp" after that shows port 53 is still in use by dnsmasq under a different PID, so it seems like it might be getting restarted instantly by another process?
The main advantage of using adguardhome on port 53 versus dnsmasq, dnsmasq is not having to forward all dns traffic to adguardhome while acting as a middle man. Instead adguard home is acting as dns on port 53 where it responds to all request and only asking dnsmasq for local lookups, also the iptables redirect method is only supported by ipv4 because of lack of ip6table support for nat redirect (i.e. it is not enabled in the kernel build options for asuswrt or asuswrt merlin and the ip6table version doesn't support it.) So with the iptables method, you are only able to handle ipv4 dns and some clients that have hard-coded dns may still appear as the routers traffic. If you set adguard home to listen on port 53 directly all client traffic will be identifiable by the clients ip , then the host name is determined by a reverse lookup back to dnsmasq at port 553.
 
Last edited:

SomeWhereOverTheRainBow

Part of the Furniture
First, thanks to all for documenting your install processes!

For anyone using a AC68U or AC1750 B1 (functionally identical to an AC68U), I had to use the 'armv5' version of AdGuardHome
even though running "uname -m" returns "armv7l"... The 'ARM64' and 'armv7' versions would give mysterious errors when trying to run the binary file.

@gspannu Are there any advantages you see to your method of redirecting DNS queries to AdGuardHome via iptable entries (as your instructions do) VS moving dnsmasq to another port and running AdGuardHome on port 53 as @SomeWhereOverTheRainBow does.

@SomeWhereOverTheRainBow I experimented with your install process, but I ran into a snag when running "killall -9 dnsmasq" returned:
killall: can't kill pid 28987: No such process

Running "netstat -tunelp" after that shows port 53 is still in use by dnsmasq under a different PID, so it seems like it might be getting restarted instantly by another process?
Yea I am not having that issue on my router. Are you running some sort of script that checks for dnsmasq connectivity.
You could simply try just
killall dnsmasq
If you are running a script that depends on dnsmasq, that would explain why
killall -9 dnsmasq
Does not work for you. If that is the case, you will first have to modify dnsmasq.postconf using to change the port of 53 to 553, then proceed to installing/setting up adguard.

I use

netstat -nlp | grep 53

To see what processes occupy port 53
 
Last edited:

gspannu

Regular Contributor
First, thanks to all for documenting your install processes!

@gspannu Are there any advantages you see to your method of redirecting DNS queries to AdGuardHome via iptable entries (as your instructions do) VS moving dnsmasq to another port and running AdGuardHome on port 53 as @SomeWhereOverTheRainBow does.
The main advantage of using adguardhome on port 53 versus dnsmasq, dnsmasq is not having to forward all dns traffic to adguardhome while acting as a middle man. Instead adguard home is acting as dns on port 53 where it responds to all request and only asking dnsmasq for local lookups, also the iptables redirect method is only supported by ipv4 because of lack of ip6table support for nat redirect (i.e. it is not enabled in the kernel build options for asuswrt or asuswrt merlin and the ip6table version doesn't support it.) So with the iptables method, you are only able to handle ipv4 dns and some clients that have hard-coded dns may still appear as the routers traffic. If you set adguard home to listen on port 53 directly all client traffic will be identifiable by the clients ip , then the host name is determined by a reverse lookup back to dnsmasq at port 553.

@yababom As explained by @SomeWhereOverTheRainBow ….
No real benefits, and SomewhereOverTheRainbow solution is likely better.

The only possible advantage I can think of is that if you write the iptable routing in the AdGuard startup script, and delete the iptables routing when AdGuard Stops, then the solution could become become a simple enable/ disable AdGuard option. If AdGuard is running, it will automatically route the DNS queries and if not running will use the router’s default. I haven’t gotten around to doing that myself yet !
 

SomeWhereOverTheRainBow

Part of the Furniture
@yababom As explained by @SomeWhereOverTheRainBow ….
No real benefits, and SomewhereOverTheRainbow solution is likely better.

The only possible advantage I can think of is that if you write the iptable routing in the AdGuard startup script, and delete the iptables routing when AdGuard Stops, then the solution could become become a simple enable/ disable AdGuard option. If AdGuard is running, it will automatically route the DNS queries and if not running will use the router’s default. I haven’t gotten around to doing that myself yet !
If that is the case you would want to answer the iptable rules as start/stop within the init.d script or as a pre or postcmd script. The first option being the better since it will delete the rules on stop and add them back on start. You would want to inform users to completely disable ipv6 on their router as these request would bypass adguardhome, unless you add ip6table drop rules for output and forward traffic from br0 on port 53

**edit** after thinking about it, you would always want the iptable rules in firewall-start just incase the firewall gets restarted. In that case it may be troublesome to do this with the iptable rules in start / stop configuration because all it would take is the firewall to get restarted and then poof the rules are gone. Instead you could setup a conditional statement inside firewall-start that checks if adguardhome is running (pidof Adguardhome). If it is then apply the firewall rules for Adguardhome. You would add
service restart_firewall
As a postcmd in the init.d script.
 
Last edited:

fsb

Occasional Visitor
I have finally managed to install AdGuard Home on an Asus Router.... this is without using any special scripts.

There was a previous forum post (here) on the same, but that involved installing using a custom script (that asked for your ssh login credentials, installed its own version of Samba, etc... and a lot of people (here, here, here, here, here) including myself were very nervous to use it for the same reasons)

My tutorial below has none of the above.... you can install it yourself by following the instructions below. No 3rd party scripts, no login creds needed... it is almost like any other addon.

UPFRONT DECLARATION


My setup:
Asus RT-AX88U running 386.3.2
Attached USB drive

Pre-requisites
Entware should be installed on Asus Router
Some previous working knowledge of AdGuard Home

TUTORIAL

1. Download AdGuard Home on your USB drive

ssh to your router
navigate to the root of your attached USB drive (in my case, it is cd /tmp/mnt/USB-ASUS
download a version of AdGuard from Github
You can use either a stable release version or the beta version
wget https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz (for a stable release)
wget https://static.adguard.com/adguardhome/beta/AdGuardHome_linux_arm64.tar.gz (for a beta release)
Or get whatever you wish from the Github page

2. Extract AdGuard to your USB root folder
tar -xvzf AdGuardHome_linux_arm64.tar.gz

3. You should now have a folder called AdGuardHome in your attached USB root folder.

4. Create a AdGuard startup script

nano /opt/etc/init.d/S99adguardhome

Your script needs to look like below...
Change the PATH statement to reflect your USB drive path (where you installed AdGuard). This is important else your script won't work.
Code:
#!/bin/sh
ENABLED=yes
PROCS=AdGuardHome
ARGS="$OPTIONS"
PREARGS=""
DESC=$PROCS
PATH=$PATH:/tmp/mnt/USB-ASUS/AdGuardHome
. /opt/etc/init.d/rc.func
The above script will cause your AdGuard Home to auto startup on router reboot

5. Make sure your script is executable
chmod 755 /opt/etc/init.d/S99adguardhome

6. Now it is time to start AdGuard...
execute the following line
/opt/etc/init.d/S99adguardhome start

You can check if AdGuard Home is running or not..
/opt/etc/init.d/S99adguardhome check
[email protected]:/tmp/home/root# /opt/etc/init.d/S99adguardhome check
Checking AdGuardHome... alive.

or it may look like
Checking AdGuardHome... dead.
Hi @gspannu, thanks for doing this! Everything works fine for up until I check if AdGuardHome is running or not.

I start AdGuardHome and get 'done'. However, I always get 'dead' as the status. I double-checked the installation steps and even rebooted the router but I get the same result. I made sure to put my correct path in step #4.

I have an RT-AC86U running Merlin 386.3_2. Any idea how to troubleshoot this or get it running?
 

SomeWhereOverTheRainBow

Part of the Furniture
Hi @gspannu, thanks for doing this! Everything works fine for up until I check if AdGuardHome is running or not.

I start AdGuardHome and get 'done'. However, I always get 'dead' as the status. I double-checked the installation steps and even rebooted the router but I get the same result. I made sure to put my correct path in step #4.

I have an RT-AC86U running Merlin 386.3_2. Any idea how to troubleshoot this or get it running?
I am not sure what uname -m is on the RT-AC86U. If it is armv7 , it is recommended to use Linux-arm armv7 or armv6 32bit. If it is arch64 it is recommended to use 64bit.Which one did you use in your download process? See if adjusting this fixes your issue.
 

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top