.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Zonemaster::Overview 3pm" .TH Zonemaster::Overview 3pm "2022-06-28" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Zonemaster::Overview \- The Zonemaster Test Engine .SH "INTRODUCTION" .IX Header "INTRODUCTION" The Zonemaster system is a quality control tool for \s-1DNS\s0 zones, produced in cooperation between \s-1AFNIC\s0 and \s-1IIS\s0 (the top-level registries for respectively France and Sweden). It is a successor both to \s-1AFNIC\s0's tool Zonecheck and \s-1IIS\s0's tool DNSCheck, and is intended to be an improvement over both. .PP The system as a whole consists of the test engine and, as distributed by the project, two different front ends. One is a command-line interface intended for use by experienced technicians, and one is a web interface meant for use by anyone. This document only talks about the test engine. .SH "DESCRIPTION" .IX Header "DESCRIPTION" .SS "Brief overview" .IX Subsection "Brief overview" Conceptually, the test engine consists of a number of test implementation modules surrounded by a support framework. Anyone wanting to use Zonemaster to perform tests communicates with the framework from the \*(L"outside\*(R", and all modules implementing tests see the world entirely through the framework. Doing things this way lets us have features like the ability to test domains before they are published, to record entire test runs for later analysis and to make sure that test restults are (as far as reality allows) predictable and repeatable. .SS "For users of Zonemaster" .IX Subsection "For users of Zonemaster" If all you want to do is run tests, you need to care about four or five modules. Zonemaster is the main access point to the framework, and it is via its methods that you set the configuration (if needed), request that tests be started and access the logger. The logger is where the test results end up, so that's pretty important. On top of those, you may want to use the Zonemaster::Translator to turn the results into human-readable messages. .PP There are two ways that you can get the results of a test you've requested: the simple-but-inflexible way and the flexible-but-complex way. .PP The simple-but-inflexible way is that all the methods in Zonemaster that run tests return lists of Zonemaster::Logger::Entry objects. Those lists include all the results that the writer of the test module(s) considered important enough to return by default. The advantage of this method is that it is extremely easy to use. The following is a functional (if not very useful) way to run a full test and print the results from a command line prompt: .PP .Vb 1 \& perl \-MZonemaster \-E \*(Aqsay "$_" for Zonemaster\->new\->test_zone("example.org")\*(Aq .Ve .PP The main drawbacks of this method are that there is no choice about what messages to see, and it's entirely asynchronous. The code that started the test does not get a chance to do anything at all until the whole test has finished, which may be several minutes later. .PP The get around those drawbacks there is the flexible-but-complex way, which consists of installing a callback that gets executed every time a message is logged. It's not that much more complicated, code-wise. The following example does roughly the same thing as the one above: .PP .Vb 1 \& perl \-MZonemaster \-E \*(AqZonemaster\->logger\->callback(sub {say "$_[0]"}); Zonemaster\->new\->test_zone("example.org");\*(Aq .Ve .PP If you try running those, you'll notice two main differences. First, the second variant prints results as they are generated. Second, it generates a \fBlot\fR more output. On my machine right now, the first example gives me 94 lines of output. The second example gives me 17684. .PP You can do pretty much whatever you want with the message objects in the callback (including modifying them, although we don't promise that behavior will stay around). If the callback code throws an exception, and that exception is not a subcless of Zonemaster::Exception, the callback will be removed. Note also that while the callback is running, the test engine itself is not. So think twice before you do potentially time-consuming tasks (like sticking the message in a database) in the callback. After waiting for responses from remote name servers (which usually stands for more than 90% of the time used), the result logging is the single most time-consuming task in a Zonemaster test run. .PP From here, you probably want to look at the documentation for Zonemaster, Zonemaster::Logger, Zonemaster::Logger::Entry, Zonemaster::Config and Zonemaster::Translator. .SS "For developers of Zonemaster Test Modules" .IX Subsection "For developers of Zonemaster Test Modules" If you want to develop a test module of your own, the Zonemaster::Test::Example module is intended to serve as an example. The standard set of modules also fulfil that purpose to various degrees, of course. Zonemaster::Test::DNSSEC may be especially interesting, since it is an example of including default translation and policy data with the module source code. .PP As an entry point to the \*(L"inside\*(R" of the Zonemaster framework, you want to read Zonemaster::Zone and follow references from there. Of particular interest after the zone class should be the Zonemaster::Nameserver and possibly Zonemaster::Recursor classes. .PP If you do write your own test module, I would very much appreciate feedback on which parts were tricky to figure out, because I'm honestly not sure what I need to explain here. So please, if there's somethat that you think really needs to be written about, add an issue about at . .SS "For developers of the Zonemaster Test Framework" .IX Subsection "For developers of the Zonemaster Test Framework" Random recommendations and advice. May be replaced with more coherent developer documentation in the future. .IP "\(bu" 4 Stability, predictability and reliability are more important than performance. .IP "\(bu" 4 Don't forget that starting with Perl version 5.18, the order in which you get the keys out of a hash will be different every time the script is run. Get used to always writing \f(CW\*(C`sort keys %hash\*(C'\fR. .IP "\(bu" 4 If two (or more) test implementation modules implement the same (or very similar) thing, it should probably be extracted into the framework. .IP "\(bu" 4 The unit tests run against pre-recorded data, unless the environment variable \f(CW\*(C`ZONEMASTER_RECORD\*(C'\fR is set to a (perl\-)true value. In that case, it runs against the live \s-1DNS\s0 world and records all results for future use. Unfortunately this sometime means that some tests fail, when we were relying on seeing certain problems in certain domains, and those no longer look the same. .IP "\(bu" 4 The translation strings returned from a test module are used as keys in the \s-1GNU\s0 gettext system, so if you change anything in them don't forget to also change the translation \f(CW\*(C`.po\*(C'\fR files in \fIshare\fR. .IP "\(bu" 4 Adding a new message tag is more work than it first looks, since it needs to be added to the test module metadata, the default policy and the translation system in order to be fully functional. .SH "REFERENCES" .IX Header "REFERENCES" .IP "" 4 .IX Item "" Main repository, holding among other things our test specifications. .SS "List of all RFCs referred to in the test specifications" .IX Subsection "List of all RFCs referred to in the test specifications" .IP "\(bu" 4 \&\s-1RFC0822 \*(L"STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES\*(R"\s0 .IP "\(bu" 4 \&\s-1RFC0919\s0 \*(L"Broadcasting Internet Datagrams\*(R" .IP "\(bu" 4 \&\s-1RFC0952\s0 \*(L"DoD Internet host table specification\*(R" .IP "\(bu" 4 \&\s-1RFC1033\s0 \*(L"Domain Administrators Operations Guide\*(R" .IP "\(bu" 4 \&\s-1RFC1034\s0 \*(L"Domain names \- concepts and facilities\*(R" .IP "\(bu" 4 \&\s-1RFC1035\s0 \*(L"Domain names \- implementation and specification\*(R" .IP "\(bu" 4 \&\s-1RFC1112\s0 \*(L"Host extensions for \s-1IP\s0 multicasting\*(R" .IP "\(bu" 4 \&\s-1RFC1122\s0 \*(L"Requirements for Internet Hosts \- Communication Layers\*(R" .IP "\(bu" 4 \&\s-1RFC1123\s0 \*(L"Requirements for Internet Hosts \- Application and Support\*(R" .IP "\(bu" 4 \&\s-1RFC1912\s0 \*(L"Common \s-1DNS\s0 Operational and Configuration Errors\*(R" .IP "\(bu" 4 \&\s-1RFC1918\s0 \*(L"Address Allocation for Private Internets\*(R" .IP "\(bu" 4 \&\s-1RFC1930\s0 \*(L"Guidelines for creation, selection, and registration of an Autonomous System (\s-1AS\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC1982\s0 \*(L"Serial Number Arithmetic\*(R" .IP "\(bu" 4 \&\s-1RFC1996 \*(L"A\s0 Mechanism for Prompt Notification of Zone Changes (\s-1DNS NOTIFY\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC2142\s0 \*(L"Mailbox Names for Common Services, Roles and Functions\*(R" .IP "\(bu" 4 \&\s-1RFC2181\s0 \*(L"Clarifications to the \s-1DNS\s0 Specification\*(R" .IP "\(bu" 4 \&\s-1RFC2182\s0 \*(L"Selection and Operation of Secondary \s-1DNS\s0 Servers\*(R" .IP "\(bu" 4 \&\s-1RFC2308\s0 \*(L"Negative Caching of \s-1DNS\s0 Queries (\s-1DNS NCACHE\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC2544\s0 \*(L"Benchmarking Methodology for Network Interconnect Devices\*(R" .IP "\(bu" 4 \&\s-1RFC2671\s0 \*(L"Extension Mechanisms for \s-1DNS\s0 (\s-1EDNS0\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC2822\s0 \*(L"Internet Message Format\*(R" .IP "\(bu" 4 \&\s-1RFC2870\s0 \*(L"Root Name Server Operational Requirements\*(R" .IP "\(bu" 4 \&\s-1RFC2928\s0 \*(L"Initial IPv6 Sub-TLA \s-1ID\s0 Assignments\*(R" .IP "\(bu" 4 \&\s-1RFC3056\s0 \*(L"Connection of IPv6 Domains via IPv4 Clouds\*(R" .IP "\(bu" 4 \&\s-1RFC3068\s0 \*(L"An Anycast Prefix for 6to4 Relay Routers\*(R" .IP "\(bu" 4 \&\s-1RFC3658\s0 \*(L"Delegation Signer (\s-1DS\s0) Resource Record (\s-1RR\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC3696\s0 \*(L"Application Techniques for Checking and Transformation of Names\*(R" .IP "\(bu" 4 \&\s-1RFC3701\s0 \*(L"6bone (IPv6 Testing Address Allocation) Phaseout\*(R" .IP "\(bu" 4 \&\s-1RFC3849\s0 \*(L"IPv6 Address Prefix Reserved for Documentation\*(R" .IP "\(bu" 4 \&\s-1RFC3927\s0 \*(L"Dynamic Configuration of IPv4 Link-Local Addresses\*(R" .IP "\(bu" 4 \&\s-1RFC4034\s0 \*(L"Resource Records for the \s-1DNS\s0 Security Extensions\*(R" .IP "\(bu" 4 \&\s-1RFC4035\s0 \*(L"Protocol Modifications for the \s-1DNS\s0 Security Extensions\*(R" .IP "\(bu" 4 \&\s-1RFC4074\s0 \*(L"Common Misbehavior Against \s-1DNS\s0 Queries for IPv6 Addresses\*(R" .IP "\(bu" 4 \&\s-1RFC4193\s0 \*(L"Unique Local IPv6 Unicast Addresses\*(R" .IP "\(bu" 4 \&\s-1RFC4291 \*(L"IP\s0 Version 6 Addressing Architecture\*(R" .IP "\(bu" 4 \&\s-1RFC4343\s0 \*(L"Domain Name System (\s-1DNS\s0) Case Insensitivity Clarification\*(R" .IP "\(bu" 4 \&\s-1RFC4380\s0 \*(L"Teredo: Tunneling IPv6 over \s-1UDP\s0 through Network Address Translations (NATs)\*(R" .IP "\(bu" 4 \&\s-1RFC4843\s0 \*(L"An IPv6 Prefix for Overlay Routable Cryptographic Hash Identifiers (\s-1ORCHID\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC5155 \*(L"DNS\s0 Security (\s-1DNSSEC\s0) Hashed Authenticated Denial of Existence\*(R" .IP "\(bu" 4 \&\s-1RFC5156\s0 \*(L"Special-Use IPv6 Addresses\*(R" .IP "\(bu" 4 \&\s-1RFC5180\s0 \*(L"IPv6 Benchmarking Methodology for Network Interconnect Devices\*(R" .IP "\(bu" 4 \&\s-1RFC5321\s0 \*(L"Simple Mail Transfer Protocol\*(R" .IP "\(bu" 4 \&\s-1RFC5358\s0 \*(L"Preventing Use of Recursive Nameservers in Reflector Attacks\*(R" .IP "\(bu" 4 \&\s-1RFC5737\s0 \*(L"IPv4 Address Blocks Reserved for Documentation\*(R" .IP "\(bu" 4 \&\s-1RFC5771 \*(L"IANA\s0 Guidelines for IPv4 Multicast Address Assignments\*(R" .IP "\(bu" 4 \&\s-1RFC5892\s0 \*(L"The Unicode Code Points and Internationalized Domain Names for Applications (\s-1IDNA\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC5936 \*(L"DNS\s0 Zone Transfer Protocol (\s-1AXFR\s0)\*(R" .IP "\(bu" 4 \&\s-1RFC6052\s0 \*(L"IPv6 Addressing of IPv4/IPv6 Translators\*(R" .IP "\(bu" 4 \&\s-1RFC6333\s0 \*(L"Dual-Stack Lite Broadband Deployments Following IPv4 Exhaustion\*(R" .IP "\(bu" 4 \&\s-1RFC6598\s0 \*(L"IANA-Reserved IPv4 Prefix for Shared Address Space\*(R" .IP "\(bu" 4 \&\s-1RFC6666 \*(L"A\s0 Discard Prefix for IPv6\*(R" .IP "\(bu" 4 \&\s-1RFC6781 \*(L"DNSSEC\s0 Operational Practices, Version 2\*(R" .IP "\(bu" 4 \&\s-1RFC6890\s0 \*(L"Special-Purpose \s-1IP\s0 Address Registries\*(R" .IP "\(bu" 4 \&\s-1RFC6891\s0 \*(L"Extension Mechanisms for \s-1DNS\s0 (\s-1\fBEDNS\s0\fR\|(0))\*(R" .IP "\(bu" 4 \&\s-1RFC7050\s0 \*(L"Discovery of the IPv6 Prefix Used for IPv6 Address Synthesis\*(R"