[How-To-Updated 2021] Installing AdGuardHome on OpenWrt [Manual and opkg method]

Introduction:

This thread mostly covers the manual installation of AdGuard Home's edge/beta version. OpenWrt's opkg version is the stable release. The edge version installs to /opt/AdGuardHome , the opkg version to /etc/adguardhome for the config files and /tmp for filters, logs etc thus you WILL loose them when your router reboots.

AGH - https://github.com/AdguardTeam/AdGuardHome

A few points first of all.

I do NOT use SSL for AGH's web frontend. Luci (OpenWrt's web interface) runs on port 80 and port 443 for SSL. I run AGH on port 8080. If you wish to use SSL for AGH you will need to move Luci or run AGH on non standard ports. AGH does use SSL for encrypted DNS but that is separate to the web interface. You can also use nginx to proxy AGH. See https://openwrt.org/docs/guide-user/services/dns/adguard-home#nginx_reverse_proxy_through_luci for more details.

Installation:

I use Putty for SSH shell access and WinSCP for remote file access to my router. This means I can edit files directly and also create the scripts required for install. It also avoids windows to unix file issues that can occur with editing of files. (unix uses Line Feed for new line, windows uses Carriage Return / Line Feed. This will cause unexpected errors in unix.)

Ok. Having had some free time today I have updated my backup router to OpenWrt 21.02.1.

Completely clean install and reset to defaults. OpenWrt uses 192.168.1.1 thus all my scripts assume and follow that convention.

I updated opkg and pulled new updates. (listed below if you are curious.)

opkg results
root@OpenWrt:~# opkg list-upgradable
luci-app-opkg - git-21.079.58598-6639e31 - git-21.312.69848-4745991
iw - 5.9-8fab0c9e-1 - 5.9-8fab0c9e-3
busybox - 1.33.1-6 - 1.33.2-1
luci-mod-system - git-21.295.66903-8acd0d7 - git-21.305.74567-388dae9
luci-theme-bootstrap - git-21.298.68362-d24760e - git-21.320.44446-0cee46b
wpad-basic-wolfssl - 2020-06-08-5a8b3662-35 - 2020-06-08-5a8b3662-37
netifd - 2021-07-26-440eb064-1 - 2021-10-30-8f82742c-1
luci-app-firewall - git-21.295.66767-8eceb63 - git-21.312.70727-3eac573
luci-base - git-21.295.67054-13df80d - git-21.327.65561-7f37a58
luci-mod-network - git-21.295.67048-4d3de0e - git-21.335.80427-5091496
hostapd-common - 2020-06-08-5a8b3662-35 - 2020-06-08-5a8b3662-37
wireless-regdb - 2021.04.21-1 - 2021.08.28-1

With that done I now use the following script to install packages required for AGH install and a few test tools.

  • The most important is sudo. This is required for setting up AGH service.

  • ca-certificates ca-bundle - These are the certificates required for SSL.

  • curl wget tar unzip - System tools for downloading AGH and unzipping updates etc.

  • Bind-tools is all the DNS tools. This package is for testing DNS queries and ensuring DNSSec is on and proper resolution of DNS queries.

The script then pulls the AGH installer script and installs the Edge version. This is the most up to date and is generally best version to use.

Now the fun bit. With AGH installed, we now switch OpenWrts DNSMasq to the background so we can pull client info from it and resolve the OpenWrt clients. Rebind protection is removed. DHCP options are added so AGH will take over from DNSMasq. Unless DNSMasq is moved from port 53 to port 54 then AGH cannot take over and be primary DNS. Luci's web interface lives on port 80 so we just tell AGH when we set it up to use port 8080 for its web interface instead.

:warning:
(The reason you setup OpenWrt to use a different unencrypted upstream is so when it brings up your connection it can do NTP and updates as AGH will still be loading. Without NTP setting your router time / date correctly, SSL will fail and thus no encrypted DNS.)
:warning:
See https://openwrt.org/docs/guide-user/services/dns/adguard-home#bypassing_encrypted_dns_for_ntp for more details.

I have split my install script into two. The first swaps the routers upstream DNS for Cloudflare DNS. As some may want to keep their existing DNS settings I've moved this to a separate script that you can run or ignore and continue to the installation script instead.

routerDNS.sh

#!/bin/sh
# Reconfigure router DNS provider to cloudflare upstream

# Disable peer ISP DNS
uci set network.wan.peerdns="0"
uci set network.wan6.peerdns="0"

# Reconfigure router IPv4 DNS provider to cloudflare upstream
uci -q delete network.wan.dns
uci add_list network.wan.dns="1.1.1.1"
uci add_list network.wan.dns="1.0.0.1"
 
# Reconfigure router IPv6 DNS provider to cloudflare upstream
uci -q delete network.wan6.dns
uci add_list network.wan6.dns="2606:4700:4700::1111"
uci add_list network.wan6.dns="2606:4700:4700::1001"
 
# Save changes
uci commit network

# Restart network service to reflect changes
/etc/init.d/network restart

installAGH.sh The install script looks up the first ipv4 and v6 addresses to use for installing. It uses the br-lan interface for this. If you have a different interface you will need to change the script.

#!/bin/sh
# Switch to Adguard setup
# Grab packages for AGH and updates.
opkg update
opkg install sudo ca-certificates ca-bundle curl wget wget-ssl tar unzip bind-tools

#grab and install AGH
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -c edge

# 1. Enable dnsmasq to do PTR requests.
# 2. Reduce dnsmasq cache size as it will only provide PTR/rDNS info.
# 3. Disable rebind protection. Filtered DNS service responses from blocked domains are 0.0.0.0 which causes dnsmasq to fill the system log with possible DNS-rebind attack detected messages.
# 4. Move dnsmasq to port 54.
# 5. Set Ipv4 DNS advertised by option 6 DHCP 
# 6. Set Ipv6 DNS advertised by DHCP
# 7. Set 24hr DHCP Leases
# Get the first IPv4 and IPv6 Address of router and store them in following variables for use during the script.
NET_ADDR=$(/sbin/ip -o -4 addr list br-lan | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')
NET_ADDR6=$(/sbin/ip -o -6 addr list br-lan scope global | awk 'NR==1{ split($4, ip_addr, "/"); print ip_addr[1] }')
 
echo "Router IPv4 : ""${NET_ADDR}"
echo "Router IPv6 : ""${NET_ADDR6}"

uci set dhcp.@dnsmasq[0].noresolv='0'
uci set dhcp.@dnsmasq[0].cachesize='1000'
uci set dhcp.@dnsmasq[0].rebind_protection='0'
uci set dhcp.@dnsmasq[0].port='54'
uci -q delete dhcp.@dnsmasq[0].server
uci add_list dhcp.@dnsmasq[0].server="${NET_ADDR}"
uci set dhcp.lan.leasetime='24h' 

#Delete existing config ready to install new options.
uci -q delete dhcp.lan.dhcp_option
uci -q delete dhcp.lan.dns

# DHCP option 6: which DNS (Domain Name Server) to include in the IP configuration for name resolution
uci add_list dhcp.lan.dhcp_option='6,'"${NET_ADDR}" 

#DHCP option 3: default router or last resort gateway for this interface
uci add_list dhcp.lan.dhcp_option='3,'"${NET_ADDR}"

#Set IPv6 Announced DNS
for OUTPUT in $(ip -o -6 addr list br-lan scope global | awk '{ split($4, ip_addr, "/"); print ip_addr[1] }')
do
	echo "Adding $OUTPUT to IPV6 DNS"
	uci add_list dhcp.lan.dns=$OUTPUT
done

# Save changes
uci commit dhcp

# Restart dnsmasq service to reflect changes
/etc/init.d/dnsmasq restart

echo 'Goto http://'"${NET_ADDR}"':3000 and configure AdGuardHome.'
Output from the install.
Router IPv4 : 192.168.1.1
Router IPv6 : fd1a:c860:7174::1
Adding fd1a:c860:7174::1 to IPV6 DNS
starting AdGuard Home installation script
2021/12/06 11:29:10 [info] service: control action: install
2021/12/06 11:29:11 [info] service: started
2021/12/06 11:29:11 [info] Almost ready!
AdGuard Home is successfully installed and will automatically start on boot.
There are a few more things that must be configured before you can use it.
Click on the link below and follow the Installation Wizard steps to finish setup.
AdGuard Home is now available at the following addresses:
2021/12/06 11:29:11 [info] Go to http://127.0.0.1:3000
2021/12/06 11:29:11 [info] Go to http://[::1]:3000
2021/12/06 11:29:11 [info] Go to http://192.168.1.1:3000
2021/12/06 11:29:11 [info] Go to http://[fd1a:c860:7174::1]:3000
2021/12/06 11:29:11 [info] Go to http://192.168.1.1:3000
2021/12/06 11:29:11 [info] service: action install has been done successfully on unix-systemv
AdGuard Home is now installed and running
you can control the service status with the following commands:
sudo /opt/AdGuardHome/AdGuardHome -s start|stop|restart|status|install|uninstall

udhcpc: started, v1.33.2
udhcpc: sending discover
udhcpc: no lease, failing
Goto http://192.168.1.1:3000 and configure AdGuardHome.

With that complete now we login http://192.168.1.1:3000 and configure AGH.
AGH should see port 53 for DNS is clear so that option is fine.
However Luci runs on port 80 so AGH detects this and will not let you proceed.
Change the web interface port to 8080 and continue the install.

Setup your user and password and then you should be at the main web interface.

At this point you can just follow AGH's wiki to guide you into setting up AGH. But for completeness I have documented the process below.

There are a few needed tweaks depending on if you selected listen on all interfaces during setup. To fix this some manual editing is required of the yaml file. By default AGH in its setup asks you what interfaces to bind to. It either lets you select a single interface or ALL interfaces. (That means if your WAN interface is up you will have DNS listening there. There is an issue in for that to be selectable so you can deselect WAN interfaces. Its currently filed as an improvement for the 108 version I believe)

Open the /opt/AdGuardhome.yaml file and find the following:

dns:
  bind_hosts:
  - 127.0.0.1
  - ::1
  - 192.168.1.1
  - fd1a:c860:7174::1
  port: 53

That config serves DNS on localhost ipv4, ::1 localhost ipv6, 192.168.1.1 and ipv6 fd1a:c860:7174

DNS Settings:

On your AGH web interface open the DNS settings page http://192.168.1.1:8080/#dns and then configure your provider as you want.

I use Cloudflare but other providers are listed here.

https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration#upstreams - Configure upstreams

(edit - Added example DNS picture as guide. You do not need to use any other programs like Unbound or DNS-Over-Https. AGH does it internally. All you have to do is pick your provider and method of encrypted DNS.)

Domain interception :

If you have the default OpenWrt DHCP then adding :

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

to the upstream list that will intercept lan and domainless requests and pass those requests back to openwrt. "lan" is OpenWrt's default domain. (127.0.0.1) local loopback is used here to enable statistics tracking but you may also use your router ip (192.168.1.1) here too. Domain Interception is necessary for multi ip networks. For simple IP networks rDNS should cover this.

Bootstrap Servers

Then I setup the bootstrap servers. These are known ip addresses to allow AGH to find DNS resolvers.

https://kb.adguard.com/en/general/dns-providers#cloudflare-dns - Cloudflare DNS info.

(edit - List of providers here - https://kb.adguard.com/en/general/dns-providers)

Reverse DNS (rDNS)

To enable rDNS so AGH 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 192.168.1.1:54

  4. Tick both “Use private reverse DNS resolvers” and “Enable reverse resolving of clients' IP addresses” boxes and click apply.

https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration#rdns-clients - Configuring rdns.

yaml settings for this:

  resolve_clients: true
  use_private_ptr_resolvers: true
  local_ptr_upstreams:
  - 192.168.1.1:54

Filters:

AGH comes with built in filters. Add as you see fit. There are more filter lists available on the internet but be aware as you add more filters, you use more memory and space. Limited space/mem routers will need to be monitored to ensure you do not run out of memory with huge lists.

image

Filter Sites:

https://firebog.net/
https://oisd.nl/ For AdGuardHome you must use abp.oisd.nl

I have updated info about filter lists here : [How-To-Updated 2021] Installing AdGuardHome on OpenWrt [Manual and opkg method] - #401 by mercygroundabyss

Interface:

You will notice that the interface shows "0 malware/phishing sites blocked".
You will only see Blocked lists showing for your results from your filter lists.
It is their DNS which gives those definitions so you will have to use AGH DNS as upstream if you wish to use those counters.


It is explained in their blog here :

Limited space routers:

Due to space limitations and AGH silently failing to update from the web interface I created a manual script to update AGH from SSH. It will not backup AGH like the web interface does. It just downloads and then overwrites the binary.
(Issue filed - https://github.com/AdguardTeam/AdGuardHome/issues/3801)
(more explanation here - [HowTo] Running Adguard Home on OpenWrt - #442 by mercygroundabyss) Please refer to the AGH wiki for manual updating.

https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#manual-update - Manual Update documented here.

Data Files:

The /opt/AdGuardHome/data folder contains the following.

root@OpenWrt:/opt/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        8.9M Oct 29 09:00 querylog.json.1
-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 files : These are your DNS queries. Can be removed.
sessions.db : active logins to AGH currently. This can be deleted but you will need to relog back in.
stats.db : Your statistics database. can purge but you will lose your statistics data.

filters folder contains all your filter downloads. Purge if it is full but it will re-download your filters. If your filters are too large for your diskspace you will have to disable large filters and restrict their usage.

Future Updates:

For those wondering what's coming next in AGH - https://github.com/AdguardTeam/AdGuardHome/milestone/37 )

https://github.com/AdguardTeam/AdGuardHome/issues/2830 is potentially the bit we have been waiting for to have AGH take over DHCP from OpenWrt.

Space:

One of the reasons I use the lists I do is down to memory. While big lists have their place, we have to bear in mind that what we are doing here is adding AGH to OpenWrt routers. This usually means limitations on disk space and memory, especially for older routers. OpenWrt already has depreciated 4 and 8mb routers. I tested with a 128mb BT Hub 5. I can get about 140k of filter rules before I run into memory issues. The bigger problem is the disk space and AGH binary being 35mb alone. Its why I created my script to do updates and filed an issue on AGH's hub. https://github.com/AdguardTeam/AdGuardHome/issues/3801

DNS Lockdown:

If you want to lock things down? https://openwrt.org/docs/guide-user/services/dns/adguard-home#dns_interception

Firewall rules to enforce your Adguard DNS to be the only DNS and to block other outgoing attempts.

Just make sure you have an exclusion for your router and Adguard or you will find yourself DNSless.

Uninstalling:

This script uninstalls AGH and resets your router to Google DNS as your upstream. This is a known good default and should always work.

uninstallAGH.sh

#!/bin/sh
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v -u
 
# 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

Changelog:

  • Tidied up a few sentances and improved layout.
  • Added more info about encrypted DNS and no need for external modules/programs.
  • Added screen shots for configuring upstreams.
  • Added post about using NextDNS. (see here) December 7, 2021
  • Tweaked script to do IPv6 DNS December 9, 2021
  • Removed my filter list. AGH has updated theirs. December 15, 2021
  • Added local domain interception. Thanks to @Cheddoleum - December 16, 2021
  • opkg version update. December 25, 2021
  • Uninstall instructions. January 14, 2022
  • Minor editing and readability tweaks. January 19, 2022
  • IPV6 DNS Fix and Script updates January 29, 2022
  • apparently jq for json parsing isnt default installed. January 31, 2022
  • Added AGH Manual Update FAQ February 1, 2022
  • IPV6 - removed json/jq replaced with awk February 4, 2022
  • Added introduction, changed title, linked to opkg version, warning on unix/windows file issues, nginx proxy info added. April 3, 2022
  • NTP Warning enhanced. Replaced PTR picture. NFT tables added/DNS Interception. June 24, 2022
  • dnsmasq port replaced from 5353 to 54 due to clash with mDNS service. June 25, 2022
  • Fixed router PTR lookups to dnsmasq. June 28, 2022
  • Removed manual update and left link to AGH wiki. October 6, 2022
  • Revisiting filter lists. November 19, 2022
21 Likes

Thank you for the beautiful write up. I will give a try this on my APU2 (probably this weekend).

Custom firewall rules to prevent any DNS leaks

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

I'm not sure if this is really necessary. But I would like to leave it here as an addendum. Hope you don't mind!

ulpian

2 Likes

Thank you for this write up. I have reinstalled AGH on my router three (3) times and have yet to see the update button despite having 15GB free on my OpenWRT using extroot from OpenWRT wiki.

image

1 Like

This will forward requests to dnsmasq and not AdGuard. In the OP's writeup, he's trying to eliminate dnsmasq and only use it for local lookups (hostname of clients)

2 Likes

Sorry my bad. Thank you for the tip!

ulpian

1 Like

AGH and NextDNS

@nikojaro found that current recommendations are to use AGH with filtering disabled and NextDNS as an upstream provider instead of using the NextDNS client.

Use the guide above to install AGH. Disable all filtering and set NextDNS up as upstream provider, then you can use your NextDNS dashboard to control your home filtering and while out on mobile too. (as long as you have setup your mobiles with NextDNS)

2 Likes

They are updating how the updates work and do have an issue filed for the space / update issue.

1 Like

Thank you! Appreciate it.

1 Like

I've tidied my install script up a bit more. I hadn't redirected the router dnsmasq IPv6 (mostly because my ISP is in the dark ages and doesn't supply IPv6.)

Now the script will set OpenWrt router dnsmasq to use cloudflare IPv4 and IPv6 for upstream dns and it will set Lan DHCP options to point to AGH for both IPv4 and IPv6.

I am relatively sure this shouldn't break existing IPv6 assignments as I just announce ::1 as local IPv6 dns. However I am unable to test this with an upstream provider to be sure. Without this however, your IPv6 clients will take the upstream DNS (and if you used my script then it will use Cloudflare DNS and bypass AGH)

My setup of AGH [hopefully] follows the one so nicely explained by @mercygroundabyss.

All is working good, but I would still like to clarify a couple of questions, please:

  1. When stopping AGH (through LuCI), DNS is no longer supplied. Reasonable, but I also have the custom backup DNS servers set for WAN, I expected that there will be fallback to these servers...

  2. In AGH query log I see quite a number of *.lan and arpa requests, some of them sent back to local host, some upstream. Not sure why these requests get to AGH in the first place and why AGH treats them differently...

  3. I have AGH installed in /overlay (external flash), the guide above use /opt as the install folder. Does it have any practical differences, i.e. when I will need to upgrade / flash anew OpenWrt, or update AGH, perhaps in other circumstances?

As I said, all is working good, the items above are just for understanding about the inner working of this setup.

Thanks!

1 Like

Your router will use the alternative DNS that is separate to AGH (and because we need to do NTP and updates before AGH kicks in.) We need not filter the routers requests. Only the clients.

Your clients only use AGH and thus if you stop it... You stop getting DNS.

If you want a fall back for your clients you need to specify a backup DNS for them too. However if you do this, they can bypass AGH and thus your filtering stops working. There is a way around that thou. If you use AGH DNS or even NextDNS (because you can use their webpanel for filtering) and point the backup DNS to AGH DNS or NextDNS then the clients will "fallover" to the upstream DNS.

Those should be handled/passed onto the OpenWrt dnsmasq for local resolving. They are lookup requests for your internal lan clients. If we could have AGH DHCP running then it would be handled by AGH but at present we have a hybrid config and just pass them to OpenWrt instead.

(edit - they are what are called rDNS lookups. It is part of the config setup as a picture. You should have it set to the OpenWrt Dnsmasq setup so either 192.168.1.1:5353 or 127.0.0.1:5353 if following my setup. Or your own Dnsmasq ip if you have different IP range)

The AGH script assumes to install into /opt thus that's how I setup my taskflow to assume that and thus keep things simple. However when people use Ex-Root or even /overlay on external flash its just another filesystem. As long as you understand how you have done this and the space that is to be used it shouldn't be an issue. If there is a new update for OpenWrt you will have to reflash and reinstall. Then reinstall AGH as well but there should be no reason you couldn't then put your yaml file and data files over the top of the clean install and resume from there.

Never a problem. I've always tried to explain why I have done things so people can make their own determinations. Explaining and documenting makes it a process that can be looked at and understood. Blindly following instructions with no explanation requires trust and trusting random strangers on the internet should be followed with caution :slight_smile:

However I do hope that people have followed and understood what and how I have done to do this and the reasons behind it.

1 Like

Thanks a lot for explaining in detail! :slightly_smiling_face: Really kind of you!

1 Like

AGH has updated their internal filter lists and improved their vetted lists. Thus I have edited my install procedure and removed my lists. These lists are a good default start point. For more powerful routers you can add more but on limited space/memory routers I would be careful you do not use too many blocklists as your router will run out of memory quickly.

They have also added a list of known companies/trackers/service to use internally https://github.com/AdguardTeam/companiesdb

So for multiple ip networks, domain interception is needed to redirect local lookups to OpenWrt and not pass them to the upstream (which will only reply NXDOMAIN as it has no knowledge of local hosts.)

Adding these intercepts :

[/lan/]127.0.0.1:5353 #change lan to your domain
[//]127.0.0.1:5353 #intercept domainless requests

to the upstream list will intercept lan (or what ever domain you are using locally) and domainless requests and pass those requests back to openwrt. "lan" is OpenWrt's default domain, change this if you are using something else. (You may need to put your ip address instead of just local host if you are hosting AGH on another router.)

Thanks to @Cheddoleum

1 Like

new update is coming out

Shouldn't affect anyone who's installed the Edge version which I detailed. However if you want to only use stable versions then 107 should be fine to use.

opkg AGH now updated to 107. This build is useable and now you can just opkg install and use openwrt's build.

Please note this does NOT install into /opt but into /var so there are differances to using the AGH install script that i detail in my updated install post and instructions in this thread.

Wondering what the thoughts are around avoiding non standard ports for the web if?

Why not bind another LAN IP address to your router, so you can run AdGuard Home from a separate IP address with port 80/443? This means LuCI and the AdGuard Home web interface can co-exist, without having to change the ports. You can still bind DNS to 192.168.1.1 providing you've moved dnsmasq.

SSL wise, I'm able to use ACME and share the same SSL certificate across LuCI and AdGuard Home, I do have a wildcard *.internal.domain.com certificate though to make this easier, however with SAN requests, you don't have to use a wildcard, just specify the hostnames required in the certificate and then you can point the private key, cert path etc in AdGuard Home to the location on the OpenWrt filesystem.

I went for the simple route and just punted AGH web interface to 8080. Its not ideal but it is a workable solution as ideally we want luci as the primary web interface. The aim was to simplify things and integrate without replacing, while making it easily accessible for users without such a technical background.

A better one is what was discussed on the PR. Using a reverse proxy like Traefik or even nginx (which is supported by luci and AGH) https://github.com/AdguardTeam/AdGuardHome/wiki/FAQ#nginx

There was also a luci app for agh but its 2yrs out of date and seems abandoned. https://github.com/rufengsuixing/luci-app-adguardhome

Ah, reverse proxy is a good shout. Admittedly the binding of an additional IP while not exactly difficult would be hard to script, given the LAN range could be anything, you could in theory check this with UCI variables but it is more complicated and not as straight forward. That's what I do though, have AdGuard Home on it's own IP for the web interface, so I don't have to worry about non standard ports. I'm probably a bit of purist when it comes to random non standard ports on things when you don't need to.

I'm going to test the reverse proxy now actually, I already use nginx with LuCI.