I am trying to run some python code to dynamically update nftables sets of IPs from selected domains. The domains IPs change so setting static IPs will not do.
included packages:
unbound-1.26.1-1
python3-unbound-1.26.1-1
python3-3.14.8-1
/etc/unbound/unbound.conf (among other thing)
server:
module-config: "validator python iterator"
python:
python-script: "/etc/unbound/nft_container_domains.py"
/etc/unbound/nft_container_domains.py
import unbound
import os
# Define the domains you want to allowlist
ALLOWLIST = [
"docker.io.",
"ghcr.io.",
"lscr.io."
]
def init(id, cfg):
return True
def deinit(id):
return True
def inform_super(id, qstate, superqstate):
return True
def operate(id, event, qstate, qdata):
if event == unboundmod.MODULE_EVENT_NEW or event == unboundmod.MODULE_EVENT_PASS:
# Check if the query has a valid response and in allowlist
if qstate.return_msg and qstate.return_msg.rep:
reply = qstate.return_msg.rep
# Loop through answer records
for i in range(reply.an_numrrsets):
rrset = reply.rrsets[i]
rk = rrset.rk
# Check for A (IPv4) or AAAA (IPv6) records
if rk.type_str in ["A", "AAAA"]:
data = rrset.entry.data
# Loop through all returned IP blocks
for j in range(data.num):
# Extract the raw IP byte string (skip first 2 bytes length data)
raw_ip = data.data[j][2:]
# Format bytes into readable IP string
if rk.type_str == "A":
ip_str = ".".join(str(b) for b in raw_ip)
else:
ip_str = ":".join(f"{raw_ip[m]:02x}{raw_ip[m+1]:02x}" for m in range(0, len(raw_ip), 2))
# Push dynamically to an online nftables set named 'container_domains'
try:
subprocess.run(["nft", "add", "element", "ip", "filter", "container_domains", f"{{ {ip_str} }}"], check=True)
except Exception:
pass # Handle or log system execution errors here
qstate.ext_state[id] = unboundmod.MODULE_TYPE_SETRESULT
return True
I’m getting errors:
unbound[1983]: [1983:3] error: pythonmod: Exception occurred in function operate, event: module_event_pass
unbound[1983]: [1983:3] error: pythonmod: cannot print exception, cannot ImportModule cStringIO or StringIO or io
I know I have to put in a check for allowlist. But how can I fix the errors? Is this python2 vs python3 code? This unbound-user mailing list looks dead.
Thanks for help.