[Unbound-users] Sending a query from within processing a query in the python module
Paul Wouters
paul at nohats.ca
Mon Jan 20 01:11:41 UTC 2014
Hi,
We're using a modified "unbound python example". The idea is that when
an A or AAAA query comes in, we wait to query for an IPSECKEY record
before returning the A/AAAA to the application.
As a proof of concept, we used python-dns to fire off the query for the
IPSECKEY record within the unbound python module we load, which then
hits unbound from the outside. This was just a hack, but clearly not
the right way to use it.
How can we do this within the unbound? Can it be done in the python
module, or do we need to use a C module to get more access to various
parts of the iterator?
Or how can we invoke a sub-query? How can we combine the results of a
subquery with the query we are postponing?
Further issue is that our code needs to have the IPSECKEY query result at
the same time as the A record result. This way, we can pass this IPsec
key and the IP address to a shell command (commands.getstatusoutput())
to build an IPsec tunnel, before the A record is returned to the application.
Attached is our little proof of concept code hack.
Paul
-------------- next part --------------
import sys, commands
sys.path.append("/usr/lib/python2.6/site-packages/")
import dns.resolver
import base64
myname = "rhel6.nohats.ca"
myip = "193.110.157.150"
def init(id, cfg):
global mykey
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
return True
def deinit(id):
log_info("pythonmod: deinit called, module id is %d" % id)
return True
def inform_super(id, qstate, superqstate, qdata):
log_info("pythonmod: inform_super called, module id is %s, qstate:%s, superqstate:%s, qdata:%s" % (id, qstate, superqstate, qdata))
return True
def operate(id, event, qstate, qdata):
global myname
global myip
#log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
if event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS:
qstate.ext_state[id] = MODULE_WAIT_MODULE
mykey = "<unknown>"
if qstate.qinfo.qtype in ( 1, 28 ):
log_info("qname:%s qtype:%s rcode:%s"%(qstate.qinfo.qname_str,qstate.qinfo.qtype, qstate.return_rcode))
ipseckey = commands.getoutput("ipsec showhostkey --ipseckey")
if "IPSECKEY" in ipseckey:
mykey = ipseckey.rsplit(" ")[-1]
log_info("We found our IPSECKEY to be: %s"%mykey)
else:
log_info("We failed to find our IPSECKEY in: %s"%ipseckey)
try:
ipseckeys = dns.resolver.query(qstate.qinfo.qname_str, 'IPSECKEY')
for answer in ipseckeys:
b64_answer = base64.b64encode(answer.key)
log_info("IPSECKEY record found for '%s': %s"%(qstate.qinfo.qname_str,b64_answer))
leftwhack = 'ipsec whack --label "%s leftrsasigkey" --keyid "@%s" --pubkeyrsa "0s%s"'%(qstate.qinfo.qname_str, myname, mykey)
rightwhack = 'ipsec whack --label "%s rightrsasigkey" --keyid "@%s" --pubkeyrsa "0s%s"'%(qstate.qinfo.qname_str,qstate.qinfo.qname_str,b64_answer)
addwhack = 'ipsec whack --name %s --encrypt --tunnel --pfs --rsasig --host "%s" --updown "ipsec _updown" --id @%s --to --host "193.110.157.102" --updown "ipsec _updown" --id "@%s" --keyingtries "1" ' %(qstate.qinfo.qname_str, myip, myname, qstate.qinfo.qname_str)
upwhack = 'ipsec whack --initiate --name %s'%qstate.qinfo.qname_str
log_info(leftwhack)
log_info(rightwhack)
log_info(addwhack)
log_info(upwhack)
for cmd in ( leftwhack, rightwhack, addwhack, upwhack ):
status, result = commands.getstatusoutput(cmd)
log_info("Status:%s, Output: %s"%(status,result))
except:
log_info("ERROR in IPSECKEY record query for '%s' - ignoring for now"%qstate.qinfo.qname_str)
qstate.ext_state[id] = MODULE_WAIT_MODULE
return True
return True
if event == MODULE_EVENT_MODDONE:
#log_info("pythonmod: module we are waiting for is done")
qstate.ext_state[id] = MODULE_FINISHED
return True
log_err("pythonmod: BAD event")
qstate.ext_state[id] = MODULE_ERROR
return True
log_info("pythonmod: script loaded.")
More information about the Unbound-users
mailing list