Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get validate DNSSEC with python?

Tags:

python

dns

dnssec

As the title says I want to programmatically check if a DNS response for a domain are protected with DNSSEC.
How could I do this?

It would be great, if there is a pythonic solution for this.

UPDATE: changed request to response, sorry for the confusion

like image 547
Thorben Avatar asked Nov 07 '22 17:11

Thorben


2 Answers

Using a DNS resolver (e.g. dnspython), you can query the domain for its DNSKEY RRset and turn on the DO (dnssec OK) query flag. If the query succeeds, the answer will have the AD (authenticated data) flag set and will contain the RRSIG signatures for the zone (if it is signed).

Update: a basic example using dnspython

import dns.name
import dns.query
import dns.dnssec
import dns.message
import dns.resolver
import dns.rdatatype

# get nameservers for target domain
response = dns.resolver.query('example.com.',dns.rdatatype.NS)

# we'll use the first nameserver in this example
nsname = response.rrset[0].to_text() # name
response = dns.resolver.query(nsname,dns.rdatatype.A)
nsaddr = response.rrset[0].to_text() # IPv4

# get DNSKEY for zone
request = dns.message.make_query('example.com.',
                                 dns.rdatatype.DNSKEY,
                                 want_dnssec=True)

# send the query
response = dns.query.udp(request,nsaddr)
if response.rcode() != 0:
    # HANDLE QUERY FAILED (SERVER ERROR OR NO DNSKEY RECORD)

# answer should contain two RRSET: DNSKEY and RRSIG(DNSKEY)
answer = response.answer
if len(answer) != 2:
    # SOMETHING WENT WRONG

# the DNSKEY should be self signed, validate it
name = dns.name.from_text('example.com.')
try:
    dns.dnssec.validate(answer[0],answer[1],{name:answer[0]})
except dns.dnssec.ValidationFailure:
    # BE SUSPICIOUS
else:
    # WE'RE GOOD, THERE'S A VALID DNSSEC SELF-SIGNED KEY FOR example.com
like image 136
isedev Avatar answered Nov 14 '22 09:11

isedev


To see if a particular request is protected, look at the DO flag in the request packet. Whatever language and library you use to interface to DNS should have an accessor for it (it may be called something else, like "dnssec").

The first answer is correct but incomplete if you want to know if a certain zone is protected. The described procedure will tell you if the zone's own data is signed. In order to check that the delegation to the zone is protected, you need to ask the parent zone's name servers for a (correctly signed) DS record for the zone you're interested in.

like image 45
Calle Dybedahl Avatar answered Nov 14 '22 09:11

Calle Dybedahl