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:
2026-04-21 08:19:24 +02:00
commit 8d4eaa1489
1567 changed files with 204155 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
# Connectivity Test Plan
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|
|:---------|:--------------------|
|[CONNECTIVITY01](connectivity01.md)|UDP connectivity to name servers|
|[CONNECTIVITY02](connectivity02.md)|TCP connectivity to name servers|
|[CONNECTIVITY03](connectivity03.md)|AS Diversity|
|[CONNECTIVITY04](connectivity04.md)|IP Prefix Diversity|

View File

@@ -0,0 +1,219 @@
# CONNECTIVITY01: UDP connectivity to name servers
## Test case identifier
**CONNECTIVITY01**
## 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
UDP is the fundamental protocol to reach a general purpose name server hosting
a zone, "DNS servers MUST be able to service UDP \[...]" ([RFC 1123], section
6.1.3.2, page 75), also restated in [RFC 7766][RFC 7766#5], section 5.
This Test Case will verify if the name servers of *Child Zone* are reachable over
UDP. The name servers tested are both those in the delegation of *Child Zone* and
those in the NS records in the *Child Zone* itself.
Most Zonemaster Test Cases will query the name servers in the delegation or the
name servers appointed by the NS records in the zone for the NS or SOA record,
or both. It is crucial that problems are reported, but instead of letting several
Test Cases report the same problems found, most Test Cases assume that this test
case is run. Only this Test Case will report problems found in the following
areas over UDP:
* Name Server not responding to a query without EDNS.
* Name Server not including SOA record of *Child Zone* in the answer section in
the response on a SOA query for *Child Zone*.
* Name Server not including NS record of *Child Zone* in the answer section in
the response on an NS query for *Child Zone*.
* Name Server not setting the AA flag in a response with SOA or NS in answer
section.
* Name Server responding with unexpected [RCODE Name] (any except "NoError") on
query for SOA or NS for *Child Zone*.
In addition, this test case will output a message if transport over IPv4 or IPv6
has been disabled.
## Scope
The only UDP port defined for DNS is port 53 ([RFC 1035][RFC 1035#4.2.1], section
4.2.1), and that is the only port used by this and other Test Cases for DNS
queries to the name servers.
## Inputs
* "Child Zone" - The domain name to be tested.
## Summary
Message Tag |Level |Arguments | Message ID for message tag
:-----------------------------------|:------|:----------|:------------------------------------------------------------------------------------------
CN01_IPV4_DISABLED | NOTICE| ns_list | IPv4 is disabled. No DNS queries are sent to these name servers: "{ns_list}".
CN01_IPV6_DISABLED | NOTICE| ns_list | IPv6 is disabled. No DNS queries are sent to these name servers: "{ns_list}".
CN01_MISSING_NS_RECORD_UDP |WARNING| ns | Nameserver {ns} responds to a NS query with no NS records in the answer section over UDP.
CN01_MISSING_SOA_RECORD_UDP |WARNING| ns | Nameserver {ns} responds to a SOA query with no SOA records in the answer section over UDP.
CN01_NO_RESPONSE_NS_QUERY_UDP |WARNING| ns | Nameserver {ns} does not respond to NS queries over UDP.
CN01_NO_RESPONSE_SOA_QUERY_UDP |WARNING| ns | Nameserver {ns} does not respond to SOA queries over UDP.
CN01_NO_RESPONSE_UDP |WARNING| ns | Nameserver {ns} does not respond to any queries over UDP.
CN01_NS_RECORD_NOT_AA_UDP |WARNING| ns | Nameserver {ns} does not give an authoritative response on an NS query over UDP.
CN01_SOA_RECORD_NOT_AA_UDP |WARNING| ns | Nameserver {ns} does not give an authoritative response on an SOA query over UDP.
CN01_UNEXPECTED_RCODE_NS_QUERY_UDP |WARNING| ns, rcode | Nameserver {ns} responds with an unexpected RCODE ({rcode}) on an NS query over UDP.
CN01_UNEXPECTED_RCODE_SOA_QUERY_UDP |WARNING| ns, rcode | Nameserver {ns} responds with an unexpected RCODE ({rcode}) on an SOA query over UDP.
CN01_WRONG_NS_RECORD_UDP |WARNING| ns, domain_found, domain_expected | Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over UDP.
CN01_WRONG_SOA_RECORD_UDP |WARNING| ns, domain_found, domain_expected | Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over UDP.
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 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 [DNS Queries][DNS Query]:
1. Query type SOA and query name *Child Zone* ("SOA Query").
1. Query type NS and query name *Child Zone* ("NS Query").
2. Obtain the set of name server IP addresses using [Method4] and [Method5]
("Name Server IP").
3. If IPv4 is disabled then do:
1. Extract all name servers with IPv4 address from *Name Server IP*.
2. If the set of IPv4 name servers is non-empty then output
*[CN01_IPV4_DISABLED]* with the set of IPv4 name servers (names and IP
addresses).
4. If IPv6 is disabled then do:
1. Extract all name servers with IPv6 address from *Name Server IP*.
2. If the set of IPv6 name servers is non-empty then output
*[CN01_IPV6_DISABLED]* with the set of IPv6 name servers (names and IP
addresses).
5. For each name server in *Name Server IP* do:
1. Send *SOA Query* and *NS Query* to the name server and collect
the [DNS Responses][DNS Response].
2. If there is no DNS response on neither query, then:
1. Output *[CN01_NO_RESPONSE_UDP]* with name and IP address of the name
server.
2. Go to next name server.
3. Else:
1. Process the response on *SOA Query*:
1. If there is no [DNS response], then output
*[CN01_NO_RESPONSE_SOA_QUERY_UDP]* with name and IP address of the
name server.
2. Else, if [RCODE Name] is not "NoError" then output
*[CN01_UNEXPECTED_RCODE_SOA_QUERY_UDP]* with [RCODE Name] and name
and IP address of the name server.
3. Else, if there is no SOA record in the answer section, then
output *[CN01_MISSING_SOA_RECORD_UDP]* with name and IP address of
the name server.
4. Else, if the SOA record has owner name other than *Child Zone*
then output *[CN01_WRONG_SOA_RECORD_UDP]* with name and IP address of
the name server, the SOA record owner name and *Child Zone*.
5. Else, if AA flag is unset, then output *[CN01_SOA_RECORD_NOT_AA_UDP]*
with name and IP address of the name server.
2. Process the response on *NS Query*:
1. If there is no [DNS Response], then output
*[CN01_NO_RESPONSE_NS_QUERY_UDP]* with name and IP address of the
name server.
2. Else, if [RCODE Name] is not "NoError" then output
*[CN01_UNEXPECTED_RCODE_NS_QUERY_UDP]* with [RCODE Name] and name and
IP address of the name server.
3. Else, if there is no NS record in the answer section, then
output *[CN01_MISSING_NS_RECORD_UDP]* with name and IP address of the
name server.
4. Else, if the NS record has owner name other than *Child Zone*
then output *[CN01_WRONG_NS_RECORD_UDP]* with name and IP address of
the name server, the NS record owner name and *Child Zone*.
5. Else, if AA flag is unset, then output *[CN01_NS_RECORD_NOT_AA_UDP]*
with name and IP address of the name server.
## 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.
## Intercase dependencies
None.
## Terminology
No special terminology for this test case.
[Argument list]: ../ArgumentsForTestCaseMessages.md
[Basic02]: basic02.md
[CN01_IPV4_DISABLED]: #summary
[CN01_IPV6_DISABLED]: #summary
[CN01_MISSING_NS_RECORD_UDP]: #summary
[CN01_MISSING_SOA_RECORD_UDP]: #summary
[CN01_NO_RESPONSE_NS_QUERY_UDP]: #summary
[CN01_NO_RESPONSE_SOA_QUERY_UDP]: #summary
[CN01_NO_RESPONSE_UDP]: #summary
[CN01_NS_RECORD_NOT_AA_UDP]: #summary
[CN01_SOA_RECORD_NOT_AA_UDP]: #summary
[CN01_UNEXPECTED_RCODE_NS_QUERY_UDP]: #summary
[CN01_UNEXPECTED_RCODE_SOA_QUERY_UDP]: #summary
[CN01_WRONG_NS_RECORD_UDP]: #summary
[CN01_WRONG_SOA_RECORD_UDP]: #summary
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
[DEBUG]: ../SeverityLevelDefinitions.md#notice
[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
[INFO]: ../SeverityLevelDefinitions.md#info
[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
[RFC 1035#4.2.1]: https://www.rfc-editor.org/rfc/rfc1035#section-4.2.1
[RFC 1123]: https://www.rfc-editor.org/rfc/rfc1123
[RFC 7766#5]: https://www.rfc-editor.org/rfc/rfc7766#section-5
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
[WARNING]: ../SeverityLevelDefinitions.md#warning
[Zonemaster-Engine profile]: ../../../configuration/profiles.md

View File

@@ -0,0 +1,194 @@
# CONNECTIVITY02: TCP connectivity to name servers
## Test case identifier
**CONNECTIVITY02**
## 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
TCP is a protocol to reach a general purpose name server hosting a zone, "All
general-purpose DNS implementations MUST support \[...] TCP transport"
([RFC 7766][RFC 7766#5], section 5).
This Test Case will verify if the name servers of *Child Zone* are reachable over
TCP. The name servers tested are both those in the delegation of *Child Zone* and
those in the NS records in the *Child Zone* itself.
This Test Case will mimic the tests done by [Connectivity01], but over TCP
instead:
* Name Server responding to a query.
* Name Server including SOA record of *Child Zone* in the answer section in the
response on a SOA query for *Child Zone*.
* Name Server including NS record of *Child Zone* in the answer section in the
response on an NS query for *Child Zone*.
* Name Server setting the AA flag in a response with SOA or NS in answer section.
* Name Server responding with expected [RCODE Name] ("NoError") on query for SOA
or NS for *Child Zone*.
## Scope
The only TCP port defined for DNS is port 53 ([RFC 1035][RFC 1035#4.2.1], section
4.2.1), and that is the only port used by this and other Test Cases for DNS
queries to the name servers.
UDP connectivity is tested by Test Case [Connectivity01].
## Inputs
* "Child Zone" - The domain name to be tested.
## Summary
Message Tag |Level |Arguments | Message ID for message tag
:-----------------------------------|:------|:----------|:---------------------------------------------------------------------------------------
CN02_MISSING_NS_RECORD_TCP |WARNING| ns | Nameserver {ns} responds to a NS query with no NS records in the answer section over TCP.
CN02_MISSING_SOA_RECORD_TCP |WARNING| ns | Nameserver {ns} responds to a SOA query with no SOA records in the answer section over TCP.
CN02_NO_RESPONSE_NS_QUERY_TCP |WARNING| ns | Nameserver {ns} does not respond to NS queries over TCP.
CN02_NO_RESPONSE_SOA_QUERY_TCP |WARNING| ns | Nameserver {ns} does not respond to SOA queries over TCP.
CN02_NO_RESPONSE_TCP |WARNING| ns | Nameserver {ns} does not respond to any queries over TCP.
CN02_NS_RECORD_NOT_AA_TCP |WARNING| ns | Nameserver {ns} does not give an authoritative response on an NS query over TCP.
CN02_SOA_RECORD_NOT_AA_TCP |WARNING| ns | Nameserver {ns} does not give an authoritative response on an SOA query over TCP.
CN02_UNEXPECTED_RCODE_NS_QUERY_TCP |WARNING| ns, rcode | Nameserver {ns} responds with an unexpected RCODE ({rcode}) on an NS query over TCP.
CN02_UNEXPECTED_RCODE_SOA_QUERY_TCP |WARNING| ns, rcode | Nameserver {ns} responds with an unexpected RCODE ({rcode}) on an SOA query over TCP.
CN02_WRONG_NS_RECORD_TCP |WARNING| ns, , domain_found, domain_expected | Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on NS queries over TCP.
CN02_WRONG_SOA_RECORD_TCP |WARNING| ns, , domain_found, domain_expected | Nameserver {ns} responds with a wrong owner name ({domain_found} instead of {domain_expected}) on SOA queries over TCP.
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 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 [DNS Queries][DNS Query]:
1. Query type SOA and query name *Child Zone* over TCP ("SOA Query TCP").
1. Query type NS and query name *Child Zone* over TCP ("NS Query TCP").
2. Obtain the set of name server IP addresses using [Method4] and [Method5]
("Name Server IP").
3. For each name server in *Name Server IP* do:
1. Send *SOA Query TCP* and *NS Query TCP* to the name server and collect
the [DNS Responses][DNS Response].
2. If there is no DNS response on neither query, then:
1. Output *[CN02_NO_RESPONSE_TCP]* with name and IP address of the name
server.
2. Go to next name server.
3. Else:
1. Process the response on *SOA Query TCP*:
1. If there is no [DNS response], then output
*[CN02_NO_RESPONSE_SOA_QUERY_TCP]* with name and IP address of the
name server.
2. Else, if [RCODE Name] is not "NoError" then output
*[CN02_UNEXPECTED_RCODE_SOA_QUERY_TCP]* with [RCODE Name] and name
and IP address of the name server.
3. Else, if there is no SOA record in the answer section, then
output *[CN02_MISSING_SOA_RECORD_TCP]* with name and IP address of
the name server.
4. Else, if the SOA record has owner name other than *Child Zone*
then output *[CN02_WRONG_SOA_RECORD_TCP]* with name and IP address of
the name server, the SOA record owner name and *Child Zone*.
5. Else, if AA flag is unset, then output *[CN02_SOA_RECORD_NOT_AA_TCP]*
with name and IP address of the name server.
2. Process the response on *NS Query TCP*:
1. If there is no [DNS Response], then output
*[CN02_NO_RESPONSE_NS_QUERY_TCP]* with name and IP address of the
name server.
2. Else, if [RCODE Name] is not "NoError" then output
*[CN02_UNEXPECTED_RCODE_NS_QUERY_TCP]* with [RCODE Name] and name and
IP address of the name server.
3. Else, if there is no NS record in the answer section, then
output *[CN02_MISSING_NS_RECORD_TCP]* with name and IP address of the
name server.
4. Else, if the NS record has owner name other than *Child Zone*
then output *[CN02_WRONG_NS_RECORD_TCP]* with name and IP address of
the name server, the NS record owner name and *Child Zone*.
5. Else, if AA flag is unset, then output *[CN02_NS_RECORD_NOT_AA_TCP]*
with name and IP address of the name server.
## 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.
## Intercase dependencies
None.
## Terminology
No special terminology for this Test Case.
[Argument list]: ../ArgumentsForTestCaseMessages.md
[CN02_MISSING_NS_RECORD_TCP]: #summary
[CN02_MISSING_SOA_RECORD_TCP]: #summary
[CN02_NO_RESPONSE_NS_QUERY_TCP]: #summary
[CN02_NO_RESPONSE_SOA_QUERY_TCP]: #summary
[CN02_NO_RESPONSE_TCP]: #summary
[CN02_NS_RECORD_NOT_AA_TCP]: #summary
[CN02_SOA_RECORD_NOT_AA_TCP]: #summary
[CN02_UNEXPECTED_RCODE_NS_QUERY_TCP]: #summary
[CN02_UNEXPECTED_RCODE_SOA_QUERY_TCP]: #summary
[CN02_WRONG_NS_RECORD_TCP]: #summary
[CN02_WRONG_SOA_RECORD_TCP]: #summary
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
[Connectivity01]: connectivity01.md
[DEBUG]: ../SeverityLevelDefinitions.md#notice
[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
[INFO]: ../SeverityLevelDefinitions.md#info
[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
[RFC 1035#4.2.1]: https://www.rfc-editor.org/rfc/rfc1035#section-4.2.1
[RFC 7766#5]: https://www.rfc-editor.org/rfc/rfc7766#section-5
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
[WARNING]: ../SeverityLevelDefinitions.md#warning
[Zonemaster-Engine profile]: ../../../configuration/profiles.md

View File

@@ -0,0 +1,206 @@
# CONNECTIVITY03: AS Diversity
## Test case identifier
**CONNECTIVITY03**
## Objective
The objective in this test is to verify that all IP addresses of the domain's
authoritative name servers are announced from different ASNs (autonomous system
number). See [RFC 1930] and [Wikipedia] for an explanation of AS (autonomous
system).
This test is done separately on IPv4 and IPv6, and both must match the criterion.
[RFC 2182][RFC 2182#3.1], section 3.1, clearly specifies that distinct authoritative
name servers for a child domain should be placed in different topological and
geographical locations. The objective is to minimise the likelihood of a single
failure disabling all of them.
## Inputs
* "Child Zone" - The domain name to be tested.
* "ASN Database" - The database of ASN data to be used. Possible values
are "RIPE" and "Cymru" (the default value).
* "Cymru Base Name" - If the *ASN Database* is "Cymru", the default value
is "asnlookup.zonemaster.net".
* "Ris Whois Server" - If the *ASN Database* is "RIPE", the default value
is "riswhois.ripe.net".
## Ordered description of steps to be taken to execute the test case
1. Obtain the total set of IP addresses of the name servers for the
*Child Zone* using [Method4] and [Method5] and split those IP addresses
into one set of IPv4 addresses ("NS IPv4") and one set of IPv6 addresses
("NS IPv6"). (One of two sets may be empty.)
2. For each IP address in the set *NS IPv4* and *NS IPv6*, respectively,
determine the ASN set announcing the IP address using either the
*[Cymru database]* or the *[RIPE database]* as described in separate
sections below. Create two sets of ASN data ("NS IPv4 ASN" and
"NS IPv6 ASN", respectively).
3. Analyze the *NS IPv4 ASN* set:
1. If *NS IPv4 ASN* is empty (no IPv4 address) do nothing.
2. Else, if all IPv4 addresses are announced from one and the same ASN, output
*[IPV4_ONE_ASN]*.
3. Else, if all IPv4 addresses are announced from the same set of multiple
ASNs, output *[IPV4_SAME_ASN]*.
4. Else, output *[IPV4_DIFFERENT_ASN]*.
4. Analyze the *NS IPv6 ASN* set:
1. If *NS IPv6 ASN* is empty (no IPv6 address) do nothing.
2. Else, if all IPv6 addresses are announced from one and the same ASN, output
*[IPV6_ONE_ASN]*.
3. Else, if all IPv6 addresses are announced from the same set of multiple
ASNs, output *[IPV6_SAME_ASN]*.
4. Else, output *[IPV6_DIFFERENT_ASN]*.
## 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
:------------------|:------------
EMPTY_ASN_SET |NOTICE
ERROR_ASN_DATABASE |NOTICE
IPV4_ONE_ASN |WARNING
IPV4_SAME_ASN |NOTICE
IPV4_DIFFERENT_ASN |INFO
IPV6_ONE_ASN |WARNING
IPV6_SAME_ASN |NOTICE
IPV6_DIFFERENT_ASN |INFO
## Special procedural requirements
This test case is dependent on one of two possible services that can provide
ASN lookup, RIPE or Cymru. The service must be available over the network.
### Cymru ASN lookup
The Cymru lookup method is described on the Team Cymru [IP to ASN Mapping]
using DNS lookup, but the default data comes from [bgp.tools] (Port 179 Ltd
in England and Wales) and is continuously being mapped into
`asnlookup.zonemaster.net` by the Zonemaster project. Data is fetched from
<https://bgp.tools/table.txt>. The Cymru source can also be used, if
requested.
1. Prepend the *Cymru Base Name* with the label "origin" (IPv4) or
"origin6" (IPv6). Example of expanded basenames
("expanded base name"):
```
origin.asnlookup.zonemaster.net
origin6.asnlookup.zonemaster.net
```
2. Reverse the IP address with the same method as is used for
reverse lookup. For description see [RFC 1035][RFC 1035#3.5], section 3.5,
for IPv4 and [RFC 3596][RFC 3596#2.5], section 2.5, for IPv6.
3. Prepend the *expanded base name* with the reversed IP address. For
description see [IP to ASN Mapping].
4. Send a DNS query for the TXT record of the full name created in step 3.
5. If either the DNS response has RCODE "NXDOMAIN" or the DNS response
has RCODE "NOERROR" but empty answer section, output
*[EMPTY_ASN_SET]* and end these steps for Cymru look-up of the specific
IP address.
6. If there is no response (timeout) or the DNS response does not have
the RCODE "NOERROR", output *[ERROR_ASN_DATABASE]* and
end these steps for Cymru look-up of the specific IP address.
8. The expected response is a non-empty string in the TXT record or
records. See [IP to ASN Mapping] for examples.
9. Do the following:
1. Split the string or strings into fields.
2. If there are multiple strings (TXT records), ignore all strings
except for the string with the most specific subnet.
3. Extract the ASN or ASNs.
4. If it was not possible to extract the ASN or ASNs, output
*[ERROR_ASN_DATABASE]* and end these steps for Cymru look-up of
the specific IP address (the response was malformed).
10. Create the ASN set, for the IP address, from the ASN or ASNs from
the steps above and use it for the further processing.
### RIPE ASN lookup
The RIPE ASN lookup is described on the RIPE [RISwhois] page.
1. Construct a query string by prepending the IP address with
" -F -M ". Using "192.0.2.10" as an example, the query string will
be the following (the leading space is intentional)
```
" -F -M 192.0.2.10"
```
2. Send the query string to the *Ris Whois Server* on port
43 with the nicname (whois) protocol. Example of command
line command on unix:
```
whois -h riswhois.ripe.net " -F -M 192.0.2.10"
```
3. Do the following:
1. The non-empty line not prepended with "%" contains the string
with data (no or one such line).
2. Check if there is no string with data (empty reply). If so,
output *[EMPTY_ASN_SET]* and end these steps for RIPE look-up
of the specific IP address.
3. If there is no response from the *Ris Whois Server*, output
*[ERROR_ASN_DATABASE]* and end these steps for RIPE look-up
of the specific IP address.
4. The first field has the ASN or list of ASNs. Split that into ASNs.
5. If it was not possible to extract the ASN or ASNs, output
*[ERROR_ASN_DATABASE]* and end these steps (the response was
malformed).
8. Create the ASN set, for the IP address, from the ASN or ASNs from
the steps above and use it for the further processing.
## Intercase dependencies
None
[Bgp.tools]: https://bgp.tools/
[Cymru database]: #cymru-asn-lookup
[EMPTY_ASN_SET]: #outcomes
[ERROR_ASN_DATABASE]: #outcomes
[IP to ASN Mapping]: https://www.team-cymru.com/ip-asn-mapping
[IPV4_DIFFERENT_ASN]: #outcomes
[IPV4_ONE_ASN]: #outcomes
[IPV4_SAME_ASN]: #outcomes
[IPV6_DIFFERENT_ASN]: #outcomes
[IPV6_ONE_ASN]: #outcomes
[IPV6_SAME_ASN]: #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
[RFC 1035#3.5]: https://datatracker.ietf.org/doc/html/rfc1035#section-3.5
[RFC 1930]: https://datatracker.ietf.org/doc/html/rfc1930
[RFC 2182#3.1]: https://datatracker.ietf.org/doc/html/rfc2182#section-3.1
[RFC 3596#2.5]: https://datatracker.ietf.org/doc/html/rfc3596#section-2.5
[RIPE database]: #ripe-asn-lookup
[RISwhois]: https://www.ripe.net/analyse/archived-projects/ris-tools-web-interfaces/riswhois
[Wikipedia]: https://en.wikipedia.org/wiki/Autonomous_system_(Internet)

View File

@@ -0,0 +1,282 @@
# CONNECTIVITY04: IP Prefix Diversity
## Test case identifier
**CONNECTIVITY04**
## Table of contents
* [Objective](#objective)
* [Scope](#scope)
* [Inputs](#inputs)
* [Summary](#summary)
* [Test procedure](#test-procedure)
* [Outcome(s)](#outcomes)
* [Special procedural requirements](#special-procedural-requirements)
* [Prefix lookup methods](#prefix-lookup-methods)
* [Cymru prefix lookup](#cymru-prefix-lookup)
* [RIPE prefix lookup](#ripe-prefix-lookup)
* [Intercase dependencies](#intercase-dependencies)
* [Terminology](#terminology)
## Objective
The objective in this Test Case is to verify that all IP addresses of the
domain's authoritative name servers are not announced from the same IP prefix.
[RFC 2182, section 3.1][RFC 2182#3.1], clearly specifies that distinct authoritative
name servers for a child domain should be placed in different topological and
geographical locations. The objective is to minimise the likelihood of a single
failure disabling all of them.
## Scope
It is assumed that *Child Zone* is also 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.
* "Prefix Database" - The database of IP Prefix data to be used. Possible values
are "RIPE" and "Cymru" (the default value).
* "Cymru Base Name" - If the *Prefix Database* is "Cymru", the default value
is "asnlookup.zonemaster.net".
* "RIS Whois Server" - If the *Prefix Database* is "RIPE", the default value
is "riswhois.ripe.net".
## Summary
Message Tag | Level | Arguments | Message ID for message tag
:---------------------------|:--------|:----------------------------|:------------------------------------------------------------------------------------------------
CN04_EMPTY_PREFIX_SET | NOTICE | ns_ip | Prefix database returned no information for IP address {ns_ip}.
CN04_ERROR_PREFIX_DATABASE | NOTICE | ns_ip | Prefix database error for IP address {ns_ip}.
CN04_IPV4_DIFFERENT_PREFIX | INFO | ns_list | The following name server(s) are announced in unique IPv4 prefix(es): "{ns_list}"
CN04_IPV4_SAME_PREFIX | NOTICE | ns_list, ip_prefix | The following name server(s) are announced in the same IPv4 prefix ({ip_prefix}): "{ns_list}"
CN04_IPV4_SINGLE_PREFIX | WARNING | | All name server(s) IPv4 address(es) are announced in the same IPv4 prefix.
CN04_IPV6_DIFFERENT_PREFIX | INFO | ns_list | The following name server(s) are announced in unique IPv6 prefix(es): "{ns_list}"
CN04_IPV6_SAME_PREFIX | NOTICE | ns_list, ip_prefix | The following name server(s) are announced in the same IPv6 prefix ({ip_prefix}): "{ns_list}"
CN04_IPV6_SINGLE_PREFIX | WARNING | | All name server(s) IPv6 address(es) are announced in the same IPv6 prefix.
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
1. Create the following empty sets:
1. IP prefix, name server name and IP address ("IPv4 Prefix")
2. IP prefix, name server name and IP address ("IPv6 Prefix")
2. Obtain the set of name server names and IP addresses using
[Get-Del-NS-Names-and-IPs] and [Get-Zone-NS-Names-and-IPs] in [MethodsV2] and
split those into IPv4 and IPv6 ("NS IPv4" and "NS IPv6", respectively).
3. For each IP address in *NS IPv4* and *NS IPv6* ("NS IP Address"),
respectively, do:
1. Determine the IP prefix in which *NS IP Address* is announced
using *Prefix Database*. Go to [Prefix Lookup Methods] section below
with the IP address as input.
2. Add found IP prefix, if any, with *NS IP Address* and name server name
to the *IPv4 Prefix* and *IPv6 Prefix* sets, respectively.
4. If the *IPv4 Prefix* set is non-empty, then do:
1. For each IP prefix in the set that has two or more members, output
*[CN04_IPV4_SAME_PREFIX]* with the prefix and list of all members (name
server names and IP addresses) for that prefix.
2. For all IP prefixes in the set that have exactly one member, output
*[CN04_IPV4_DIFFERENT_PREFIX]* with the combined set of their associated
members (name server names and IP addresses).
3. If all members of *NS IPv4* are members of the same IP prefix in
*IPv4 Prefix* then output *[CN04_IPV4_SINGLE_PREFIX]*.
5. If the *IPv6 Prefix* set is non-empty, then do:
1. For each IP prefix in the set that has two or more members, output
*[CN04_IPV6_SAME_PREFIX]* with the prefix and list of all members (name
server names and IP addresses) for that prefix.
2. For all IP prefixes in the set that have exactly one member, output
*[CN04_IPV6_DIFFERENT_PREFIX]* with the combined set of their associated
members (name server names and IP addresses).
3. If all members of *NS IPv6* are members of the same IP prefix in
*IPv6 Prefix* then output *[CN04_IPV6_SINGLE_PREFIX]*.
## 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
This Test Case is dependent on one of two possible services that can provide
ASN lookup (Cymru or RIPE RIS). The service must be available over the network.
The *Child Zone* must be a valid name meeting
"[Requirements and normalization of domain names in input]".
## Prefix lookup methods
Use the prefix method set in *Prefix Database* and the IP address in the call to
this section. Refer to the appropriate section below with the IP address as
input.
### Cymru prefix lookup
The Cymru prefix lookup is described on the Team Cymru [IP to ASN Mapping]
using DNS lookup, but the default data comes from [bgp.tools] (Port 179 Ltd
in England and Wales) and is continuously being mapped into
`asnlookup.zonemaster.net` by the Zonemaster project. Data is fetched from
<https://bgp.tools/table.txt>. The Cymru source can also be used, if
requested.
1. Input is the IP address in the call to this section ("Input IP").
2. Prepend the *Cymru Base Name* with the label "origin" (IPv4) or
"origin6" (IPv6) ("Expanded Base Name"). Example of expanded basenames :
```
origin.asnlookup.zonemaster.net
origin6.asnlookup.zonemaster.net
```
3. Reverse *Input IP* with the same method as is used for reverse lookup
("Reverse IP"). For description see [RFC 1035][RFC 1035#3.5], section 3.5, for
IPv4 and [RFC 3596][RFC 3596#2.5], section 2.5, for IPv6.
4. Prepend the *Expanded Base Name* with *Reverse IP* ("Query Name").
See [IP to ASN Mapping] for details.
5. Create a [DNS Query] with query type TXT and query name *Query Name*.
("TXT Query").
6. Do [DNS Lookup] of *TXT Query*.
7. If at least one of the following criteria is met, output
*[CN04_EMPTY_PREFIX_SET]* and exit this lookup:
1. The [DNS Response] has the [RCODE Name] NXDomain.
2. The [DNS Response] has the [RCODE Name] NoError and an empty answer section.
8. If at least one of the following criteria is met, output
*[CN04_ERROR_PREFIX_DATABASE]* and exit this lookup:
1. There is no DNS response.
2. The [DNS Response] does not have the [RCODE Name] NoError.
3. The answer section has no TXT record.
9. Extract the TXT record(s) from the answer section (see [IP to ASN Mapping]
for examples). Do for each TXT record:
1. If the TXT record consists of multiple strings in RDATA, then [concatenate]
the strings into one string.
2. Using the format of such string parse the string into its parts and
extract the subnet specification.
1. If it was not possible to parse the string, ignore it and go to next TXT
record.
3. If *Input IP* does not match the extracted subnet, output
*[CN04_ERROR_PREFIX_DATABASE]*, break the processing of TXT records and
exit this loop without returning any prefix.
4. Store the extracted prefix.
10. If more than one IP prefix was stored from the loop above, keep the most
specific and discard the rest.
11. If no IP prefix was stored, output *[CN04_EMPTY_PREFIX_SET]*.
12. Return the IP prefix, or an empty string if no IP prefix was stored.
### RIPE prefix lookup
The RIPE Prefix lookup is described on the RIPE [RISwhois] page.
1. Create a query string by prepending the IP address with
" -F -M " ("WHOIS String"). E.g., using IP address "192.0.2.10":
```
" -F -M 192.0.2.10"
```
2. Create a WHOIS query (port 43 with the nicname ((whois)) protocol)
using the *WHOIS String* ("WHOIS Query"). E.g., on Linux:
```
whois -h riswhois.ripe.net " -F -M 192.0.2.10"
```
3. [Send] *WHOIS Query* to the *RIS Whois Server*.
4. If there is no response, output *[CN04_ERROR_PREFIX_DATABASE]* and exit this lookup.
5. Extract the string (non-empty line not prepended with "%") from the response, and do:
1. If there is no such string, output *[CN04_EMPTY_PREFIX_SET]* and exit this lookup.
2. Extract the IP prefix from the second field of the string.
3. If it was not possible to extract the IP prefix (i.e., malformed response),
output *[CN04_ERROR_PREFIX_DATABASE]* and exit this lookup.
6. Return the IP prefix.
## Intercase dependencies
None
## Terminology
* "Concatenate" - The term is used to refer to the conversion of a TXT
resource records data to a single contiguous string, as specified in [RFC
7208, section 3.3][RFC7208#3.3].
* "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. Compare with "[Send]".
* "Send" - The term "send" (to an IP address) is used when a DNS query is sent to
a specific name server IP address. Compare with "[DNS Lookup]".
[Argument List]: ../ArgumentsForTestCaseMessages.md
[Bgp.tools]: https://bgp.tools/
[CN04_EMPTY_PREFIX_SET]: #outcomes
[CN04_ERROR_PREFIX_DATABASE]: #outcomes
[CN04_IPV4_DIFFERENT_PREFIX]: #outcomes
[CN04_IPV4_SAME_PREFIX]: #outcomes
[CN04_IPV4_SINGLE_PREFIX]: #outcomes
[CN04_IPV6_DIFFERENT_PREFIX]: #outcomes
[CN04_IPV6_SAME_PREFIX]: #outcomes
[CN04_IPV6_SINGLE_PREFIX]: #outcomes
[Concatenate]: #terminology
[Connectivity01]: connectivity01.md
[CRITICAL]: ../SeverityLevelDefinitions.md#critical
[Cymru Database]: #cymru-prefix-lookup
[DEBUG]: ../SeverityLevelDefinitions.md#notice
[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
[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
[IP to ASN Mapping]: https://www.team-cymru.com/ip-asn-mapping
[MethodsV2]: ../MethodsV2.md
[NOTICE]: ../SeverityLevelDefinitions.md#notice
[Prefix Lookup Methods]: #prefix-lookup-methods
[RCODE Name]: https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
[Requirements and normalization of domain names in input]: ../RequirementsAndNormalizationOfDomainNames.md
[RFC 1035#3.5]: https://datatracker.ietf.org/doc/html/rfc1035#section-3.5
[RFC 2182#3.1]: https://datatracker.ietf.org/doc/html/rfc2182#section-3.1
[RFC 3596#2.5]: https://datatracker.ietf.org/doc/html/rfc3596#section-2.5
[RFC7208#3.3]: https://datatracker.ietf.org/doc/html/rfc7208#section-3.3
[RIPE Database]: #ripe-prefix-lookup
[RISwhois]: https://www.ripe.net/analyse/archived-projects/ris-tools-web-interfaces/riswhois
[Send]: #terminology
[Severity Level Definitions]: ../SeverityLevelDefinitions.md
[Undelegated test]: ../../test-types/undelegated-test.md
[WARNING]: ../SeverityLevelDefinitions.md#warning
[Zonemaster-Engine Profile]: ../../../configuration/profiles.md