#!/usr/bin/env python3 '''Test for server version over CH/TXT''' from dnstest.test import Test t = Test() ver = "ver. 1.3.1-p3" server1 = t.server("knot", version=ver) server2 = t.server("knot", version=True) server3 = t.server("knot", version=False) server4 = t.server("knot") t.start() # 1a) Custom version string. resp = server1.dig("version.server", "TXT", "CH") resp.check('"' + ver + '"') # 1b) Bind old version of above. resp = server1.dig("version.bind", "TXT", "CH") resp.check('"' + ver + '"') # 2) Automatic version string (can't be tested). resp = server2.dig("version.server", "TXT", "CH") resp.check(rcode="NOERROR") # 3) Explicitly disabled. resp = server3.dig("version.server", "TXT", "CH") resp.check(rcode="REFUSED")
#!/usr/bin/env python3 ''' Check 'whoami' query module functionality. ''' from dnstest.test import Test from dnstest.module import ModWhoami t = Test() ModWhoami.check() # IPv4 test configuration. knot4 = t.server("knot", address="127.0.0.2") zone4 = t.zone("whoami.domain.example.", storage=".") t.link(zone4, knot4) knot4.add_module(zone4, ModWhoami()) # IPv6 test configuration. knot6 = t.server("knot", address=6) zone6 = t.zone("whoami6.domain.example.", storage=".") t.link(zone6, knot6) knot6.add_module(zone6, ModWhoami()) t.start() # IPv4 test. resp = knot4.dig("whoami.domain.example", "NS") resp.check(rcode="NOERROR", rdata="ns.whoami.domain.example.", ttl=86400) resp = knot4.dig("whoami.domain.example", "A") resp.check(rcode="NOERROR", rdata="127.0.0.1", ttl=1) resp = knot4.dig("whoami.domain.example", "AAAA")
#!/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")
# 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") master_nsec3.gen_key(zone, alg="RSASHA256")
#!/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 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()
#!/usr/bin/env python3 '''Test for server identification over CH/TXT''' from dnstest.test import Test t = Test() name = "Knot DNS server name" server1 = t.server("knot", ident=name) server2 = t.server("knot") server3 = t.server("knot", ident=False) t.start() # 1a) Custom identification string. resp = server1.dig("id.server", "TXT", "CH") resp.check('"' + name + '"') # 1b) Bind old version of above. resp = server1.dig("hostname.bind", "TXT", "CH") resp.check('"' + name + '"') # 2) Default FQDN hostname. resp = server2.dig("id.server", "TXT", "CH") resp.check(t.hostname) # 3) Disabled. resp = server3.dig("id.server", "TXT", "CH") resp.check(rcode="REFUSED")
#!/usr/bin/env python3 ''' Check 'dnsproxy' query module functionality. ''' from dnstest.test import Test from dnstest.module import ModDnsproxy t = Test(stress=False) ModDnsproxy.check() # Initialize server configuration local_zone = t.zone("test", storage=".", file_name="test.local_zone") remote_zone1 = t.zone("test", storage=".", file_name="test.remote_zone") remote_zone2 = t.zone("example.com.") local1 = t.server("knot") t.link(local_zone, local1) local2 = t.server("knot") t.link(local_zone, local2) remote = t.server("knot") t.link(remote_zone1, remote) t.link(remote_zone2, remote) t.start() # Only after successful start the remote address is known! local1.add_module(None, ModDnsproxy(remote.addr, remote.port)) local1.gen_confile() local1.reload()
#!/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")
t.sleep(3) wait_for_rrsig_count(t, server, "DNSKEY", 2, 20) check_zone(server, zone, total_keys, 2, 1, 1 if before_keys > 1 else 2, desc + ": both keys active") wait_for_rrsig_count(t, server, "DNSKEY", 1, 20) check_zone(server, zone, total_keys, 1, 1, 1, desc + ": old key retired") wait_for_dnskey_count(t, server, after_keys, 20) check_zone(server, zone, after_keys, 1, 1, 1, desc + ": old key removed") t = Test(tsig=False) parent = t.server("knot") parent_zone = t.zone("com.", storage=".") t.link(parent_zone, parent, ddns=True) parent.dnssec(parent_zone).enable = True child = t.server("knot") child_zone = t.zone("example.com.", storage=".") t.link(child_zone, child) child.zonefile_sync = 24 * 60 * 60 child.dnssec(child_zone).enable = True child.dnssec(child_zone).manual = False child.dnssec(child_zone).alg = "ECDSAP256SHA256" child.dnssec(child_zone).dnskey_ttl = 2
#!/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) if not s1.valgrind: s2.tcp_remote_io_timeout = 8000 s3.tcp_remote_io_timeout = 8000 else: s1.tcp_remote_io_timeout = 45000 s2.tcp_remote_io_timeout = 45000 s3.tcp_remote_io_timeout = 45000 s1.ctl_params_append = ["-b", "-t", "45"] s2.ctl_params_append = ["-b", "-t", "45"] s3.ctl_params_append = ["-b", "-t", "45"] for zone in zones: s1.dnssec(zone).enable = True t.start()
""" Tests for TC flag setting in delegations. """ from dnstest.test import Test t = Test() knot = t.server("knot", tsig=False) zone = t.zone("tc.test", storage=".") t.link(zone, knot) t.start() class DelegationTest: def __init__(self, name, authoritative=False): self._name = name self._auth = authoritative def _get_flags(self, truncated): if self._auth: return ("AA TC", "") if truncated else ("AA", "TC") else: return ("TC", "AA") if truncated else ("", "AA TC") def run(self, bufsize=None, truncated=False, counts=None): name = "%s%s" % ("" if self._auth else "www.", self._name) rtype = "NS" if self._auth else "A" flags, noflags = self._get_flags(truncated) resp = knot.dig(name, rtype, udp=True, dnssec=True, bufsize=bufsize) resp.check(rcode="NOERROR", noflags=noflags, flags=flags)
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 t.start() # DNSSEC-less test check_log("============ Plain test ===========")
#!/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
#!/usr/bin/env python3 ''' For various query processing states. ''' from dnstest.utils import * from dnstest.test import Test t = Test() knot = t.server("knot") knot.DIG_TIMEOUT = 2 bind = t.server("bind") zone = t.zone("flags.") t.link(zone, knot) t.link(zone, bind) t.start() ''' Negative answers. ''' # Negative (REFUSED) resp = knot.dig("another.world", "SOA", udp=True) resp.check(rcode="REFUSED", flags="QR", noflags="AA TC AD RA") resp.cmp(bind) # Negative (NXDOMAIN) resp = knot.dig("nxdomain.flags", "A", udp=True) resp.check(rcode="NXDOMAIN", flags="QR AA", noflags="TC AD RA") resp.cmp(bind) # Check that SOA TTL is limited by minimum-ttl field. resp = knot.dig("nxdomain.flags", "A", udp=True)
rr = None updates = [] for i in range(UPDATE_COUNT): update = server.update(zone) for j in range(UPDATE_SIZE): rr = [randstr() + "." + zone[0].name, 3600, "TXT", randstr()] update.add(*rr) update.send() return rr 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)
expect_dnskeys = 3 if expect_dnskey else 2 expect_rrsigs = 2 if expect_rrsig else 1 check_log("DNSKEYs: %d (expected %d) RRSIGs: %d (expected %d)" % (found_dnskeys, expect_dnskeys, found_rrsigs, expect_rrsigs)) if found_dnskeys != expect_dnskeys or found_rrsigs != expect_rrsigs: set_err("BAD DNSKEY: " + msg) detail_log("!DNSKEYs not published and activated as expected: " + msg) detail_log(SEP) t = Test() knot = t.server("knot") zone = t.zone("example.com.") t.link(zone, knot) knot.dnssec(zone).enable = True knot.dnssec(zone).manual = True # parameters ZONE = "example.com." WAIT_SIGN = 2 # generate initial keys (one always enabled, one for testing) knot.key_gen(ZONE, ksk="true", created="t+0", publish="t+0", ready="t+0",
# add records serials = [] update_zone(master, slave, zone, range(1, CHANGE_COUNT + 1), change_serial=False, serials=serials) # remove added records, in descending order rev = list(range(1, CHANGE_COUNT + 1)) rev.reverse() # 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
update = master.update(zone) for j in range(mod_count): add_rand_name(update, zone, i) remove_added_name(update) update.send("NOERROR") verify(master, zone) ############################## TEST START ##################################### random.seed() t = Test() zone = t.zone_rnd(1, dnssec=False) master = t.server("knot") t.link(zone, master, ddns=True) master.dnssec(zone).enable = True master.gen_confile() t.start() master.zone_wait(zone) # Test NSEC fix check_log("============ NSEC test ============") test_run(master, zone, "NSEC") master.dnssec(zone).nsec3 = True master.reload() t.sleep(2)
#!/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 """ 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=10, equal=True, greater=False) # stop servers
#!/usr/bin/env python3 ''' 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"
#!/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
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() t.sleep(EXPIRE_SLEEP); test_expire(zone, slave)
#!/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=True) server3 = t.server("knot", nsid=False) server4 = t.server("knot") server5 = 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.link(zone, server5) t.start() # 1) Custom identification string. resp = server1.dig("example.com", "SOA", nsid=True) resp.check_edns(nsid=name) # 2) FQDN hostname. resp = server2.dig("example.com", "SOA", nsid=True) resp.check_edns(nsid=t.hostname)