"""
$Id: README.txt 29 2012-03-23 18:28:53Z bobnovas $
"""
The python/dnspython Validating Stub Resolver - vsResolver
vsResolver is a DNSSEC validating stub resolver, for Windows, linux and Mac - the prerequisites are that dnspython and pycrypto must be installed. I've also built a py2exe package for it on Windows 7 x64 that wraps the prerequisites up into a folder so that there is no need to install anything - it's self-contained. It should be possible to do the same for linux and Mac versions, so that there are no prerequistes for those platforms either.
vsResolver is a DNS validating stub resolver according to the Domain Name System Security Extensions (DNSSEC) as documented in RFC4033, RFC4034 and RFC4035. vsResolver requires at least a security aware recursive resolver against which it does queries. I test with unbound running on an Ubuntu box.
I can configure unbound in three different ways:
1) Security aware recursive resolver. In this mode, unbound does no crypto processing.
2) Validating recursive resolver in "permissive" mode. In this mode, unbound does crypto processing but returns bogus data (with the AD bit clear on bogus data). The crypto processing is essentially redundant but does prevent the unbound cache from being poisoned.
3) Validating recursive resolver in non-permissive mode. In this mode, unbound does crypto processing by default. vsResolver always queries with the CD (Checking Disabled) bit set, so that unbound does not do crypto processing for a vsResolver query. Unbound also returns all data, including bogus data.
vsResolver delivers the same results regardless of the way unbound is configured.
Here's the "self-test" output of vsResolver with unbound (in any of the above modes):
C: vsResolver.py 127.0.0.1 0
usgs.gov,A is NOERROR/SECURE
nist.gov,A is NOERROR/SECURE
comcast.net,A is NOERROR/SECURE
comcast.com,A is NOERROR/SECURE
comcast.org,A is NOERROR/SECURE
comcast.net,A is NOERROR/SECURE
dns101.comcast.net,A is NOERROR/SECURE
aaaaaaa.comcast.com,A is NXDOMAIN/SECURE
xyz.comcast.net,A is NXDOMAIN/SECURE
verizon.net,A is NOERROR/PROVABLY_INSECURE
bankofamerica.com,A is NOERROR/PROVABLY_INSECURE
shinkuro.net,A is NOERROR/SECURE
shinkuro.se,A is NOERROR/SECURE
shinkuro.org,A is NOERROR/SECURE
shinkuro.com,A is NOERROR/PROVABLY_INSECURE
shkx.org,A is NOERROR/PROVABLY_INSECURE
admin.shkx.org,A is NOERROR/PROVABLY_INSECURE
novas.us,A is NOERROR/PROVABLY_INSECURE
xyz.shinkuro.org,A is NXDOMAIN/PROVABLY_INSECURE
www.shinkuro.com,A is NOERROR/PROVABLY_INSECURE
www.shinkuro.org,A is NOERROR/PROVABLY_INSECURE
www.comcast.net,A is NOERROR/PROVABLY_INSECURE
www.comcast.com,A is NOERROR/PROVABLY_INSECURE
www.comcast.org,A is NOERROR/SECURE
customer.comcast.com,A is NOERROR/PROVABLY_INSECURE
customer.g.comcast.com,A is NOERROR/PROVABLY_INSECURE
test.dnssec-test.org,A is NXDOMAIN/SECURE
tjeb.nl,A is NOERROR/SECURE
ok.dnssec.tjeb.nl,A is NOERROR/SECURE
nods.dnssec.tjeb.nl,A is NOERROR/SECURE
ok.nods.dnssec.tjeb.nl,A is NOERROR/BOGUS *Exception*
sigexpired.dnssec.tjeb.nl,A is NOERROR/BOGUS *Exception*
signotincepted.dnssec.tjeb.nl,A is NOERROR/BOGUS *Exception*
unknownalgorithm.dnssec.tjeb.nl,A is NOERROR/BOGUS *Exception*
ok.nsec3.tjeb.nl,A is NOERROR/SECURE
bogussig.dnssec.tjeb.nl,A is NOERROR/BOGUS *Exception*
sources.org,A is NOERROR/PROVABLY_INSECURE
cha.ru,A is NOERROR/PROVABLY_INSECURE
0.217.88.in-addr.arpa,A is NOERROR/PROVABLY_INSECURE
cz,A is NOERROR/SECURE
cat,A is NOERROR/SECURE
badsign-a.testsub.dnssec-deployment.org,A is NOERROR/BOGUS *Exception*
Passed 42/42, PASSED
In "query" mode, vsResolver does a query and validates the result for a given input.
For example:
C: vsResolver.py 192.168.1.9 0 comcast.net A
comcast.net,A is NOERROR/SECURE
Finally, vsResolver has a verbose mode that mimics the dnssec-debugger.verisignlabs.com output.
For example:
C: vsResolver.py 192.168.1.9 1 www.shinkuro.org A
Found 2 DNSKEY records for .
DS=19036/sha256 verifies DNSKEY=19036/SEP
Found 1 RRSIGs over DNSKEY RRset
RRSIG=19036 and DNSKEY=19036 verifies the DNSKEY RRset
query for www.shinkuro.org/A
. is trusted until 2012-02-12 12:44:10.030000
Found 2 DS records for org in the . zone
Found 1 RRSIGs over DS RRset
RRSIG=51201 and DNSKEY=51201 verifies the DS RRset
Found 4 DNSKEY records for org
DS=21366/sha256 verifies DNSKEY=21366/SEP
DS=21366/sha1 verifies DNSKEY=21366/SEP
Found 2 RRSIGs over DNSKEY RRset
RRSIG=21366 and DNSKEY=21366 verifies the DNSKEY RRset
Found 1 DS records for shinkuro.org in the org zone
Found 1 RRSIGs over DS RRset
RRSIG=55440 and DNSKEY=55440 verifies the DS RRset
Found 2 DNSKEY records for shinkuro.org
DS=31129/sha1 verifies DNSKEY=31129/SEP
Found 2 RRSIGs over DNSKEY RRset
RRSIG=31129 and DNSKEY=31129 verifies the DNSKEY RRset
Found 0 DS records for www.shinkuro.org in the shinkuro.org zone
Found 1 RRSIGs over DNAME RRset
RRSIG=53703 and DNSKEY=53703 verifies the DNAME RRset
shinkuro.org is a DNAME to shinkuro.info
. is trusted until 2012-02-12 12:44:10.030000
Found 2 DS records for info in the . zone
Found 1 RRSIGs over DS RRset
RRSIG=51201 and DNSKEY=51201 verifies the DS RRset
Found 4 DNSKEY records for info
DS=54531/sha1 verifies DNSKEY=54531/SEP
DS=54531/sha256 verifies DNSKEY=54531/SEP
Found 2 RRSIGs over DNSKEY RRset
RRSIG=5570 and DNSKEY=5570 verifies the DNSKEY RRset
Found 2 DS records for shinkuro.info in the info zone
Found 1 RRSIGs over DS RRset
RRSIG=5570 and DNSKEY=5570 verifies the DS RRset
Found 2 DNSKEY records for shinkuro.info
DS=41101/sha1 verifies DNSKEY=41101/SEP
DS=41101/sha256 verifies DNSKEY=41101/SEP
Found 2 RRSIGs over DNSKEY RRset
RRSIG=38847 and DNSKEY=38847 verifies the DNSKEY RRset
Found 0 DS records for www.shinkuro.info in the shinkuro.info zone
Found 1 RRSIGs over DNAME RRset
RRSIG=38847 and DNSKEY=38847 verifies the DNAME RRset
shinkuro.info is a DNAME to shinkuro.com
. is trusted until 2012-02-12 12:44:10.030000
Found 1 DS records for com in the . zone
Found 1 RRSIGs over DS RRset
RRSIG=51201 and DNSKEY=51201 verifies the DS RRset
Found 2 DNSKEY records for com
DS=30909/sha256 verifies DNSKEY=30909/SEP
Found 1 RRSIGs over DNSKEY RRset
RRSIG=30909 and DNSKEY=30909 verifies the DNSKEY RRset
Found 1 RRSIGs over NSEC3 RRset
RRSIG=54350 and DNSKEY=54350 verifies the NSEC3 RRset
Found 1 RRSIGs over SOA RRset
RRSIG=54350 and DNSKEY=54350 verifies the SOA RRset
Found 1 RRSIGs over NSEC3 RRset
RRSIG=54350 and DNSKEY=54350 verifies the NSEC3 RRset
validate_name got NegativeProved: (shinkuro.com has no DS in com, SECURE)
www.shinkuro.org,A is NOERROR/PROVABLY_INSECURE
www.shinkuro.com. A RR has value 66.92.164.104
www.shinkuro.com. A RR has value 70.88.139.89
The vsResolver API is simple and is demonstrated in the main() program in
vsResolver.py. Here are the steps for using vsResolver:
1. Instantiate a dnspython Resolver object, with EDNS enabled and pointing to at least a security aware recursive resolver.
2. Pass that to ValidatingStubResolver, along with an optional logging function.
3. call query(name, rdtype, rdclass) on the ValidatingStubResolver object, passing the name of the domain, the rdata type of the record (e.g., 'A' for ipv4 address record), and the rdata class of the record (e.g., 'IN') for which you are querying.
4. query() returns a dnspython dns.resolver.Answer object that is identical to the object that dnspython dns.Resolver.query() returns, except that it is decorated with a new securityOutcome field, which is one of the following constants: BOGUS, PROVABLY_INSECURE, SECURE.
There are 3 behavours or overall operating modes that ValidatingStubResolver can be set to. These are:
0: Permissive - return all results regardless of securityOutcome
1: *NoBogus - return results that are not BOGUS. BOGUS results raise a BadResult Exception. NoBogus is the DEFAULT behavior if none is specified.
2: SecureOnly - return results that are SECURE. BOGUS and PROVABLY_INSECURE results raise a BadResult Exception
The BadResult exception has an actualResult field that provides the result (that would have been returned).
The ValidatingStubResolver is essentially backwards compatible with dns.Resolver. ValidatingStubResolver provides a query() method that is indistiguishable - there is an additional field in dns.Resolver.Answer, and ValidatingStubResolver does raise additional exceptions. A difference is that ValidatingStubResolver returns results for NXDOMAIN whereas dns.Resolver didn't. But in DNSSEC, it's knowable if you should have gotten an answer but didn't (a BOGUS NXDOMAIN).
That's pretty much it.
Changes:
2/29/2012 - Added flaggableResolver.py, which overrides dns.Resolver.Query. This eliminates the need to patch dnspython and provides 3 features that dns.Resolver.query does not:
- return_response_on_nxdomain - need a response for the NSEC/NSEC3 records
- flags - specify CD so that a validating recursive resolver does not do validation and does return all records. This allows for running the recursive resolver that vsResolver uses as a validating resolver (but tells that resolver not to validate).
- fixes a bug wherein an answer with rrset null raises an exception.
3/23/2012
- added logging to FlaggableResolver, log queries
- fixed bug in nameHolder reverseDirection so it now works correctly when called mulitple times. added test case to test this.
- added RRSetSource.has_RRSIG() method
- major revision to vsResolver.py to fix several bad bugs in validation. Added 2 test cases. Passes all test cases.
Source: README.txt, updated 2012-03-23