""" Basic checks for CNAME following. - Query for CNAME, NSEC, RRSIG is not followed. - Query for ANY meta type is not followed. - Query for any other type is followed. """ from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("follow", storage=".") t.link(zone, knot) t.start() # follow CNAME (type exists) resp = knot.dig("test.follow", "AAAA") resp.check(rcode="NOERROR", flags="AA") resp.check_rr("answer", "test.follow", "CNAME") resp.check_rr("answer", "follow", "AAAA") resp.check_empty("authority") # follow CNAME (type doesn't exist) resp = knot.dig("test.follow", "TXT")
def test_expire(zone, server): resp = server.dig(zone[0].name, "SOA") resp.check(rcode="SERVFAIL") def break_xfrout(server): with open(server.confile, "r+") as f: config = f.read() f.seek(0) f.truncate() config = config.replace(" acl:", " #acl:") f.write(config) t = Test(tsig=False) # this zone has refresh = 1s, retry = 1s and expire = 8s zone = t.zone("example.", storage=".") EXPIRE_SLEEP = 15 master = t.server("knot") slave = t.server("knot") slave.tcp_idle_timeout = "1s" t.link(zone, master, slave) t.start() master.zone_wait(zone) slave.zone_wait(zone) # expire by shutting down the master master.stop()
#!/usr/bin/env python3 '''Test for response to IXFR request with newer serial''' from dnstest.utils import * from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("example.com.") t.link(zone, knot, ixfr=True) t.start() serial_init = knot.zone_wait(zone) resp = knot.dig("example.com", "IXFR", serial=serial_init + 1) resp.check_xfr() compare(resp.msg_count(), 1, "Only one message") compare(resp.count("SOA"), 1, "Only one RR in Answer section") compare(resp.count("ANY"), 1, "Only one RR in the whole message.") t.end()
#!/usr/bin/env python3 '''TTL mismatch test''' from dnstest.utils import * from dnstest.test import Test t = Test() zone = t.zone("example.com.") master = t.server("knot") t.link(zone, master, ddns=True) t.start() # Add new RR with different TTL to a RRSet that is already in the zone # The UPDATE should be REFUSED check_log("Add RR with different TTL") up = master.update(zone) up.add("mail.example.com.", 1000, "A", "1.2.3.4") up.send("REFUSED") resp = master.dig("mail.example.com.", "A") resp.check_record(section="answer", rtype="A", ttl="3600", rdata="192.0.2.3") resp.check_record(section="answer", rtype="A", nordata="1.2.3.4") # Try to add two RRs belonging to one RRSet, but with different TTLs # The UPDATE should be REFUSED # This also tests rollback in case of addition
#!/usr/bin/env python3 '''Test insecure<->secure delegation transitions with NSEC3PARAM changes.''' import random from dnstest.test import Test t = Test() master = t.server("knot") zones = t.zone("example.") t.link(zones, master) master.dnssec(zones[0]).enable = True master.dnssec(zones[0]).nsec3 = True master.dnssec(zones[0]).nsec3_opt_out = True master.dnssec(zones[0]).nsec3_iters = 1 t.start() master.zones_wait(zones) master.dnssec(zones[0]).nsec3_iters = 2 master.gen_confile() master.reload() t.sleep(8) up = master.update(zones) up.add("b.example.", 3600, "DS", "57855 5 1 B6DCD485719ADCA18E5F3D48A2331627FDD3636B") up.send()
#!/usr/bin/env python3 '''Test that removal of nonexisting or addition of existing record over IXFR is not accepted by a slave''' from dnstest.test import Test from dnstest.utils import * t = Test() master = t.server("knot") slave = t.server("knot") zone = t.zone("existing.", storage=".") t.link(zone, master, slave, ixfr=True) slave.update_zonefile(zone, version="slave0") t.start() serial = master.zone_wait(zone) slave.zone_wait(zone) # Check that removal of nonexisting record is not accepted master.update_zonefile(zone, version=1) master.reload() serial = slave.zone_wait(zone, serial) if not slave.log_search("no such record in zone found" ) or not slave.log_search("fallback to AXFR"):
#!/usr/bin/env python3 '''Test for loading of dumped zone''' from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") reference = t.server("bind") zones = t.zone_rnd(4) + t.zone(".") + t.zone("records.") t.link(zones, master, slave) t.link(zones, reference) t.start() # Wait for servers. master.zones_wait(zones) slave.zones_wait(zones) reference.zones_wait(zones) # Dump zones on slave. slave.flush(wait=True) # Compare master with reference server t.xfr_diff(reference, master, zones) # Compare slave with reference server t.xfr_diff(reference, slave, zones)
#!/usr/bin/env python3 '''Test for EDNS0 UDP payload size''' from dnstest.test import Test t = Test() knot = t.server("knot") bind = t.server("bind") zones = t.zone("flags.") + t.zone("example.", "example.zone.nsec", storage=".") t.link(zones, knot) t.link(zones, bind) t.start() # TC - TXT record doesn't fit into UDP message. resp = knot.dig("513resp.flags", "TXT", udp=True) resp.check(flags="TC") resp.cmp(bind, authority=False) # Knot puts SOA compared to Bind! # no TC - UDP message is extended using EDNS0/payload. resp = knot.dig("513resp.flags", "TXT", udp=True, bufsize=600) resp.check(noflags="TC") resp.cmp(bind) # no TC - UDP message is extended using EDNS0/payload just for answer. resp = knot.dig("513resp.flags", "TXT", udp=True, bufsize=524) resp.check(noflags="TC")
#!/usr/bin/env python3 '''Test for dropping of out of zone records during incoming XFR''' from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") zone = t.zone("out-of-zone.") t.link(zone, master, slave) t.start() master.zones_wait(zone) slave.zones_wait(zone) t.xfr_diff(master, slave, zone) t.end()
#!/usr/bin/env python3 '''Test for loading of dumped zone''' from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") reference = t.server("bind") zones = t.zone_rnd(10) + t.zone(".") + t.zone("wild.") + t.zone("cname-loop.") t.link(zones, master, slave) t.link(zones, reference) t.start() # Wait for AXFR and dump zones. master.zones_wait(zones) slave.zones_wait(zones) slave.flush() # Stop master. master.stop() # Reload dumped zone files. slave.stop() slave.start()
#!/usr/bin/env python3 '''Test for signing a zone with wierd records.''' from dnstest.utils import * from dnstest.test import Test t = Test() master = t.server("knot") zone = t.zone("records.") t.link(zone, master) # Enable autosigning. master.dnssec_enable = True master.gen_key(zone, ksk=True, alg="RSASHA1") master.gen_key(zone, alg="RSASHA1") master.gen_confile() t.start() master.zone_wait(zone) t.sleep(1) master.flush() t.sleep(1) # Verify signed zone file. master.zone_verify(zone) t.stop()
#!/usr/bin/env python3 """Test for record removal over IXFR to slave zone which doesn't contain this record""" from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") zone = t.zone("existing.", storage=".") t.link(zone, master, slave, ixfr=True) # Remove the record from slave zone file (no SOA serial change). slave.update_zonefile(zone, version=2) t.start() # Wait for zones. serial = master.zone_wait(zone) slave.zone_wait(zone) # Update master file without the record (new SOA serial). master.update_zonefile(zone, version=1) master.reload() # Wait for zones and compare them. master.zone_wait(zone, serial) slave.zone_wait(zone, serial)
#!/usr/bin/env python3 '''Test for support of obsolete records over XFR''' from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") zone = t.zone("obsolete.", storage=".") t.link(zone, master, slave) t.start() master.zones_wait(zone) slave.zones_wait(zone) t.xfr_diff(master, slave, zone) t.end()
#!/usr/bin/env python3 '''Test for loading non-existing zone file''' from dnstest.test import Test t = Test() master = t.server("knot") zones = t.zone("notexist.", exists=False) + t.zone("example.com.") t.link(zones, master) t.start() # Check if the server is answering and zone _isn't_ loaded resp = master.dig("notexist.", "SOA", udp=True) resp.check(rcode="SERVFAIL") # Unloadable zone, but in the zone database # Check if the server is answering and zone is unknown resp = master.dig("xfiles.", "SOA", udp=True) resp.check(rcode="REFUSED") # The other zone should answer without problem resp = master.dig("example.com.", "SOA", udp=True) resp.check(rcode="NOERROR") # Stop master. master.stop()
import random def check_keys(server, zone_name, expect_keys): cmd = Popen([dnstest.params.keymgr_bin, "-d", server.dir + "/keys", zone_name, "list"], stdout=PIPE, stderr=PIPE, universal_newlines=True) (stdout, stderr) = cmd.communicate() lines = len(stdout.splitlines()) if lines != expect_keys: set_err("CHECK # of KEYS (%d != %d)" % (lines, expect_keys)) t = Test() master = t.server("knot") slave = t.server("knot") # Zone setup zone = t.zone("example.com.") + t.zone("catalog1.", storage=".") t.link(zone, master, slave, ixfr=True) master.zones["catalog1."].catalog = True slave.zones["catalog1."].catalog = True if random.choice([True, False]): slave.dnssec(zone[1]).enable = True else: slave.add_module(zone[1], ModOnlineSign(algorithm="ECDSAP256SHA256", single_type_signing=False)) for zf in glob.glob(t.data_dir + "/*.zone"): shutil.copy(zf, master.dir + "/master") t.start()
#!/usr/bin/env python3 '''Test for loading of zone containing mismatched TTLs''' from dnstest.test import Test t = Test() master = t.server("knot") zone = t.zone("ttl-mismatch", storage=".") t.link(zone, master) t.start() # Just check if the zone was loaded. It should be refused on master. resp = master.dig(zone, "SOA") resp.check(rcode="REFUSED", flags="QR", noflags="AA TC AD RA") t.end()
#!/usr/bin/env python3 '''NSEC test based on RFC-4035 example.''' from dnstest.test import Test t = Test() knot = t.server("knot") knot.DIG_TIMEOUT = 2 bind = t.server("bind") zone = t.zone("example.", "example.zone.nsec", storage=".") t.link(zone, knot) t.link(zone, bind) t.start() # B1. Answer. resp = knot.dig("x.w.example", "MX", dnssec=True) resp.check(rcode="NOERROR", flags="QR AA", eflags="DO") resp.cmp(bind) # B2. Name Error. resp = knot.dig("ml.example", "A", dnssec=True) resp.check(rcode="NXDOMAIN", flags="QR AA", eflags="DO") resp.cmp(bind) # B3. No Data Error. resp = knot.dig("ns1.example", "MX", dnssec=True) resp.check(rcode="NOERROR", flags="QR AA", eflags="DO")
#!/usr/bin/env python3 '''Test for loading of NSEC records with upper-case letters in rdata.''' from dnstest.test import Test t = Test() knot = t.server("knot") bind = t.server("bind") zone = t.zone("rdatacase.", "rdatacase.zone.signed", storage=".") t.link(zone, knot) t.link(zone, bind) t.start() knot.zones_wait(zone) bind.zones_wait(zone) t.xfr_diff(knot, bind, zone) t.end()
#!/usr/bin/env python3 '''NSEC test based on RFC-4035 example.''' from dnstest.test import Test t = Test() knot = t.server("knot") knot.DIG_TIMEOUT = 2 bind = t.server("bind") zone = t.zone("example.", "example.zone.nsec", storage=".") t.link(zone, knot) t.link(zone, bind) t.start() # B1. Answer. resp = knot.dig("x.w.example", "MX", dnssec=True) resp.check(rcode="NOERROR", flags="QR AA", eflags="DO") resp.cmp(bind) # B2. Name Error. resp = knot.dig("ml.example", "A", dnssec=True) resp.check(rcode="NXDOMAIN", flags="QR AA", eflags="DO") resp.cmp(bind) # B3. No Data Error. resp = knot.dig("ns1.example", "MX", dnssec=True) resp.check(rcode="NOERROR", flags="QR AA", eflags="DO") resp.cmp(bind)
Basic checks of Additional section content. - Query into a delegation scope adds glue into additionals. - Query for NS/MX/SRV adds target A+AAAA into additionals. - Query for other types (like PTR) does NOT cause lookup of additionals. - Query for NS/MX/SRV pointing to CNAME does NOT cause lookup of additionals. """ from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("test", storage=".") t.link(zone, knot) t.start() # NS authoritative resp = knot.dig("test", "NS") resp.check(rcode="NOERROR", flags="AA") resp.check_rr("answer", "test", "NS") resp.check_rr("additional", "a.ns.test", "A") resp.check_rr("additional", "a.ns.test", "AAAA") resp.check_rr("additional", "b.ns.test", "AAAA") # NS delegation
''' Check 'dnstap' query module functionality. ''' import os import re from dnstest.test import Test from dnstest.module import ModDnstap from dnstest.utils import * t = Test() ModDnstap.check() # Initialize server configuration knot = t.server("knot") zone = t.zone("flags.") t.link(zone, knot) # Configure 'dnstap' module for all queries (default). dflt_sink = t.out_dir + "/all.tap" knot.add_module(None, ModDnstap(dflt_sink)) # Configure 'dnstap' module for flags zone only. flags_sink = t.out_dir + "/flags.tap" knot.add_module(zone, ModDnstap(flags_sink)) t.start() dflt_qname = "dnstap_default_test" resp = knot.dig(dflt_qname + ".example", "NS") flags_qname = "dnstap_flags_test" resp = knot.dig(flags_qname + ".flags", "NS")
#!/usr/bin/env python3 ''' Test for loading records with RDATA and owners differing only in case ''' from dnstest.utils import * from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("duplicates.", storage=".") t.link(zone, knot) t.start() knot.zones_wait(zone) # Request AXFR from Knot resp = knot.dig("duplicates.", "AXFR") # If Knot has not properly handled the case, there will be some redundant record count = 0 for msg in resp.resp: count += len(msg.answer) compare(count, 6, "AXFR record count") t.end()
#!/usr/bin/env python3 '''Test for maximum UDP payload size with respect to IP family''' from dnstest.test import Test t = Test() server4 = t.server("knot", address=4) server6 = t.server("knot", address=6) zone = t.zone("flags.") # Set common payload limit for 512-byte message with 11-byte EDNS section. server4.max_udp_payload = 523 server6.max_udp_payload = 523 t.link(zone, server4) t.link(zone, server6) t.start() # Check common limit if 512 fits and 513 does not. resp = server4.dig("512resp.flags", "TXT", udp=True, bufsize=4096) resp.check(noflags="TC") resp = server4.dig("513resp.flags", "TXT", udp=True, bufsize=4096) resp.check(flags="TC") resp = server6.dig("512resp.flags", "TXT", udp=True, bufsize=4096) resp.check(noflags="TC") resp = server6.dig("513resp.flags", "TXT", udp=True, bufsize=4096)
#!/usr/bin/env python3 '''Test for empty rdata loading.''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("knot") zone = t.zone("empty.", storage=".") t.link(zone, master, slave) t.start() master.zones_wait(zone) slave.zones_wait(zone) slave.flush() t.sleep(1) t.end()
'''Test for flush event''' from dnstest.utils import * from dnstest.test import Test import os FLUSH_SLEEP = 5.5 t = Test() master = t.server("bind") slave = t.server("knot") slave.zonefile_sync = "5s" zone = t.zone("example.") zone_path = slave.dir + "/slave/" + zone[0].file_name t.link(zone, master, slave) t.start() slave.stop() try: os.remove(zone_path) except: pass slave.start() slave.zone_wait(zone) #check that the zone file has not been flushed if os.path.exists(zone_path): check_log("Zonefile created too soon: " + str(os.stat(zone_path).st_ctime))
#!/usr/bin/env python3 ''' Test for loading badly formed record ''' from dnstest.test import Test t = Test() master = t.server("knot") zone = t.zone("badrecord.", "badrecord.zone", storage=".") t.link(zone, master) t.start() # Check if the server is answering and zone _isn't_ loaded resp = master.dig("badrecord.", "SOA", udp=True) # @note Either REFUSED or SERVFAIL is fine, Knot treats unloadable # zone as expired while the older version ignored such zone. resp.check(rcode="SERVFAIL") # Stop master. master.stop() t.end()
import random import dns.exception import dns.rcode import dns.tsig from dnstest.utils import * from dnstest.test import Test t = Test(tsig=False) master = t.server("knot") ZONE = "example.com." HUGE = "huge.%s" % ZONE zone = t.zone(ZONE, storage=".") rndfix = random.randint(1, 65000) for i in range(1, 3000): zone[0].append_rndAAAA(HUGE, rndfix, i) t.link(zone, master) t.start() master.zone_wait(zone) resp = master.dig(HUGE, "AAAA", udp=True) resp.check(rcode="NOERROR", flags="TC") resp.check_count(0, section="answer")
#!/usr/bin/env python3 '''Test for loading of zone containing mismatched TTLs in RRSet''' from dnstest.test import Test t = Test() master = t.server("knot") zone = t.zone("ttl-mismatch", storage=".") t.link(zone, master) t.start() master.zones_wait(zone) resp = master.dig("ttl.ttl-mismatch.", "A") resp.check(rcode="NOERROR", flags="QR AA", noflags="TC AD RA", ttl=7200) t.end()
#!/usr/bin/env python3 '''Test for reload of a changed zone (serial up, nochange, serial down). ''' from dnstest.test import Test from dnstest.utils import set_err, detail_log t = Test() master = t.server("knot") # Zone setup zone = t.zone("serial.", storage = ".") t.link(zone, master, ixfr = True) t.start() # Load zones serial = master.zone_wait(zone) def reload_zone(serial, version): master.update_zonefile(zone, version) master.reload() new_serial = master.zone_wait(zone) if new_serial != serial: set_err("SOA MISMATCH") detail_log("!Zone '%s' SOA serial %s != %s" % (zone[0].name, new_serial, serial)) return resp = master.dig("new-record%d.%s" % (version, zone[0].name), "A") resp.check(rcode="NOERROR")
#!/usr/bin/env python3 '''Check that only-SOA-serial-incremented zone file change is correctly detected and signed.''' from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("example.com")[0] t.link([zone], knot, ixfr=True) knot.dnssec(zone).enable = True t.start() serial = knot.zone_wait(zone) knot.flush(zone, wait=True) knot.zone_verify(zone) knot.zones[zone.name].zfile.update_soa(serial=int(serial)+1) knot.reload() knot.zone_wait(zone, serial) knot.flush(zone, wait=True) knot.zone_verify(zone) t.end()
#!/usr/bin/env python3 '''Test for AXFR-style IXFR''' from dnstest.test import Test import os t = Test(tsig=False) master = t.server("knot") slave = t.server("knot") zone = t.zone("xfr", storage=".") t.link(zone, master, slave, journal_content="none") t.start() serial = master.zone_wait(zone) # update zone with small change master.update_zonefile(zone, version=1) master.reload() master.zone_wait(zone, serial) # check that master properly sends AXFR-style IXFR t.check_axfr_style_ixfr(master, "xfr", serial) serial = slave.zone_wait(zone, serial) t.xfr_diff(master, slave, zone) # update zone with large change (3 messages worth)
from dnstest.test import Test from dnstest.module import ModSynthRecord t = Test() ModSynthRecord.check() # Zone indexes FWD = 0 REV4 = 1 REV6 = 2 REV = 3 # Initialize server configuration knot = t.server("knot") zone = t.zone("forward.", storage=".") + \ t.zone("1.168.192.in-addr.arpa.", storage=".") + \ t.zone("1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa.", storage=".") + \ t.zone("ip6.arpa.", storage=".") t.link(zone, knot) # Enable DNSSEC for z in zone: knot.dnssec(z).enable = True # Configure 'synth_record' modules for auto forward/reverse zones knot.add_module(zone[FWD], ModSynthRecord("forward", None, None, "192.168.0.1")) knot.add_module( zone[FWD], ModSynthRecord("forward", "dynamic-", "900",
#!/usr/bin/env python3 """ Test of zone-in-journal dynamic configuration. """ from dnstest.utils import * from dnstest.test import Test t = Test() knot = t.server("knot") zone = t.zone("example.") t.link(zone, knot) t.start() knot.zone_wait(zone) knot.ctl("conf-begin") knot.ctl("conf-set zone[%s].journal-content all" % zone[0].name) knot.ctl("conf-commit") t.sleep(2) knot.stop() knot.zones[zone[0].name].journal_content = "all" knot.zonefile_load = "none" knot.gen_confile() knot.zones[zone[0].name].zfile.remove() # just to make sure knot.start()
#!/usr/bin/env python3 '''Test for IXFR from Knot to Knot''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("knot") zones = t.zone_rnd(5, records=50) + t.zone("records.") t.link(zones, master, slave, ixfr=True) t.start() # Wait for AXFR to slave server. serials_init = master.zones_wait(zones) slave.zones_wait(zones) serials_prev = serials_init for i in range(4): # Update zone files on master. for zone in zones: master.update_zonefile(zone, random=True) master.reload() # Wait for IXFR to slave. serials = master.zones_wait(zones, serials_prev) slave.zones_wait(zones, serials_prev) serials_prev = serials
(first_bitmap, nsec3_bitmap, msg)) if first_bitmap != nsec3_bitmap: set_err("NSEC3 bitmap for '%s'" % msg) first_flags = first_nsec3.split()[5] if first_flags != str(opt_out_flag): set_err("NSEC3 opt-out flag %s != %s for '%s'" % (first_flags, str(opt_out_flag), msg)) detail_log(SEP) master.zone_backup(zone, flush=True) master.zone_verify(zone) master = t.server("knot") zone = t.zone(zone_name) t.link(zone, master) master.dnssec(zone).enable = True master.dnssec(zone).nsec3 = True master.dnssec(zone).nsec3_iters = 2 master.dnssec(zone).nsec3_salt_len = 8 master.dnssec(zone).nsec3_opt_out = False t.start() master.zones_wait(zone) master.zone_backup(zone, flush=True) master.zone_verify(zone)
#!/usr/bin/env python3 '''Test for knotc zone-notify''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("knot") zone = t.zone("notify.", storage=".") t.link(zone, master, slave) t.start() master.zone_wait(zone) slave.zone_wait(zone) slave.stop() master.update_zonefile( zone, version=1) # notify doesn't succeed while slave is offline master.reload() master.zone_wait(zone) slave.start( ) # slave starts with older version of zone and doesn't attempt refersh since it's in timers slave.zone_wait(zone)
def writef(filename, contents): with open(filename, "w") as f: f.write(contents) t = Test() knot = t.server("knot") ZONE = "example.com." FUTURE = 55 TICK = 5 STARTUP = 10 zone = t.zone(ZONE) t.link(zone, knot) knot.zonefile_sync = 24 * 60 * 60 knot.dnssec(zone).enable = True knot.dnssec(zone).manual = True knot.dnssec(zone).alg = "ECDSAP384SHA384" knot.dnssec(zone).dnskey_ttl = 2 knot.dnssec(zone).zone_max_ttl = 3 knot.dnssec(zone).zsk_lifetime = STARTUP + 6 * TICK # see ksk1 lifetime knot.dnssec(zone).ksk_lifetime = 300 # this can be possibly left also infinity knot.dnssec(zone).propagation_delay = TICK - 2 knot.dnssec(zone).offline_ksk = "on" knot.dnssec(zone).cds_publish = "rollover" knot.dnssec(zone).rrsig_lifetime = 15
#!/usr/bin/env python3 '''Test for IXFR from Knot to Knot''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("knot") zones = t.zone_rnd(5, records=50) + t.zone("records.") t.link(zones, master, slave, ixfr=True) if master.valgrind: master.tcp_io_timeout = 2000 slave.tcp_remote_io_timeout = 8000 t.start() # Wait for AXFR to slave server. serials_init = master.zones_wait(zones) slave.zones_wait(zones) serials_prev = serials_init for i in range(4): # Update zone files on master. for zone in zones: master.update_zonefile(zone, random=True) master.reload() # Wait for IXFR to slave.
verify(master, zone, dnssec=True) # Delete and add NSEC3PARAM check_log("Delete and add NSEC3PARAM") up = master.update(zone) up.delete("ddns.", "NSEC3PARAM", "1 0 10 CAFEBABE") up.add("ddns.", "0", "NSEC3PARAM", "1 0 10 BADDCAFE") up.send("NOERROR") resp = master.dig("ddns", "NSEC3PARAM") resp.check(rcode="NOERROR", nordata="1 0 10 CAFEBABE") resp.check(rcode="NOERROR", rdata="1 0 10 BADDCAFE") verify(master, zone, dnssec=True) # Normal deletion tested in DNSSEC tests zone = t.zone("ddns.", storage=".") master_plain = t.server("knot") t.link(zone, master_plain, ddns=True) master_nsec = t.server("knot") t.link(zone, master_nsec, ddns=True) master_nsec.dnssec_enable = True master_nsec.gen_key(zone, ksk=True, alg="RSASHA256") master_nsec.gen_key(zone, alg="RSASHA256") master_nsec3 = t.server("knot") t.link(zone, master_nsec3, ddns=True) master_nsec3.dnssec_enable = True master_nsec3.enable_nsec3(zone) master_nsec3.gen_key(zone, ksk=True, alg="RSASHA256")
#!/usr/bin/env python3 ''' Check 'dnsproxy' query module functionality. ''' from dnstest.test import Test from dnstest.module import ModDnsproxy import dnstest.keys t = Test(tsig=False) ModDnsproxy.check() # Initialize server configuration zone_common1 = t.zone("test", storage=".", file_name="test.local_zone") zone_common2 = t.zone("test", storage=".", file_name="test.remote_zone") zone_local = t.zone_rnd(1) zone_remote = t.zone_rnd(1) key1 = dnstest.keys.Tsig(name="key1", alg="hmac-sha1", key="Zm9v") local = t.server("knot", tsig=key1) t.link(zone_common1, local) t.link(zone_local, local) key2 = dnstest.keys.Tsig(name="key2", alg="hmac-sha1", key="YmFy") remote = t.server("knot", tsig=key2) t.link(zone_common2, remote) t.link(zone_remote, remote) def fallback_checks(server, zone_local, zone_remote): # Local preferred OK, try with local TSIG. resp = server.dig("dns1.test", "A", tsig=key1)
#!/usr/bin/env python3 '''Test for signing a zone with weird records.''' from dnstest.utils import * from dnstest.test import Test t = Test() master = t.server("knot") zone = t.zone("records.") t.link(zone, master) master.dnssec(zone).enable = True t.start() master.zone_wait(zone) resp = master.dig("nxdomain.records", "A", udp=False, dnssec=True) resp.check_auth_soa_ttl(dnssec=True) resp = master.dig("mail.records.", "RRSIG", dnssec=True) resp.check_count(1, rtype="RRSIG") t.sleep(1) master.flush() t.sleep(1) # Verify signed zone file. master.zone_verify(zone) t.stop()
#!/usr/bin/env python3 """Test for AXFR from Bind to Knot""" from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") zones = t.zone_rnd(10) + t.zone(".") + t.zone("records.") t.link(zones, master, slave) t.start() master.zones_wait(zones) slave.zones_wait(zones) t.xfr_diff(master, slave, zones) t.end()
#!/usr/bin/env python3 '''Test for AXFR from Knot to Bind''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("bind") zones = t.zone_rnd(10) + t.zone(".") + t.zone("wild.") + \ t.zone("cname-loop.") + t.zone("records.") t.link(zones, master, slave) t.start() master.zones_wait(zones) slave.zones_wait(zones) t.xfr_diff(master, slave, zones) t.end()
#!/usr/bin/env python3 '''Test for empty rdata loading.''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("knot") zone = t.zone("empty.", storage=".") t.link(zone, master, slave) t.start() master.zones_wait(zone) slave.zones_wait(zone) slave.flush(wait=True) t.end()
from dnstest.params import get_binary # Find PROTOS binaries protos_bin = [ "c09-dns-query-r1.jar", "c09-dns-zonetransfer-r1.jar" ] protos_java_bin = get_binary("PROTOS_JAVA_BIN", "java") protos_query_bin = get_binary("PROTOS_QUERY_BIN", protos_bin[0]) protos_zonetransfer_bin = get_binary("PROTOS_ZONETRANSFER_BIN", protos_bin[1]) if not protos_java_bin: raise Skip("Java not found") if not protos_query_bin: raise Skip("'%s' PROTOS binary not found" % protos_bin[0]) t = Test(address=4, tsig=False) # PROTOS works on IPv4, no TSIG master = t.server("dummy") slave = t.server("knot") zone = t.zone("protos.invalid.", exists=False) t.link(zone, master, slave) # Update configuration t.start() ''' Run PROTOS test case with given parameters. ''' def protos_run(name, binfile, params): if not binfile: return check_call([protos_java_bin, "-jar", binfile] + params, stdout=open(master.fout, mode="w"), stderr=open(master.ferr, mode="w")) shutil.move(master.fout, master.fout + "." + name) shutil.move(master.ferr, master.ferr + "." + name) # Evaluate parameters
#!/usr/bin/env python3 '''Test for IXFR from Knot to Bind''' from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("bind") zones = t.zone_rnd(5, records=50) + t.zone("wild.") + \ t.zone("cname-loop.") + t.zone("records.") t.link(zones, master, slave, ixfr=True) t.start() # Wait for AXFR to slave server. serials_init = master.zones_wait(zones) slave.zones_wait(zones) serials_prev = serials_init for i in range(4): # Update zone files on master. for zone in zones: master.update_zonefile(zone, random=True) master.reload() t.sleep(5) # Wait for IXFR to slave.
def get_dnskeys(server, zones): return [ str(server.dig(z.name, "DNSKEY").resp.answer[0].to_rdataset()) for z in zones ] def test_added(server, zones, results): for (z, res) in zip(zones, results): resp = server.dig("added.%s" % z.name, "A") resp.check(rcode=res) t = Test() zones = t.zone("example.", storage=".") + t.zone("serial.", storage=".") master = t.server("knot") slave = t.server("knot") t.link(zones, master, slave) for z in zones: if random.choice([True, False]): master.dnssec(z).enable = True else: master.add_module(z, ModOnlineSign()) slave.zones[z.name].journal_content = "all" slave.zonefile_load = "none" backup_dir = master.dir + "/backup"
wait_for_rrsig_count(t, server, "DNSKEY", 1, 20) if before_keys < 2 or after_keys > 1: check_zone(server, zone, total_keys, 1, 1, 1, desc + ": old key retired") # else skip the test as we have no control on KSK and ZSK retiring asynchronously wait_for_dnskey_count(t, server, after_keys, 20) check_zone(server, zone, after_keys, 1, 1, 1, desc + ": old key removed") t = Test() ModOnlineSign.check() parent = t.server("knot") parent_zone = t.zone("com.", storage=".") t.link(parent_zone, parent) child = t.server("knot") child_zone = t.zone("example.com.") t.link(child_zone, child) def cds_submission(): cds = child.dig(ZONE, "CDS") cds_rdata = cds.resp.answer[0].to_rdataset()[0].to_text() up = parent.update(parent_zone) up.add(ZONE, 3600, "DS", cds_rdata) up.send("NOERROR")
mail A 192.0.2.3 AAAA 2001:DB8::3 new A 1.1.1.%d""" SERIALS = { "z1.": [0, 1, 2147483648, 4294967295, 0], "z2.": [0, 1, 2147483648, 4294967295, 1], "z3.": [0, 1, 2147483648, 4294967295, 2] } t = Test() master = t.server("knot") refer = t.server("bind") zones = [t.zone(z, storage=t.zones_dir, exists=False)[0] for z in SERIALS] for dname in SERIALS: sequence = SERIALS[dname] for index, serial in enumerate(sequence): fn = "%szone" % dname if index == 0 else "%szone.%d" % (dname, index) with open(os.path.join(t.zones_dir, fn), "w") as f: f.write(TEMPL % (dname, serial, index)) t.link(zones, master, ixfr=True) t.link(zones, refer, ixfr=True) t.start() master.zones_wait(zones) refer.zones_wait(zones)
check_log("non-apex DNSKEY addition") up = master.update(zone) up.add( "nonapex.ddns.", "3600", "DNSKEY", "256 3 5 AwEAAbs0AlA6xWQn/lECfGt3S6TaeEmgJfEVVEMh06iNMNWMRHOfbqLF h3N52Ob7trmzlrzGlGLPnAZJvMB8lsFGC5CtaLUBD+4xCh5tl5QifZ+y o+MJvPGlVQI2cs7aMWV9CyFrRmuRcJaSZU2uBz9KFJ955UCq/WIy5KqS 7qaKLzzN" ) up.send("NOERROR") resp = master.dig("nonapex.ddns.", "DNSKEY") resp.check( rcode="NOERROR", rdata= "256 3 5 AwEAAbs0AlA6xWQn/lECfGt3S6TaeEmgJfEVVEMh06iNMNWMRHOfbqLF h3N52Ob7trmzlrzGlGLPnAZJvMB8lsFGC5CtaLUBD+4xCh5tl5QifZ+y o+MJvPGlVQI2cs7aMWV9CyFrRmuRcJaSZU2uBz9KFJ955UCq/WIy5KqS 7qaKLzzN" ) zone = t.zone("ddns.", storage=".") master_plain = t.server("knot") t.link(zone, master_plain, ddns=True) master_nsec = t.server("knot") t.link(zone, master_nsec, ddns=True) master_nsec.dnssec(zone).enable = True master_nsec3 = t.server("knot") t.link(zone, master_nsec3, ddns=True) master_nsec3.dnssec(zone).enable = True master_nsec3.dnssec(zone).nsec3 = True master_nsec3.dnssec(zone).nsec3_opt_out = (random.random() < 0.5) t.start()
from dnstest.test import Test from dnstest.module import ModSynthRecord t = Test() ModSynthRecord.check() # Zone indexes FWD = 0 REV4 = 1 REV6 = 2 # Initialize server configuration knot = t.server("knot") zone = t.zone("forward.", storage=".") + \ t.zone("1.168.192.in-addr.arpa.", storage=".") + \ t.zone("1.6.b.0.0.0.0.0.0.2.6.2.ip6.arpa.", storage=".") t.link(zone, knot) # Enable DNSSEC knot.dnssec_enable = True for z in zone: knot.gen_key(z, ksk=True, alg="RSASHA256") knot.gen_key(z, alg="RSASHA256") # Configure 'synth_record' modules for auto forward/reverse zones knot.add_module(zone[FWD], ModSynthRecord("forward", None, None, "192.168.0.1")) knot.add_module(zone[FWD], ModSynthRecord("forward", "dynamic4-", "900", "192.168.1.0-192.168.1.127")) knot.add_module(zone[FWD], ModSynthRecord("forward", "dynamic6-", "900", "2620:0:b61::/52")) knot.add_module(zone[REV4], ModSynthRecord("reverse", "dynamic4-", "900", "192.168.1.0/25", "forward."))
'''Test for NSEC and NSEC3 fix after zone update (ddns, ixfr)''' from dnstest.utils import * from dnstest.test import Test from dnstest.keys import Keymgr import random t = Test() master0 = t.server("knot") master = t.server("knot") slave = t.server("knot") zones1 = t.zone_rnd(20, dnssec=False, records=1) + \ t.zone_rnd(20, dnssec=False, records=10) + \ t.zone_rnd(5, dnssec=False, records=100) + \ t.zone("records.") zone0 = t.zone("dk.", storage=".") zones = zones1 + zone0 t.link(zone0, master0, master) t.link(zones, master, slave) master.disable_notify = True slave.disable_notify = True for zone in zones: master.dnssec(zone).enable = True master.dnssec(zone).nsec3 = random.choice([True, False]) master.dnssec(zone).nsec3_iters = 2 master.dnssec(zone).nsec3_salt_len = random.choice([0, 1, 9, 64, 128, 255]) master.dnssec(zone).nsec3_opt_out = (random.random() < 0.5)
#!/usr/bin/env python3 '''Test for auto-rebootstrap if the slave zone file is invalid.''' from dnstest.test import Test t = Test() master = t.server("bind") slave = t.server("knot") zone = t.zone("invalid.", storage=".") t.link(zone, master, slave) # Create invalid zone file. slave.update_zonefile(zone, version=1) t.start() # Wait for zones and compare them. master.zones_wait(zone) slave.zones_wait(zone) t.xfr_diff(master, slave, zone) t.end()
#!/usr/bin/env python3 '''Test for reload of a changed zone (serial up, nochange, serial down).''' from dnstest.test import Test from dnstest.utils import set_err, detail_log import random t = Test() master = t.server("knot") # Zone setup zone = t.zone("serial.", storage=".") t.link(zone, master, ixfr=True) t.start() # Load zones serial = master.zone_wait(zone) def reload_zone(version, exp_serial, exp_version): master.update_zonefile(zone, version) if random.random() < 0.5: master.reload() else: master.ctl(random.choice(["-f", " "]) + " zone-reload " + zone[0].name, wait=True)
#!/usr/bin/env python3 '''Test for mismatched TTLs handling on slave zone load.''' '''NOTE: dnspython can't keep different TTLs in one rrset. So we can't check the slave server properly.''' from dnstest.test import Test t = Test() master = t.server("dummy") slave = t.server("knot") zone = t.zone("ttl-mismatch.", storage=".", exists=False) t.link(zone, master, slave) # Create invalid zone file. slave.update_zonefile(zone, version=1) t.start() # Check if the zone was loaded. resp = slave.dig("ttl.ttl-mismatch.", "A") resp.check(rcode="NOERROR", flags="QR AA", noflags="TC AD RA") t.end()
check_log("ZONE SOA TIMERS: REFRESH = 1, RETRY = 20, EXPIRE = 10") master.update_zonefile(zone, version=2) init_servers(master, slave) test_run_case(t, master, slave, action) def reload_server(t, s): s.reload() t.sleep(1) def restart_server(t, s): s.stop() s.start() t = Test() zone = t.zone("example.", storage=".") servers = create_servers(t, 2, zone) t.start() check_log("/// ACTION RELOAD ///") test_run(t, servers[0], zone, reload_server) check_log("/// ACTION RESTART ///") test_run(t, servers[1], zone, restart_server) t.stop()
#!/usr/bin/env python3 '''Test for AXFR-style IXFR''' from dnstest.test import Test import os t = Test(tsig=False) master = t.server("knot") slave = t.server("knot") zone = t.zone("xfr", storage=".") t.link(zone, master, slave) t.start() serial = master.zone_wait(zone) # update zone with small change master.update_zonefile(zone, version=1) master.reload() master.zone_wait(zone, serial) # check that master properly sends AXFR-style IXFR t.check_axfr_style_ixfr(master, "xfr", serial) serial = slave.zone_wait(zone, serial) t.xfr_diff(master, slave, zone)