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,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 record’s 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
|
||||
Reference in New Issue
Block a user