In this post - we'll take a look at how to set up & configure AdGuard Home on OPNsense.
Please note that the AdGuard Home plugin for OPNsense is a community built plugin, and not officially supported by OPNsense.
What's AdGuard Home? Why use it?
Almost every website we visit these days is loaded with additional components for advertisements, analytics, and engagement tracking. One one side, these tools can be very helpful for the company or website owner to monetize their platform and/or track & understand their audience's interests.
However, it's also becoming more popular to want to avoid being tracked on every website, or reduce the amount of advertisements you see. Unfortunately, a lot of these scripts & code snippets are automatically embedded in websites and most don't allow you to opt-out.
A while back, there were a few browser extensions that became popular by automatically blocking the advertisement & tracking elements from loading. These were great (and still are!), but a lot of website owners have been fighting it & making it harder to block their content. In addition, these types of extensions operate at your web browser level - meaning that your computer has already made a few calls out to the internet before the extension even has a chance to block something.
Here's where we've started to see more ad blockers come out that operate at the network level. AdGuard Home is one of them, but you also may have seen similar packages like Pi-hole or NextDNS. These are typically packages that you install on your home network & run as a local Domain Name System (DNS) server.
Each time your browser needs to load something from the web, the first step is figuring out what IP address to connect to. For this, the computer reaches out to it's configured DNS server and provides the website name (like 0x2142.com). The DNS server looks up where that lives & provides the computer with the IP address (like 203.0.113.52). Then your computer can load the website by connecting to that address.
With a DNS-level blocker, like AdGuard Home, we can block your computer from ever trying to establish that connection. If you tried to go to a website (like 0x2142.com), and there was an embedded advertisement or tracking, AdGuard would tell your computer that the domain hosting the advertisement doesn't exist (usually via returning a 0.0.0.0 or NXDOMAIN response). So your browser would still be able to load the main site (0x2142.com), but it would never even try to establish a connection to the advertisement or tracking components.
So we gain a few benefits here - the big ones being some level of privacy & reduced advertisement noise when browsing the web. But also since we block so much of that noise early in the process, your computer never has the opportunity to load that content - meaning that we also save on bandwidth usage & data costs. There may also be small performance improvements since each site has less content that needs to be loaded.
The other bonus worth considering is security. There are quite a handful of DNS blocklists that are constantly updated with the latest malicious or suspicious domains. The quicker we can block & stop clients from potentially connecting to those domains, the better off we are!
Is there a down side? Yeah, of course there is! A lot of these DNS-level blockers pull from varying website blocklists - which are not always 100% accurate. So sometimes you may still see advertisements or get tracked. It's not a perfect system. In addition, you may also (and sometimes often) see the reverse - parts of websites being blocked that are legitimate. And there are quite a handful of websites these days that won't work correctly unless they can load 3rd party components. Most of the time everything will be fine, but just be aware that there may be some time spent troubleshooting & manually unblocking website components.
Do I have to install this on OPNsense?
Nope. AdGuard Home has a number of packages & ways to get running. Check out their GitHub repo.
If you're already running OPNsense, it's easy to install this as an add-on package & not have another system to manage. However, if you prefer to set up AdGuard (or Pi-hole, or others) elsewhere, that's fine too. You'll just need to update your client network's DHCP options to use the new DNS servers. See the last section below on how to do that.
Okay - Let's get started with setting this up!
Topology
For the purposes of this walkthrough, we'll be using a fairly simple & straightforward topology. A single OPNsense appliance connected to the internet via it's WAN port, as well as a single client PC connected via the LAN port.
In this setup, the OPNsense appliance is configured to provide IP address & DNS information to our client PCs via DHCP.
Adding the Community Repository to OPNsense
So by default, AdGuard Home is not included in the available plugins to download/install in OPNsense. However, someone built a community plugin repository that includes a small handful of additional packages.
Before we can install the AdGuard Home plugin, we will need to setup & install that community repository.
To do this, we'll need direct SSH or console access to our OPNsense appliance.
SSH is disabled by default, but we can enable it quickly by navigating to System > Settings > Administration and then scrolling down to the Secure Shell section.
We'll need to check the box for Enable Secure Shell and Permit Password Login. If you're logging into OPNsense with the root account, you'll also need to select Permit root user login.
Then scroll down to the bottom of the page & click Save.
Note: By default OPNsense will also have the SSH Listen Interface set to All. I would highly recommend setting this to only enable on your LAN interface
Also: If you don't need SSH access all the time, please remember to disable this service once you're finished setting this up!
Okay, now that's enabled - we can connect to our OPNsense appliance using your preferred SSH client (like PuTTY).
If you're using the root account, you'll likely be dropped into the OPNsense shell - but you can select option 8 here to access the underlying FreeBSD shell.
In order to install the community repository, we'll pull down the repository config file using the following command:
fetch -o /usr/local/etc/pkg/repos/mimugmail.conf https://www.routerperformance.net/mimugmail.conf
Then, we'll need to ask OPNsense to update it's local cache with the new repo - so it knows what packages are hosted there:
pkg update
If everything is successful, you'll see output similar to below - which lists the mimugmail
repository now:
[email protected]:/home/matt # pkg update
Updating OPNsense repository catalogue...
Fetching meta.conf: 100% 163 B 0.2kB/s 00:01
Fetching packagesite.pkg: 100% 229 KiB 234.3kB/s 00:01
Processing entries: 100%
OPNsense repository update completed. 822 packages processed.
Updating mimugmail repository catalogue...
Fetching meta.conf: 100% 163 B 0.2kB/s 00:01
Fetching packagesite.pkg: 100% 54 KiB 54.8kB/s 00:01
Processing entries: 100%
mimugmail repository update completed. 177 packages processed.
All repositories are up to date.
Installing the AdGuard Home Package
Now that the additional package repository is set up, we can download & install the AdGuard Home plugin via the OPNsense web interface.
So back in our browser, we can nagivate to: System > Firmware > Plugins. On this page we can search for adguard or scroll through the list to find it.
Then we just click the plus icon on the right side to install (not shown in the screenshot above).
This should install pretty quickly:
***GOT REQUEST TO INSTALL***
Currently running OPNsense 22.7.9 (amd64/OpenSSL) at Sun Dec 4 12:48:38 EST 2022
Updating OPNsense repository catalogue...
OPNsense repository is up to date.
Updating mimugmail repository catalogue...
mimugmail repository is up to date.
All repositories are up to date.
The following 1 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
os-adguardhome-maxit: 1.8 [mimugmail]
Number of packages to be installed: 1
The process will require 35 MiB more space.
7 MiB to be downloaded.
[1/1] Fetching os-adguardhome-maxit-1.8.pkg: .......... done
Checking integrity... done (0 conflicting)
[1/1] Installing os-adguardhome-maxit-1.8...
[1/1] Extracting os-adguardhome-maxit-1.8: .......... done
Stopping configd...done
Starting configd.
Migrated OPNsense\Adguardhome\General from 0.0.0 to 0.0.1
Reloading plugin configuration
Configuring system logging...done.
Reloading template OPNsense/Adguardhome: OK
Checking integrity... done (0 conflicting)
Nothing to do.
***DONE***
Now all we have to do is enable the plugin.
So we'll navigate down to Services > Adguardhome > General. Our only option here will be an Enable checkbox, so we'll select that & Save.
The rest of the setup & initial configuration will be done directly from the AdGuard-specific web interface.
Initial Setup
By default, the AdGuard Home web interface will run on port 3000 & is not HTTPS-enabled. So if your OPNsense firewall is at https://192.168.1.1
, you'll need to connect to http://192.168.1.1:3000
.
As long as that works - we'll see the initial setup prompt below:
We'll click on Get Started.
Now we'll be asked to configure the Admin Web interface (the interface we're connected to now) and the DNS server interface (which clients will use to resolve domain names).
By default, AdGuard home will try to set both of these to listen on All interfaces - and set the web on port 80 & DNS on port 53.
I would recommend setting the Listen Interface on both of these to only your LAN-side networks. There is no reason to enable them on your WAN, and it can be a security risk to do so.
You may also get warnings that port 80 & 53 may already be in use. For the web interface, we could change 80 to 3000 & just keep what we're using now.
However, if we change the default DNS port, that will cause some additional problems since client machines will query port 53. Likely if port 53 is already in use, it's because another service on OPNsense (like Unbound DNS) is already enabled. In my case, I disabled this in favor of using AdGuard. However, if you want to use both - you can change the default DNS port in AdGuard to something like 65353, then have Unbound forward requests to AdGuard (More on this down below).
So here's what my set up looks like so far, with 192.168.1.1
being my LAN side interface:
On the next page, we'll be prompted to set up an administrative user & password for logging into AdGuard.
Next we'll be given instructions on how to set up client devices. In my lab network, the OPNsense firewall is providing DNS server configuration via DHCP - so we'll get to that configuration shortly.
For now, we'll just click Next.
On the last screen, we'll just get a message saying that setup is complete & a link to open the dashboard:
And now we can log in:
AdGuard Home Configuration
After logging in, the first thing we'll see is a pretty empty dashboard. We don't have any clients configured to use this yet, so there isn't anything to report on.
Blocking Domains
First thing we'll look at is our DNS blocklists. We'll navigate to Filters > DNS blocklists.
Here is where we can ask AdGuard to query lists of what domains to block. By default, AdGuard does include two - but we can add more if we want:
If we want to add to the configured blocklists, we can do so by clicking the Add Blocklist button. This will prompt us whether we want to choose from a pre-populated list, or supply our own custom list:
The easy option will be selecting from the provided lists:
There are a ton of different curated block lists available depending on what you're trying to block. If we wanted to use a custom list, a lot can be found on GitHub just by searching for PiHole or Adguard blocklists.
How to pick a blocklist will be up to you. There are blocklists that focus on advertisements, tracking & analytics, parental controls, etc. So it just depends on what areas you want to focus on.
Allowing Domains & Custom Filtering
If we have a list of known services that we want to ensure are never blocked, we can pull those lists via Filters > DNS allowlists. However, it's more likely you'll find a handful of domains you want to unblock, rather than a whole list.
For that - we can go to Filters > Custom filtering rules. At the bottom of this page there is a tool to check filtering, where we can enter a domain name & instantly see what the result is.
For example, with the default ruleset I'll check to see if 0x2142.com is filtered:
So by default that domain isn't found anywhere, so it will be permitted. The tool also gives us a convenient button to quickly block a domain.
We can click that button, or add the syntax ||0x2142.com^
to the custom filtering rules at the top of the page (and saving via the Apply button). Now if we check the results again - the filter check will show the domain is blocked:
And of course, we don't want to block 0x2142.com!! So let's add this to our allowlist instead, so that it can never be blocked 🙃. We can do that by adding @@||0x2142.com^
to the custom filtering.
And now we'll see a green box that shows that the domain is permitted via an allowlist:
Blocking Known Services
The other option worth mentioning is the ability to block certain known services, like WhatsApp, Twitter, Reddit, etc. This can be great if there are certain services you want to block, or for use as parental controls.
This can be found on the Filters > Blocked Services page.
This way we can select a service to block, rather than having to know all of the individual domains that service uses. For example, I'll go ahead and select YouTube to block - and we'll check that later on after we configure our clients.
Configure OPNsense DHCP to use AdGuard
Now that we've taken a quick look at the AdGuard Home settings & have a few things configured - let's look at setting up our clients to use our new DNS server.
In the lab environment I'm using, the OPNsense appliance is providing client IP address configuration via Dynamic Host Configuration Protocol (DHCP).
By default, if a specific DNS server is not configured for your client DHCP settings, then OPNsense will provide the clients with the same DNS server it uses. This could have been a DNS server that was configured when you set up OPNsense, or it also can use DNS servers that are provided by your internet service provider.
So to update our LAN DHCP configuration, we'll head back to our OPNsense web interface. From there, we'll navigate to Services > DHCPv4 > [LAN].
In the configuration, there is an open option for DNS Servers. We'll set this to our OPNsense LAN IP address. In my case, that is 192.168.1.1
. Then scroll to the bottom of the page & click Save.
Client Testing
Now we should be all set up! However, it's important to note that because of the way DHCP works, clients may not pick up the new configuration immediately. When DHCP assigns an IP address, it also tells the client how long it can use that address for. So if a client stays powered-on & connected, it won't ask for new configuration until that timer expires.
We can speed that up by resetting the network interface on our clients. This can be done in a number of ways including rebooting the client or simply disconnecting from wifi/ethernet & reconnecting.
I'm using a Linux computer as my test system, so first I'll check via the nslookup
command - which will query our configured DNS server & return the resolved IP addresses.
If you remember, I blocked all of YouTube's services earlier:
As we can see, we did get the correct IP addresses - which means our filtering isn't working yet.
I'll reset the network adapter on the test PC, which will refresh the DHCP configuration - then try again:
Now that's the result we want! By returning the 0.0.0.0
result, our client can no longer resolve that domain. So if this was an advertisement or tracking domain, it's now blocked from loading.
And sure enough, if we now try to browse to that site via a web browser - we don't be able to access it:
Troubleshooting Blocked Domains
Okay, so now we know our blocking works.... But now someone in our home is trying to access YouTube & it's not working. How can we tell if that's our AdGuard service?
Our first stop might be the AdGuard query log. Opening this log, we can filter by domain name or client - or show only blocked queries if we like.
Pretty quickly we can see the issue - we blocked YouTube's services:
Now we know how to fix the issue, which would be to unblock that service. However, if it was just a specific domain that was blocked, we would likely want to add it to our custom filtering as we showed earlier.
Reporting
Last but not least, we can also check our AdGuard Home dashboard again, which should be much more interesting than before:
Here we can quickly see how many queries have been made & how many were blocked for various reasons. We'll also see what clients are using our DNS server, and which are making the most queries.
Most interesting (at least to me), is being able to see the top domains that were queried or blocked. Here's where you might find some interesting information. For example, on my test machine - it's a fresh installation of Ubuntu & we used FireFox to test. But we can see that even during the brief time it's been set up, almost all of the highest queried domains belong to Mozilla's analytics services. So it may be tempting to add those to our custom blocklists.
Additional Info
What if I have AdGuard running on a different server? Or want to keep using Unbound DNS?
Sure - we can make both of those work.
For the first scenario, maybe we have AdGuard Home installed & set up on a Raspberry Pi on our network. For that, all we need to do is set that Raspberry Pi as the DNS server in our DHCP configuration on OPNsense. See above where we did that for our on-box AdGuard setup.
For the other situation, perhaps you want to use Unbound on OPNsense, but also AdGuard. There might be reasons for this - like even though Unbound does support DNS blocklists, AdGuard has better reporting tools. But on the other hand, Unbound has more features & configuration options for DNS than Unbound.
In this case, we would want to run AdGuard on a different DNS port (like 65353), then have Unbound forward those to AdGuard. See below if you need to change the port AdGuard uses for DNS.
Within OPNsense, we could go to Services > Unbound DNS > Query Forwarding. Then add a new custom forwarding entry. Here we can forward requests for specific domains if we want - or if we want to forward all DNS requests, we can leave the domain field empty. Then fill in the AdGuard information - so in my example this would be 192.168.1.1 and port 65353.
Then click Save and Apply!
How do I change the interface / port for the Web UI or DNS?
So perhaps we mis-typed something when configuring AdGuard. Or just wanted to change the interface IP address AdGuard listens on. No problem!
Unfortunately, since this is a community plugin - there is no configuration for the plugin within the OPNsense interface.
We'll need to reconnect to the OPNsense command line to make some additional configuration changes. This can be done via SSH or the device console.
Once there, we can use the command edit /usr/local/AdGuardHome/AdGuardHome.yaml
.
That config file looks like this:
At the top, bind_host
& bind_port
pertains to the admin web interface. A little below there, under the dns
section - you'll see another bind_hosts
and port
config. Those ones are specific to the DNS server side of things.
Once done, save the config file by pressing Esc
then selecting to quit the editor & save the file.
Lastly - Go back into the OPNsense web UI & restart the AdGuard Home service for the changes to take effect.