preload cachedb redis backend using python
Bino Oetomo
wowon01 at gmail.com
Wed Sep 10 10:30:15 UTC 2025
dear all
I use cachedb with redis backend.
try to preload redis using python.
```
import dns.message
import dns.rcode
import dns.flags
import struct
import time
import redis
def make_minimal_nxdomain(domain: str) -> bytes:
q = dns.message.make_query(domain, 'A')
r = dns.message.make_response(q)
r.set_rcode(dns.rcode.NXDOMAIN)
r.flags |= dns.flags.QR
r.flags |= dns.flags.AA
r.flags &= ~dns.flags.RD # Clear RD
r.flags &= ~dns.flags.RA # Clear RA
r.answer = []
wire = r.to_wire()
now = int(time.time())
wire += struct.pack('>QQ', now, now + 31536000) # 1 year
return wire
def make_key(domain: str, qtype: int = 1, qclass: int = 1, secret_seed: str
= "mysecretseed2025") -> str:
"""
Generate Redis key using SHA256(secret_seed + wire_name + qtype +
qclass)
"""
import hashlib
import struct
if not domain.endswith('.'):
domain += '.'
labels = domain.rstrip('.').split('.')
wire = b''.join(bytes([len(label)]) + label.encode() for label in
labels) + b'\x00'
qtype_n = struct.pack('!H', qtype)
qclass_n = struct.pack('!H', qclass)
data = wire + qtype_n + qclass_n + secret_seed.encode()
return hashlib.sha256(data).hexdigest().upper()
if __name__ == '__main__':
# Test domain
domain = "tulisan.nggonku.xyz"
# Generate NXDOMAIN response
response_wire = make_minimal_nxdomain(domain)
print(f"Generated NXDOMAIN response for {domain}, {len(response_wire)}
bytes")
# Generate Redis key
key = make_key(domain)
print(f"Redis key: {key}")
# Connect to Redis
r = redis.Redis(host='127.0.0.1', port=6379, db=0,
decode_responses=False)
# Set in Redis
r.set(key, response_wire)
print(f"Loaded into Redis: {key}")
# Optional: Verify
print("\nVerifying from Redis...")
retrieved = r.get(key)
if retrieved:
print(f"Retrieved {len(retrieved)} bytes")
timestamp, expiry = struct.unpack('>QQ', retrieved[-16:])
print(f"Timestamp: {time.ctime(timestamp)}")
print(f"Expiry: {time.ctime(expiry)}")
else:
print("Not found in Redis")
```
When I dig for my domain name (dig @127.0.0.1 tulisan.nggonku.xyz) , I got
this from unbound debug
```
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] info: 127.0.0.1
tulisan.nggonku.xyz. A IN
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: udp request from
ip4 127.0.0.1 port 41514 (len 16)
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: mesh_run: start
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: cachedb[module 0]
operate: extstate:module_state_initial event:module_event_new
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: redis_lookup of
BE0C12BF95D4BA92F06B0F3291977F068DE61AD2161DB013AAC4A6B999877A02
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: redis_lookup found
53 bytes
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: cachedb msg expired
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: cachedb msg
adjusted down by -1
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] info: redis ;;
->>HEADER<<- opcode: QUERY, rcode: NXDOMAIN, id: 0
;; flags: qr aa ; QUERY: 1, ANSWER:
0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
tulisan.nggonku.xyz. IN
A
;; ANSWER SECTION:
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
;; MSG SIZE rcvd: 37
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: mesh_run: cachedb
module exit state is module_wait_module
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: validator[module
1] operate: extstate:module_state_initial event:module_event_pass
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] info: validator operate:
query tulisan.nggonku.xyz. A IN
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: validator: pass to
next module
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: mesh_run:
validator module exit state is module_wait_module
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: iterator[module 2]
operate: extstate:module_state_initial event:module_event_pass
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: process_request:
new external request event
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] debug: iter_handle
processing q with state INIT REQUEST STATE
Sep 10 17:22:05 unbound unbound[25748]: [25748:0] info: resolving
tulisan.nggonku.xyz. A IN
```
Looks like the message "content" is right, but timestamp/ttl/expiry is
wrong.
How to write good wire message?
-wowon-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.nlnetlabs.nl/pipermail/unbound-users/attachments/20250910/cab70ab3/attachment-0001.htm>
More information about the Unbound-users
mailing list