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,73 @@
# Testing Library
This is the central part of the whole system, that actually performs DNS tests and evaluates the results.
Conceptually, the library is divided into three layers: objects that model the underlying DNS reality we're looking at, objects that look at the DNS information, perform tests on it and evaluate the results, and finally structural objects needed for the first two layers to work.
A certain amount of global state is kept (in order to make sure the zone and nameserver object caches are complete). If more than one test is run in the same process, it may or may not be desirable to clear the cache between tests.
## Design Goals
Our experience with earlier designs of tools for testing and verification of DNS leads us to consider the following attributes important in such a system.
1. Accuracy
The results reported by a testing tool must accurately reflect the reality the tool sees. This may at times make reported results difficult to interpret, and it is tempting to have the system do automated interpretation. It is useful to have a layer that helps a non-technical users understand what is being reported, but such a layer must be a high level and it must be possible for an expert user to get an unfiltered view of the results. For the results to be consistently accurate, it is also important that the tests be well defined and the software well tested.
2. Repeatability
To the largest extent possible, immediately successive probes of the same target should give the same results. Perfect repeatability cannot be achieved since the reality of the Internet is complex and changes constantly, but no randomness or unpredictability should be added by the testing tool itself.
3. Traceability
It must be possible to tell exactly what sequence of DNS responses led to a certain result being reported by the tool. The ingenuity of humans is endless, and there will always be excentric, unusual and/or faulty configurations and servers out there that we haven't seen before. When we encounter a new thing for the first time, it should be possible to examine it in detail.
Notably *not* on this list is performance. It is of course important that tests be executed as quickly as possible, but speed must not come at the cost of any of the listed characteristics. Experience also tells us that DNS testing software spends the vast majority of its time waiting for responses from nameservers, and that thus the most useful thing we can do to speed tests up is to reduce the number of questions we send to the absolute minimum. Which, conveniently enough, usually also helps make the results accurate, repeatable and traceable.
## DNS-Modeling Layer
This layer has two main types of objects.
### Zone Object
A zone is identified by its name. In a running program, there is always at most one object for every zone. A zone object contains, among other things, pointers to its parent zone, its authoritative nameservers (as listed by those nameservers themselves), the nameserves listed for it in the parent zone, and the glue address records the parent zone holds for it.
### Nameserver Object
A nameserver is identified by its name and IP address, and like for zone objects there will only be one object for each such pair. All DNS queries made by the program go through a nameserver object, and the object will cache the response to every unique query, in order to minimize the number of queries sent in total (this caching may be made by IP address alone).
## Testing Layer
This layer holds the main entry point to the testing system, where as the most basic case one can enter a domain name and run all available tests. There is a single top-level object for every complete set of tests run, holding information such as the times when the test was started and ended, as well as the results of all performed subtests.
The function of the top-level testing object is:
1. To create the zone object for the zone to be tested.
2. To perform basic tests on the zone to determine if it is possible to perform more complex tests (basically checking that the zone exists and has nameservers).
3. Load all available test modules.
4. Run requested tests in the loaded modules (by default, all tests in all modules).
5. Provide a way for tests in one loaded module to execute tests in other modules if they're available.
The tests themselves are, as indicated above, implemented as plugin modules. The modules must provide some specified methods, providing metadata about their function as well as the ability to have tests executed and their results returned.
## Structural Layer
### DNS Recursor Object
We have our own recursor in order to be able to observe and manipulate the recursion process. The main thing we want to be able to do is to see which domain delegates directly to the zone being tested, and to be able to perform tests on domains which are not yet published into the global DNS tree (undelegated tests).
### Log Entry Object
Object used to record atomic pieces of information from tests.
### Logger Object
Object used to collect Log Entry Objects from a test run, assign severity levels to single Log Entry Objects and translate them into human-readable text in various languages.
### Configuration Object
Read configuration from suitable sources and make it available to the rest of the system.
### Information Object
An object through which a user can read meta-information about the system. This should include (but not necessarily be limited to) information on which tests are available, which messages can be emitted, which translations are available and the message-to-severity mapping policy in effect.

View File

@@ -0,0 +1,66 @@
# Guidelines to implementing tests with Zonemaster
Zonemaster is a Perl framework meant to aid the implementation of DNS tests. The design of the framework is based primarily on IIS's experiences with the DNSCheck tool and the top-level-domain Pre-Delegation Testing platform. This document aims to present the rationales for the various design decisions in Zonemaster.
## Goals of the system as a whole
All design decisions are intended to contribute toward one or more of a number of overall goals. These are, in rough order of descending importance:
1. Correctness
First and foremost, the results produced by tests must be _correct_. By correct here we mean that they accurately implement the specification for a given test, and that they can be verified to do so by a competent observer.
2. Predictability
Given an identical view of the outside world, the test must always give the exact same result. There must be nothing random or arbitrary in the implementation (or the specification).
3. Transparency
We should be able to tell after the fact why a test produced the result it did. It is acceptable for this to require re-running a test with settings that record more detailed (and thus voluminous) information, but in the extreme case it should be possible to go back and look at the details of every single incoming DNS packet in order to figure out why something strange happened.
4. Modifiability
We should be able to modify the test's view of the outside world. The must common use for this is to test zones that have not yet been delegated from their intended parents.
## Looking at Zonemaster with the goals in mind
In the Zonemaster framework, tests are implemented in plugin modules. These modules must have a method called `all`, which takes a _zone object_ as its single argument. This object represents the entire outside world for the tests. Test code must never communicate with the outside world (like for example nameservers) except via the methods in the zone object.
### The zone object is the world
By forcing all communication to pass through a single chokepoint, we serve all of the goals listed above. For example, the `query_one` method makes sure to always send queries to the same child-side server (the first one in lexicographic order by stringified name). The query methods also have the ability to transparently store incoming packets for future inspection, and it will have the ability to answer queries with pre-loaded information instead of sending them out into the world (which makes it vastly easier to write unit tests for the testing code). And by having all this functionality hidden away in another object, the test code itself can be written in a more straightforward way, which in turn makes it easier to determine if it is correct.
### Zonemaster packet and record objects have helpers
The less code there is, the easier it is to determine if it actually does what it should. When writing DNS tests, there are certain actions that come up often. In order to reduce the amount of code implementing the tests themselves, we extract such actions into helper methods in the objects representing DNS packets and (possibly in the future) resource records.
The intention is that as often occurring patterns are found, they will be extracted out into surrounding objects. As a rule of thumb, I'd suggest that once a certain structure has been needed in three or more places, extracting it out should be considered.
## Implementation guidelines
### Returning information from tests, the theory
There are basically two levels at which a user is interested in the result of a test: only the plain results, or the results plus intermediate and debugging information created during the testing process. They way this separation is intended to work in Zonemaster is by a test implementation creating log entry objects for all information that might be interesting, but only return a list of the ones representing actual test results to the caller. The other ones will be kept track of by the framework, and a user can ask to get them if and when they so desire. So a user who is only interested in the results will run the test(s) and get the results as a list of log entry objects as the return value. A user who has more complex needs can ask the framework to also get the rest of the log entries.
### Test Policy
It is recommended, although not required, that each test case be implemented as its own method. What _is_ required is that a test module check with the global configuration that a certain test case should be executed before it does so.
### Code formatting
The top level of the Zonemaster git repository contains `.perltidyrc`, a config file for [Perl::Tidy]. Please use it before you push, make a pull request or otherwise send code outside of your own repository.
### Code style
The top level of the Zonemaster git repository also contains `.perlcriticrc`, a config file for [Perl::Critic]. Strive to make your code free from warnings on at least levels 4 and 5 before you send it out into the world.
### Exposing test metadata
### Returning information from tests, the practice
(to be continued)
[Perl::Critic]: https://metacpan.org/pod/Perl::Critic
[Perl::Tidy]: https://metacpan.org/pod/Perl::Tidy

View File

@@ -0,0 +1,52 @@
# Profiles
## Overview
Profiles is a configuration format and feature of Zonemaster Engine.
Each of Zonemaster CLI, Backend and GUI allow users and administrators to configure Zonemaster Engine with different profiles.
This document provides a high-level view of how profiles are applied across the different Zonemaster components.
For details on how profiles integrate with a given component, refer to the respective component documentations.
Links to the relevant sections are provided below.
## Background
The Zonemaster requirements and specification documents speak of user-configurable profiles and policies
for Zonemaster Engine and CLI.
In release v2018.2 all of the configurable features "config", "filter", "policy" and "profile" from the
requirements and specifications were integrated into a single data structure, also called "profile".
## Profiles in Zonemaster Engine
Zonemaster Engine has an effective profile that guides how it performs its tests and analyzes their results.
It comes with a sensible default profile while allowing applications to override the default behavior.
This is described in greater detail in the [Zonemaster::Engine::Profile] documentation.
## Profiles in Zonemaster Backend
Zonemaster Backend allows its administrators to configure available profiles for its users to choose from.
Configuration is described in greater detail in the [Zonemaster Backend configuration] documentation.
The [Zonemaster Backend RPC-API] documentation lists methods that accept profile name arguments.
## Profiles in Zonemaster CLI
Zonemaster CLI allows users to specify the path to a profile to be used when starting a test.
If no profile is specified, the Zonemaster Engine default profile is used.
## Profiles in Zonemaster GUI
Zonemaster GUI allows the user select profile from a set of choices.
The available profile choices are configured in a JSON file that maps profile name strings to description strings.
-------
[Zonemaster Backend RPC-API]: ../../public/using/backend/rpcapi-reference.md
[Zonemaster Backend configuration]: ../../public/configuration/backend.md#public-profiles-and-private-profiles-sections
[Zonemaster::Engine::Profile]: https://metacpan.org/pod/Zonemaster::Engine::Profile

View File

@@ -0,0 +1,28 @@
# README
## Overview
This directory contains documentation relating to the architecture of the
Zonemaster components and how they interact to achieve the desired result.
## Contents
* [Architecture Notes.md]
TBD
* [Implementation Guidelines.md]
TBD
* [Profiles.md]
Profiles is a configuration format and feature of Zonemaster Engine.
Each of Zonemaster CLI, Backend and GUI allow users and administrators to configure Zonemaster Engine with different profiles.
* [Versions and Releases.md]
TBD
[Architecture Notes.md]: Architecture%20Notes.md
[Implementation Guidelines.md]: Implementation%20Guidelines.md
[Profiles.md]: Profiles.md
[Versions and Releases.md]: Versions%20and%20Releases.md

View File

@@ -0,0 +1,120 @@
# Versions and Releases
## Introduction
This document is intended to specify the semantics of the versions numbers used for the Zonemaster Product and its
components. There are two different version schema, one for the Zonemaster Product, and one for its components.
The main Zonemaster Repository ([Zonemaster]) stores the specifications
and documentation for the Zonemaster Product. There is no direct code for Zonemaster in that repository. The Zonemaster
components are part of the Zonemaster Product, but stored in separate repositories
([Zonemaster-LDNS], [Zonemaster-Engine], [Zonemaster-CLI], [Zonemaster-Backend] and [Zonemaster-GUI].
This document also discusses how the Zonemaster project intend to do new releases.
## Version Number Syntax for Zonemaster product
Published version numbers of the Zonemaster Product (stored in the main repository, i.e. [Zonemaster]) are in format
_vYYYY.I.i_, where
* "v" is the literal character,
* "YYYY" is the year of the creation of the release in four digits,
* "." is the literal dot, and
* "I" and "i" are integer counters starting with 1.
* "I" or "i" (not both) is incremented for each release unless "YYYY" is incremented.
* If "YYYY" is incremented, then "I" is reset to 1 and "i" is omitted.
* If "I" is incremented, then ".i" omitted, e.g. from _v2016.1.2_ to _v2016.2_.
* If "i" is incremented, then "I" remains the same as the previous version, e.g. from _v2016.1.1_ to _v2016.1.2_.
* "I" can be incremented even if there is no ".i", e.g. from _v2016.3_ to _v2016.4_.
The product version is normally incremented with the "i" only, e.g. from _v2016.3_ to _v2016.3.1_, when no component has
been updated on major or minor version. If any component has been updated on major or minor version, then the "YYYY" or
"I" must be updated in the product version.
### Versioning principle
A specific version of the Zonemaster Product includes, besides specifications and other documents, a specific
version of each of the Zonemaster components. The specifications and other documents are stored in the main
repository, and the version is defined in Git by a tag on the last commit. The included versions of the components is
defined by the [Changes][Zonemaster-Changes] file.
## Version Number Syntax for Zonemaster components
Published version numbers of each Zonemaster component is in the common x.y.z triplet form. The x part is referred to
as the _major version_, the y part as the _minor version_ and the z part as the _patch version_.
### Versioning principle
Zonemaster follow the ideas of [Semantic Versioning]. This is how it is stated (version 2.0.0):
>Given a version number MAJOR.MINOR.PATCH, increment the:
>1. MAJOR version when you make incompatible API changes,
>2. MINOR version when you add functionality in a backwards-compatible manner, and
>3. PATCH version when you make backwards-compatible bug fixes.
### Major version
Changes in this number indicate changes in the outward-facing interface, and it means that users of
the interface probably have to do changes to their code, or changes of the usage.
### Minor Version
Changes in the minor version number indicate that there are functional changes that is fully backward compatible.
If the user wants to utilize the new features and functions, calls to Zonemaster might have to be changed.
Interface changes are permitted, as long as they
are of such a nature that they do not affect current users. That is, the interface after a minor version upgrade should be
a strict superset of the interface as it was before.
### Patch Version
Changes in the patch version number indicate internal changes in the library, that need not be visible to an external user
in any way other than the reported test results being more correct or previous bug does not show up.
### Development Versions
Interim versions for development use (that is, intended for developers working on the versioned component itself rather
than developers using the component) are created directly from the "develop" branch of the Git repositories, and are
not published on [CPAN] ([Zonemaster-GUI] is never published at [CPAN]).
## Publication of releases
Major, minor and patch releases of the Zonemaster Components, including the mail repository, are published in the GitHub
repositories by merging the code to the "master" branch in Git and by creating a release note in GitHub. In the normal
case the Perl based components are also published at [CPAN]. The rest of the Zonemaster Product
([Zonemaster-GUI], specifications and documentation) is only available in the "master" branch in each repository.
All components have clear installation instructions for installing the latest version.
## Release Handling
### Development Releases
Issued as needed.
### Patch Versions
The goal is that it should be easy to do patch releases, in order to encourage fixing problems quickly. All unit tests
must pass, and all changes must be properly documented. Besides that, enough testing should be completed before a new
version is released. Automated tests that cover the corrected code should be included.
### Minor Versions
These should be done with more care. Not only must all unit tests pass and everything be documented, but release
candidates should be produced and known major users of the component should be encouraged to test the release
candidates.
### Major version
When this happens, it must be clearly documented and all parts of Zonemaster must work together. Automated tests for new
functionality must be created before release, and integration testing between components must be performed.
[CPAN]: https://www.cpan.org/
[Semantic Versioning]: https://semver.org/
[Zonemaster-Backend]: https://github.com/zonemaster/zonemaster-backend
[Zonemaster-CLI]: https://github.com/zonemaster/zonemaster-cli
[Zonemaster-Changes]: https://github.com/zonemaster/zonemaster/blob/master/Changes
[Zonemaster-Engine]: https://github.com/zonemaster/zonemaster-engine
[Zonemaster-GUI package file]:https://github.com/zonemaster/zonemaster-gui/blob/master/package.json
[Zonemaster-GUI]: https://github.com/zonemaster/zonemaster-gui
[Zonemaster-LDNS]: https://github.com/zonemaster/zonemaster-ldns
[Zonemaster]: https://github.com/zonemaster/zonemaster