[TUTORIAL] - How to modify Adguard Home on GL.iNet devices to enable webui without logging in to the admin interface

I had a poke around in the GL.iNet software to try and work out where the current behaviour of Adguard was implemented, which is that you must login to the router webui to access the Adguard interface.

This is problematic for a number of reasons, and a behaviour that many people have asked be changed.

As a new GL.iNet Marble owner I needed an easy way for others in the household to be able to toggle Adguard blocking on and off without requiring them to login to the router, especially as they all had an established "workflow" of clicking a browser bookmark and toggling it from my previous implementation of Adguard on a raspberry pi.

Examining the init routine so we understand how the current behaviour is implemented.

Examining the init routine, specifically the one relevant line, which can be output to the terminal with the following command.

cat /etc/init.d/adguardhome | grep command

Which outputs:

procd_set_param command /usr/bin/AdGuardHome --glinet --no-check-update -c /etc/AdGuardHome/config.yaml -w /etc/AdGuardHome -l syslog

I noticed a specific runtime flag --glinet so I wondered what would happen if I removed it and found removing this does two things:

  • It allows you to access the Adguard Home webui without logging into the GL.iNet device (and add optional username/password authentication - see further down)
  • It breaks the router webui integration for Adguard home, so it's no longer possible to view the stats in the router webui.

Now that we understand how the current authorisation is implemented, we can now go about modifying the behaviour.

This can be done in the webui without resorting to ssh but has a few downsides.

  • No backups are created of the modified file.
  • So if you wish to revert the behaviour you will need to either restore firmware or resort to using ssh
  • It's not possible to implement username/password protection of the Adguard webui as editing the relevant file is only possible via ssh
  • A reboot is required to implement the change.

If you still wish to use this method then skip to the section titled Modifying the init routine via webui

Modifying the init routine via ssh and implementing username/password in Adguard Home

Connect via SSH

On a Linux machine this is possible with

ssh -o HostkeyAlgorithms=ssh-rsa root@router-ip

use your webui admin password to obtain access.

Of note, the model I have (Marble) only accepts the ssh-rsa cipher so needs the -o HostkeyAlgorithms=ssh-rsa, I don't know if this is true for other models.

I'm afraid I'm not a Windows or Mac user and don't own any Windows or Mac machines to test so you'll have to work out how to obtain a ssh connection from either of those before proceeding.

Create a backup of the files before modifying

cp /etc/AdGuardHome/config.yaml /etc/AdGuardHome/config.yaml.backup
cp /etc/init.d/adguardhome /etc/init.d/adguardhome.backup

Install necessary packages

We're going to install two packages

  • Apache
  • Nano

Apache is a webserver but it contains the binary htpasswd which we need to create a hash of our password later to use in the Adguard config.

Nano is a text editor which is easier to use than the already installed vi, which is tricky to use if you're unfamiliar with it.

We're going to install these with

opkg update
opkg install apache nano

Implementing the changes without a reboot

Run the following commands to remove the --glinet parameter from the init routine of Adguard and then restart the service.

sed -e "s/--glinet //g" /etc/init.d/adguardhome
service adguardhome restart

You should now be able to go directly to the Adguard webui by going to

http://router-ip:3000

Modifying the init routine so it's persistent across reboots

There's a file that's run at the end of the router boot process which can be used to customise things. We're going to edit that to remove --glinet from /etc/init.d/adguardhome on each reboot or firmware upgrade.

Edit the file with:

nano /etc/rc.local

& add the follow two lines

ABOVE exit 0

sed -e "s/--glinet //g" /etc/init.d/adguardhome
service adguardhome restart

Save this in nano by pressing ctrl+x then pressing y

Now at each boot the init file will be searched for the --glinet parameter and removed if present, then the adguard service is restarted to ensure that the change is implemented.

Add username & password

First of all you need to generate a bcrypted hash of your desired password. The tool to do so is the Apache package which we installed earlier and this can be created with the following command, replacing USERNAME and PASSWORD with your desired values.

htpasswd -B -C 10 -n -b USERNAME PASSWORD

generates:

root@GL-B3000:~# htpasswd -B -C 10 -n -b USERNAME PASSWORD
USERNAME:$2y$10$hEhnJx8RtjmZXedwUCsxNek8cyjENlZZJA4IZPPYr3Ostnz4zBukS

Now we need to use this info in our AdguardHome config.yaml file.

nano /etc/AdGuardHome/config.yaml

Replace this section

users: []

with

users:
  - name: USERNAME
    password: $2y$10$hEhnJx8RtjmZXedwUCsxNek8cyjENlZZJA4IZPPYr3Ostnz4zBukS

Remember yaml is indent sensitive so the spaces are VERY important.

Save the file by pressing ctrl+x and then pressing y

Now restart the service once again with

service adguardhome restart

Go to http://router-ip:3000 and you should be prompted to login

Remove Apache and it's dependencies

We no longer need Apache installed, so remove it and it's two dependencies.

opkg remove apache libaprutil libexpat

Modifying the init routine via webui

Warning

If using this method instead of ssh there are a number of downsides.

  • No backups are created of the modified file.
  • So if you wish to revert the behaviour you will need to either restore firmware or resort to using ssh
  • It's not possible to implement username/password protection of the Adguard webui as editing the relevant file is only possible via ssh
  • A reboot is required to implement the change.

Edit the /etc/rc.local file in the luci webui by going to

  • http://router-ip/cgi-bin/luci/admin/system/startup then
  • Clicking the tab marked "Local Startup"

Adding the following lines ABOVE exit 0

sed -e "s/--glinet //g" /etc/init.d/adguardhome
service adguardhome restart

Save this and then at each boot the init file will be searched for the --glinet parameter and removed if present, then the adguard service is restarted to ensure that the change is implemented.

After a reboot you should now be able to go to http://ip-address:3000 and access the Adguardhome Webui.

2 Likes

Thanks!!! I will try It on my Marble too.

I'm getting this on the first command of your tutorial:

Terminal
BusyBox v1.36.1 (2024-10-14 07:25:47 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 24.0, r27229+44-ebe7c5f1a3
 -----------------------------------------------------
root@Flint2:~# sed -e "s/--glinet //g" /etc/init.d/adguardhome
#!/bin/sh /etc/rc.common
# shellcheck disable=SC2034
USE_PROCD=1

START=99

. /lib/functions/gl_util.sh
model=$(get_model)

start_service() {
    [ "$(uci -q get adguardhome.config.enabled)" = "1" ] || exit 0

    mkdir -p /etc/AdGuardHome

    #b1300 dose not support mmap,need link the data to tmp fs
    [ "$model" = "b1300" ] && {
        rm -rf /etc/AdGuardHome/data 2>/dev/null
        mkdir -p /tmp/AGH_data
        ln -s /tmp/AGH_data /etc/AdGuardHome/data
    }

    [ "$(uci -q get adguardhome.config.dns_enabled)" = "1" ] && {
        uci set firewall.adguard_home='redirect'
        uci set firewall.adguard_home.name="Adguard Home"
        uci set firewall.adguard_home.src='lan'
        uci set firewall.adguard_home.src_dport='53'
        uci set firewall.adguard_home.dest='lan'
        uci set firewall.adguard_home.dest_port='3053'
        uci set firewall.adguard_home.proto='tcp udp'

        has_radio="$(get_radio)"
        [ -n "$has_radio" ] && {
            uci set firewall.adguard_home_guest='redirect'
            uci set firewall.adguard_home_guest.name="Adguard Home guest"
            uci set firewall.adguard_home_guest.src='guest'
            uci set firewall.adguard_home_guest.src_dport='53'
            uci set firewall.adguard_home_guest.dest='guest'
            uci set firewall.adguard_home_guest.dest_port='3053'
            uci set firewall.adguard_home_guest.proto='tcp udp'
        }
    }

    uci commit 'firewall'
    /etc/init.d/firewall reload

    procd_open_instance
    procd_set_param respawn
    procd_set_param group explict_vpn
    procd_set_param stderr 1
    procd_set_param command /usr/bin/AdGuardHome -c /etc/AdGuardHome/config.yaml                                                                                         -w /etc/AdGuardHome -l syslog
    procd_close_instance
    [ -e /etc/edgerouter.fw ] && /etc/edgerouter.fw loaddns
}

stop_service(){
    uci delete firewall.adguard_home

    has_radio="$(get_radio)"
    [ -n "$has_radio" ] && {
        uci delete firewall.adguard_home_guest
    }

    uci commit 'firewall'
    /etc/init.d/firewall reload
    [ -e /etc/edgerouter.fw ] && /etc/edgerouter.fw loaddns
}

Any idea?
maybe because I'm using OpenWrt 24 on a Flint2?

What's the output of

cat /etc/init.d/adguardhome.backup

It might be that the init is different on your device. Also, can I just check, are you still running GL.iNet firmware or you running stock OpenWRT on your GL.iNet device?

If it's the latter then this process shouldn't be required.

No, I'm running GL.iNet op24 firmware for the Flint2,

any idea?
BusyBox v1.36.1 (2024-10-14 07:25:47 UTC) built-in shell
 (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 24.0, r27229+44-ebe7c5f1a3
 -----------------------------------------------------
root@Flint2:~# cat /etc/init.d/adguardhome.backup
#!/bin/sh /etc/rc.common
# shellcheck disable=SC2034
USE_PROCD=1

START=99

. /lib/functions/gl_util.sh
model=$(get_model)

start_service() {
    [ "$(uci -q get adguardhome.config.enabled)" = "1" ]
 || exit 0

    mkdir -p /etc/AdGuardHome

    #b1300 dose not support mmap,need link the data to t
mp fs
    [ "$model" = "b1300" ] && {
        rm -rf /etc/AdGuardHome/data 2>/dev/null
        mkdir -p /tmp/AGH_data
        ln -s /tmp/AGH_data /etc/AdGuardHome/data
    }

    [ "$(uci -q get adguardhome.config.dns_enabled)" = "
1" ] && {
        uci set firewall.adguard_home='redirect'
        uci set firewall.adguard_home.name="Adguard Home
"
        uci set firewall.adguard_home.src='lan'
        uci set firewall.adguard_home.src_dport='53'
        uci set firewall.adguard_home.dest='lan'
        uci set firewall.adguard_home.dest_port='3053'
        uci set firewall.adguard_home.proto='tcp udp'

        has_radio="$(get_radio)"
        [ -n "$has_radio" ] && {
            uci set firewall.adguard_home_guest='redirec
t'
            uci set firewall.adguard_home_guest.name="Ad
guard Home guest"
            uci set firewall.adguard_home_guest.src='gue
st'
            uci set firewall.adguard_home_guest.src_dpor
t='53'
            uci set firewall.adguard_home_guest.dest='gu
est'
            uci set firewall.adguard_home_guest.dest_por
t='3053'
            uci set firewall.adguard_home_guest.proto='t
cp udp'
        }
    }

    uci commit 'firewall'
    /etc/init.d/firewall reload

    procd_open_instance
    procd_set_param respawn
    procd_set_param group explict_vpn
    procd_set_param stderr 1
    procd_set_param command /usr/bin/AdGuardHome --gline
t -c /etc/AdGuardHome/config.yaml -w /etc/AdGuardHome -l
 syslog
    procd_close_instance
    [ -e /etc/edgerouter.fw ] && /etc/edgerouter.fw load
dns
}

stop_service(){
    uci delete firewall.adguard_home

    has_radio="$(get_radio)"
    [ -n "$has_radio" ] && {
        uci delete firewall.adguard_home_guest
    }

    uci commit 'firewall'
    /etc/init.d/firewall reload
    [ -e /etc/edgerouter.fw ] && /etc/edgerouter.fw load
dns
}
root@Flint2:~#

If you look at this line in your .backup file you can see --glinet

The original post you made was after you had run the "first" command, which I assume by that you meant:

sed -e "s/--glinet //g" /etc/init.d/adguardhome

This command parses the init file and removes --glinet from it.

The output of your original post, specifically this line:

procd_set_param command /usr/bin/AdGuardHome -c /etc/AdGuardHome/config.yaml -w etc/AdGuardHome -l syslog

shows that --glinet has been removed, which is to be expected.

I can't see there's anything untoward with things at this stage.

Thanks for the response, I'm going to looking around later :call_me_hand: