feat: add full Zonemaster stack with Docker and Spanish UI
- Clone all 5 Zonemaster component repos (LDNS, Engine, CLI, Backend, GUI) - Dockerfile.backend: 8-stage multi-stage build LDNS→Engine→CLI→Backend - Dockerfile.gui: Astro static build served via nginx - docker-compose.yml: backend (internal) + frontend (port 5353) - nginx.conf: root redirects to /es/, /api/ proxied to backend - zonemaster-gui/config.ts: defaultLanguage set to 'es' (Spanish) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# Zone Test Plan
|
||||
|
||||
These are tests of the zone content in DNS, such as SOA and MX records.
|
||||
|
||||
This document uses the terminology defined in the [Master Test Plan].
|
||||
|
||||
|
||||
[Master Test Plan]: ../MasterTestPlan.md
|
||||
[Test Case README]: ../README.md
|
||||
|
||||
<!-- Content until EOF generated by script updateTestPlanReadme.pl from Zonemaster/Zonemaster utils directory -->
|
||||
|
||||
## Test cases list
|
||||
|
||||
|Test Case |Test Case Description|
|
||||
|:---------|:--------------------|
|
||||
|[ZONE01](zone01.md)|Fully qualified master nameserver in SOA|
|
||||
|[ZONE02](zone02.md)|SOA 'refresh' minimum value|
|
||||
|[ZONE03](zone03.md)|SOA 'retry' lower than 'refresh'|
|
||||
|[ZONE04](zone04.md)|SOA 'retry' at least 1 hour|
|
||||
|[ZONE05](zone05.md)|SOA 'expire' minimum value|
|
||||
|[ZONE06](zone06.md)|SOA 'minimum' maximum value|
|
||||
|[ZONE07](zone07.md)|SOA master is not an alias|
|
||||
|[ZONE08](zone08.md)|MX is not an alias|
|
||||
|[ZONE09](zone09.md)|MX record present|
|
||||
|[ZONE10](zone10.md)|No multiple SOA records|
|
||||
|[ZONE11](zone11.md)|SPF policy validation|
|
||||
269
zonemaster/docs/public/specifications/tests/Zone-TP/zone01.md
Normal file
269
zonemaster/docs/public/specifications/tests/Zone-TP/zone01.md
Normal file
@@ -0,0 +1,269 @@
|
||||
## ZONE01: Fully qualified master nameserver in SOA
|
||||
|
||||
### Test case identifier
|
||||
**ZONE01** Fully qualified master nameserver in SOA
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Objective](#objective)
|
||||
* [Scope](#scope)
|
||||
* [Inputs](#inputs)
|
||||
* [Summary](#summary)
|
||||
* [Test procedure](#test-procedure)
|
||||
* [Outcome(s)](#outcomes)
|
||||
* [Special procedural requirements](#special-procedural-requirements)
|
||||
* [Intercase dependencies](#intercase-dependencies)
|
||||
* [Terminology](#terminology)
|
||||
|
||||
## Objective
|
||||
|
||||
The MNAME field from the SOA record of a zone is supposed to contain the master
|
||||
name server for that zone. The hostname of the MNAME field may not be listed
|
||||
in the NS records in the zone among the delegated name servers, but should
|
||||
still be authoritative for the zone. MNAME may be used for other services
|
||||
such as DNS NOTIFY described in [RFC1996].
|
||||
|
||||
[RFC1035], section 3.3.13, specifies that "the *domain-name* of the name server
|
||||
that was the original or primary source of data for this zone".
|
||||
|
||||
[RFC1996], section 2, and [RFC2136], section 1, add that "the primary master is
|
||||
named in the zone's SOA MNAME field and optionally by an NS RR.
|
||||
There is by definition only one primary master server per zone".
|
||||
|
||||
[RFC2181], section 7.2, clarifies that "it is quite clear in the specifications,
|
||||
yet seems to have been widely ignored, that the MNAME field of the SOA record
|
||||
should contain the name of the primary (master) server for the zone identified
|
||||
by the SOA. It should not contain the name of the zone itself. That information
|
||||
would be useless, as to discover it, one needs to start with the domain name of
|
||||
the SOA record - that is the name of the zone".
|
||||
|
||||
There exists an unstandardized practice to set the SOA MNAME to ".", which
|
||||
should not be interpreted that there is no primary master server, but to
|
||||
indicate that there is no default server for dynamic updates. With ".", SOA
|
||||
MNAME has no server name. There is at least one old and expired Internet-Draft
|
||||
that attempted to standardize that behavior, [draft-jabley-dnsop-missing-mname].
|
||||
If the SOA MNAME is an empty name (".") this Test Case will not try to connect
|
||||
to a server behind it since there will never be a server behind that name, as
|
||||
the purpose is most definitely to follow that practice. Instead, a special
|
||||
message will be outputted.
|
||||
|
||||
The operational consequences of errors on SOA MNAME are, however, limited. It is
|
||||
never used for finding authoritative name servers for the zone, and is not part
|
||||
of normal lookup. Therefore, the level set by this test case on SOA MNAME errors
|
||||
is not higher than NOTICE.
|
||||
|
||||
This Test Case will check that:
|
||||
- the SOA MNAME contains the master name server of *Child Zone*,
|
||||
as best as it can be determined.
|
||||
- the SOA MNAME name server is authoritative of *Child Zone*.
|
||||
- the SOA SERIAL of the SOA MNAME is at least equal to the ones found
|
||||
from the name servers in the NS record set of *Child Zone*.
|
||||
This comparison must be done following [RFC1982].
|
||||
- the SOA MNAME name server is listed as part of the NS record set of *Child Zone*.
|
||||
|
||||
## Scope
|
||||
|
||||
It is assumed that *Child Zone* is tested and reported by [CONNECTIVITY01].
|
||||
This Test Case will just ignore non-responsive name servers or name servers
|
||||
not giving a correct DNS response for an authoritative name server, except
|
||||
if the name server is listed in the SOA MNAME.
|
||||
|
||||
The syntax of the SOA MNAME for *Child Zone* is not tested in this Test
|
||||
Case, see [SYNTAX07].
|
||||
|
||||
The consistency of the SOA MNAME between different servers of *Child Zone*
|
||||
is not tested by this Test Case, see [CONSISTENCY06].
|
||||
|
||||
## Inputs
|
||||
|
||||
* "Child Zone" - The domain name to be tested.
|
||||
|
||||
## Summary
|
||||
|
||||
Message Tag | Level | Arguments | Message ID for message tag
|
||||
:---------------------------- |:--------|:-------------------------------------|:---------------------------------------------------------------------------------------
|
||||
Z01_MNAME_HAS_LOCALHOST_ADDR | NOTICE | nsname, ns_ip | SOA MNAME name server "{nsname}" resolves to a localhost IP address ({ns_ip}).
|
||||
Z01_MNAME_IS_DOT | NOTICE | ns_ip_list | SOA MNAME is specified as "." which usually means "no server". Fetched from name servers "{ns_ip_list}".
|
||||
Z01_MNAME_IS_LOCALHOST | NOTICE | ns_ip_list | SOA MNAME name server is "localhost", which is invalid. Fetched from name servers "{ns_ip_list}".
|
||||
Z01_MNAME_IS_MASTER | DEBUG | ns_list | SOA MNAME name server(s) "{ns_list}" appears to be master.
|
||||
Z01_MNAME_MISSING_SOA_RECORD | NOTICE | ns | SOA MNAME name server "{ns}" responds to an SOA query with no SOA records in the answer section.
|
||||
Z01_MNAME_NO_RESPONSE | NOTICE | ns | SOA MNAME name server "{ns}" does not respond to an SOA query.
|
||||
Z01_MNAME_NOT_AUTHORITATIVE | NOTICE | ns | SOA MNAME name server "{ns}" is not authoritative for the zone.
|
||||
Z01_MNAME_NOT_IN_NS_LIST | INFO | nsname | SOA MNAME name server "{nsname}" is not listed as NS record for the zone.
|
||||
Z01_MNAME_NOT_MASTER | NOTICE | ns_list, soaserial, soaserial_list | SOA MNAME name server(s) "{ns_list}" do(es) not have the highest SOA SERIAL (expected "{soaserial}" but got "{soaserial_list}")
|
||||
Z01_MNAME_NOT_RESOLVE | NOTICE | nsname | SOA MNAME name server "{nsname}" cannot be resolved into an IP address.
|
||||
Z01_MNAME_UNEXPECTED_RCODE | NOTICE | ns, rcode | SOA MNAME name server "{ns}" gives unexpected RCODE name ("{rcode}") in response to an SOA query.
|
||||
|
||||
The value in the Level column is the default severity level of the message. The
|
||||
severity level can be changed in the [Zonemaster-Engine profile]. Also see the
|
||||
[Severity Level Definitions] document.
|
||||
|
||||
The argument names in the Arguments column lists the arguments used in the
|
||||
message. The argument names are defined in the [argument list].
|
||||
|
||||
## Test procedure
|
||||
|
||||
In this section and unless otherwise specified below, the terms "[DNS Query]"
|
||||
follow the specification for DNS queries as specified in [DNS Query and Response Defaults].
|
||||
The handling of the DNS responses on the DNS queries follow, unless otherwise
|
||||
specified below, what is specified for [DNS Response] in the same specification.
|
||||
|
||||
1. Create a [DNS Query] with query type SOA and query name *Child Zone* ("SOA Query").
|
||||
|
||||
2. Create the following empty sets:
|
||||
1. Name server SOA MNAME name, SOA MNAME IP address(es), SOA SERIAL(s) ("MNAME Nameservers")
|
||||
2. Name server SOA SERIAL ("SERIAL Nameservers")
|
||||
3. Name server SOA MNAME name, SOA MNAME IP address, SOA SERIAL ("MNAME Not Master")
|
||||
4. Name server SOA MNAME name, SOA MNAME IP address ("MNAME Is Master")
|
||||
5. Name server IP address ("MNAME Is Localhost")
|
||||
6. Name server IP address ("MNAME Is Dot")
|
||||
|
||||
3. Obtain the set of name server IP addresses using
|
||||
[Method4] and [Method5] ("Name Server IP").
|
||||
|
||||
4. For each name server IP address in *Name Server IP* do:
|
||||
1. Send *SOA Query* to the name server IP and collect the response.
|
||||
2. Go to next name server IP address if at least one of
|
||||
the following criteria is met:
|
||||
1. There is no DNS response.
|
||||
2. [RCODE Name] of the response is not "NoError".
|
||||
3. The AA flag is not set in the response.
|
||||
4. There is no SOA record with owner name matching the query.
|
||||
3. From the DNS response, extract the name server name from the SOA MNAME field:
|
||||
1. If the name is "localhost", then add name server IP address to
|
||||
the *MNAME Is Localhost* set.
|
||||
2. Else if the name is ".", then add name server IP address to
|
||||
the *MNAME Is Dot* set.
|
||||
3. Else, add SOA MNAME name server name to the *MNAME Nameservers* set.
|
||||
4. From the SOA record in the DNS response, extract the value from the SOA SERIAL
|
||||
field and add it to the *SERIAL Nameservers* set.
|
||||
5. Go to next name server IP address.
|
||||
|
||||
5. If the set *MNAME Is Localhost* is non-empty, then output
|
||||
*[Z01_MNAME_IS_LOCALHOST]* with name server(s) IP address(es).
|
||||
|
||||
6. If the set *MNAME Is Dot* is non-empty, then output
|
||||
*[Z01_MNAME_IS_DOT]* with name server(s) IP address(es).
|
||||
|
||||
7. If the set *MNAME Nameservers* is empty, then terminate these procedures.
|
||||
|
||||
8. Obtain the set of name server names using [Method3] ("Child Nameservers").
|
||||
|
||||
9. For each SOA MNAME name server name in *MNAME Nameservers* do:
|
||||
1. If the SOA MNAME name server name is not part of the
|
||||
*Child Nameservers* set, then output *[Z01_MNAME_NOT_IN_NS_LIST]* with
|
||||
SOA MNAME name server name.
|
||||
2. Do a [DNS Lookup] of SOA MNAME name server name (A and AAAA) and add the
|
||||
SOA MNAME name server IP address(es) found to the *MNAME Nameservers* set
|
||||
for the same entry as the SOA MNAME name server name.
|
||||
3. If at least one IP address from the previous step was found, then:
|
||||
1. For each SOA MNAME name server IP address for the SOA MNAME name server name do:
|
||||
1. If the IP address is a localhost address (127.0.0.1 or ::1), then output
|
||||
*[Z01_MNAME_HAS_LOCALHOST_ADDR]* with SOA MNAME name server name and IP.
|
||||
2. Else, send *SOA Query* to the name server IP and collect the response.
|
||||
1. If there is a DNS response, with [RCODE Name] "NoError" and
|
||||
an SOA record in the answer section, then:
|
||||
1. If the AA flag is not set, then output *[Z01_MNAME_NOT_AUTHORITATIVE]*
|
||||
with SOA MNAME name server name and IP address.
|
||||
2. Else, add the SOA SERIAL value to the *MNAME Nameservers* set
|
||||
for the SOA MNAME name server name and IP pair.
|
||||
2. Else if [RCODE Name] is not "NoError", then output
|
||||
*[Z01_MNAME_UNEXPECTED_RCODE]* with [RCODE Name], SOA MNAME name server
|
||||
name and IP address.
|
||||
3. Else if there is no SOA record in the answer section, then output
|
||||
*[Z01_MNAME_MISSING_SOA_RECORD]* with SOA MNAME name server
|
||||
name and IP address.
|
||||
4. Else, output *[Z01_MNAME_NO_RESPONSE]* with SOA MNAME name server
|
||||
name and IP address.
|
||||
3. Go to next SOA MNAME name server IP.
|
||||
4. Else, output *[Z01_MNAME_NOT_RESOLVE]* with SOA MNAME name server name.
|
||||
5. Go to next SOA MNAME name server name.
|
||||
|
||||
10. If there is no SOA SERIAL in the *MNAME Nameservers* set, then
|
||||
terminate these procedures.
|
||||
|
||||
11. For each SOA SERIAL (per SOA MNAME name server name and IP address pair)
|
||||
in *MNAME Nameservers* do:
|
||||
1. For each SOA SERIAL in *SERIAL Nameservers* do:
|
||||
1. Compare both SOA SERIAL values (using the arithmetic in [RFC1982]).
|
||||
2. If the one from *SERIAL Nameservers* is higher, then add SOA MNAME name
|
||||
server name, IP address and SOA SERIAL of the current SOA SERIAL value from
|
||||
the *MNAME Nameservers* set to the *MNAME Not Master* set, and go
|
||||
to next SOA SERIAL (from the *MNAME Nameservers* set).
|
||||
2. Add SOA MNAME name server name and IP address to the *MNAME Is Master* set.
|
||||
|
||||
12. If the set *MNAME Not Master* is non-empty, then output *[Z01_MNAME_NOT_MASTER]*
|
||||
with SOA MNAME name server name(s), IP address(es) and SOA SERIAL from the set,
|
||||
along with the SOA SERIAL values from the *SERIAL Nameservers* set.
|
||||
|
||||
13. If the set *MNAME Is Master* is non-empty, then output *[Z01_MNAME_IS_MASTER]*
|
||||
with SOA MNAME name server name(s) and IP address(es) from the set.
|
||||
|
||||
## Outcome(s)
|
||||
|
||||
The outcome of this Test Case is "fail" if there is at least one message
|
||||
with the severity level *[ERROR]* or *[CRITICAL]*.
|
||||
|
||||
The outcome of this Test Case is "warning" if there is at least one message
|
||||
with the severity level *[WARNING]*, but no message with severity level
|
||||
*ERROR* or *CRITICAL*.
|
||||
|
||||
In other cases, no message or only messages with severity level
|
||||
*[INFO]* or *[NOTICE]*, the outcome of this Test Case is "pass".
|
||||
|
||||
## Special procedural requirements
|
||||
|
||||
If either IPv4 or IPv6 transport is disabled, skip sending queries over that
|
||||
transport protocol. A message will be outputted reporting that the transport
|
||||
protocol has been skipped.
|
||||
|
||||
## Intercase dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Terminology
|
||||
|
||||
* "DNS Lookup" - The term is used when a recursive lookup is used, though
|
||||
any changes to the DNS tree introduced by an [undelegated test] must be
|
||||
respected.
|
||||
|
||||
[Argument list]: ../ArgumentsForTestCaseMessages.md
|
||||
[CONNECTIVITY01]: ../Connectivity-TP/connectivity01.md
|
||||
[CONSISTENCY06]: ../Consistency-TP/consistency06.md
|
||||
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
|
||||
[DNS Lookup]: #terminology
|
||||
[DNS Query and Response Defaults]: ../DNSQueryAndResponseDefaults.md
|
||||
[DNS Query]: ../DNSQueryAndResponseDefaults.md#default-setting-in-dns-query
|
||||
[DNS Response]: ../DNSQueryAndResponseDefaults.md#default-handling-of-a-dns-response
|
||||
[draft-jabley-dnsop-missing-mname]: https://www.ietf.org/archive/id/draft-jabley-dnsop-missing-mname-00.html
|
||||
[ERROR]: ../SeverityLevelDefinitions.md#error
|
||||
[INFO]: ../SeverityLevelDefinitions.md#info
|
||||
[Message Tag Specification]: MessageTagSpecification.md
|
||||
[Methods]: ../Methods.md
|
||||
[Method3]: ../Methods.md#method-3-obtain-name-servers-from-child
|
||||
[Method4]: ../Methods.md#method-4-obtain-glue-address-records-from-parent
|
||||
[Method5]: ../Methods.md#method-5-obtain-the-name-server-address-records-from-child
|
||||
[NOTICE]: ../SeverityLevelDefinitions.md#notice
|
||||
[RCODE Name]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
|
||||
[RFC1035]: https://datatracker.ietf.org/doc/html/rfc1035#section-3.3.13
|
||||
[RFC1982]: https://datatracker.ietf.org/doc/html/rfc1982
|
||||
[RFC1996]: https://datatracker.ietf.org/doc/html/rfc1996#section-2
|
||||
[RFC2136]: https://datatracker.ietf.org/doc/html/rfc2136#section-1
|
||||
[RFC2181]: https://datatracker.ietf.org/doc/html/rfc2181#section-7.3
|
||||
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
|
||||
[SYNTAX07]: ../Syntax-TP/syntax07.md
|
||||
[Test Case Identifier Specification]: TestCaseIdentifierSpecification.md
|
||||
[Undelegated test]: ../../test-types/undelegated-test.md
|
||||
[WARNING]: ../SeverityLevelDefinitions.md#warning
|
||||
[Zonemaster-Engine profile]: ../../../configuration/profiles.md
|
||||
[Z01_MNAME_HAS_LOCALHOST_ADDR]: #summary
|
||||
[Z01_MNAME_IS_DOT]: #summary
|
||||
[Z01_MNAME_IS_LOCALHOST]: #summary
|
||||
[Z01_MNAME_IS_MASTER]: #summary
|
||||
[Z01_MNAME_MISSING_SOA_RECORD]: #summary
|
||||
[Z01_MNAME_NO_RESPONSE]: #summary
|
||||
[Z01_MNAME_NOT_AUTHORITATIVE]: #summary
|
||||
[Z01_MNAME_NOT_IN_NS_LIST]: #summary
|
||||
[Z01_MNAME_NOT_MASTER]: #summary
|
||||
[Z01_MNAME_NOT_RESOLVE]: #summary
|
||||
[Z01_MNAME_UNEXPECTED_RCODE]: #summary
|
||||
@@ -0,0 +1,47 @@
|
||||
## ZONE02: SOA 'refresh' minimum value
|
||||
|
||||
### Test case identifier
|
||||
**ZONE02** SOA 'refresh' minimum value
|
||||
|
||||
### Objective
|
||||
|
||||
The SOA refresh value is the number of seconds that describes
|
||||
how often a secondary name server will poll the primary name server
|
||||
to see if there is any updates. The SOA refresh value is described
|
||||
in section 3.3.13 in [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035),
|
||||
and clarified in section 2.2 of
|
||||
[RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912).
|
||||
Setting the refresh value low will increase the DNS traffic between
|
||||
the servers, and also increase the load on the master name server.
|
||||
The primary name server will in most cases send DNS notifications to
|
||||
tell the secondary name servers that zone content has been updated,
|
||||
as described in [RFC 1996](https://datatracker.ietf.org/doc/html/rfc1996).
|
||||
|
||||
The [RIPE-203](https://www.ripe.net/publications/docs/ripe-203) recommendation
|
||||
for the refresh value is 24 hours (86400 seconds). Older DNSCheck code
|
||||
had a four hour minimum value, and this is the minimum value we
|
||||
recommend.
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Retrieve the SOA record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. Retrieve the refresh value from the SOA record.
|
||||
4. If the refresh value is less than 14400 (four hours in seconds)
|
||||
this test case fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the SOA refresh value is less than 14400 this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
@@ -0,0 +1,43 @@
|
||||
## ZONE03: SOA 'retry' lower than 'refresh'
|
||||
|
||||
### Test case identifier
|
||||
**ZONE03** SOA 'retry' lower than 'refresh'
|
||||
|
||||
### Objective
|
||||
|
||||
The SOA retry value is the number of seconds that describes
|
||||
minimum time elapsed since a failed zone refresh from the primary
|
||||
name server. The SOA refresh value is described
|
||||
in section 3.3.13 in [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035),
|
||||
and clarified in section 2.2 of
|
||||
[RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912).
|
||||
|
||||
> It's typically some fraction of the refresh interval.
|
||||
|
||||
Setting the retry value low will increase the DNS traffic between
|
||||
the servers, and also increase the load on the master name server.
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Retrieve the SOA record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. Retrieve the retry value from the SOA record.
|
||||
4. If the retry value is higher than or equal to the refresh value,
|
||||
this test case fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the SOA retry value is higher than or equal to the refresh value,
|
||||
this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
@@ -0,0 +1,44 @@
|
||||
## ZONE04: SOA 'retry' at least 1 hour
|
||||
|
||||
### Test case identifier
|
||||
**ZONE04** SOA 'retry' at least 1 hour
|
||||
|
||||
### Objective
|
||||
|
||||
The SOA retry value is the number of seconds that describes
|
||||
minimum time elapsed since a failed zone refresh from the primary
|
||||
name server. The SOA refresh value is described
|
||||
in section 3.3.13 in [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035),
|
||||
and clarified in section 2.2 of
|
||||
[RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912).
|
||||
|
||||
Setting the retry value low will increase the DNS traffic between
|
||||
the servers, and also increase the load on the master name server.
|
||||
|
||||
The [RIPE-203](https://www.ripe.net/publications/docs/ripe-203) recommendation
|
||||
for the retry value is 2 hours (7200 seconds). Older DNSCheck code
|
||||
had a one hour minimum value (3600 seconds), and this is the minimum
|
||||
value we recommend.
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Retrieve the SOA record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. Retrieve the retry value from the SOA record.
|
||||
4. If the retry value is less than 3600 seconds, this test case fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the retry value is less than 3600 seconds, this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
@@ -0,0 +1,50 @@
|
||||
## ZONE05: SOA 'expire' minimum value
|
||||
|
||||
### Test case identifier
|
||||
**ZONE05** SOA 'expire' minimum value
|
||||
|
||||
### Objective
|
||||
|
||||
The SOA expire value specifies for how long any secondary name server
|
||||
keeps the zone valid without any contact with the primary name server.
|
||||
This value should be greater than how long a major outage would
|
||||
typically last. The expire value should also be larger than the
|
||||
refresh and retry values, as described in section 3.3.13 in
|
||||
[RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035), and clarified in
|
||||
section 2.2 of [RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912).
|
||||
|
||||
Setting the expire value low will increase the risk of any unwanted
|
||||
non-availability of the zone because of any failures in contacting
|
||||
the primary name server.
|
||||
|
||||
The [RIPE-203](https://www.ripe.net/publications/docs/ripe-203) recommendation
|
||||
for the expire value is 1000 hours (roughly 41 days). Older DNSCheck code
|
||||
had a 7 day minimum value (604800 seconds), and this is the minimum
|
||||
value we recommend as an absolute minimum.
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Retrieve the SOA record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. Retrieve the expire value and the refresh value from the SOA record.
|
||||
4. If the expire value is less than 604800 seconds (7 days), this test
|
||||
case fails.
|
||||
5. If the expire value is lower than the refresh value, this test case
|
||||
fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the expire value is less than 604800 seconds or if the expire value is
|
||||
lower than the refresh value, this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
@@ -0,0 +1,59 @@
|
||||
## ZONE06: SOA 'minimum' maximum value
|
||||
|
||||
### Test case identifier
|
||||
**ZONE06** SOA 'minimum' maximum value
|
||||
|
||||
### Objective
|
||||
|
||||
The SOA minimum field sets the default TTL for all records in a zone.
|
||||
The recommended value is to be "cache-friendly". However, for a zone
|
||||
that changes content often, there is a need to keep the TTL values
|
||||
shorter. The use of the SOA minimum value today is the negative cache
|
||||
(where a resolver find content is missing).
|
||||
|
||||
The SOA minimum field is described in section 3.3.13 in
|
||||
[RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035), and clarified in
|
||||
section 2.2 of [RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912).
|
||||
The description of the implementation of negative caching is in
|
||||
[RFC 2308](https://datatracker.ietf.org/doc/html/rfc2308) (although it has been
|
||||
updated by several DNSSEC related RFCs, it is still relevant for this
|
||||
purpose).
|
||||
|
||||
The [RIPE-203](https://www.ripe.net/publications/docs/ripe-203) recommendation
|
||||
for the minimum value 2 days, but the negative caching is now the norm.
|
||||
DNSCheck has a recommended value of between 300 seconds (5 minutes) and
|
||||
86400 seconds (1 day).
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Obtain a set of name server IP addresses using [Method4] and [Method5].
|
||||
2. Create a SOA query for the zone.
|
||||
3. Send the SOA query over UDP to each name server IP address until
|
||||
a response is received or until the set is exhausted.
|
||||
4. If the answer from step 3 is not authoritative, iterate step 3 until there is an authoritative answer.
|
||||
5. Retrieve the SOA minimum value from the SOA record.
|
||||
6. If the minimum value is larger than 86400 seconds (1 day), this test
|
||||
case fails.
|
||||
7. If the minimum value is lower than 300 seconds (5 minutes), this test case
|
||||
fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the minimum value is larger than 86400 seconds or if the minimum value is
|
||||
lower than 300 seconds, this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
|
||||
-------
|
||||
[Method4]: ../Methods.md#method-4-obtain-glue-address-records-from-parent
|
||||
[Method5]: ../Methods.md#method-5-obtain-the-name-server-address-records-from-child
|
||||
@@ -0,0 +1,46 @@
|
||||
## ZONE07: SOA master is not an alias
|
||||
|
||||
### Test case identifier
|
||||
**ZONE07** SOA master is not an alias
|
||||
|
||||
### Objective
|
||||
|
||||
Any NS type record should not be a CNAME. The SOA MNAME should in this
|
||||
respect not be a CNAME.
|
||||
|
||||
Quote from 2.4 in [RFC 1912](https://datatracker.ietf.org/doc/html/rfc1912):
|
||||
|
||||
> Having NS records pointing to a CNAME is bad and may conflict badly
|
||||
> with current BIND servers.
|
||||
|
||||
The SOA MNAME field is described in section 3.3.13 in
|
||||
[RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035).
|
||||
|
||||
The [RIPE-203](https://www.ripe.net/publications/docs/ripe-203) recommendation
|
||||
for the minimum value 2 days, but the negative caching is now the norm.
|
||||
DNSCheck has a recommended value of between 300 seconds (5 minutes) and
|
||||
86400 seconds (1 day).
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Retrieve the SOA record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. Retrieve the SOA MNAME value from the SOA record.
|
||||
4. Query for A and AAAA records for the host from MNAME.
|
||||
5. If the answer to the query is a CNAME, this test case fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the SOA MNAME field is pointing to a CNAME, this test case fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
@@ -0,0 +1,34 @@
|
||||
## ZONE08: MX is not an alias
|
||||
|
||||
### Test case identifier
|
||||
**ZONE08** MX is not an alias
|
||||
|
||||
### Objective
|
||||
|
||||
An MX type record for a domain must not resolve to a CNAME, following
|
||||
the text in section 10.3 of [RFC 2181](https://datatracker.ietf.org/doc/html/rfc2181)
|
||||
and section 2.3.5 in
|
||||
[RFC 5321](https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.5).
|
||||
|
||||
### Inputs
|
||||
|
||||
The domain name to be tested.
|
||||
|
||||
### Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Query the MX record from a delegated name server for the domain.
|
||||
2. If the answer from step 1 is not authoritative, iterate step 1 until there is an authoritative answer.
|
||||
3. If the MX answer is a CNAME, this test case fails.
|
||||
|
||||
### Outcome(s)
|
||||
|
||||
If the MX record for the domain is pointing to a CNAME, this test case
|
||||
fails.
|
||||
|
||||
### Special procedural requirements
|
||||
|
||||
None.
|
||||
|
||||
### Intercase dependencies
|
||||
|
||||
None.
|
||||
302
zonemaster/docs/public/specifications/tests/Zone-TP/zone09.md
Normal file
302
zonemaster/docs/public/specifications/tests/Zone-TP/zone09.md
Normal file
@@ -0,0 +1,302 @@
|
||||
# ZONE09: MX record present
|
||||
|
||||
|
||||
## Test case identifier
|
||||
**ZONE09**
|
||||
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Objective](#objective)
|
||||
* [Scope](#scope)
|
||||
* [Inputs](#inputs)
|
||||
* [Summary](#summary)
|
||||
* [Test procedure](#test-procedure)
|
||||
* [Outcome(s)](#outcomes)
|
||||
* [Special procedural requirements](#special-procedural-requirements)
|
||||
* [Intercase dependencies](#intercase-dependencies)
|
||||
* [Terminology](#terminology)
|
||||
|
||||
|
||||
## Objective
|
||||
|
||||
It is strongly recommended in [RFC 2142][RFC 2142#section-7],
|
||||
section 7, that every domain should have a mailbox named
|
||||
HOSTMASTER@domain (where "domain" is *Child Zone* in this test case).
|
||||
|
||||
> For simplicity and regularity, it is strongly recommended that the
|
||||
> well known mailbox name HOSTMASTER always be used
|
||||
> \<HOSTMASTER@domain\>.
|
||||
|
||||
This test case therefore expects for every domain (zone), excluding some cases
|
||||
described below, to publish an MX record in apex of the zone (i.e. in the same
|
||||
node as the SOA record).
|
||||
|
||||
If MX is not present, SMTP *can* deliver email using an address record (A or
|
||||
AAAA) as specified in [RFC 5321][RFC 5321#section-5.1], section 5.1, but that
|
||||
possibility is not in common use. This test case only checks for MX record and
|
||||
ignores the possibility to use address records for email.
|
||||
|
||||
Even if not mentioned in [RFC 2142], there are some exceptions to the
|
||||
rule to include MX and mail target for a domain.
|
||||
|
||||
The purpose of a zone in the .ARPA tree is to hold infrastructural identifiers,
|
||||
and it is not expected that such a zone name is used as [Email Domain]
|
||||
([RFC 3172]). This also means that the well known mailbox is not expected for
|
||||
reverse zones (zone under in-addr.arpa or ip6.arpa). Such zone are therefore
|
||||
excluded by this test case from the requirement of MX in the apex.
|
||||
|
||||
The root zone cannot be an [Email Domain] since the email domain is
|
||||
the part to the left of the trailing dot, and the root zone owner name has
|
||||
nothing left of the trailing dot. The root zone is excluded by this test case from
|
||||
the requirement of MX in the apex.
|
||||
|
||||
Top-level domains ([TLDs][TLD]) can technically function as
|
||||
[Email Domains][Email Domain] ([RCF 5321][RFC 5321#section-2.3.5], section 2.3.5)
|
||||
but they rarely have that function and are probably not meant to be included in
|
||||
the specification in [RFC 2142]. [Internet Architecture Board]
|
||||
concludes in a report "[Dotless Domains Considered Harmful][IAB Statement]" that
|
||||
domain names that only consists of one label, e.g. "se", "fr" or "com", should
|
||||
not be used for various Internet services. This means [TLD] names should not be
|
||||
used as [Email Domains][Email Domain]. In this test case [TLDs][TLD] are not only
|
||||
excluded from the requirement of being an [Email Domain], if found to be, a
|
||||
message will be generated that points that out.
|
||||
|
||||
[RFC 7505] standardizes "[Null MX]" which means that there is no email service
|
||||
for the domain. A "[Null MX]" is accepted for any type of domain.
|
||||
[RFC 7505][RFC 7505#section-3], section 3, also specifies that the "[Null MX]"
|
||||
must be the sole MX record and its preference must be zero.
|
||||
|
||||
In this test case, the following zone types are excluded from the requirement of
|
||||
MX:
|
||||
|
||||
* Root zone
|
||||
* [TLD] zone
|
||||
* Zone in the .ARPA tree
|
||||
|
||||
The following zone type is expected not to have any MX (considered harmful,
|
||||
see [IAB Statement]):
|
||||
|
||||
* [TLD] zone
|
||||
|
||||
|
||||
## Scope
|
||||
|
||||
It is assumed that *Child Zone* is tested and reported by [Connectivity01]. This test
|
||||
case will just ignore non-responsive name servers or name servers not giving a
|
||||
correct DNS response for an authoritative name server.
|
||||
|
||||
|
||||
## Inputs
|
||||
|
||||
* "Child Zone" - The domain name to be tested.
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
* A notify is issued if MX is missing, except for root, a zone in the ARPA tree
|
||||
or a [TLD].
|
||||
* A warning is issued if a [TLD] *has* a [non-Null MX][Null MX].
|
||||
|
||||
Message Tag | Level | Arguments | Message ID for message tag
|
||||
:--------------------------|:------|:----------------------------|:--------------------------------------------
|
||||
Z09_INCONSISTENT_MX |WARNING| | Some name servers return an MX RRset while others return none.
|
||||
Z09_INCONSISTENT_MX_DATA |WARNING| | The MX RRset data is inconsistent between the name servers.
|
||||
Z09_MISSING_MAIL_TARGET | NOTICE| | The child zone has no mail target (no MX).
|
||||
Z09_MX_DATA | INFO | ns_ip_list, mailtarget_list | The mail targets in the MX RRset, "{mailtarget_list}", as returned by name servers "{ns_ip_list}".
|
||||
Z09_MX_FOUND | INFO | ns_ip_list | MX RRset was returned by name servers "{ns_ip_list}".
|
||||
Z09_NON_AUTH_MX_RESPONSE |WARNING| ns_ip_list | Non-authoritative response on MX query from name servers "{ns_ip_list}".
|
||||
Z09_NO_MX_FOUND | INFO | ns_ip_list | No MX RRset was returned by name servers "{ns_ip_list}".
|
||||
Z09_NO_RESPONSE_MX_QUERY |WARNING| ns_ip_list | No response on MX query from name servers "{ns_ip_list}".
|
||||
Z09_NULL_MX_NON_ZERO_PREF | NOTICE| | The zone has a Null MX with non-zero preference.
|
||||
Z09_NULL_MX_WITH_OTHER_MX |WARNING| | The zone has a Null MX mixed with other MX records.
|
||||
Z09_ROOT_EMAIL_DOMAIN | NOTICE| | Root zone with an unexpected MX RRset (non-Null MX).
|
||||
Z09_TLD_EMAIL_DOMAIN |WARNING| | The zone is a TLD and has an unexpected MX RRset (non-Null MX).
|
||||
Z09_UNEXPECTED_RCODE_MX |WARNING | ns_ip_list, rcode | Unexpected RCODE value ({rcode}) in response to MX query. Responses from name servers "{ns_ip_list}".
|
||||
|
||||
The value in the Level column is the default severity level of the message. The
|
||||
severity level can be changed in the [Zonemaster-Engine profile]. Also see the
|
||||
[Severity Level Definitions] document.
|
||||
|
||||
The argument names in the Arguments column lists the arguments used in the
|
||||
message. The argument names are defined in the [argument list].
|
||||
|
||||
|
||||
## Test procedure
|
||||
|
||||
In this section and unless otherwise specified below, the terms "[DNS Query]"
|
||||
follow the specification for DNS queries as specified in
|
||||
[DNS Query and Response Defaults]. The handling of the DNS responses on the DNS
|
||||
queries follow, unless otherwise specified below, what is specified for
|
||||
[DNS Response] in the same specification.
|
||||
|
||||
1. Create a [DNS Query] with query type SOA and query name *Child Zone*
|
||||
("SOA Query").
|
||||
|
||||
2. Create a [DNS Query] with query type MX and query name *Child Zone*
|
||||
("MX Query").
|
||||
|
||||
3. Obtain the set of name server IP addresses using [Method4] and [Method5]
|
||||
("Name Server IP").
|
||||
|
||||
4. Create the following empty sets
|
||||
|
||||
1. Name server IP address ("No Response MX Query").
|
||||
2. Name server IP address and associated RCODE value
|
||||
("Unexpected RCODE MX Response").
|
||||
3. Name server IP address ("Non-authoritative MX").
|
||||
4. Name server IP address ("No MX RRset").
|
||||
5. Name server IP address and associated MX RRset ("MX RRset").
|
||||
|
||||
5. For each name server IP in *Name Server IP* do:
|
||||
|
||||
1. Send *SOA Query* over UDP to the name server.
|
||||
2. Go to next name server IP if at least one of the following criteria is
|
||||
met:
|
||||
1. There is no DNS response.
|
||||
2. The RCODE of the response is not "NoError" ([IANA RCODE List]).
|
||||
3. The AA flag is not set in the response.
|
||||
4. There is no SOA record with owner name matching the query.
|
||||
|
||||
2. Send *MX Query* over UDP to the name server and collect the
|
||||
response, and:
|
||||
1. If the response has the TC flag set, re-query over TCP and use that
|
||||
response instead.
|
||||
2. If there is no DNS response, then add the name server IP to the
|
||||
*No Response MX Query* set.
|
||||
3. Else, if the RCODE of response is not "NoError" ([IANA RCODE List]),
|
||||
then add the name server IP and the RCODE to the
|
||||
*Unexpected RCODE MX Response* set.
|
||||
4. Else, if the AA flag is not set in the response, then add the name
|
||||
server IP to the *Non-authoritative MX* set.
|
||||
5. Else, if there is no MX record with matching owner name in the answer
|
||||
section, then add the name server (IP) to the *No MX RRset* set.
|
||||
6. Else do:
|
||||
1. Extract the MX RRset from the response.
|
||||
2. Add the name server IP and the MX RRset to the *MX RRset* set.
|
||||
|
||||
6. If the set *No Response MX Query* is non-empty, then output
|
||||
*[Z09_NO_RESPONSE_MX_QUERY]* with the name server IP addresses from the set.
|
||||
|
||||
7. If the set *Unexpected RCODE MX Response* is non-empty, then for each RCODE
|
||||
in the set, do:
|
||||
* Output *[Z09_UNEXPECTED_RCODE_MX]* with the RCODE value
|
||||
([IANA RCODE List]) and the name server IP addresses from the set.
|
||||
|
||||
8. If the set *Non-authoritative MX* is non-empty, then output
|
||||
*[Z09_NON_AUTH_MX_RESPONSE]* with the name server IP addresses from
|
||||
the set.
|
||||
|
||||
9. If both *No MX RRset* set and *MX RRset* set are non-empty then:
|
||||
1. Output *[Z09_INCONSISTENT_MX]*.
|
||||
2. Output *[Z09_NO_MX_FOUND]* with the name server IP addresses from the
|
||||
*No MX RRset* set.
|
||||
3. Output *[Z09_MX_FOUND]* with the name server IP addresses from the
|
||||
*MX RRset* set.
|
||||
|
||||
10. If the *MX RRset* set is non-empty (the *No MX RRset* set is empty or
|
||||
non-empty), then do:
|
||||
1. If the RRsets in *MX RRset* are not equal for all name servers then do:
|
||||
1. Output *[Z09_INCONSISTENT_MX_DATA]*.
|
||||
2. For each RRset in *MX RRset*, output *[Z09_MX_DATA]* with the mail
|
||||
targets from the RDATA and the associated name server IP addresses in
|
||||
the set.
|
||||
2. Else do:
|
||||
1. If the mailtarget of any of the MX records in the RRset in *MX RRset*
|
||||
is a [Null MX] then do:
|
||||
1. If there are more than one record in the MX RRset, then output
|
||||
*[Z09_NULL_MX_WITH_OTHER_MX]* with the mail targets from the RDATA
|
||||
of MX records.
|
||||
2. If the preference of the [Null MX] is non-zero then output
|
||||
*[Z09_NULL_MX_NON_ZERO_PREF]*.
|
||||
2. Else, if *Child Zone* is a [TLD] with a [non-Null MX][Null MX] then
|
||||
output *[Z09_TLD_EMAIL_DOMAIN]*.
|
||||
3. Else, if *Child Zone* is the root zone with a [non-Null MX][Null MX] then
|
||||
output *[Z09_ROOT_EMAIL_DOMAIN]*.
|
||||
4. Else, output *[Z09_MX_DATA]* with the mail targets from the RDATA and
|
||||
the associated name server IP addresses in the set.
|
||||
|
||||
11. If the *No MX RRset* set is non-empty and the *MX RRset* set is empty, then
|
||||
output *[Z09_MISSING_MAIL_TARGET]* unless
|
||||
1. *Child Zone* is the root zone ("."), or
|
||||
2. *Child Zone* is a [TLD], or
|
||||
3. *Child Zone* is a zone in the .ARPA tree.
|
||||
|
||||
|
||||
## Outcome(s)
|
||||
|
||||
The outcome of this Test Case is "fail" if there is at least one message
|
||||
with the severity level *[ERROR]* or *[CRITICAL]*.
|
||||
|
||||
The outcome of this Test Case is "warning" if there is at least one message
|
||||
with the severity level *[WARNING]*, but no message with severity level
|
||||
*ERROR* or *CRITICAL*.
|
||||
|
||||
In other cases, no message or only messages with severity level
|
||||
*[INFO]* or *[NOTICE]*, the outcome of this Test Case is "pass".
|
||||
|
||||
|
||||
## Special procedural requirements
|
||||
|
||||
If either IPv4 or IPv6 transport is disabled, ignore the evaluation of the
|
||||
result of any test using this transport protocol and log a message reporting
|
||||
the ignored result.
|
||||
|
||||
|
||||
## Intercase dependencies
|
||||
|
||||
None.
|
||||
|
||||
|
||||
## Terminology
|
||||
|
||||
The term "Null MX" is used for an MX record where the mail target is "." as
|
||||
defined in [RFC 7505] with the specific restrictions given in
|
||||
[section 3][RFC 7505#section-3] of that RFC.
|
||||
|
||||
The term "TLD" is used for "Top Level Domain", i.e. a zone whose name consists
|
||||
of a single label (ignoring the empty label after the final dot).
|
||||
|
||||
The term "Email Domain" is used for the domain name at right of the at-sign ("@")
|
||||
in an email address.
|
||||
|
||||
[Argument list]: ../ArgumentsForTestCaseMessages.md
|
||||
[Connectivity01]: ../Connectivity-TP/connectivity01.md
|
||||
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
|
||||
[DNS Query and Response Defaults]: ../DNSQueryAndResponseDefaults.md
|
||||
[DNS Query]: ../DNSQueryAndResponseDefaults.md#default-setting-in-dns-query
|
||||
[DNS Response]: ../DNSQueryAndResponseDefaults.md#default-handling-of-a-dns-response
|
||||
[ERROR]: ../SeverityLevelDefinitions.md#error
|
||||
[Email Domain]: #terminology
|
||||
[IAB Statement]: https://www.iab.org/documents/correspondence-reports-documents/2013-2/iab-statement-dotless-domains-considered-harmful/
|
||||
[IANA RCODE List]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
|
||||
[INFO]: ../SeverityLevelDefinitions.md#info
|
||||
[Internet Architecture Board]: https://en.wikipedia.org/wiki/Internet_Architecture_Board
|
||||
[Method4]: ../Methods.md#method-4-obtain-glue-address-records-from-parent
|
||||
[Method5]: ../Methods.md#method-5-obtain-the-name-server-address-records-from-child
|
||||
[NOTICE]: ../SeverityLevelDefinitions.md#notice
|
||||
[Null MX]: #terminology
|
||||
[RFC 2142#section-7]: https://datatracker.ietf.org/doc/html/rfc2142#section-7
|
||||
[RFC 2142]: https://datatracker.ietf.org/doc/html/rfc2142
|
||||
[RFC 3172]: https://datatracker.ietf.org/doc/html/rfc3172
|
||||
[RFC 5321#section-2.3.5]: https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.5
|
||||
[RFC 5321#section-5.1]: https://datatracker.ietf.org/doc/html/rfc5321#section-5.1
|
||||
[RFC 7505#section-3]: https://datatracker.ietf.org/doc/html/rfc7505#section-3
|
||||
[RFC 7505]: https://datatracker.ietf.org/doc/html/rfc7505
|
||||
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
|
||||
[TLD]: #terminology
|
||||
[WARNING]: ../SeverityLevelDefinitions.md#warning
|
||||
[Z09_INCONSISTENT_MX]: #summary
|
||||
[Z09_INCONSISTENT_MX_DATA]: #summary
|
||||
[Z09_MISSING_MAIL_TARGET]: #summary
|
||||
[Z09_MX_DATA]: #summary
|
||||
[Z09_MX_FOUND]: #summary
|
||||
[Z09_NON_AUTH_MX_RESPONSE]: #summary
|
||||
[Z09_NO_MX_FOUND]: #summary
|
||||
[Z09_NO_RESPONSE_MX_QUERY]: #summary
|
||||
[Z09_NULL_MX_NON_ZERO_PREF]: #summary
|
||||
[Z09_NULL_MX_WITH_OTHER_MX]: #summary
|
||||
[Z09_ROOT_EMAIL_DOMAIN]: #summary
|
||||
[Z09_TLD_EMAIL_DOMAIN]: #summary
|
||||
[Z09_UNEXPECTED_RCODE_MX]: #summary
|
||||
[Zonemaster-Engine profile]: ../../../configuration/profiles.md
|
||||
100
zonemaster/docs/public/specifications/tests/Zone-TP/zone10.md
Normal file
100
zonemaster/docs/public/specifications/tests/Zone-TP/zone10.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# ZONE10: No multiple SOA records
|
||||
|
||||
|
||||
## Test case identifier
|
||||
**ZONE10**
|
||||
|
||||
|
||||
## Objective
|
||||
|
||||
The SOA record is crucial for the DNS zone and "exactly one SOA RR should
|
||||
be present at the top of the zone" ([RFC 1035][RFC 1035#5.2], section 5.2).
|
||||
This test case will verify that the zone of the domain to be tested return
|
||||
exactly one SOA record.
|
||||
|
||||
|
||||
## Scope
|
||||
|
||||
It is assumed that *Child Zone* is also tested by [Connectivity01]. This test
|
||||
case will set DEBUG level on messages for non-responsive name servers.
|
||||
|
||||
|
||||
## Inputs
|
||||
|
||||
* "Child Zone" - The domain name to be tested.
|
||||
|
||||
|
||||
## Ordered description of steps to be taken to execute the test case
|
||||
|
||||
1. Obtain the set of name server IP addresses using [Method4] and [Method5]
|
||||
("NS IP").
|
||||
|
||||
2. Create a SOA query for the apex of the *Child Zone* with RD flag unset.
|
||||
|
||||
3. For each name server in *NS IP* do:
|
||||
1. Send the SOA query over UDP to the name server.
|
||||
2. If the name server does not respond with a DNS response, then
|
||||
output *[NO_RESPONSE]*.
|
||||
3. Else, if the DNS response does not include a SOA record in the
|
||||
answer section, then output *[NO_SOA_IN_RESPONSE]*.
|
||||
4. Else, if the SOA record or records in the answer section do not
|
||||
have *Child Zone* as owner name, then output *[WRONG_SOA]*.
|
||||
5. Else, if the DNS response includes multiple SOA records in the
|
||||
answer section, then output *[MULTIPLE_SOA]*.
|
||||
|
||||
4. If no message is outputted for any server, then output *[ONE_SOA]*.
|
||||
|
||||
|
||||
## Outcome(s)
|
||||
|
||||
The outcome of this Test Case is "fail" if there is at least one message
|
||||
with the severity level *ERROR* or *CRITICAL*.
|
||||
|
||||
The outcome of this Test Case is "warning" if there is at least one message
|
||||
with the severity level *WARNING*, but no message with severity level
|
||||
*ERROR* or *CRITICAL*.
|
||||
|
||||
In other cases the outcome of this Test Case is "pass".
|
||||
|
||||
Message | Default severity level
|
||||
:-----------------------------|:-----------------------------------
|
||||
MULTIPLE_SOA | ERROR
|
||||
NO_RESPONSE | DEBUG
|
||||
NO_SOA_IN_RESPONSE | DEBUG
|
||||
ONE_SOA | INFO
|
||||
WRONG_SOA | DEBUG
|
||||
|
||||
|
||||
## Special procedural requirements
|
||||
|
||||
If either IPv4 or IPv6 transport is disabled, ignore the evaluation of the
|
||||
result of any test using this transport protocol. Log a message reporting
|
||||
on the ignored result.
|
||||
|
||||
|
||||
## Intercase dependencies
|
||||
|
||||
None.
|
||||
|
||||
|
||||
## Terminology
|
||||
|
||||
When the term "using Method" is used, names and IP addresses are fetched
|
||||
using the defined [Methods].
|
||||
|
||||
The term "send" (to an IP address) is used when a DNS query is sent to
|
||||
a specific name server.
|
||||
|
||||
|
||||
[Connectivity01]: ../Connectivity-TP/connectivity01.md
|
||||
[MULTIPLE_SOA]: #outcomes
|
||||
[Method4]: ../Methods.md#method-4-obtain-glue-address-records-from-parent
|
||||
[Method5]: ../Methods.md#method-5-obtain-the-name-server-address-records-from-child
|
||||
[Methods]: ../Methods.md
|
||||
[NO_RESPONSE]: #outcomes
|
||||
[NO_SOA_IN_RESPONSE]: #outcomes
|
||||
[ONE_SOA]: #outcomes
|
||||
[RFC 1035#5.2]: https://datatracker.ietf.org/doc/html/rfc1035#section-5.2
|
||||
[WRONG_SOA]: #outcomes
|
||||
[terminology]: #terminology
|
||||
|
||||
287
zonemaster/docs/public/specifications/tests/Zone-TP/zone11.md
Normal file
287
zonemaster/docs/public/specifications/tests/Zone-TP/zone11.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# ZONE11: SPF policy validation
|
||||
|
||||
## Test case identifier
|
||||
**ZONE11**
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Objective](#objective)
|
||||
* [Scope](#scope)
|
||||
* [Inputs](#inputs)
|
||||
* [Summary](#summary)
|
||||
* [Test procedure](#test-procedure)
|
||||
* [Outcome(s)](#outcomes)
|
||||
* [Special procedural requirements](#special-procedural-requirements)
|
||||
* [Intercase dependencies](#intercase-dependencies)
|
||||
* [Terminology](#terminology)
|
||||
|
||||
## Objective
|
||||
|
||||
Sender Policy Framework (SPF) version 1, defined in [RFC 7208], is a mechanism
|
||||
allowing domain name owners to specify which hosts are allowed to send mail
|
||||
claiming to be from that domain. It is implemented by means of TXT records in
|
||||
a structured format.
|
||||
|
||||
This test case looks up SPF records in the apex of *Child Zone*. It checks
|
||||
that there is at most one published SPF policy and, if present, also checks
|
||||
its syntax.
|
||||
|
||||
The root zone ("."), [TLD] zones and zones under .ARPA are treated
|
||||
differently. These zones are not expected to be used as [Email Domains][Email
|
||||
Domain]. For these zones, this test case generates a message if an [non-null
|
||||
SPF][Null SPF] policy is found.
|
||||
|
||||
The root zone cannot be an [Email Domain] because according to the syntax
|
||||
rules in [RFC 5321, section 4.1.2][RFC 5321#4.1.2], it is not possible to
|
||||
construct an email address having the root name (".") as domain part.
|
||||
|
||||
Although top-level domains ([TLDs][TLD]) can technically function as [Email
|
||||
Domains][Email Domain] ([RFC 5321, section 2.3.5][RFC 5321#2.3.5]), they
|
||||
usually do not have this purpose. The [Internet Architecture Board] concludes
|
||||
in a report named "[Dotless Domains Considered Harmful]" that domain names
|
||||
that only consists of one label, e.g. "se", "fr" or "com", should not be used
|
||||
for various Internet services. This means [TLD] names should not be used as
|
||||
[Email Domains][Email Domain].
|
||||
|
||||
As for .ARPA, [RFC 3172] states that "This domain is termed an 'infrastructure
|
||||
domain', as its role is to support the operating infrastructure of the
|
||||
Internet. In particular, the 'arpa' domain is not to be used in the same
|
||||
manner (e.g., for naming hosts) as other generic Top Level Domains are
|
||||
commonly used". This means any name under .ARPA should not be used as [Email
|
||||
Domains][Email Domain].
|
||||
|
||||
## Scope
|
||||
|
||||
It is assumed that *Child Zone* has been tested and reported by
|
||||
[Connectivity01]. This test case will just ignore non-responsive name servers
|
||||
or name servers not giving a correct DNS response for an authoritative name
|
||||
server.
|
||||
|
||||
## Inputs
|
||||
|
||||
* "Child Zone" - The domain name to be tested.
|
||||
|
||||
## Summary
|
||||
|
||||
Message Tag | Level | Arguments | Message ID for message tag
|
||||
:--------------------------------|:--------|:----------------|:--------------------------------------------
|
||||
Z11_DIFFERENT_SPF_POLICIES_FOUND | NOTICE | ns_list | The following name servers returned the same SPF policy. Name servers: {ns_list}.
|
||||
Z11_INCONSISTENT_SPF_POLICIES | WARNING | | One or more name servers do not publish the same SPF policy as the others.
|
||||
Z11_NO_SPF_FOUND | NOTICE | domain | No SPF policy was found for {domain}.
|
||||
Z11_NO_SPF_NON_MAIL_DOMAIN | INFO | domain | No SPF policy was found for {domain}, which is a type of domain (root, TLD or under .ARPA) not expected to be used for email.
|
||||
Z11_NON_NULL_SPF_NON_MAIL_DOMAIN | NOTICE | domain | A non-null SPF policy was found on {domain}, although this type of domain (root, TLD or under .ARPA) is not expected to be used for email.
|
||||
Z11_NULL_SPF_NON_MAIL_DOMAIN | INFO | domain | A null SPF policy was found on {domain}, which is a type of domain (root, TLD or under .ARPA) not expected to be used for email.
|
||||
Z11_SPF_MULTIPLE_RECORDS | WARNING | ns_list | The following name servers returned more than one SPF policy. Name servers: {ns_list}.
|
||||
Z11_SPF_SYNTAX_ERROR | WARNING | domain, ns_list | The SPF policy of {domain} has a syntax error. Policy retrieved from the following nameservers: {ns_list}.
|
||||
Z11_SPF_SYNTAX_OK | INFO | domain | The SPF policy of {domain} has correct syntax.
|
||||
Z11_UNABLE_TO_CHECK_FOR_SPF | WARNING | | None of the zone’s name servers responded with an authoritative response to queries for SPF policies.
|
||||
|
||||
The value in the Level column is the default severity level of the message. The
|
||||
severity level can be changed in the [Zonemaster-Engine profile]. Also see the
|
||||
[Severity Level Definitions] document.
|
||||
|
||||
The argument names in the Arguments column lists the arguments used in the
|
||||
message. The argument names are defined in the [argument list].
|
||||
|
||||
Name servers may have multiple IP addresses bound to the same name, and the
|
||||
same IP address may be used by multiple name server names. Message tags whose
|
||||
argument lists include "ns_list" shall contain all such name and IP address
|
||||
pairs.
|
||||
|
||||
## Test procedure
|
||||
|
||||
In this section and unless otherwise specified below, the term "[DNS Query]"
|
||||
follows the specification for DNS queries as specified in [DNS Query and
|
||||
Response Defaults]. The handling of the DNS responses on the DNS queries follow,
|
||||
unless otherwise specified below, what is specified for [DNS Response] in the
|
||||
same specification.
|
||||
|
||||
1. Create a [DNS Query] with query type TXT and query name *Child Zone* ("TXT
|
||||
query").
|
||||
|
||||
2. Create an empty set of pairs of (names and IP address) pairs and strings,
|
||||
"SPF-Policies".
|
||||
|
||||
3. Retrieve all name server names and IP addresses for *Child Zone* using
|
||||
methods [Get-Del-NS-Names-and-IPs] and [Get-Zone-NS-Names-and-IPs] ("Name
|
||||
Servers").
|
||||
|
||||
4. For each distinct name server IP address in *Name Servers* do:
|
||||
|
||||
1. Send *TXT Query* to the name server and collect the [DNS Response].
|
||||
|
||||
2. Go to the next name server if at least one of the following criteria is
|
||||
met:
|
||||
|
||||
1. There is no DNS response.
|
||||
2. [RCODE Name] of the response is not "NoError".
|
||||
3. The AA flag is not set in the response.
|
||||
|
||||
3. If the name server responds with no TXT record, then add the pair
|
||||
consisting of the *Name Servers* and the empty string to the
|
||||
*SPF-Policies* set.
|
||||
|
||||
4. If the name server responds with at least one TXT record and none is an
|
||||
[SPF TXT record], then add the pair consisting of the *Name Servers*
|
||||
and the empty string to the *SPF-Policies* set.
|
||||
|
||||
5. If the name server responds with at least one TXT record that is an [SPF
|
||||
TXT record], then, for each [SPF TXT record] do:
|
||||
|
||||
1. [Concatenate] all strings in the RDATA field.
|
||||
2. Lowercase the resulting string.
|
||||
3. Add a pair consisting of the *Name Servers* and the lowercase
|
||||
string thus derived from the RDATA field to the *SPF-Policies* set.
|
||||
|
||||
6. Go to the next name server.
|
||||
|
||||
5. If the *SPF-Policies* set is empty, then output
|
||||
*[Z11_UNABLE_TO_CHECK_FOR_SPF]* and terminate the test.
|
||||
|
||||
6. If all the name server IPs in the *SPF-Policies* set contain empty strings
|
||||
(no "SPF policy"), then:
|
||||
|
||||
1. If the *Child Zone* is the root zone ("."), a [TLD] or a zone under
|
||||
.ARPA, then output *[Z11_NO_SPF_NON_MAIL_DOMAIN]* for *Child Zone* and
|
||||
terminate the test.
|
||||
|
||||
2. Else, output *[Z11_NO_SPF_FOUND]* for *Child Zone* and terminate the
|
||||
test.
|
||||
|
||||
7. For all messages outputted below, if an IP address in *Name Servers* is
|
||||
connected to more than one name server name, then all names should be
|
||||
included with the message tag.
|
||||
|
||||
8. Compare the set of *SPF-Policies* retrieved from all name servers (in the
|
||||
*SPF-Policies* set). If at least two different name servers have returned
|
||||
different sets of SPF policies, then:
|
||||
|
||||
1. Output *[Z11_INCONSISTENT_SPF_POLICIES]*.
|
||||
2. Group *SPF-Policies* by equal sets of SPF policies, such that a set of
|
||||
SPF policies is mapped to the list of *Name Servers* that returned it.
|
||||
3. For each such group of name servers, output
|
||||
*[Z11_DIFFERENT_SPF_POLICIES_FOUND]* with the set of name servers
|
||||
("ns_list") in the group.
|
||||
4. Terminate the test.
|
||||
|
||||
9. If the *SPF-Policies* set contains at least two entries with the same IP
|
||||
address, then output *[Z11_SPF_MULTIPLE_RECORDS]* with the list of
|
||||
name servers that returned more than one SPF policy and terminate the test.
|
||||
|
||||
10. The following steps assume that all name server IPs in the *SPF-Policies*
|
||||
set have the same string ("SPF policy").
|
||||
|
||||
11. If the *SPF Policy* does not [pass the syntax check][passing the syntax
|
||||
check] for SPF records, then output *[Z11_SPF_SYNTAX_ERROR]* for *Child
|
||||
Zone* and the set of name servers from which the *SPF Policy* was
|
||||
retrieved, and terminate the test.
|
||||
|
||||
12. If the *Child Zone* is the root zone ("."), a [TLD] or a zone under
|
||||
.ARPA, then:
|
||||
|
||||
1. If the *SPF Policy* is a [Null SPF] policy, then output
|
||||
*[Z11_NULL_SPF_NON_MAIL_DOMAIN]* for *Child Zone* and terminate the
|
||||
test.
|
||||
|
||||
2. If the *SPF Policy* is not a [Null SPF] policy, then output
|
||||
*[Z11_NON_NULL_SPF_NON_MAIL_DOMAIN]* for *Child Zone* and terminate the
|
||||
test.
|
||||
|
||||
13. If no other message was outputted by this test case, then output
|
||||
*[Z11_SPF_SYNTAX_OK]* for *Child Zone*.
|
||||
|
||||
## Outcome(s)
|
||||
|
||||
The outcome of this Test Case is "fail" if there is at least one message
|
||||
with the severity level *[ERROR]* or *[CRITICAL]*.
|
||||
|
||||
The outcome of this Test Case is "warning" if there is at least one message
|
||||
with the severity level *[WARNING]*, but no message with severity level
|
||||
*ERROR* or *CRITICAL*.
|
||||
|
||||
In other cases, no message or only messages with severity level
|
||||
*[INFO]* or *[NOTICE]*, the outcome of this Test Case is "pass".
|
||||
|
||||
## Special procedural requirements
|
||||
|
||||
If either IPv4 or IPv6 transport is disabled, skip sending queries over that
|
||||
transport protocol. A message will be outputted reporting that the transport
|
||||
protocol has been skipped.
|
||||
|
||||
## Intercase dependencies
|
||||
|
||||
None.
|
||||
|
||||
## Terminology
|
||||
|
||||
* "concatenate" - The term is used to refer to the conversion of a TXT
|
||||
resource record’s data to a single contiguous string, as specified in [RFC
|
||||
7208, section 3.3][RFC 7208#3.3].
|
||||
|
||||
* "Email Domain" - the domain name at the right of the at-sign ("@") in an
|
||||
email address.
|
||||
|
||||
* "passing the syntax check" - The term is used in this document to refer to
|
||||
text that is valid according to the ABNF grammar published in [RFC 7208]
|
||||
starting from [section 4.5][RFC 7208#4.5]. Alternatively, the reader may use
|
||||
an [online SPF syntax validator]; however, such online validators should not
|
||||
be used as normative references.
|
||||
|
||||
* "Null SPF" - The term is used to refer to a SPF policy record which contains
|
||||
a single term, `-all`. It designates no server as permitted sender and
|
||||
evaluation of such an SPF policy is therefore guaranteed to return a failure.
|
||||
|
||||
* "SPF TXT record" - The term is used to refer to a TXT resource record which,
|
||||
after [concatenating][concatenate] all strings within that resource record
|
||||
into one string, yields a string either equal to `v=spf1` or starting with
|
||||
`v=spf1` followed by a space, irrespective of character case.
|
||||
|
||||
* "TLD" - The term is used to refer to a "Top Level Domain", i.e. a zone whose
|
||||
name consists of a single label (ignoring the empty label after the final
|
||||
dot).
|
||||
|
||||
[Argument list]: ../ArgumentsForTestCaseMessages.md
|
||||
[argument]: #terminology
|
||||
[concatenate]: #terminology
|
||||
[Connectivity01]: ../Connectivity-TP/connectivity01.md
|
||||
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
|
||||
[DNS Query and Response Defaults]: ../DNSQueryAndResponseDefaults.md
|
||||
[DNS Query]: ../DNSQueryAndResponseDefaults.md#default-setting-in-dns-query
|
||||
[DNS Response]: ../DNSQueryAndResponseDefaults.md#default-handling-of-a-dns-response
|
||||
[Dotless Domains Considered Harmful]: https://www.iab.org/documents/correspondence-reports-documents/2013-2/iab-statement-dotless-domains-considered-harmful/
|
||||
[Email Domain]: #terminology
|
||||
[ERROR]: ../SeverityLevelDefinitions.md#error
|
||||
[Get-Del-NS-Names-and-IPs]: ../MethodsV2.md#method-get-delegation-ns-names-and-ip-addresses
|
||||
[Get-Zone-NS-Names-and-IPs]: ../MethodsV2.md#method-get-zone-ns-names-and-ip-addresses
|
||||
[INFO]: ../SeverityLevelDefinitions.md#info
|
||||
[Internet Architecture Board]: https://www.iab.org/
|
||||
[Message Tag Specification]: MessageTagSpecification.md
|
||||
[Null SPF]: #terminology
|
||||
[NOTICE]: ../SeverityLevelDefinitions.md#notice
|
||||
[online SPF syntax validator]: https://vamsoft.com/support/tools/spf-syntax-validator
|
||||
[passing the syntax check]: #terminology
|
||||
[RCODE Name]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
|
||||
[RFC 3172]: https://datatracker.ietf.org/doc/html/rfc3172
|
||||
[RFC 5321#2.3.5]: https://datatracker.ietf.org/doc/html/rfc5321#section-2.3.5
|
||||
[RFC 5321#4.1.2]: https://datatracker.ietf.org/doc/html/rfc5321#section-4.1.2
|
||||
[RFC 7208#3.3]: https://www.rfc-editor.org/rfc/rfc7208#section-3.3
|
||||
[RFC 7208#4.5]: https://www.rfc-editor.org/rfc/rfc7208#section-4.5
|
||||
[RFC 7208]: https://www.rfc-editor.org/rfc/rfc7208
|
||||
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
|
||||
[SPF TXT record]: #terminology
|
||||
[Test Case Identifier Specification]: TestCaseIdentifierSpecification.md
|
||||
[TLD]: #terminology
|
||||
[Undelegated test]: ../../test-types/undelegated-test.md
|
||||
[WARNING]: ../SeverityLevelDefinitions.md#warning
|
||||
[Z11_DIFFERENT_SPF_POLICIES_FOUND]: #summary
|
||||
[Z11_INCONSISTENT_SPF_POLICIES]: #summary
|
||||
[Z11_NO_SPF_FOUND]: #summary
|
||||
[Z11_NO_SPF_NON_MAIL_DOMAIN]: #summary
|
||||
[Z11_NON_NULL_SPF_NON_MAIL_DOMAIN]: #summary
|
||||
[Z11_NULL_SPF_NON_MAIL_DOMAIN]: #summary
|
||||
[Z11_SPF_MULTIPLE_RECORDS]: #summary
|
||||
[Z11_SPF_SYNTAX_ERROR]: #summary
|
||||
[Z11_SPF_SYNTAX_OK]: #summary
|
||||
[Z11_UNABLE_TO_CHECK_FOR_SPF]: #summary
|
||||
[Zone09 test specification]: zone09.md
|
||||
[Zonemaster-Engine profile]: ../../../configuration/profiles.md
|
||||
Reference in New Issue
Block a user