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") master_nsec3.gen_key(zone, alg="RSASHA256") t.start()
''' 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 transition from NSEC to NSEC3 on auto-signed zone using DDNS.''' from dnstest.utils import * from dnstest.test import Test t = Test() master = t.server("knot") slave = t.server("bind") zone = t.zone_rnd(1, dnssec=False) t.link(zone, master, slave, ddns=True) t.start() # Wait for listening server with unsigned zone. old_serial = master.zone_wait(zone) slave.zone_wait(zone) t.xfr_diff(master, slave, zone) # Check NSEC absence. master.check_nsec(zone, nonsec=True) master.stop() # Enable autosigning. master.dnssec_enable = True master.gen_key(zone, ksk=True, alg="NSEC3RSASHA1") master.gen_key(zone, alg="NSEC3RSASHA1") master.gen_key(zone, ksk=True, alg="RSASHA256")
#!/usr/bin/env python3 '''Test for EDNS0/NSID identification''' from dnstest.test import Test t = Test() name = "Knot DNS server" hex_name = "0x01020304" server1 = t.server("knot", nsid=name) server2 = t.server("knot", nsid=False) server3 = t.server("knot") server4 = t.server("knot", nsid=hex_name) zone = t.zone("example.com.") t.link(zone, server1) t.link(zone, server2) t.link(zone, server3) t.link(zone, server4) t.start() # 1) Custom identification string. resp = server1.dig("example.com", "SOA", nsid=True) resp.check_edns(nsid=name) # 2) Disabled. resp = server2.dig("example.com", "SOA", nsid=True) resp.check_edns() # 3) FQDN hostname.
'''Test for EDNS0/NSID identification''' from dnstest.test import Test t = Test() name = "Knot DNS server" hex_name = "0x01020304" server1 = t.server("knot", nsid=name) server2 = t.server("knot", nsid=False) server3 = t.server("knot") server4 = t.server("knot", nsid=hex_name) zone = t.zone("example.com.") t.link(zone, server1) t.link(zone, server2) t.link(zone, server3) t.link(zone, server4) t.start() # 1) Custom identification string. resp = server1.dig("example.com", "SOA", nsid=True) resp.check_edns(nsid=name) # 2) Disabled. resp = server2.dig("example.com", "SOA", nsid=True) resp.check_edns() # 3) FQDN hostname.
} 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) t.xfr_diff(master, refer, zones) for i in range(1, 5): # Update zone files. for zone in zones: master.update_zonefile(zone, version=i, storage=t.zones_dir) refer.update_zonefile(zone, version=i, storage=t.zones_dir) master.reload() refer.reload()
#!/usr/bin/env python3 """ DNSSEC Single-Type Signing Scheme, RFC 6781 """ from dnstest.utils import * from dnstest.test import Test t = Test() knot = t.server("knot") zones = t.zone_rnd(4, dnssec=False, records=10) t.link(zones, knot) t.start() # one KSK knot.gen_key(zones[0], ksk=True, alg="RSASHA256", key_len="512") # one ZSK knot.gen_key(zones[1], ksk=False, alg="RSASHA512", key_len="1024") # multiple KSKs knot.gen_key(zones[2], ksk=True, alg="RSASHA512", key_len="1024") knot.gen_key(zones[2], ksk=True, alg="RSASHA256", key_len="512") # different algorithms: KSK+ZSK pair, one ZSK knot.gen_key(zones[3], ksk=True, alg="RSASHA256", key_len="1024") knot.gen_key(zones[3], ksk=False, alg="RSASHA256", key_len="1024") knot.gen_key(zones[3], ksk=False, alg="RSASHA512", key_len="1024") knot.dnssec_enable = True knot.gen_confile()
#!/usr/bin/env python3 '''Test for chain IXFR with middle man being frozen''' from dnstest.test import Test from dnstest.utils import * t = Test() s1 = t.server("knot") s2 = t.server("knot") s3 = t.server("knot") zones = t.zone_rnd(5) t.link(zones, s1, s2, ixfr=True) t.link(zones, s2, s3, ixfr=True) s2.tcp_remote_io_timeout = 8000 s3.tcp_remote_io_timeout = 8000 for zone in zones: s1.dnssec(zone).enable = True t.start() serials_init = s3.zones_wait(zones) s2.ctl("zone-freeze") t.sleep(1) s1.ctl("zone-sign") t.sleep(2)
#!/usr/bin/env python3 from dnstest.test import Test import dnstest.utils t = Test() ixfr_master = t.server("bind") ixfr_slave = t.server("knot") axfr_master = t.server("bind") axfr_slave = t.server("knot") zone = t.zone("example.com.", storage=".") t.link(zone, ixfr_master, ixfr_slave, ixfr=True) t.link(zone, axfr_master, axfr_slave, ixfr=False) def prepare(master, slave, zone): # Wait for zones. serial = master.zone_wait(zone) slave.zone_wait(zone) # Update master file with the record (new SOA serial). master.update_zonefile(zone, version=1) master.reload() # Wait for zones and compare them. master_serial = master.zone_wait(zone, serial) return master_serial
#!/usr/bin/env python3 """Test for DDNS prerequisites""" from dnstest.test import Test t = Test() srv = t.server("knot") zone = t.zone("ddns.", storage=".") t.link(zone, srv, ddns=True) t.start() # PREREQ YXDOMAIN # =============== # OK update = srv.update(zone) update.prereq_yx("existing.ddns.") update.add("1.ddns.", 1, "TXT", "text") update.send("NOERROR") resp = srv.dig("1.ddns.", "TXT") resp.check("text") # OK in apex update = srv.update(zone) update.prereq_yx("ddns.") update.add("2.ddns.", 1, "TXT", "text") update.send("NOERROR") resp = srv.dig("2.ddns.", "TXT")
#!/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 '''Test for no resigning if the zone is properly signed.''' from dnstest.utils import * from dnstest.test import Test t = Test() master = t.server("knot") nsec_zone = t.zone_rnd(1, dnssec=True, nsec3=False) nsec3_zone = t.zone_rnd(1, dnssec=True, nsec3=True) t.link(nsec_zone, master) t.link(nsec3_zone, master) t.start() # Get zone serial. old_nsec_serial = master.zone_wait(nsec_zone) old_nsec3_serial = master.zone_wait(nsec3_zone) # Enable autosigning. master.dnssec_enable = True master.use_keys(nsec_zone) master.use_keys(nsec3_zone) master.gen_confile() master.reload() t.sleep(4) new_nsec_serial = master.zone_wait(nsec_zone)
#!/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()
#!/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.
if rr.rdtype not in [dns.rdatatype.SOA, dns.rdatatype.NSEC, dns.rdatatype.RRSIG]: return False if rr.rdtype == dns.rdatatype.RRSIG: if (not rr.match(rr.name, rr.rdclass, dns.rdatatype.RRSIG, dns.rdatatype.NSEC)) and \ (not rr.match(rr.name, rr.rdclass, dns.rdatatype.RRSIG, dns.rdatatype.SOA)): # RRSIG covering something else than NSEC or SOA. return False return True t = Test() master = t.server("knot") nsec_zone = t.zone_rnd(1, dnssec=True, nsec3=False) nsec3_zone = t.zone_rnd(1, dnssec=True, nsec3=True) static_zone = t.zone("example.", storage=".") t.link(nsec_zone, master) t.link(nsec3_zone, master) t.link(static_zone, master) t.start() # Get zone serial. old_nsec_serial = master.zone_wait(nsec_zone) old_nsec3_serial = master.zone_wait(nsec3_zone) old_static_serial = master.zone_wait(static_zone) # Enable autosigning. master.dnssec_enable = True master.use_keys(nsec_zone) master.use_keys(nsec3_zone) master.use_keys(static_zone)
#!/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 ''' 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()
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) resp.check(rcode="NOERROR", flags="AA", rdata="192.0.2.1", nordata="192.0.2.2")
random.seed() t = Test() zone = t.zone_rnd(1, dnssec=False, records=4) master = t.server("knot") # set journal limit for the master master.ixfr_fslimit = "800k" slaves = [t.server("knot") for _ in range(2)] # set journal limit for one of the slaves slaves[0].ixfr_fslimit = "500k" for s in slaves: t.link(zone, master, s, ddns=True, ixfr=True) t.start() for s in slaves + [master]: s.zone_wait(zone) # flood server with updates last_rr = flood(master, zone) # wait for update and ixfr processing t.sleep(10) # restart servers and dig for last change for s in slaves + [master]: s.stop()
# increase serials so that server accepts them serials = list(map(lambda x: x + 1000, serials)) serials.reverse() update_zone(master, slave, zone, rev[1:], change_serial=True, serials=serials) t = Test() # Create NSEC and NSEC3 servers nsec_master = t.server("knot") nsec3_master = t.server("knot") nsec_slave = t.server("bind") nsec3_slave = t.server("bind") zone = t.zone("example.", storage=".") t.link(zone, nsec_master, nsec_slave) t.link(zone, nsec3_master, nsec3_slave) # Enable autosigning nsec_master.dnssec_enable = True nsec_master.gen_key(zone, ksk=True, alg="RSASHA256") nsec_master.gen_key(zone, alg="RSASHA256") nsec3_master.dnssec_enable = True nsec3_master.enable_nsec3(zone) nsec3_master.gen_key(zone, ksk=True, alg="RSASHA256") nsec3_master.gen_key(zone, alg="RSASHA256") t.start() check_log("============ testing NSEC changes ===============")
#!/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() # Compare master with reference server t.xfr_diff(reference, master, zones) # Compare slave with reference server
response = slave.dig("new.example.com.", "RRSIG"); #Should get a RRSIG for the new A record and the new NSEC record response.check_count(2) slave.zone_backup(zone, flush=True) slave.zone_verify(zone) t = Test() # Create master and slave servers bind_master = t.server("bind") knot_master = t.server("knot") knot_slave1 = t.server("knot") knot_slave2 = t.server("knot") zone = t.zone("example.com.", storage=".") t.link(zone, bind_master, knot_slave1, ddns=True) t.link(zone, knot_master, knot_slave2, ddns=True) # Enable autosigning on slave knot_slave1.dnssec(zone).enable = True knot_slave2.dnssec(zone).enable = True t.start() test_update(bind_master, knot_slave1, zone) test_update(knot_master, knot_slave2, zone) t.end()
resp = slave.dig("mail.example.com.", "RRSIG") if ans_len(resp) != 1: print(msg + ": two RRSIGs for unchanged") set_err(msg + ": two RRSIGs for unchanged") t = Test() # Create master and slave servers knot_master = t.server("knot") knot_slave1 = t.server("knot") zone = t.zone("example.com.", storage=".") t.link(zone, knot_master, knot_slave1, ddns=True, ixfr=True) # Enable autosigning on slave knot_slave1.dnssec(zone).enable = True knot_slave1.dnssec(zone).nsec3 = True # to avoid NSEC-RRSIGs in zone nodes t.start() serial = knot_slave1.zone_wait(zone) resp = knot_slave1.dig("node.example.com.", "RRSIG") rrsig1 = resp.resp.answer[0].to_rdataset()[0].to_text() knot_master.zones["example.com."].zfile.update_soa() with open(knot_master.zones["example.com."].zfile.path, "a") as zf: zf.write('node.example.com. 3600 A 100.0.0.2\n')
#!/usr/bin/env python3 from dnstest.test import Test t = Test(tsig=True, stress=False) knot = t.server("knot") zone = t.zone("example.com") t.link(zone, knot, ddns=True) t.start() zone[0].name = "examPle.com" update = knot.update(zone) update.add("kNoT.ExamPle.com.", 60, "TXT", "test") update.add("test.example.com.", 60, "TXT", "test") update.send("NOERROR") resp = knot.dig("knot.example.com.", "TXT") resp.check(rcode="NOERROR", rdata="test") t.end()
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 knot.dnssec(zone).rrsig_refresh = 5
# | master1 <-------+ master2 | # +----^----+ +----^----+ # | | # | +---------+ | # +---+ slave +---+ # +---------+ master1 = t.server("knot") master2 = t.server("bind") slave = t.server("knot") # flush zones immediatelly for server in [master1, master2, slave]: slave.zonefile_sync = "0" t.link([zone], master1, master2) t.link([zone], master1, slave) t.link([zone], master2, slave) t.start() # zone boostrap for server in [master1, master2, slave]: server.zone_wait(zone) # transfer with fully working topology master1.zones[zone.name].zfile.update_soa(serial=10) master1.reload() for server in [master1, master2, slave]: server.zone_wait(zone, serial=9)
#!/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)
slave.zone_wait(zone, 2, equal=True) # Force refresh should work slave.ctl("zone-refresh %s" % zone.name) slave.zone_wait(zone, 3, equal=True) t = Test() # this zone has refresh = 1s, retry = 1s and expire = 15s [zone] = t.zone("example.", storage=".") master = t.server("knot") slave = t.server("knot") for server in [master, slave]: server.disable_notify = True server.tcp_remote_io_timeout = "1000" t.link([zone], master, slave) t.start() master.zone_wait(zone) slave.zone_wait(zone) expire_tests(t, zone, master, slave) refresh_tests(t, zone, master, slave) t.stop()
#!/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 for EDNS version""" from dnstest.test import Test from dnstest.utils import * t = Test() server = t.server("knot") zone = t.zone("example.com.") t.link(zone, server) t.start() # Supported EDNS version 0. resp = server.dig("example.com", "SOA", edns=0) resp.check(rcode="NOERROR", edns_version=0) # Unsupported EDNS version 1. resp = server.dig("example.com", "SOA", edns=1) resp.check(rcode="BADVERS", edns_version=0) compare(resp.count(section="answer"), 0, "Answer count") compare(resp.count(section="authority"), 0, "Authority count") compare(resp.count(section="additional"), 0, "Additional count") t.end()
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() t.sleep(EXPIRE_SLEEP); test_expire(zone, slave) # bring back master (notifies slave) master.start() master.zone_wait(zone) slave.zone_wait(zone)
""" Zone persistence on a slave server without AXFR. """ from dnstest.test import Test t = Test() zone = t.zone_rnd(1, records=1, dnssec=False)[0] zone.update_soa(serial=1, refresh=600, retry=600, expire=3600) master = t.server("knot") slave = t.server("knot") slave.zonefile_sync = 24 * 60 * 60 t.link([zone], master, slave) t.start() # verify zone boostrap for server in [master, slave]: server.zone_wait(zone) # update zone master.zones[zone.name].zfile.update_soa(serial=10) master.reload() for server in [master, slave]: server.zone_wait(zone, serial=9) # stop servers master.stop()