Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions packages/adblock/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ endef

define Package/adblock/conffiles
/etc/config/adblock
/etc/adblock/adblock.allowlist
/etc/adblock/adblock.blocklist
/etc/adblock/adblock.custom.feeds
endef

Expand All @@ -56,14 +54,13 @@ define Package/adblock/install

$(INSTALL_DIR) $(1)/etc/adblock
$(INSTALL_BIN) ./files/adblock.mail $(1)/etc/adblock
$(INSTALL_CONF) ./files/adblock.allowlist $(1)/etc/adblock
$(INSTALL_CONF) ./files/adblock.blocklist $(1)/etc/adblock
$(INSTALL_CONF) ./files/adblock.categories $(1)/etc/adblock
$(INSTALL_CONF) ./files/adblock.feeds $(1)/etc/adblock
$(INSTALL_CONF) ./files/adblock.custom.feeds $(1)/etc/adblock

$(INSTALL_DIR) $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/95-adblock-housekeeping $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/99_adblock_migrate_lists.sh $(1)/etc/uci-defaults/99_adblock_migrate_lists
endef

$(eval $(call BuildPackage,adblock))
24 changes: 24 additions & 0 deletions packages/adblock/files/99_adblock_migrate_lists.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh

#
# Copyright (C) 2026 Nethesis S.r.l.
# SPDX-License-Identifier: GPL-2.0-only
#

# Migrate local allow/block list files to staged UCI storage.
# Skip once the dedicated section is already present.
uci -q get adblock.ns_lists >/dev/null 2>&1 && exit 0

uci set adblock.ns_lists=ns_lists

for type in allowlist blocklist; do
file="/etc/adblock/adblock.${type}"
[ -f "${file}" ] || continue

while IFS= read -r line || [ -n "${line}" ]; do
[ -z "${line}" ] && continue
uci add_list "adblock.ns_lists.${type}=${line}"
done < "${file}"
done

uci commit adblock
Empty file.
Empty file.
38 changes: 33 additions & 5 deletions packages/adblock/files/adblock.init
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,37 @@ boot() {
rc_procd start_service boot
}

f_append_local_list_entry() {
local entry="${1}"
local file="${2}"

printf '%s\n' "${entry}" >> "${file}"
}

f_write_local_lists() {
local allowlist_file='/etc/adblock/adblock.allowlist'
local blocklist_file='/etc/adblock/adblock.blocklist'

uci -q get adblock.ns_lists >/dev/null 2>&1 || return 0

config_load adblock

: > "${allowlist_file}"
config_list_foreach ns_lists allowlist f_append_local_list_entry "${allowlist_file}"

: > "${blocklist_file}"
config_list_foreach ns_lists blocklist f_append_local_list_entry "${blocklist_file}"
}

start_service() {
if "${adb_init}" enabled; then
/usr/sbin/ts-dns # configure threat shield dns, if needed
if [ "${action}" = "boot" ]; then
[ -n "$(uci_get adblock global adb_trigger)" ] && return 0
fi
# Start NethSecurity patch
f_write_local_lists
# End NethSecurity patch
procd_open_instance "adblock"
procd_set_param command "${adb_script}" "${@:-"${action}"}"
procd_set_param pidfile "${adb_pidfile}"
Expand All @@ -70,16 +95,19 @@ start_service() {
}

restart() {
# Start NethSecurity patch
/usr/sbin/ts-dns # configure threat shield dns, if needed
# End NethSecurity patch
stop_service "restart"
rc_procd start_service restart
}

reload_service() {
# Start NethSecurity patch
# Start NethSecurity patch
/usr/sbin/ts-dns # configure threat shield dns, if needed
${adb_script} nft-reload
# End NethSecurity patch
f_write_local_lists
${adb_script} nft-reload
# End NethSecurity patch
rc_procd start_service reload
}

Expand Down Expand Up @@ -140,7 +168,7 @@ service_triggers() {
for iface in ${trigger}; do
procd_add_interface_trigger "interface.*.up" "${iface}" "${adb_init}" start
done
# Start NethSecurity patch
# Start NethSecurity patch
procd_add_reload_trigger adblock
# End NethSecurity patch
# End NethSecurity patch
}
5 changes: 4 additions & 1 deletion packages/ns-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6171,12 +6171,15 @@ Response example:
{
"data": [
{
"address": "nethesis.it"
"address": "nethesis.it",
"description": "my allow1"
}
]
}
```

The allow and block list methods work on UCI-staged data. Changes are visible immediately through the API and are written to `/etc/adblock/adblock.allowlist` and `/etc/adblock/adblock.blocklist` during the next adblock reload triggered by `ns.commit` or `reload_config`.

### dns-add-allowed

Add a domain which is always allowed:
Expand Down
98 changes: 60 additions & 38 deletions packages/ns-api/files/ns.threatshield
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,36 @@ def write_allow_list(allow_list, file='/etc/banip/banip.allowlist'):
f.write('\n')
subprocess.run(["/etc/init.d/banip", "reload"], capture_output=True)

def dns_write_local_list(local_list, file):
with open(file, 'w') as f:
for x in local_list:
f.write(x['address'])
if x['description']:
f.write(' #' + x['description'])
f.write('\n')
subprocess.run(["/etc/init.d/adblock", "restart"], capture_output=True)
def dns_get_local_list(e_uci, list_type):
values = e_uci.get('adblock', 'ns_lists', list_type, list=True, default=[])
ret = []
for value in values:
parts = value.split('#', 1)
ret.append({'address': parts[0].strip(), 'description': parts[1].strip() if len(parts) > 1 else ''})
return ret

def dns_write_local_list(e_uci, local_list, list_type):
option = 'allowlist' if list_type == 'allowlist' else 'blocklist'
e_uci.set('adblock', 'ns_lists', 'ns_lists')

values = tuple(
f"{entry['address']} #{entry['description']}" if entry.get('description') else entry['address']
for entry in local_list
)
if values:
e_uci.set('adblock', 'ns_lists', option, values)
elif e_uci.get('adblock', 'ns_lists', option, list=True, default=[]):
e_uci.delete('adblock', 'ns_lists', option)

e_uci.save('adblock')

def restart_adblock():
try:
subprocess.run(["/etc/init.d/adblock", "restart"], capture_output=True, check=True)
except subprocess.CalledProcessError:
return generic_error("restart_failed")
return None
>>>>>>> ead35d90 (fix(adblock): stage dns list changes)

def write_block_list(block_list):
write_allow_list(block_list, '/etc/banip/banip.blocklist')
Expand Down Expand Up @@ -470,74 +492,74 @@ def dns_edit_settings(e_uci, payload):
e_uci.save('adblock')
return {'message': 'success'}

def dns_list_allowed():
return { "data": get_allow_list('/etc/adblock/adblock.allowlist') }
def dns_list_allowed(e_uci):
return { "data": dns_get_local_list(e_uci, 'allowlist') }

def dns_list_blocked():
return { "data": get_allow_list('/etc/adblock/adblock.blocklist') }
def dns_list_blocked(e_uci):
return { "data": dns_get_local_list(e_uci, 'blocklist') }

def dns_add_allowed(payload):
cur = get_allow_list('/etc/adblock/adblock.allowlist')
def dns_add_allowed(e_uci, payload):
cur = dns_get_local_list(e_uci, 'allowlist')
# extract address from cur list
if payload['address'] in [x['address'] for x in cur]:
raise ValidationError('address', 'address_already_present', payload['address'])
cur.append({ "address": payload['address'], "description": payload['description'] })
dns_write_local_list(cur, '/etc/adblock/adblock.allowlist')
dns_write_local_list(e_uci, cur, 'allowlist')
return {'message': 'success'}

def dns_add_blocked(payload):
cur = get_allow_list('/etc/adblock/adblock.blocklist')
def dns_add_blocked(e_uci, payload):
cur = dns_get_local_list(e_uci, 'blocklist')
# extract address from cur list
if payload['address'] in [x['address'] for x in cur]:
raise ValidationError('address', 'address_already_present', payload['address'])
cur.append({ "address": payload['address'], "description": payload.get('description') })
dns_write_local_list(cur, '/etc/adblock/adblock.blocklist')
dns_write_local_list(e_uci, cur, 'blocklist')
return {'message': 'success'}

def dns_edit_allowed(payload):
cur = get_allow_list('/etc/adblock/adblock.allowlist')
def dns_edit_allowed(e_uci, payload):
cur = dns_get_local_list(e_uci, 'allowlist')
if payload['address'] not in [x['address'] for x in cur]:
raise ValidationError('address', 'address_not_found', payload['address'])
for i in range(len(cur)):
if cur[i]['address'] == payload['address']:
cur[i]['description'] = payload['description']
break
dns_write_local_list(cur, '/etc/adblock/adblock.allowlist')
dns_write_local_list(e_uci, cur, 'allowlist')
return {'message': 'success'}

def dns_edit_blocked(payload):
cur = get_allow_list('/etc/adblock/adblock.blocklist')
def dns_edit_blocked(e_uci, payload):
cur = dns_get_local_list(e_uci, 'blocklist')
if payload['address'] not in [x['address'] for x in cur]:
raise ValidationError('address', 'address_not_found', payload['address'])
for i in range(len(cur)):
if cur[i]['address'] == payload['address']:
cur[i]['description'] = payload.get('description')
break
dns_write_local_list(cur, '/etc/adblock/adblock.blocklist')
dns_write_local_list(e_uci, cur, 'blocklist')
return {'message': 'success'}

def dns_delete_allowed(payload):
cur = get_allow_list('/etc/adblock/adblock.allowlist')
def dns_delete_allowed(e_uci, payload):
cur = dns_get_local_list(e_uci, 'allowlist')
if payload['address'] not in [x['address'] for x in cur]:
raise ValidationError('address', 'address_not_found', payload['address'])
# remove address from cur list
for i in range(len(cur)):
if cur[i]['address'] == payload['address']:
del cur[i]
break
dns_write_local_list(cur, '/etc/adblock/adblock.allowlist')
dns_write_local_list(e_uci, cur, 'allowlist')
return {'message': 'success'}

def dns_delete_blocked(payload):
cur = get_allow_list('/etc/adblock/adblock.blocklist')
def dns_delete_blocked(e_uci, payload):
cur = dns_get_local_list(e_uci, 'blocklist')
if payload['address'] not in [x['address'] for x in cur]:
raise ValidationError('address', 'address_not_found', payload['address'])
# remove address from cur list
for i in range(len(cur)):
if cur[i]['address'] == payload['address']:
del cur[i]
break
dns_write_local_list(cur, '/etc/adblock/adblock.blocklist')
dns_write_local_list(e_uci, cur, 'blocklist')
return {'message': 'success'}

def dns_list_bypass(e_uci):
Expand Down Expand Up @@ -809,15 +831,15 @@ elif cmd == 'call':
ret = dns_list_zones(e_uci)
elif action == 'dns-add-allowed':
payload = json.loads(sys.stdin.read())
ret = dns_add_allowed(payload)
ret = dns_add_allowed(e_uci, payload)
elif action == 'dns-edit-allowed':
payload = json.loads(sys.stdin.read())
ret = dns_edit_allowed(payload)
ret = dns_edit_allowed(e_uci, payload)
elif action == 'dns-list-allowed':
ret = dns_list_allowed()
ret = dns_list_allowed(e_uci)
elif action == 'dns-delete-allowed':
payload = json.loads(sys.stdin.read())
ret = dns_delete_allowed(payload)
ret = dns_delete_allowed(e_uci, payload)
elif action == 'dns-list-bypass':
ret = dns_list_bypass(e_uci)
elif action == 'dns-add-bypass':
Expand All @@ -827,16 +849,16 @@ elif cmd == 'call':
payload = json.loads(sys.stdin.read())
ret = dns_delete_bypass(e_uci, payload)
elif action == 'dns-list-blocked':
ret = dns_list_blocked()
ret = dns_list_blocked(e_uci)
elif action == 'dns-add-blocked':
payload = json.loads(sys.stdin.read())
ret = dns_add_blocked(payload)
ret = dns_add_blocked(e_uci, payload)
elif action == 'dns-edit-blocked':
payload = json.loads(sys.stdin.read())
ret = dns_edit_blocked(payload)
ret = dns_edit_blocked(e_uci, payload)
elif action == 'dns-delete-blocked':
payload = json.loads(sys.stdin.read())
ret = dns_delete_blocked(payload)
ret = dns_delete_blocked(e_uci, payload)

print(json.dumps(ret))
except ValidationError as ex:
Expand Down
Loading
Loading