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,21 @@
# Delegation 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|
|:---------|:--------------------|
|[DELEGATION01](delegation01.md)|Minimum number of name servers |
|[DELEGATION02](delegation02.md)|Name servers must have distinct IP addresses|
|[DELEGATION03](delegation03.md)|No truncation of referrals|
|[DELEGATION04](delegation04.md)|Name server is authoritative|
|[DELEGATION05](delegation05.md)|Name server must not point at CNAME alias|
|[DELEGATION06](delegation06.md)|Existence of SOA|
|[DELEGATION07](delegation07.md)|Parent glue name records present in child|

View File

@@ -0,0 +1,135 @@
# DELEGATION01: Minimum number of name servers
## Test case identifier
**DELEGATION01**
## Objective
Section 4.1 of [RFC 1034] specifies that there must be a minimum of two name servers
for a domain. This test is done to verify this condition.
The RFC ([RFC 1034]) predates IPv6. Since IPv4 and IPv6 work as separate networks, this
test case has been extended to test for two name servers that resolve into IPv4 addresses
and IPv6 addresses respectively.
Both [RFC 3901] (section 3) and [RFC 4472] (section 1.3) states that a domain
(zone) should be available over IPv4 for the time being. Therefore, it is by the
default level in this test case considered to be more problematic not being available
over IPv4 than not being available over IPv6.
## Inputs
"Child Zone" - The domain name to be tested
## Ordered description of steps to be taken to execute the test case
1. Using [Method2], obtain the complete set of names of the name servers
from the delegation of the *Child Zone*.
2. Count the name server names:
1. If zero or one, emit *[NOT_ENOUGH_NS_DEL]*.
2. If two or more, emit *[ENOUGH_NS_DEL]*.
3. Using [Method4], obtain the IP addresses for the name servers of the
delegation of the *Child Zone*.
4. Count the number of name server names that resolve into at least one IPv4
address:
1. If zero, emit *[NO_IPV4_NS_DEL]*.
2. If one, emit *[NOT_ENOUGH_IPV4_NS_DEL]*.
3. If two or more, emit *[ENOUGH_IPV4_NS_DEL]*.
5. Count the number of name server names that resolve into at least one IPv6
address:
1. If zero, emit *[NO_IPV6_NS_DEL]*.
2. If one, emit *[NOT_ENOUGH_IPV6_NS_DEL]*.
3. If two or more, emit *[ENOUGH_IPV6_NS_DEL]*.
6. Using [Method3], obtain the complete set of names of the name servers
from the *Child Zone* for the *Child Zone*.
7. Count the name server names:
1. If zero or one, emit *[NOT_ENOUGH_NS_CHILD]*.
2. If two or more, emit *[ENOUGH_NS_CHILD]*.
8. Using [Method5], obtain the IP addresses for the name servers from
the *Child Zone* for the *Child Zone*.
9. Count the number of name server names that resolve into at least one IPv4
address:
1. If zero, emit *[NO_IPV4_NS_CHILD]*.
2. If one, emit *[NOT_ENOUGH_IPV4_NS_CHILD]*.
3. If two or more, emit *[ENOUGH_IPV4_NS_CHILD]*.
10. Count the number of name server names that resolve into at least one IPv6
address:
1. If zero, emit *[NO_IPV6_NS_CHILD]*.
2. If one, emit *[NOT_ENOUGH_IPV6_NS_CHILD]*.
3. If two or more, emit *[ENOUGH_IPV6_NS_CHILD]*.
## 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*.
Else the outcome of this Test Case is "pass".
Message | Default severity level
:-----------------------------|:-----------------------------------
ENOUGH_IPV4_NS_CHILD | INFO
ENOUGH_IPV4_NS_DEL | INFO
ENOUGH_IPV6_NS_CHILD | INFO
ENOUGH_IPV6_NS_DEL | INFO
ENOUGH_NS_CHILD | INFO
ENOUGH_NS_DEL | INFO
NOT_ENOUGH_IPV4_NS_CHILD | ERROR
NOT_ENOUGH_IPV4_NS_DEL | ERROR
NOT_ENOUGH_IPV6_NS_CHILD | ERROR
NOT_ENOUGH_IPV6_NS_DEL | ERROR
NOT_ENOUGH_NS_CHILD | ERROR
NOT_ENOUGH_NS_DEL | ERROR
NO_IPV4_NS_CHILD | WARNING
NO_IPV4_NS_DEL | WARNING
NO_IPV6_NS_CHILD | NOTICE
NO_IPV6_NS_DEL | NOTICE
## Special procedural requirements
None
## Intercase dependencies
None
[RFC 1034]: https://datatracker.ietf.org/doc/html/rfc1034
[RFC 3901]: https://datatracker.ietf.org/doc/html/rfc3901
[RFC 4472]: https://datatracker.ietf.org/doc/html/rfc4472
[Method2]: ../Methods.md#method-2-obtain-glue-name-records-from-parent
[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
[ENOUGH_IPV4_NS_CHILD]: #outcomes
[ENOUGH_IPV4_NS_DEL]: #outcomes
[ENOUGH_IPV6_NS_CHILD]: #outcomes
[ENOUGH_IPV6_NS_DEL]: #outcomes
[ENOUGH_NS_CHILD]: #outcomes
[ENOUGH_NS_DEL]: #outcomes
[NOT_ENOUGH_IPV4_NS_CHILD]: #outcomes
[NOT_ENOUGH_IPV4_NS_DEL]: #outcomes
[NOT_ENOUGH_IPV6_NS_CHILD]: #outcomes
[NOT_ENOUGH_IPV6_NS_DEL]: #outcomes
[NOT_ENOUGH_NS_CHILD]: #outcomes
[NOT_ENOUGH_NS_DEL]: #outcomes
[NO_IPV4_NS_CHILD]: #outcomes
[NO_IPV4_NS_DEL]: #outcomes
[NO_IPV6_NS_CHILD]: #outcomes
[NO_IPV6_NS_DEL]: #outcomes

View File

@@ -0,0 +1,81 @@
# DELEGATION02: Name servers must have distinct IP addresses
## Test case identifier
**DELEGATION02:** Name servers must have distinct IP addresses
## Objective
If the domain's name servers use several different names, they can all
be using the same IP address. This may be due to a configuration error, or
a workaround for a certain policy restriction. This test case checks that
the name servers used do not reuse the same IP addresses.
Section 4.1 of [RFC 1034] says at least two name servers must be used
for a delegation.
## Inputs
"Child Zone" - The domain name to be tested.
## Ordered description of steps to be taken to execute the test case
1. Obtain the complete set of name server names in the delegation of
the *Child Zone* using [Method2] and the IP addresses for each name
using [Method4].
2. If the same IP address is found for two or more name server names,
emit *[DEL_NS_SAME_IP]* for each repeated address, else emit
*[DEL_DISTINCT_NS_IP]*.
3. Obtain the complete set of name server names from the *Child Zone*
using [Method3] and the IP addresses for each name using [Method5].
4. If the same IP address is found for two or more name server names,
emit *[CHILD_NS_SAME_IP]* for each repeated address, else emit
*[CHILD_DISTINCT_NS_IP]*.
## 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 (if message is emitted)
:---------------------|:-----------------------------------
DEL_NS_SAME_IP | ERROR
CHILD_NS_SAME_IP | ERROR
DEL_DISTINCT_NS_IP | INFO
CHILD_DISTINCT_NS_IP | INFO
## Special procedural requirements
None
## Intercase dependencies
None
[RFC 1034]: https://datatracker.ietf.org/doc/html/rfc1034
[Method2]: ../Methods.md#method-2-obtain-glue-name-records-from-parent
[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
[DEL_NS_SAME_IP]: #outcomes
[CHILD_NS_SAME_IP]: #outcomes
[DEL_DISTINCT_NS_IP]: #outcomes
[CHILD_DISTINCT_NS_IP]: #outcomes

View File

@@ -0,0 +1,137 @@
# DELEGATION03: No truncation of referrals
## Test case identifier
**DELEGATION03**
## Objective
The Domain Name System defaults to using UDP for queries and answers with a
DNS payload limit of 512 octets (bytes). Larger replies cause an initial
truncation indication leading to a subsequent handling via TCP with
substantially higher overhead. EDNS0 is used to allow for larger UDP
responses thus reducing the need for use of TCP.
But [IANA] still maintains that referrals from the parent zone name servers
must fit into a non-EDNS0 UDP DNS packet.
## Inputs
* "Child Zone" - The domain name to be tested.
## Ordered description of steps to be taken to execute the test case
1. Create a DNS packet with a maximally long subdomain
under the *Child Zone* apex (that is, 255 octets including label
separators) in the Query section.
2. Obtain the set of name server names from the delegation of
the *Child Zone* from the parent using [Method2].
3. For each name server name obtained in the previous step:
1. Create an NS record with the *Child Zone* apex as owner name
and the name server name as RDATA.
2. Add the NS record to the Authority section of the DNS packet
created above using the message compression schema defined
in section 4.1.4 of [RFC 1035] where applicable.
4. Using [Method1], get the parent zone of *Child Zone*.
5. Obtain the name server IP addresses per name server name for
the delegation using [Method4].
6. Make a set of the name server names that resolve into at least one
IPv4 address ("IPv4 Name Server Set").
7. If the *IPv4 Name Server Set* is not empty and all name server
names in it are [In-Bailiwick of Parent] then:
1. Create an A record using one of the name server names and any
IPv4 address.
2. Add the A record to the Additional section of the DNS packet
created above using the message compression schema defined in
section 4.1.4 of [RFC 1035].
8. Make a set of the name server names that resolve into at least one
IPv6 address ("IPv6 Name Server Set").
9. If the *IPv6 Name Server Set* is not empty and all name server
names in it are [In-Bailiwick of Parent] then:
1. Create a AAAA record using one of the name server names and any
IPv6 address.
2. Add the AAAA record to the Additional section of the DNS packet
created above using the message compression schema defined in
section 4.1.4 of [RFC 1035].
10. If the size of the DNS packet after encoding exceeds 512 octets
then output *[REFERRAL_SIZE_TOO_LARGE]* else output
*[REFERRAL_SIZE_OK]*.
## 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 of message
:---------------------------------|:-----------------------------------
REFERRAL_SIZE_TOO_LARGE | WARNING
REFERRAL_SIZE_OK | INFO
## Special procedural requirements
None
## Intercase dependencies
None
## Terminology
The terms "in-bailiwick" and "out-of-bailiwick" are used as defined
in [RFC 7719], section 6, page 15.
## In-Bailiwick of Parent
A name server name is *In-Bailiwick of Parent* if the name is a or
below the zone cut of the parent zone. If "example.com" is the parent
zone of "foofoo.example.com" then name server "ns1.barbar.example.com"
is *In-Bailiwick of Parent* for "foofoo.example.com".
All name servers of a TLD are *In-Bailiwick of Parent* since all
names are below the root apex '.'.
[RFC 7719]: https://datatracker.ietf.org/doc/html/rfc7719
[RFC 1035]: https://datatracker.ietf.org/doc/html/rfc1035
[IANA]: https://www.iana.org/help/nameserver-requirements
[in-bailiwick]: #terminology
[In-Bailiwick of Parent]: #in-bailiwick-of-parent
[Method1]: ../Methods.md#method-1-obtain-the-parent-domain
[Method2]: ../Methods.md#method-2-obtain-glue-name-records-from-parent
[Method4]: ../Methods.md#method-4-obtain-glue-address-records-from-parent
[REFERRAL_SIZE_TOO_LARGE]: #outcomes
[REFERRAL_SIZE_OK]: #outcomes

View File

@@ -0,0 +1,43 @@
## DELEGATION04: Name server is authoritative
### Test case identifier
**DELEGATION04:** Name server is authoritative
### Objective
Subsection 6.1 of [RFC 2181](https://datatracker.ietf.org/doc/html/rfc2181) specifies
that the nameservers must answer authoritatively for the domain. Answers
to queries to the name servers for the designated zone must have the "AA"
bit set.
### Inputs
The domain name to be tested.
### Ordered description of steps to be taken to execute the test case
1. Obtain the complete set of name server address records from the parent using
[Method4](../Methods.md) and the child using [Method5](../Methods.md).
2. All the uniquely obtained address records are queried for the SOA record
over TCP and UDP on port 53.
3. For each query in step 2, check whether DNS answer (bogus response are not
checked here) is obtained. If any of the query fails to respond with an
answer, then do not proceed to step 4 for that query. Exit from the test
without any exceptions.
4. If any name server fail to give an authoritative answer ("AA-bit" is set
in the answer), the test fails.
### Outcome(s)
If all the name servers answer with the AA-bit set, then the test succeeds.
### 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

View File

@@ -0,0 +1,129 @@
# DELEGATION05: Name server must not point at CNAME alias
## Test case identifier
**DELEGATION05**
## Objective
Name servers for a zone are defined in NS records. An NS record points
at a name, i.e. the RDATA for an NS record is a domain name. That
name is the name of the name server. [RFC 2181][RFC 2181#10.3], section
10.3, states that the name of the name server must not itself point at
a CNAME.
The objective of this test is to verify that name servers of the tested
domain (zone) do not point at CNAME records.
## Inputs
"Child Zone" - The domain name to be tested.
## 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.
## Ordered description of steps to be taken to execute the test case
1. Obtain the set of name server names using [Method2] and [Method3]
("NS Name").
2. Obtain the set of name server IP addresses using [Method4] and
[Method5] ("NS IP").
3. For each name server name in *NS Name* do:
1. Create a query for A record (A query) with the name server
name as owner name.
2. If the name server name is [in-domain] (sub-type of
[in-bailiwick]) then for each name server IP in
*NS IP* do:
1. Send the A query to the name server IP with the RD flag unset.
2. If the name server does not respond with a DNS response, then
output *[NO_RESPONSE]*.
3. Else, if the RCODE is not NOERROR, then output
*[UNEXPECTED_RCODE]*.
4. Else, if the answer section of the response includes a CNAME
record then output *[NS_IS_CNAME]*.
5. Else, if the response is a delegation (referral) to a
sub-zone of *Child Zone*, then:
1. Do a [DNS Lookup] of the A query with the RD
flag set.
2. If the answer section of the response includes a CNAME
record then output *[NS_IS_CNAME]*.
3. Else (the name server name is either [sibling domain]
or [out-of-bailiwick]) then do:
1. Do a [DNS Lookup] of the A query with the RD
flag set.
2. If the answer section of the response includes a CNAME
record then output *[NS_IS_CNAME]*.
4. If no *[NS_IS_CNAME]* was outputted, then output *[NO_NS_CNAME]*.
## 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
:---------------------|:-----------------------------------
NO_RESPONSE | DEBUG
UNEXPECTED_RCODE | WARNING
NS_IS_CNAME | ERROR
NO_NS_CNAME | INFO
## 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
The terms "in-domain", "sibling domain", "in-bailiwick" and
"out-of-bailiwick" are used as defined in [RFC 8499][RFC 8499#7], section 7
(p 25), where "in-domain" and "sibling domain" are defined as a sub-types
of "in-bailiwick".
The term "DNS Lookup" is used when a recursive lookup is used, though
any changes to the DNS tree introduced by an [undelegated test] must be
respected.
[Connectivity01]: ../Connectivity-TP/connectivity01.md
[DNS Lookup]: #terminology
[Method2]: ../Methods.md#method-2-obtain-glue-name-records-from-parent
[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
[NO_NS_CNAME]: #outcomes
[NO_RESPONSE]: #outcomes
[NS_IS_CNAME]: #outcomes
[RFC 2181#10.3]: https://datatracker.ietf.org/doc/html/rfc2181#section-10.3
[RFC 8499#7]: https://datatracker.ietf.org/doc/html/rfc8499#section-7
[UNEXPECTED_RCODE]: #outcomes
[in-bailiwick]: #terminology
[in-domain]: #terminology
[out-of-bailiwick]: #terminology
[sibling domain]: #terminology
[terminology]: #terminology
[undelegated test]: ../../test-types/undelegated-test.md

View File

@@ -0,0 +1,39 @@
## DELEGATION06: Existence of SOA
### Test case identifier
**DELEGATION06:** Existence of SOA
### Objective
Section 6.1 of the [RFC 2181](https://datatracker.ietf.org/doc/html/rfc2181) specifies
that the SOA record is mandatory for every zone.
This test is intended to verify the presence of a SOA record for the
domain.
### Inputs
The domain name to be tested.
### Ordered description of steps to be taken to execute the test case
1. Obtain the complete set of name server address records from the parent using
[Method4](../Methods.md) and the child using [Method5](../Methods.md).
2. All the uniquely obtained address records are queried for the SOA record.
3. If there is an answer with NOERROR and there is no content in the
answer section, this test case fails.
### Outcome(s)
If there is a SOA record present for the domain this test case succeeds.
### 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

View File

@@ -0,0 +1,35 @@
## DELEGATION07: Parent glue name records present in child
### Test case identifier
**DELEGATION07:** Parent glue name records present in child
### Objective
If the list of name servers for a domain obtained from its parent are not
found in its child zone, then it leads to an inconsistency (section 2.3
of [RIPE-114](https://www.ripe.net/publications/docs/ripe-114))
### Inputs
The domain name to be tested.
### Ordered description of steps to be taken to execute the test case
1. Obtain the complete set of name servers from the parent using
[Method2](../Methods.md) and the child using [Method3](../Methods.md).
3. If the set of NS names obtained from [Method2](../Methods.md) are
not found in [Method3](../Methods.md), then the test fails.
### Outcome(s)
If the set of glue name records obtained are found in the list of name
servers obtained from the child also, then the test succeeds
### Special procedural requirements
None
### Intercase dependencies
None