/cgi-bin/adblock (preferably transferred via QR code shown in LuCI)
* The script automatically detects the device’s MAC address
* If the MAC is authorized, the script displays the current status:
* Not in the nftables set → option to request a temporary allow (“Bypass”)
* Already active → shows remaining timeout
* When renewing, the CGI adds the MAC to an nftables Set with a per‑entry timeout
The CGI interface is mobile‑friendly and includes a LuCI‑style loading spinner during the renew process, giving immediate visual feedback while the nftables entry is created. All operations are atomic and safe even when multiple devices renew access in parallel.
**Temporary DNS Bridging (Zero‑Downtime during DNS Restarts)**
Adblock can optionally enable a temporary DNS bridging mode to avoid DNS downtime during DNS backend restarts.
When this feature is enabled, all DNS queries from LAN clients are briefly redirected to an external fallback resolver until the local DNS backend becomes available again. This ensures that DNS resolution continues to work seamlessly for all clients, even while adblock reloads blocklists or restarts the DNS service. Just set the options `adb_nftbridge`, `adb_bridgednsv4` and `adb_bridgednsv6` accordingly.
**Jail mode (allowlist-only):**
Enforces a strict allowlist‑only DNS policy in which only domains listed in the allowlist file are resolved, while every other query is rejected. This mode is intended for highly restrictive environments and depends on a carefully maintained allowlist, typically managed manually.
**Download options**
By default adblock uses the following pre-configured download options:
```
* curl: --connect-timeout 20 --retry-delay 10 --retry 4 --retry-max-time 80 --retry-all-errors --fail --silent --show-error --location -o
* wget: --no-cache --no-cookies --timeout=20 --waitretry=10 --tries=5 --retry-connrefused -O
* uclient-fetch: --timeout=20 -O
```
To override the default set `adb_fetchretry`, `adb_fetchinsecure` or globally `adb_fetchparm` to your needs.
**Enable E-Mail notification via `msmtp`:**
To use the email notification you have to install & configure the package `msmtp`.
Modify the file `/etc/msmtprc`:
[...]
defaults
auth on
tls on
tls_certcheck off
timeout 5
syslog LOG_MAIL
[...]
account adb_notify
host smtp.gmail.com
port 587
from dev.adblock@gmail.com
user dev.adblock
password xxx
Finally enable E-Mail support, add a valid E-Mail receiver address in LuCI and setup an appropriate cron job.
**Automatic adblock feed updates and E-Mail reports**
For a regular, automatic update of the used feeds or other regular adblock tasks set up a cron job. Use `reload` here — `start`/`restart` would only restore the backups instead of fetching fresh feeds. In LuCI you find the cron settings under `System` => `Scheduled Tasks`. On the command line the cron file is located at `/etc/crontabs/root`:
Example 1
```sh
# update the adblock feeds every morning at 4 o'clock
00 04 * * * /etc/init.d/adblock reload
```
Example 2
```sh
# update the adblock feeds every hour
0 */1 * * * /etc/init.d/adblock reload
```
Example 3
```sh
# send an adblock E-Mail report every morning at 3 o'clock
00 03 * * * /etc/init.d/adblock report mail
```
**Change/add adblock feeds**
The adblock default blocklist feeds are stored in an external JSON file `/etc/adblock/adblock.feeds`. This file is shipped with the package and is **overwritten on every package update**, so never edit it directly. All of your custom changes belong in the separate JSON file `/etc/adblock/adblock.custom.feeds` (empty by default), which is preserved across updates. It's recommended to use the LuCI based Custom Feed Editor (`Custom Feed Editor` tab), which validates the JSON for you.
**Please note:** if `/etc/adblock/adblock.custom.feeds` exists and is non-empty, it is loaded **instead of** the shipped `adblock.feeds` — it replaces the feed set, it does not merge with it. A custom feed file must therefore contain *every* feed you want active, not just your additions. The Custom Feed Editor handles this for you by working on a full copy.
A feed is a single JSON object, keyed by a unique feed name (no spaces, no special characters). Example:
```json
[...]
"stevenblack": {
"url": "https://raw.githubusercontent.com/StevenBlack/hosts/master/",
"rule": "feed 0.0.0.0 2",
"size": "VAR",
"descr": "compilation"
},
[...]
```
The object supports the following fields:
| Field | Required | Description |
| :---- | :------: | :-------------------------------------------------------------------------------------------------------- |
| url | yes | download URL of the domain list (for category feeds: the base URL, see below) |
| rule | yes | the parsing ruleset, max. 4 space separated parameters (see below) |
| size | yes | size hint shown in LuCI: `S`, `M`, `L`, `XL`, `XXL` or `VAR` (see the feed table legend in Main Features) |
| descr | yes | a short human-readable description shown in LuCI and the feed table |
**The `rule` field**
The rule consists of max. 4 individual, space separated parameters:
1. **type**: always `feed` (required). adblock only supports the `feed` type for external sources; any source whose rule does not start with `feed` is skipped.
2. **prefix**: an optional search term (a literal string, not a regex) that a line must contain to be treated as a valid entry. Use it to pick the relevant rows of a hosts-style file, e.g. `0.0.0.0`. Omit it for a plain list with one bare domain per line.
3. **column**: the 1-based column that holds the domain within a matching line, e.g. `2` for a `0.0.0.0 example.com` hosts file or `1` for a bare list (required). When no prefix is used, give the column directly, e.g. `feed 1`.
4. **separator**: an optional field separator; default is the whitespace character class `[[:space:]]+`. Pass a literal character such as `,` for comma-separated sources.
Examples:
* `feed 1` — plain list, one domain per line, domain in column 1
* `feed 0.0.0.0 2` — hosts-style file, keep only `0.0.0.0` lines, domain in column 2
* `feed 1 ,` — comma-separated source, domain in the first field
**Category-based feeds (size `VAR`)**
The feeds marked `VAR` in the feed table (`1hosts`, `hagezi`, `ipfire_dbl`, `stevenblack`, `utcapitole`) are built-in feeds that require an additional category selection via the dedicated options `adb_hst_feed`, `adb_hag_feed`, `adb_ipf_feed`, `adb_stb_feed` and `adb_utc_feed` (or the LuCI feed configuration). For these, the `url` is a **base URL** to which the selected category is appended at download time. This category mechanism is wired to those specific feed names in the backend, so it cannot be reused for arbitrary new feeds — a custom feed you add yourself should point `url` at a single, complete list URL.
After editing `/etc/adblock/adblock.custom.feeds`, reload adblock (`/etc/init.d/adblock reload`) and check the `Log View` tab (or `logread -e adblock-`). With `adb_debug` enabled, a malformed JSON object or a wrong column/separator typically shows up there as a feed that produces zero domains.
## Troubleshooting & debug options
Adblock provides an optional debug mode that writes diagnostic information to the system log and captures internal error output in a dedicated error logfile - by default located in the adblock base directory as `/tmp/adb_error.log`. The log file is automatically cleared at the beginning of each run. Under normal conditions, all error messages are discarded to keep regular runs clean and silent. To enable debug mode, set the option `adb_debug` to `1`. When enabled, the script produces significantly more log output to assist with troubleshooting.
Whenever you encounter adblock related processing problems, please enable debug logging, restart adblock and check the `Log View` tab in LuCI (or the syslog via `logread -e adblock-`).
## Support
Please join the adblock discussion in this [forum thread](https://forum.openwrt.org/t/adblock-support-thread/507) or contact me by mail
## Removal
Stop all adblock related services with _/etc/init.d/adblock stop_ and remove the adblock package if necessary.
## Donations
You like this project - is there a way to donate? Generally speaking "No" - I have a well-paying full-time job and my OpenWrt projects are just a hobby of mine in my spare time.
If you still insist to donate some bucks ...
* I would be happy if you put your money in kind into other, social projects in your area, e.g. a children's hospice
* Let's meet and invite me for a coffee if you are in my area, the “Markgräfler Land” in southern Germany or in Switzerland (Basel)
* Send your money to my [PayPal account](https://www.paypal.me/DirkBrenken) and I will collect your donations over the year to support various social projects in my area
No matter what you decide - thank you very much for your support!
Have fun!
Dirk