diff --git a/config.yml b/config.yml index db10f4b..0348435 100644 --- a/config.yml +++ b/config.yml @@ -1,10 +1,10 @@ baseURL: https://help.happydomain.org/ defaultContentLanguage: en defaultContentLanguageInSubdir: true +enableGitInfo: true theme: hugo-theme-relearn - languages: en: title: "happyDomain help center" @@ -50,6 +50,7 @@ params: # next to it (a single space resolves to an empty logo title). linkTitle: " " showVisitedLinks: true + hideAuthorEmail: true mermaid: false # "auto" follows the OS light/dark preference: light -> green, dark -> # relearn-dark. Both must be declared as variants so the theme attaches the @@ -61,6 +62,17 @@ params: - identifier: green - identifier: relearn-dark +# The relearn theme attaches CSS classes to generated blocks (e.g. the +# `children` shortcode appends `{class="children ..."}` after its list). +# Goldmark only interprets that as block attributes when block parsing is +# enabled; otherwise it is rendered as literal text. +markup: + goldmark: + parser: + attribute: + block: true + renderer: + unsafe: true outputs: - home: [ "HTML", "RSS", "PRINT"] + home: ["HTML", "RSS", "PRINT"] diff --git a/content/_index.en.md b/content/_index.en.md index f70cf8a..476e4f1 100644 --- a/content/_index.en.md +++ b/content/_index.en.md @@ -4,9 +4,6 @@ title: Welcome to happyDomain author: Frederic description: "Finally a simple interface for domain names." archetype: home -aliases: - en/pages/login - en/pages/signup --- happyDomain is an interface that centralize your domain names and reduces the usual friction points. @@ -18,13 +15,15 @@ to have all the power of domain names, without having to read and learn all the Here's an overview of happyDomain's main features: - consolidate domain names from over 45 domain name providers or authoritative servers, -- guide administrators with clear forms, -- clearly visualize the changes that will be propagated, -- keep a history of changes made to the zone, -- return to a previous zone status with a single click, -- group records by services/needs: email, delegation, server, load balancing, etc. - abstract all technical complexity into a logical view, -- import/export the zone as a standard file, +- group records by services/needs: email, website, delegation, load balancing, etc. +- guide administrators with clear forms, +- review the details of your changes before publishing, and pick exactly which ones to apply, +- keep a history of changes and roll back to a previous zone state with a single click, +- monitor your domains and services with automatic checks (expiration, DNSSEC, response time, etc.), +- get notified as soon as a check changes state, +- check whether a domain is available for registration and inspect any domain (WHOIS, DNS resolver), +- import/export the zone as a standard file (BIND format), - keep track of actions for later auditing, - automate tasks via a REST API. diff --git a/content/_index.fr.md b/content/_index.fr.md index 4ba7511..12a1200 100644 --- a/content/_index.fr.md +++ b/content/_index.fr.md @@ -4,9 +4,6 @@ title: happyDomain description: "L'interface des noms de domaine." author: nemunaire archetype: home -aliases: - fr/pages/login - fr/pages/signup --- happyDomain est une interface qui centralise vos noms de domaines et réduit les points de friction habituels. @@ -18,13 +15,15 @@ avoir toute la puissances des noms de domaines, sans devoir lire et apprendre to Voici un aperçu des principales fonctionnalités d'happyDomain : - regrouper les noms de domaines de plus de 45 prestataires de nom de domaine ou serveurs faisant autorité, -- guider l'administrateur au moyen de formulaires clairs, -- visualiser clairement les changements qui seront propagés, -- garder un historique des changements effectués sur la zone, -- pouvoir revenir à un état antérieur de la zone en un clic, -- regrouper les enregistrements par services/besoins : emails, délégation, serveur, répartition de charge, ... - abstraire toute la complexité technique en une vue logique, -- importer/exporter la zone sous forme d'un fichier standard, +- regrouper les enregistrements par services/besoins : e-mails, site web, délégation, répartition de charge, ... +- guider l'administrateur au moyen de formulaires clairs, +- visualiser le détail des changements avant de les publier, et choisir précisément ceux à appliquer, +- garder un historique des changements et revenir à un état antérieur de la zone en un clic, +- surveiller vos domaines et services grâce à des vérifications automatiques (expiration, DNSSEC, temps de réponse, ...), +- être alerté par notifications dès qu'une vérification change d'état, +- vérifier la disponibilité d'un domaine à l'enregistrement et inspecter n'importe quel domaine (WHOIS, résolveur DNS), +- importer/exporter la zone sous forme d'un fichier standard (format BIND), - garder une trace des actions pour les auditer plus tard, - automatiser des tâches via une API REST. diff --git a/content/introduction/deploy/docker.en.md b/content/introduction/deploy/docker.en.md index e07dacb..7f18c6b 100644 --- a/content/introduction/deploy/docker.en.md +++ b/content/introduction/deploy/docker.en.md @@ -7,69 +7,335 @@ weight: 15 happyDomain is sponsored by Docker. You'll find the official container image on [the Docker Hub](https://hub.docker.com/r/happydomain/happydomain/). -This image will run happyDomain as a single process, with a LevelDB database (similarly to sqlite, LevelDB is stored on disk, no need to configure anything). +The image runs happyDomain as a single process with a LevelDB database stored on disk — no extra database to configure. ## Supported tags and architectures -All tags are build for `amd64`, `arm64` and `arm/v7` and are based on alpine. +All tags are built for `amd64`, `arm64` and `arm/v7` and are based on Alpine. -Currently, available tags are: +Currently available tags: -- `latest`: this is a the most up to date version, corresponding to the master branch. +- `latest`: the most up-to-date version, corresponding to the master branch. -## Using this image -### For testing purpose +## Quick start (single container) -You can test happyDomain or use it for your own usage, with the option `HAPPYDOMAIN_NO_AUTH=1`: this will automatically creates a default account, and disable all features related to the user management (signup, login, ...). +For a quick test or personal use, pass `HAPPYDOMAIN_NO_AUTH=1` to skip account management: ``` docker run -e HAPPYDOMAIN_NO_AUTH=1 -p 8081:8081 happydomain/happydomain ``` -Data are stored in `/data` directory. If you want to keep your settings from one run to another, you'll need to attach this directory to a Docker managed volume or to a directory on your host: +Data are stored inside the container. To keep them across restarts, attach a volume: ``` docker volume create happydomain_data docker run -e HAPPYDOMAIN_NO_AUTH=1 -v happydomain_data:/data -p 8081:8081 happydomain/happydomain ``` -### In production - -happyDomain needs to send e-mail, in order to verify addresses and doing password recovery, so you need basically to configure a SMTP relay. -Use the options `HAPPYDOMAIN_MAIL_SMTP_HOST`, `HAPPYDOMAIN_MAIL_SMTP_PORT` (default 25), `HAPPYDOMAIN_MAIL_SMTP_USERNAME` and `HAPPYDOMAIN_MAIL_SMTP_PASSWORD` for this purpose: +For a production single-container setup that sends e-mail: ``` -docker run -e HAPPYDOMAIN_MAIL_SMTP_HOST=smtp.yourcompany.com -e HAPPYDOMAIN_MAIL_SMTP_USERNAME=happydomain -e HAPPYDOMAIN_MAIL_SMTP_PASSWORD=secret -v /var/lib/happydomain:/data -p 8081:8081 happydomain/happydomain -``` - -If you prefer using a configuration file, you can place it either in `/data/happydomain.conf` to use the volume, or bind your file to `/etc/happydomain.conf`: - -``` -docker run -v happydomain.conf:/etc/happydomain.conf -p 8081:8081 happydomain/happydomain -``` - -#### Extend the base image - -By default, happyDomain uses `sendmail`, if you prefer, you can create you own image with the package `ssmtp`: - -``` -FROM happydomain/happydomain -RUN apk --no-cache add ssmtp -COPY my_ssmtp.conf /etc/ssmtp/ssmtp.conf +docker run \ + -e HAPPYDOMAIN_MAIL_SMTP_HOST=smtp.yourcompany.com \ + -e HAPPYDOMAIN_MAIL_SMTP_USERNAME=happydomain \ + -e HAPPYDOMAIN_MAIL_SMTP_PASSWORD=secret \ + -v /var/lib/happydomain:/data \ + -p 8081:8081 \ + happydomain/happydomain ``` -## Admin Interface +## Full deployment with all checkers -happyDomain exposes some administration command through a unix socket. The docker container contains a script to access this admin part: `hadmin`. +happyDomain ships every checker built-in, but several of them rely on +external tools (DNSViz, Zonemaster, Matrix federation tester) that are +packaged in their own container images. Running these as separate services +gives you the full checker experience and better isolation. -You can use it this way: +The recommended approach is `docker compose`. Save the following file as +`docker-compose.yml` and run `docker compose up -d`. + +```yaml +services: + happydomain: + image: happydomain/happydomain + ports: + - "8080:8081" + environment: + # Uncomment for single-user / testing + # HAPPYDOMAIN_NO_AUTH: "1" + + # Mail configuration (required for multi-user production use) + # HAPPYDOMAIN_MAIL_SMTP_HOST: "mailer" + + # ── DNS / DNSSEC ───────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_DNSVIZ_ENDPOINT: "http://checker-dnsviz:8080" + HAPPYDOMAIN_CHECKER_DNSSEC_ENDPOINT: "http://checker-dnssec:8080" + HAPPYDOMAIN_CHECKER_ZONEMASTER_ENDPOINT: "http://checker-zonemaster:8080" + HAPPYDOMAIN_CHECKER_ZONEMASTER_ZONEMASTERAPIURL: "http://zonemaster:5000" + HAPPYDOMAIN_CHECKER_DELEGATION_ENDPOINT: "http://checker-delegation:8080" + HAPPYDOMAIN_CHECKER_AUTHORITATIVE_CONSISTENCY_ENDPOINT: "http://checker-authoritative-consistency:8080" + HAPPYDOMAIN_CHECKER_ALIAS_ENDPOINT: "http://checker-alias:8080" + HAPPYDOMAIN_CHECKER_LEGACY_RECORDS_ENDPOINT: "http://checker-legacy-records:8080" + HAPPYDOMAIN_CHECKER_NS_RESTRICTIONS_ENDPOINT: "http://checker-ns-restrictions:8080" + HAPPYDOMAIN_CHECKER_RESOLVER_PROPAGATION_ENDPOINT: "http://checker-resolver-propagation:8080" + HAPPYDOMAIN_CHECKER_REVERSE_ZONE_ENDPOINT: "http://checker-reverse-zone:8080" + HAPPYDOMAIN_CHECKER_PTR_ENDPOINT: "http://checker-ptr:8080" + HAPPYDOMAIN_CHECKER_DANGLING_ENDPOINT: "http://checker-dangling:8080" + + # ── Security / Certificates ─────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_TLS_ENDPOINT: "http://checker-tls:8080" + HAPPYDOMAIN_CHECKER_DANE_ENDPOINT: "http://checker-dane:8080" + HAPPYDOMAIN_CHECKER_CAA_ENDPOINT: "http://checker-caa:8080" + HAPPYDOMAIN_CHECKER_BLACKLIST_ENDPOINT: "http://checker-blacklist:8080" + + # ── E-mail ──────────────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_SMTP_ENDPOINT: "http://checker-smtp:8080" + HAPPYDOMAIN_CHECKER_EMAIL_AUTOCONFIG_ENDPOINT: "http://checker-email-autoconfig:8080" + HAPPYDOMAIN_CHECKER_OPENPGPKEY_SMIMEA_ENDPOINT: "http://checker-email-keys:8080" + + # ── Web & Protocols ─────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_HTTP_ENDPOINT: "http://checker-http:8080" + HAPPYDOMAIN_CHECKER_SSH_ENDPOINT: "http://checker-ssh:8080" + HAPPYDOMAIN_CHECKER_PING_ENDPOINT: "http://checker-ping:8080" + HAPPYDOMAIN_CHECKER_SRV_ENDPOINT: "http://checker-srv:8080" + + # ── Collaboration / Messaging ───────────────────────────────────────── + HAPPYDOMAIN_CHECKER_MATRIXIM_ENDPOINT: "http://checker-matrix:8080" + HAPPYDOMAIN_CHECKER_MATRIXIM_FEDERATIONTESTERSERVER: "http://matrixfederationtester:8080/api/report?server_name=%s" + HAPPYDOMAIN_CHECKER_XMPP_ENDPOINT: "http://checker-xmpp:8080" + HAPPYDOMAIN_CHECKER_SIP_ENDPOINT: "http://checker-sip:8080" + + # ── Directory & Auth ────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_LDAP_ENDPOINT: "http://checker-ldap:8080" + HAPPYDOMAIN_CHECKER_KERBEROS_ENDPOINT: "http://checker-kerberos:8080" + HAPPYDOMAIN_CHECKER_STUNTURN_ENDPOINT: "http://checker-stun-turn:8080" + + # ── CalDAV / CardDAV ────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_CALDAV_ENDPOINT: "http://checker-caldav:8080" + HAPPYDOMAIN_CHECKER_CARDDAV_ENDPOINT: "http://checker-carddav:8080" + + # ── Optional: happyDeliver integration ──────────────────────────────── + # HAPPYDOMAIN_CHECKER_HAPPYDELIVER_ENDPOINT: "http://checker-happydeliver:8080" + + restart: unless-stopped + volumes: + - storage:/var/lib/happydomain:rw + + # ── DNS / DNSSEC checkers ────────────────────────────────────────────────── + + checker-dnsviz: + image: happydomain/checker-dnsviz + restart: unless-stopped + + checker-dnssec: + image: happydomain/checker-dnssec + restart: unless-stopped + + checker-zonemaster: + image: happydomain/checker-zonemaster + restart: unless-stopped + + zonemaster: + image: zonemaster/backend + command: full + restart: unless-stopped + + checker-delegation: + image: happydomain/checker-delegation + restart: unless-stopped + + checker-authoritative-consistency: + image: happydomain/checker-authoritative-consistency + restart: unless-stopped + + checker-alias: + image: happydomain/checker-alias + restart: unless-stopped + + checker-legacy-records: + image: happydomain/checker-legacy-records + restart: unless-stopped + + checker-ns-restrictions: + image: happydomain/checker-ns-restrictions + restart: unless-stopped + + checker-resolver-propagation: + image: happydomain/checker-resolver-propagation + restart: unless-stopped + + checker-reverse-zone: + image: happydomain/checker-reverse-zone + restart: unless-stopped + + checker-ptr: + image: happydomain/checker-ptr + restart: unless-stopped + + checker-dangling: + image: happydomain/checker-dangling + restart: unless-stopped + + # ── Security / Certificate checkers ─────────────────────────────────────── + + checker-tls: + image: happydomain/checker-tls + restart: unless-stopped + + checker-dane: + image: happydomain/checker-dane + restart: unless-stopped + + checker-caa: + image: happydomain/checker-caa + restart: unless-stopped + + checker-blacklist: + image: happydomain/checker-blacklist + restart: unless-stopped + + # ── E-mail checkers ──────────────────────────────────────────────────────── + + checker-smtp: + image: happydomain/checker-smtp + restart: unless-stopped + + checker-email-autoconfig: + image: happydomain/checker-email-autoconfig + restart: unless-stopped + + checker-email-keys: + image: happydomain/checker-email-keys + restart: unless-stopped + + # ── Web & Protocol checkers ──────────────────────────────────────────────── + + checker-http: + image: happydomain/checker-http + restart: unless-stopped + + checker-ssh: + image: happydomain/checker-ssh + restart: unless-stopped + + checker-ping: + image: happydomain/checker-ping + restart: unless-stopped + cap_add: + - NET_RAW # required for ICMP ping + + checker-srv: + image: happydomain/checker-srv + restart: unless-stopped + + # ── Collaboration / Messaging checkers ───────────────────────────────────── + + checker-matrix: + image: happydomain/checker-matrix + restart: unless-stopped + + matrixfederationtester: + image: matrixdotorg/federation-tester-backend + environment: + BIND_ADDRESS: "0.0.0.0:8080" + restart: unless-stopped + + checker-xmpp: + image: happydomain/checker-xmpp + restart: unless-stopped + + checker-sip: + image: happydomain/checker-sip + restart: unless-stopped + + # ── Directory & Auth checkers ────────────────────────────────────────────── + + checker-ldap: + image: happydomain/checker-ldap + restart: unless-stopped + + checker-kerberos: + image: happydomain/checker-kerberos + restart: unless-stopped + + checker-stun-turn: + image: happydomain/checker-stun-turn + restart: unless-stopped + + # ── CalDAV / CardDAV checkers ────────────────────────────────────────────── + + checker-caldav: + image: happydomain/checker-caldav + restart: unless-stopped + + checker-carddav: + image: happydomain/checker-carddav + restart: unless-stopped + +volumes: + storage: +``` + +### How it works + +Each checker runs as a standalone HTTP service. happyDomain delegates check +requests to the matching container via the `HAPPYDOMAIN_CHECKER__ENDPOINT` +environment variable. When an endpoint is not set, the corresponding checker +runs locally inside the happyDomain process instead. + +Two checkers rely on additional third-party backends: + +- **Zonemaster** (`checker-zonemaster`) queries the `zonemaster/backend` + service. The `HAPPYDOMAIN_CHECKER_ZONEMASTER_ZONEMASTERAPIURL` variable tells + the checker where that backend listens. +- **Matrix federation tester** (`checker-matrix`) queries the + `matrixdotorg/federation-tester-backend` service. The + `HAPPYDOMAIN_CHECKER_MATRIXIM_FEDERATIONTESTERSERVER` variable points to its + report endpoint. + +### Optional: happyDeliver + +If you run a [happyDeliver](https://happydeliver.io) instance for mail-flow +monitoring, uncomment the `HAPPYDOMAIN_CHECKER_HAPPYDELIVER_ENDPOINT` line and +add the corresponding service: + +```yaml + checker-happydeliver: + image: happydomain/checker-happydeliver + restart: unless-stopped +``` + +### Optional: blacklist API keys + +The `checker-blacklist` service works without API keys (it uses DNS-based +blocklists by default), but you can enable additional sources — Google Safe +Browsing, VirusTotal, abuse.ch URLhaus — by configuring the matching admin +options from the happyDomain administration interface once the stack is running. + + +## Admin interface + +happyDomain exposes administration commands through a Unix socket. The +container includes the `hadmin` wrapper: ``` docker exec my_container hadmin /api/users docker exec my_container hadmin /api/users/0123456789/send_validation_email -X POST ``` -This is in fact a wrapper above `curl`, but you have to start by the URL, and place options after it. +`hadmin` is a thin wrapper around `curl` — start with the URL path, then add +any `curl` options after it. + + +## Using a configuration file + +Instead of environment variables, you can place a configuration file either in +`/data/happydomain.conf` (inside the data volume) or bind-mount it to +`/etc/happydomain.conf`: + +``` +docker run -v happydomain.conf:/etc/happydomain.conf -p 8081:8081 happydomain/happydomain +``` diff --git a/content/introduction/deploy/docker.fr.md b/content/introduction/deploy/docker.fr.md index e66e19e..091fd8d 100644 --- a/content/introduction/deploy/docker.fr.md +++ b/content/introduction/deploy/docker.fr.md @@ -4,78 +4,340 @@ title: Avec Docker weight: 15 --- -happyDomain est sponsorisé Docker. +happyDomain est sponsorisé par Docker. Vous trouverez notre image officielle sur [le Docker Hub](https://hub.docker.com/r/happydomain/happydomain/). -Cette image exécutera happyDomain en tant que processus unique, avec une base de données LevelDB (similaire à sqlite, LevelDB est une base de données stockée sur le disque, il n'est pas nécessaire de configurer quoi que ce soit d'autre). +L'image exécute happyDomain en tant que processus unique avec une base de données LevelDB stockée sur le disque — aucune base de données supplémentaire à configurer. -## Versions, étiquettes and architectures supportés +## Versions, étiquettes et architectures supportées -Toutes les étiquettes (*tags*) sont construites pour les architectures de processeur les plus courantes (`amd64`, `arm64` et `arm/v7`). -Nous ne construisons des images uniquement basées sur la distribution Alpine Linux, ce qui assure des images de taille minimale. +Toutes les étiquettes (*tags*) sont construites pour `amd64`, `arm64` et `arm/v7` et sont basées sur Alpine. -Actuellement, les étiquettes disponibles sont : +Les étiquettes actuellement disponibles : -- `latest`: il s'agit de la version la plus récente, correspondant à la branche `master` de notre dépôt de sources. +- `latest` : la version la plus récente, correspondant à la branche `master` de notre dépôt. -## Utilisation de l'image +## Démarrage rapide (conteneur unique) -### À des fins de test - -Vous pouvez tester happyDomain ou l'utiliser pour votre usage personnel, avec l'option `HAPPYDOMAIN_NO_AUTH=1` : cela créera automatiquement un compte par défaut, et désactivera toutes les fonctionnalités liées à la gestion des utilisateurs (inscription, connexion, ...). +Pour un test rapide ou un usage personnel, utilisez `HAPPYDOMAIN_NO_AUTH=1` pour désactiver la gestion des comptes : ``` docker run -e HAPPYDOMAIN_NO_AUTH=1 -p 8081:8081 happydomain/happydomain ``` -Les données sont stockées dans le répertoire `/data`. -Si vous souhaitez conserver vos paramètres d'une exécution à l'autre, vous devrez attacher ce répertoire à un volume géré par Docker ou à un répertoire sur votre hôte : +Les données sont stockées à l'intérieur du conteneur. Pour les conserver entre les redémarrages, attachez un volume : ``` docker volume create happydomain_data docker run -e HAPPYDOMAIN_NO_AUTH=1 -v happydomain_data:/data -p 8081:8081 happydomain/happydomain ``` - -### En production - -happyDomain a besoin d'envoyer du courrier électronique, afin de vérifier les adresses et d'effectuer la récupération des mots de passe, vous devez donc configurer un relais SMTP. -Utilisez les options `HAPPYDOMAIN_MAIL_SMTP_HOST`, `HAPPYDOMAIN_MAIL_SMTP_PORT` (par défaut 25), `HAPPYDOMAIN_MAIL_SMTP_USERNAME` et `HAPPYDOMAIN_MAIL_SMTP_PASSWORD` à cette fin : +Pour une instance de production avec envoi d'e-mails : ``` -docker run -e HAPPYDOMAIN_MAIL_SMTP_HOST=smtp.yourcompany.com -e HAPPYDOMAIN_MAIL_SMTP_USERNAME=happydomain -e HAPPYDOMAIN_MAIL_SMTP_PASSWORD=secret -v /var/lib/happydomain:/data -p 8081:8081 happydomain/happydomain -``` - -Si vous préférez utiliser un fichier de configuration, vous pouvez le placer soit dans `/data/happydomain.conf` pour utiliser le volume, soit lier votre fichier à `/etc/happydomain.conf` : - -``` -docker run -v happydomain.conf:/etc/happydomain.conf -p 8081:8081 happydomain/happydomain +docker run \ + -e HAPPYDOMAIN_MAIL_SMTP_HOST=smtp.votreentreprise.com \ + -e HAPPYDOMAIN_MAIL_SMTP_USERNAME=happydomain \ + -e HAPPYDOMAIN_MAIL_SMTP_PASSWORD=secret \ + -v /var/lib/happydomain:/data \ + -p 8081:8081 \ + happydomain/happydomain ``` -#### Étendre l'image de base +## Déploiement complet avec tous les vérificateurs -Par défaut, happyDomain utilise `sendmail`, si vous préférez, vous pouvez créer votre propre image avec le paquet `ssmtp` : +happyDomain intègre tous les vérificateurs (*checkers*) en natif, mais certains +d'entre eux s'appuient sur des outils externes (DNSViz, Zonemaster, Matrix +federation tester) distribués dans leurs propres images Docker. Les faire +tourner comme des services séparés vous donne l'expérience complète des +vérificateurs et une meilleure isolation. +L'approche recommandée est `docker compose`. Enregistrez le fichier suivant +sous le nom `docker-compose.yml` et lancez `docker compose up -d`. + +```yaml +services: + happydomain: + image: happydomain/happydomain + ports: + - "8080:8081" + environment: + # Décommentez pour un usage mono-utilisateur / test + # HAPPYDOMAIN_NO_AUTH: "1" + + # Configuration mail (obligatoire en production multi-utilisateurs) + # HAPPYDOMAIN_MAIL_SMTP_HOST: "mailer" + + # ── DNS / DNSSEC ───────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_DNSVIZ_ENDPOINT: "http://checker-dnsviz:8080" + HAPPYDOMAIN_CHECKER_DNSSEC_ENDPOINT: "http://checker-dnssec:8080" + HAPPYDOMAIN_CHECKER_ZONEMASTER_ENDPOINT: "http://checker-zonemaster:8080" + HAPPYDOMAIN_CHECKER_ZONEMASTER_ZONEMASTERAPIURL: "http://zonemaster:5000" + HAPPYDOMAIN_CHECKER_DELEGATION_ENDPOINT: "http://checker-delegation:8080" + HAPPYDOMAIN_CHECKER_AUTHORITATIVE_CONSISTENCY_ENDPOINT: "http://checker-authoritative-consistency:8080" + HAPPYDOMAIN_CHECKER_ALIAS_ENDPOINT: "http://checker-alias:8080" + HAPPYDOMAIN_CHECKER_LEGACY_RECORDS_ENDPOINT: "http://checker-legacy-records:8080" + HAPPYDOMAIN_CHECKER_NS_RESTRICTIONS_ENDPOINT: "http://checker-ns-restrictions:8080" + HAPPYDOMAIN_CHECKER_RESOLVER_PROPAGATION_ENDPOINT: "http://checker-resolver-propagation:8080" + HAPPYDOMAIN_CHECKER_REVERSE_ZONE_ENDPOINT: "http://checker-reverse-zone:8080" + HAPPYDOMAIN_CHECKER_PTR_ENDPOINT: "http://checker-ptr:8080" + HAPPYDOMAIN_CHECKER_DANGLING_ENDPOINT: "http://checker-dangling:8080" + + # ── Sécurité / Certificats ──────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_TLS_ENDPOINT: "http://checker-tls:8080" + HAPPYDOMAIN_CHECKER_DANE_ENDPOINT: "http://checker-dane:8080" + HAPPYDOMAIN_CHECKER_CAA_ENDPOINT: "http://checker-caa:8080" + HAPPYDOMAIN_CHECKER_BLACKLIST_ENDPOINT: "http://checker-blacklist:8080" + + # ── E-mail ──────────────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_SMTP_ENDPOINT: "http://checker-smtp:8080" + HAPPYDOMAIN_CHECKER_EMAIL_AUTOCONFIG_ENDPOINT: "http://checker-email-autoconfig:8080" + HAPPYDOMAIN_CHECKER_OPENPGPKEY_SMIMEA_ENDPOINT: "http://checker-email-keys:8080" + + # ── Web & Protocoles ────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_HTTP_ENDPOINT: "http://checker-http:8080" + HAPPYDOMAIN_CHECKER_SSH_ENDPOINT: "http://checker-ssh:8080" + HAPPYDOMAIN_CHECKER_PING_ENDPOINT: "http://checker-ping:8080" + HAPPYDOMAIN_CHECKER_SRV_ENDPOINT: "http://checker-srv:8080" + + # ── Collaboration / Messagerie ──────────────────────────────────────── + HAPPYDOMAIN_CHECKER_MATRIXIM_ENDPOINT: "http://checker-matrix:8080" + HAPPYDOMAIN_CHECKER_MATRIXIM_FEDERATIONTESTERSERVER: "http://matrixfederationtester:8080/api/report?server_name=%s" + HAPPYDOMAIN_CHECKER_XMPP_ENDPOINT: "http://checker-xmpp:8080" + HAPPYDOMAIN_CHECKER_SIP_ENDPOINT: "http://checker-sip:8080" + + # ── Annuaire & Authentification ─────────────────────────────────────── + HAPPYDOMAIN_CHECKER_LDAP_ENDPOINT: "http://checker-ldap:8080" + HAPPYDOMAIN_CHECKER_KERBEROS_ENDPOINT: "http://checker-kerberos:8080" + HAPPYDOMAIN_CHECKER_STUNTURN_ENDPOINT: "http://checker-stun-turn:8080" + + # ── CalDAV / CardDAV ────────────────────────────────────────────────── + HAPPYDOMAIN_CHECKER_CALDAV_ENDPOINT: "http://checker-caldav:8080" + HAPPYDOMAIN_CHECKER_CARDDAV_ENDPOINT: "http://checker-carddav:8080" + + # ── Optionnel : intégration happyDeliver ────────────────────────────── + # HAPPYDOMAIN_CHECKER_HAPPYDELIVER_ENDPOINT: "http://checker-happydeliver:8080" + + restart: unless-stopped + volumes: + - storage:/var/lib/happydomain:rw + + # ── Vérificateurs DNS / DNSSEC ───────────────────────────────────────────── + + checker-dnsviz: + image: happydomain/checker-dnsviz + restart: unless-stopped + + checker-dnssec: + image: happydomain/checker-dnssec + restart: unless-stopped + + checker-zonemaster: + image: happydomain/checker-zonemaster + restart: unless-stopped + + zonemaster: + image: zonemaster/backend + command: full + restart: unless-stopped + + checker-delegation: + image: happydomain/checker-delegation + restart: unless-stopped + + checker-authoritative-consistency: + image: happydomain/checker-authoritative-consistency + restart: unless-stopped + + checker-alias: + image: happydomain/checker-alias + restart: unless-stopped + + checker-legacy-records: + image: happydomain/checker-legacy-records + restart: unless-stopped + + checker-ns-restrictions: + image: happydomain/checker-ns-restrictions + restart: unless-stopped + + checker-resolver-propagation: + image: happydomain/checker-resolver-propagation + restart: unless-stopped + + checker-reverse-zone: + image: happydomain/checker-reverse-zone + restart: unless-stopped + + checker-ptr: + image: happydomain/checker-ptr + restart: unless-stopped + + checker-dangling: + image: happydomain/checker-dangling + restart: unless-stopped + + # ── Vérificateurs Sécurité / Certificats ─────────────────────────────────── + + checker-tls: + image: happydomain/checker-tls + restart: unless-stopped + + checker-dane: + image: happydomain/checker-dane + restart: unless-stopped + + checker-caa: + image: happydomain/checker-caa + restart: unless-stopped + + checker-blacklist: + image: happydomain/checker-blacklist + restart: unless-stopped + + # ── Vérificateurs e-mail ──────────────────────────────────────────────────── + + checker-smtp: + image: happydomain/checker-smtp + restart: unless-stopped + + checker-email-autoconfig: + image: happydomain/checker-email-autoconfig + restart: unless-stopped + + checker-email-keys: + image: happydomain/checker-email-keys + restart: unless-stopped + + # ── Vérificateurs Web & Protocoles ───────────────────────────────────────── + + checker-http: + image: happydomain/checker-http + restart: unless-stopped + + checker-ssh: + image: happydomain/checker-ssh + restart: unless-stopped + + checker-ping: + image: happydomain/checker-ping + restart: unless-stopped + cap_add: + - NET_RAW # requis pour l'ICMP + + checker-srv: + image: happydomain/checker-srv + restart: unless-stopped + + # ── Vérificateurs Collaboration / Messagerie ──────────────────────────────── + + checker-matrix: + image: happydomain/checker-matrix + restart: unless-stopped + + matrixfederationtester: + image: matrixdotorg/federation-tester-backend + environment: + BIND_ADDRESS: "0.0.0.0:8080" + restart: unless-stopped + + checker-xmpp: + image: happydomain/checker-xmpp + restart: unless-stopped + + checker-sip: + image: happydomain/checker-sip + restart: unless-stopped + + # ── Vérificateurs Annuaire & Authentification ─────────────────────────────── + + checker-ldap: + image: happydomain/checker-ldap + restart: unless-stopped + + checker-kerberos: + image: happydomain/checker-kerberos + restart: unless-stopped + + checker-stun-turn: + image: happydomain/checker-stun-turn + restart: unless-stopped + + # ── Vérificateurs CalDAV / CardDAV ───────────────────────────────────────── + + checker-caldav: + image: happydomain/checker-caldav + restart: unless-stopped + + checker-carddav: + image: happydomain/checker-carddav + restart: unless-stopped + +volumes: + storage: ``` -FROM happydomain/happydomain -RUN apk --no-cache add ssmtp -COPY my_ssmtp.conf /etc/ssmtp/ssmtp.conf + +### Comment ça fonctionne + +Chaque vérificateur tourne comme un service HTTP autonome. happyDomain lui délègue +les demandes de vérification via la variable d'environnement +`HAPPYDOMAIN_CHECKER__ENDPOINT`. Si aucun point d'accès n'est configuré, le +vérificateur correspondant s'exécute localement dans le processus happyDomain. + +Deux vérificateurs s'appuient sur des services tiers supplémentaires : + +- **Zonemaster** (`checker-zonemaster`) interroge le service `zonemaster/backend`. + La variable `HAPPYDOMAIN_CHECKER_ZONEMASTER_ZONEMASTERAPIURL` indique au + vérificateur l'adresse de ce service. +- **Matrix federation tester** (`checker-matrix`) interroge le service + `matrixdotorg/federation-tester-backend`. La variable + `HAPPYDOMAIN_CHECKER_MATRIXIM_FEDERATIONTESTERSERVER` pointe vers son point + d'accès de rapport. + +### Optionnel : happyDeliver + +Si vous exploitez une instance [happyDeliver](https://happydeliver.io) pour +surveiller les flux e-mail, décommentez la ligne +`HAPPYDOMAIN_CHECKER_HAPPYDELIVER_ENDPOINT` et ajoutez le service correspondant : + +```yaml + checker-happydeliver: + image: happydomain/checker-happydeliver + restart: unless-stopped ``` +### Optionnel : clés API pour checker-blacklist + +Le service `checker-blacklist` fonctionne sans clé API (il utilise des listes +de blocage DNS par défaut), mais vous pouvez activer des sources supplémentaires +— Google Safe Browsing, VirusTotal, abuse.ch URLhaus — en configurant les +options d'administration correspondantes depuis l'interface d'administration de +happyDomain une fois la pile démarrée. + ## Interface d'administration -happyDomain expose certaines commandes d'administration à travers un socket unix. -Le conteneur docker contient un script pour accéder à cette partie d'administration : `hadmin`. - -Vous pouvez l'utiliser de cette manière : +happyDomain expose des commandes d'administration à travers un socket Unix. +Le conteneur inclut l'utilitaire `hadmin` : ``` docker exec my_container hadmin /api/users docker exec my_container hadmin /api/users/0123456789/send_validation_email -X POST ``` -Il s'agit en fait d'une surcouche au-dessus de `curl`, mais vous devez commencer par l'URL, et placer les options après. +`hadmin` est une surcouche légère autour de `curl` — commencez par le chemin +d'URL, puis ajoutez les options `curl` après. + + +## Utilisation d'un fichier de configuration + +Plutôt que des variables d'environnement, vous pouvez placer un fichier de +configuration dans `/data/happydomain.conf` (dans le volume de données) ou le +monter directement sur `/etc/happydomain.conf` : + +``` +docker run -v happydomain.conf:/etc/happydomain.conf -p 8081:8081 happydomain/happydomain +``` diff --git a/content/pages/_index.en.md b/content/pages/_index.en.md index 81c09c9..7289ecb 100644 --- a/content/pages/_index.en.md +++ b/content/pages/_index.en.md @@ -6,4 +6,30 @@ archetype: chapter weight: 10 --- +This section walks through happyDomain feature by feature, following the path a new user +takes: from creating an account to publishing a fully managed zone. + +You start by [creating an account]({{% relref "signup" %}}) and [logging in]({{% relref "login" %}}), +then land on the [dashboard]({{% relref "domains" %}}) that centralizes all your domains. + +Before importing a domain, you connect a [provider]({{% relref "provider-list" %}}): happyDomain +[adds]({{% relref "provider-new-choice" %}}) and [configures]({{% relref "provider-update" %}}) +it for you, whatever its [specific features]({{% relref "provider-features" %}}). + +You can then [import a domain]({{% relref "domain-new" %}}) and explore it in the +[zone editor]({{% relref "domain-abstract" %}}), which +lets you manage [subdomains]({{% relref "subdomains" %}}) and group records into +[services]({{% relref "services" %}}). Every change is reviewed +before you [publish]({{% relref "publish-changes" %}}) it, and the +[history]({{% relref "domain-history" %}}) keeps track of everything. You can also +[import or export]({{% relref "import-export" %}}) the whole zone as a standard file. + +happyDomain also helps you keep an eye on your domains with +[monitoring and checks]({{% relref "checks" %}}), [availability lookups]({{% relref "domain-availability" %}}) +and the [domain test tool]({{% relref "tools-client" %}}). + +Finally, you can fine-tune your account: [your account and settings]({{% relref "settings" %}}), +[sessions and API access]({{% relref "api-keys" %}}), +[notifications]({{% relref "notifications" %}}) and [quotas]({{% relref "quotas" %}}). + {{% children %}} diff --git a/content/pages/_index.fr.md b/content/pages/_index.fr.md index cba0436..4bffa13 100644 --- a/content/pages/_index.fr.md +++ b/content/pages/_index.fr.md @@ -5,4 +5,34 @@ archetype: chapter weight: 10 --- +Cette section présente happyDomain fonctionnalité par fonctionnalité, en suivant le +parcours d'un nouvel utilisateur : de la création de son compte jusqu'à la publication +d'une zone entièrement gérée. + +Vous commencez par [créer un compte]({{% relref "signup" %}}) et +[vous connecter]({{% relref "login" %}}), puis vous arrivez sur le +[tableau de bord]({{% relref "domains" %}}) qui centralise tous vos domaines. + +Avant d'importer un domaine, vous raccordez un [hébergeur]({{% relref "provider-list" %}}) : +happyDomain l'[ajoute]({{% relref "provider-new-choice" %}}) et le +[configure]({{% relref "provider-update" %}}) pour vous, quelles que soient ses +[particularités]({{% relref "provider-features" %}}). + +Vous pouvez alors [importer un domaine]({{% relref "domain-new" %}}) et le consulter dans +l'[éditeur de zone]({{% relref "domain-abstract" %}}), qui +vous permet de gérer les [sous-domaines]({{% relref "subdomains" %}}) et de regrouper les +enregistrements en [services]({{% relref "services" %}}). Chaque modification est +examinée avant que vous ne la [publiiez]({{% relref "publish-changes" %}}), +et l'[historique]({{% relref "domain-history" %}}) garde la trace de tout. Vous pouvez aussi +[importer ou exporter]({{% relref "import-export" %}}) la zone entière sous forme de fichier standard. + +happyDomain vous aide également à garder un œil sur vos domaines, grâce à la +[surveillance et aux vérifications]({{% relref "checks" %}}), aux +[recherches de disponibilité]({{% relref "domain-availability" %}}) et à +l'[outil de test de domaine]({{% relref "tools-client" %}}). + +Enfin, vous pouvez peaufiner votre compte : [votre compte et vos réglages]({{% relref "settings" %}}), +les [sessions et accès API]({{% relref "api-keys" %}}), les +[notifications]({{% relref "notifications" %}}) et les [quotas]({{% relref "quotas" %}}). + {{% children %}} diff --git a/content/pages/api-keys.en.md b/content/pages/api-keys.en.md new file mode 100644 index 0000000..d3ed063 --- /dev/null +++ b/content/pages/api-keys.en.md @@ -0,0 +1,55 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Sessions & API access +author: nemunaire +weight: 2200 +description: "Manage your active sessions and use authentication tokens to call the happyDomain REST API" +--- + +happyDomain does not have a separate "API keys" feature. Instead, every way of accessing the platform, whether through the web interface or the REST API, relies on the same kind of **session token**. Managing your sessions therefore also means managing your API access. + +You manage your sessions from the security section of your account, under **Active Sessions**. + + + +## Listing your active sessions + +The list shows every session currently open on your account. For each one you see: + +- its **description** (the name given when it was created), followed by a short fingerprint derived from the token; +- a **current session** badge on the session you are using right now; +- when it was **created**, when it was **last used**, and when it **expires**. + +Sessions are sorted with the most recently used first. + +## Creating a token for API access + +To obtain a token you can use to call the API: + +1. Click **Create API key**. +2. Give the session a **description** (for example the name of the script or machine that will use it). This helps you recognise it later in the list. +3. Validate the creation. + +The token secret is then displayed **once**. Use the eye button to reveal it and the copy button to put it on your clipboard. + +{{% notice style="warning" title="Copy the secret immediately" icon="triangle-exclamation" %}} +The session secret is shown only at creation time and is never displayed again. Copy it and store it somewhere safe before closing the dialog. If you lose it, delete the session and create a new one. +{{% /notice %}} + +## Using a token with the REST API + +The token is passed in the HTTP `Authorization` header as a Bearer token. For example, to list your domains: + +```sh +curl -H "Authorization: Bearer YOUR_SECRET_TOKEN" https://your-happydomain-server/api/domains +``` + +Replace `YOUR_SECRET_TOKEN` with the secret you copied, and the host with the address of your happyDomain instance. Any API endpoint is reached the same way, by sending this header with each request. + +## Revoking a session + +To revoke a session (and the token associated with it), click the delete button on its row. The token stops working immediately. You cannot delete the session you are currently using from this list; to end it, simply log out, or use the option below. + +{{% notice style="info" title="Terminate all sessions" icon="circle-info" %}} +The **Terminate all sessions** button closes every session at once, including the one you are using. This is useful if you suspect a token has leaked: all existing tokens become invalid and you are sent back to the [login page]({{% relref "login" %}}). You will then need to log in again and recreate any API tokens you still need. +{{% /notice %}} diff --git a/content/pages/api-keys.fr.md b/content/pages/api-keys.fr.md new file mode 100644 index 0000000..fa699e2 --- /dev/null +++ b/content/pages/api-keys.fr.md @@ -0,0 +1,54 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Sessions et accès à l'API +weight: 2200 +description: "Gérez vos sessions actives et utilisez les jetons d'authentification pour appeler l'API REST de happyDomain" +--- + +happyDomain ne propose pas de fonctionnalité distincte de « clés d'API ». À la place, toutes les façons d'accéder à la plateforme, que ce soit via l'interface web ou via l'API REST, reposent sur le même type de **jeton de session**. Gérer ses sessions revient donc aussi à gérer ses accès à l'API. + +Vous gérez vos sessions depuis la section sécurité de votre compte, sous « Sessions actives ». + + + +## Lister vos sessions actives + +La liste présente toutes les sessions actuellement ouvertes sur votre compte. Pour chacune, vous voyez : + +- sa **description** (le nom donné lors de sa création), suivie d'une courte empreinte dérivée du jeton ; +- un badge « session actuelle » sur la session que vous utilisez en ce moment ; +- sa date de **création**, sa date de **dernière utilisation** et sa date d'**expiration**. + +Les sessions sont triées de la plus récemment utilisée à la plus ancienne. + +## Créer un jeton pour accéder à l'API + +Pour obtenir un jeton utilisable pour appeler l'API : + +1. Cliquez sur « Créer une clé d'API ». +2. Donnez une **description** à la session (par exemple le nom du script ou de la machine qui l'utilisera). Cela vous aidera à la reconnaître plus tard dans la liste. +3. Validez la création. + +Le secret du jeton est alors affiché **une seule fois**. Utilisez le bouton en forme d'œil pour le révéler et le bouton de copie pour le placer dans votre presse-papiers. + +{{% notice style="warning" title="Copiez le secret immédiatement" icon="triangle-exclamation" %}} +Le secret de la session n'est affiché qu'au moment de sa création et n'est plus jamais montré ensuite. Copiez-le et conservez-le en lieu sûr avant de fermer la fenêtre. En cas de perte, supprimez la session et créez-en une nouvelle. +{{% /notice %}} + +## Utiliser un jeton avec l'API REST + +Le jeton se transmet dans l'en-tête HTTP `Authorization`, en tant que jeton « Bearer ». Par exemple, pour lister vos domaines : + +```sh +curl -H "Authorization: Bearer VOTRE_JETON_SECRET" https://votre-serveur-happydomain/api/domains +``` + +Remplacez `VOTRE_JETON_SECRET` par le secret que vous avez copié, et l'hôte par l'adresse de votre instance happyDomain. On atteint n'importe quel point d'accès de l'API de la même manière, en envoyant cet en-tête à chaque requête. + +## Révoquer une session + +Pour révoquer une session (et le jeton qui lui est associé), cliquez sur le bouton de suppression sur sa ligne. Le jeton cesse aussitôt de fonctionner. Vous ne pouvez pas supprimer depuis cette liste la session que vous utilisez actuellement ; pour y mettre fin, déconnectez-vous simplement, ou utilisez l'option ci-dessous. + +{{% notice style="info" title="Fermer toutes les sessions" icon="circle-info" %}} +Le bouton « Fermer toutes les sessions » referme l'ensemble des sessions d'un coup, y compris celle que vous utilisez. C'est utile si vous soupçonnez la fuite d'un jeton : tous les jetons existants deviennent invalides et vous êtes renvoyé vers la [page de connexion]({{% relref "login" %}}). Il vous faudra alors vous reconnecter et recréer les jetons d'API dont vous avez encore besoin. +{{% /notice %}} diff --git a/content/pages/checks.en.md b/content/pages/checks.en.md new file mode 100644 index 0000000..1ef0c3f --- /dev/null +++ b/content/pages/checks.en.md @@ -0,0 +1,174 @@ +--- +date: 2026-04-05T12:00:00+02:00 +title: Monitoring & Checks +author: nemunaire +weight: 1700 +description: "Set up automated health checks to monitor your domains and services" +--- + +happyDomain includes a built-in monitoring system that lets you run automated health checks on your domains and services. Checkers periodically collect data (such as ping response times, domain expiry dates, or DNS audit results), evaluate it against thresholds you define, and report a clear status: OK, Warning, Critical, or Error. + +## Browsing available checkers + +You can see all available checkers by navigating to the **Checkers** page from the main menu. + + + +Each checker is labelled with the scope it applies to: + +- **Domain-level**: checks that concern the domain itself, independent of DNS records (e.g. domain expiry via WHOIS). +- **Zone-level**: checks that need the full zone content (e.g. DNSSEC validation). +- **Service-level**: checks that target a specific service on a subdomain (e.g. ping, HTTP check). + +Use the search bar to filter checkers by name. Click on a checker to see its description and configuration options. + + +## Configuring a checker for your domain + +To set up a checker on one of your domains: + +1. Go to your domain's page and open the **Checks** tab. +2. You will see a table of checkers available for this domain. Click **Configure** next to the checker you want to set up. + + + +On the configuration page, you will find several sections: + +### Checker options + +Options are grouped by category: + +- **Admin Options** -- system-wide settings controlled by the administrator (read-only for regular users). +- **Configuration** -- user-level preferences such as warning and critical thresholds. These are the main settings you will adjust. +- **Domain-specific Settings** -- values automatically filled in based on the domain being checked (e.g. the domain name itself). +- **Checker Parameters** -- additional runtime parameters. + +Fill in or adjust the options to match your needs, then click **Save**. + + + +### Rules + +Each checker comes with one or more **rules** that evaluate different aspects of the collected data. For example, a ping checker might have separate rules for latency and packet loss. + +You can enable or disable individual rules using the toggle switches. Each rule may also have its own specific options that you can configure. + + + + +## Scheduling automatic checks + +Once a checker is configured, you can schedule it to run automatically at a regular interval. + +In the **Schedule** section of the checker configuration page: + +1. Toggle **Run automatically** to enable scheduling. +2. Set the **Check interval** (in hours) -- this determines how often the check runs. +3. The **Next scheduled run** time is displayed so you know when the next execution will happen. +4. Click **Save** to apply the schedule. + + + +{{% notice style="info" title="Interval limits" icon="clock" %}} +Each checker defines minimum and maximum intervals to prevent overloading external services. The interface will respect these bounds when you configure the schedule. +{{% /notice %}} + +When scheduling is disabled, the checker can still be run manually at any time. + + +## Running a check manually + +You can trigger a check at any time without waiting for the schedule: + +1. Navigate to the checker's **Executions** page (from the domain checks list, click **View Results**). +2. Click **Run Check Now**. +3. A dialog opens where you can: + - Select which rules to run for this execution. + - Override options temporarily (these overrides are not saved). +4. Click **Run Check** to start the execution. + + + +A confirmation message will appear with the execution ID. The result will show up in the executions list once the check completes. + + +## Viewing check results + +All past executions are listed on the checker's **Executions** page, accessible from your domain's Checks tab by clicking **View Results**. + + + +The executions table shows: + +| Column | Description | +|--------|-------------| +| **Executed at** | When the check ran | +| **Status** | The result: OK, Warning, Critical, Error, or Unknown | +| **Message** | A summary of the findings | +| **Duration** | How long the check took to complete | +| **Type** | Whether it was a scheduled or manual run | + +Click **View** on any execution to see its detailed results. + + +## Understanding execution details + +The execution detail page presents the results in the most appropriate format depending on what the checker provides. + +### Metrics + +When a checker produces metrics (e.g. response time, packet loss percentage), the detail page shows: + +- A **line chart** plotting the metric values over time across recent executions. +- A **data table** listing each metric with its name, value, and unit. + + + +### HTML reports + +Some checkers generate rich HTML reports (e.g. detailed DNS audit results). These are rendered directly in the page. + +### Raw data + +You can always switch to the **Raw JSON** view to inspect the full observation data collected during the execution. Use the view toggle at the top of the report section to switch between Metrics, HTML Report, and Raw JSON. + +### Rule evaluations + +Each rule that ran during the execution reports its own status and message. You can see the per-rule breakdown to understand which specific aspect triggered a warning or critical status. + + + + +## Service-level checks + +Checkers that apply at the service level are configured from the service's own page rather than the domain-level Checks tab. + +1. Navigate to your domain, then to the specific subdomain and service. +2. Open the **Checks** tab for that service. +3. The workflow is the same as for domain-level checkers: configure options, set up scheduling, run checks, and view results. + +Service-level checkers automatically receive information about the service they are attached to (such as IP addresses from a Server service), so they require less manual configuration. + + +## Managing check results + +From the executions list, you can: + +- **Delete a single result** by clicking the delete action on a specific execution. +- **Delete all results** for a checker using the bulk delete option (a confirmation dialog will appear). + +This can be useful to clean up old data or reset after configuration changes. + + +## Status reference + +Checkers report one of the following statuses, in order of severity: + +| Status | Meaning | +|--------|---------| +| **OK** | Everything is within acceptable parameters | +| **Info** | Informational finding, no action needed | +| **Warning** | A threshold is approaching; attention recommended | +| **Critical** | A threshold has been exceeded; action required | +| **Error** | The check itself failed (collection error, bad configuration) | +| **Unknown** | The check could not determine a result | diff --git a/content/pages/checks.fr.md b/content/pages/checks.fr.md new file mode 100644 index 0000000..3b183c3 --- /dev/null +++ b/content/pages/checks.fr.md @@ -0,0 +1,174 @@ +--- +date: 2026-04-05T12:00:00+02:00 +title: Surveillance & Vérifications +author: nemunaire +weight: 1700 +description: "Mettez en place des vérifications automatiques pour surveiller vos domaines et vos services" +--- + +happyDomain intègre un système de surveillance qui permet de lancer des vérifications automatiques sur vos domaines et vos services. Les vérificateurs collectent périodiquement des données (temps de réponse au ping, date d'expiration d'un domaine ou résultats d'audit DNS, par exemple), les évaluent au regard des seuils que vous définissez et rapportent un statut clair : OK, Avertissement, Critique ou Erreur. + +## Parcourir les vérificateurs disponibles + +Vous pouvez consulter l'ensemble des vérificateurs disponibles depuis la page **Vérifications**, accessible par le menu principal. + + + +Chaque vérificateur indique la portée à laquelle il s'applique : + +- **Niveau domaine** : vérifications qui concernent le domaine lui-même, indépendamment des enregistrements DNS (par exemple l'expiration du domaine via WHOIS). +- **Niveau zone** : vérifications qui nécessitent le contenu complet de la zone (par exemple la validation DNSSEC). +- **Niveau service** : vérifications qui ciblent un service précis sur un sous-domaine (par exemple un ping ou une vérification HTTP). + +Utilisez la barre de recherche pour filtrer les vérificateurs par nom. Cliquez sur un vérificateur pour afficher sa description et ses options de configuration. + + +## Configurer un vérificateur pour votre domaine + +Pour mettre en place un vérificateur sur l'un de vos domaines : + +1. Rendez-vous sur la page de votre domaine et ouvrez l'onglet **Vérifications**. +2. Un tableau présente les vérificateurs disponibles pour ce domaine. Cliquez sur **Configurer** en regard du vérificateur souhaité. + + + +La page de configuration regroupe plusieurs sections : + +### Options du vérificateur + +Les options sont réparties par catégorie : + +- **Options d'administration** : paramètres globaux contrôlés par l'administrateur (en lecture seule pour les utilisateurs ordinaires). +- **Configuration** : préférences au niveau de l'utilisateur, comme les seuils d'avertissement et critique. Ce sont les principaux réglages que vous ajusterez. +- **Paramètres propres au domaine** : valeurs renseignées automatiquement à partir du domaine vérifié (par exemple le nom de domaine lui-même). +- **Paramètres du vérificateur** : paramètres d'exécution supplémentaires. + +Renseignez ou ajustez les options selon vos besoins, puis cliquez sur **Enregistrer**. + + + +### Règles + +Chaque vérificateur s'accompagne d'une ou plusieurs **règles** qui évaluent différents aspects des données collectées. Un vérificateur de ping peut par exemple comporter des règles distinctes pour la latence et la perte de paquets. + +Vous pouvez activer ou désactiver chaque règle à l'aide des interrupteurs. Chaque règle peut également disposer de ses propres options à configurer. + + + + +## Planifier des vérifications automatiques + +Une fois un vérificateur configuré, vous pouvez planifier son exécution automatique à intervalle régulier. + +Dans la section **Planification** de la page de configuration du vérificateur : + +1. Activez **Exécuter automatiquement** pour mettre en place la planification. +2. Définissez l'**intervalle de vérification** (en heures) : il détermine la fréquence d'exécution. +3. L'heure de la **prochaine exécution planifiée** est affichée afin que vous sachiez quand aura lieu la prochaine vérification. +4. Cliquez sur **Enregistrer** pour appliquer la planification. + + + +{{% notice style="info" title="Limites d'intervalle" icon="clock" %}} +Chaque vérificateur définit un intervalle minimal et maximal afin d'éviter de surcharger les services externes. L'interface respecte ces bornes lorsque vous configurez la planification. +{{% /notice %}} + +Lorsque la planification est désactivée, le vérificateur peut tout de même être lancé manuellement à tout moment. + + +## Lancer une vérification manuellement + +Vous pouvez déclencher une vérification à tout moment, sans attendre la planification : + +1. Rendez-vous sur la page **Exécutions** du vérificateur (depuis la liste des vérifications du domaine, cliquez sur **Voir les résultats**). +2. Cliquez sur **Lancer la vérification**. +3. Une fenêtre s'ouvre, dans laquelle vous pouvez : + - Sélectionner les règles à exécuter pour cette exécution. + - Remplacer temporairement certaines options (ces remplacements ne sont pas enregistrés). +4. Cliquez sur **Lancer la vérification** pour démarrer l'exécution. + + + +Un message de confirmation apparaît avec l'identifiant de l'exécution. Le résultat s'affiche dans la liste des exécutions une fois la vérification terminée. + + +## Consulter les résultats des vérifications + +Toutes les exécutions passées sont répertoriées sur la page **Exécutions** du vérificateur, accessible depuis l'onglet Vérifications de votre domaine en cliquant sur **Voir les résultats**. + + + +Le tableau des exécutions présente : + +| Colonne | Description | +|--------|-------------| +| **Exécutée le** | Date à laquelle la vérification a été lancée | +| **Statut** | Le résultat : OK, Avertissement, Critique, Erreur ou Inconnu | +| **Message** | Un résumé des constats | +| **Durée** | Le temps qu'a pris la vérification | +| **Type** | S'il s'agit d'une exécution planifiée ou manuelle | + +Cliquez sur **Voir** sur une exécution pour en afficher les résultats détaillés. + + +## Comprendre le détail d'une exécution + +La page de détail d'une exécution présente les résultats sous la forme la plus adaptée à ce que fournit le vérificateur. + +### Métriques + +Lorsqu'un vérificateur produit des métriques (temps de réponse, pourcentage de perte de paquets, etc.), la page de détail affiche : + +- Un **graphique en courbes** qui trace l'évolution des valeurs de la métrique au fil des exécutions récentes. +- Un **tableau de données** qui répertorie chaque métrique avec son nom, sa valeur et son unité. + + + +### Rapports HTML + +Certains vérificateurs génèrent des rapports HTML détaillés (par exemple les résultats d'un audit DNS). Ces rapports sont affichés directement dans la page. + +### Données brutes + +Vous pouvez à tout moment basculer vers la vue **JSON brut** pour examiner l'ensemble des données d'observation collectées durant l'exécution. Utilisez le sélecteur de vue en haut de la section du rapport pour passer de Métriques à Rapport HTML et JSON brut. + +### Évaluation des règles + +Chaque règle exécutée durant l'exécution rapporte son propre statut et son propre message. Le détail règle par règle permet de comprendre quel aspect précis a déclenché un statut d'avertissement ou critique. + + + + +## Vérifications au niveau service + +Les vérificateurs qui s'appliquent au niveau service se configurent depuis la page du service concerné, et non depuis l'onglet Vérifications du domaine. + +1. Rendez-vous sur votre domaine, puis sur le sous-domaine et le service concernés. +2. Ouvrez l'onglet **Vérifications** de ce service. +3. Le déroulement est identique à celui des vérificateurs de niveau domaine : configurer les options, mettre en place la planification, lancer des vérifications et consulter les résultats. + +Les vérificateurs de niveau service reçoivent automatiquement les informations relatives au service auquel ils sont rattachés (comme les adresses IP d'un service Serveur), ce qui réduit la configuration manuelle. + + +## Gérer les résultats des vérifications + +Depuis la liste des exécutions, vous pouvez : + +- **Supprimer un résultat** en cliquant sur l'action de suppression d'une exécution précise. +- **Supprimer tous les résultats** d'un vérificateur grâce à l'option de suppression groupée (une fenêtre de confirmation apparaît). + +Cela peut être utile pour faire le ménage dans les anciennes données ou repartir de zéro après des changements de configuration. + + +## Référence des statuts + +Les vérificateurs rapportent l'un des statuts suivants, par ordre de gravité : + +| Statut | Signification | +|--------|---------| +| **OK** | Tout se situe dans les paramètres acceptables | +| **Information** | Constat informatif, aucune action nécessaire | +| **Avertissement** | Un seuil est sur le point d'être atteint ; une attention est recommandée | +| **Critique** | Un seuil a été dépassé ; une action est requise | +| **Erreur** | La vérification elle-même a échoué (erreur de collecte, mauvaise configuration) | +| **Inconnu** | La vérification n'a pas pu déterminer de résultat | diff --git a/content/pages/domain-abstract.en.md b/content/pages/domain-abstract.en.md deleted file mode 100644 index f8d0202..0000000 --- a/content/pages/domain-abstract.en.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -date: 2021-01-12T21:38:49+02:00 -title: Your domain -author: Frederic -weight: 30 ---- - -Need help to write this Documentation page \ No newline at end of file diff --git a/content/pages/domain-abstract.fr.md b/content/pages/domain-abstract.fr.md deleted file mode 100644 index 6f50052..0000000 --- a/content/pages/domain-abstract.fr.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -date: 2020-12-09T18:12:45+01:00 -title: Éditer votre zone -weight: 30 ---- - -Documentation à faire diff --git a/content/pages/domain-abstract/happydomain-abstract-zone-records.webp b/content/pages/domain-abstract/happydomain-abstract-zone-records.webp new file mode 100644 index 0000000..bdb5aa2 Binary files /dev/null and b/content/pages/domain-abstract/happydomain-abstract-zone-records.webp differ diff --git a/content/pages/domain-abstract/happydomain-modal-new-subdomain.webp b/content/pages/domain-abstract/happydomain-modal-new-subdomain.webp new file mode 100644 index 0000000..4541b75 Binary files /dev/null and b/content/pages/domain-abstract/happydomain-modal-new-subdomain.webp differ diff --git a/content/pages/domain-abstract/happydomain-modal-service-selector.webp b/content/pages/domain-abstract/happydomain-modal-service-selector.webp new file mode 100644 index 0000000..c1a6164 Binary files /dev/null and b/content/pages/domain-abstract/happydomain-modal-service-selector.webp differ diff --git a/content/pages/domain-abstract/happydomain-offcanva-service-details.webp b/content/pages/domain-abstract/happydomain-offcanva-service-details.webp new file mode 100644 index 0000000..609621c Binary files /dev/null and b/content/pages/domain-abstract/happydomain-offcanva-service-details.webp differ diff --git a/content/pages/domain-abstract/index.en.md b/content/pages/domain-abstract/index.en.md new file mode 100644 index 0000000..caec9fc --- /dev/null +++ b/content/pages/domain-abstract/index.en.md @@ -0,0 +1,107 @@ +--- +date: 2021-01-12T21:38:49+02:00 +title: "Using the zone editor" +author: Frederic +weight: 900 +description: "View, add, edit and delete records and services in your zone, grouped by subdomain" +--- + +The zone editor is the main screen for working with a domain. It presents the content of your zone grouped by subdomain, and lets you add, edit and delete the services and records that make up your zone, all without touching your hosting provider until you decide to [publish changes]({{% relref "publish-changes" %}}). + +## The editor layout + +When you open a domain, the screen is split in two parts: + +- On the left, a **sidebar** lists every subdomain of the zone. It also gives access to domain-wide actions (history, audit log, checks, WHOIS, import/export, etc.). +- On the right, the **Zone Viewer** displays the content of the zone, one block per subdomain. + +![The happyDomain zone editor, with the subdomain sidebar and the zone viewer](happydomain-abstract-zone-records.webp) + +At the very top of the sidebar you will find the **Add a subdomain** button and a gear menu grouping the other actions. The button used to send your changes to your provider (**Publish my changes**) is also reachable from here; see [this page]({{% relref "publish-changes" %}}) for details. + +{{% notice style="info" title="Nothing is sent automatically" icon="cloud" %}} +Every change you make in the editor is kept locally in happyDomain. It is only transmitted to your hosting provider once you explicitly publish it. +{{% /notice %}} + +## Browsing the zone + +The zone is organised **by subdomain**. The root of the domain is shown first (displayed with the bare domain name), followed by each subdomain. Intermediate subdomains that hold no service of their own are still shown, marked with a dotted icon, so you can always see the full tree. + +- Click a subdomain heading to **expand or collapse** it and reveal the services it contains. +- When a block is collapsed, a badge shows how many services it holds; hover it to get a quick summary. +- Use the **sidebar** to jump straight to a subdomain: it mirrors the list and scrolls the viewer to the matching block. + +Aliases pointing to a subdomain are shown next to its heading with a `+ N aliases` badge. + + + +## Records and services + +happyDomain does not show you a raw list of DNS records by default. Instead, it groups related records into **services**, higher-level objects that are easier to reason about (a mail server, a website, a delegation, etc.). Each service expands into the actual records it generates. + +If you prefer to work directly with individual records, you can switch the zone view mode in your [account settings]({{% relref "settings" %}}). The editor then offers an **Add a record** button instead of **Add a service**. + +## Adding a subdomain + +1. Click **Add a subdomain** at the top of the sidebar. +2. Enter the name of the subdomain to create (relative to your domain). +3. happyDomain then proposes to add a first service on that subdomain right away. + +A subdomain only really exists once it carries at least one service, so the two steps are chained together. + +![The add-a-subdomain dialog](happydomain-modal-new-subdomain.webp) + +## Adding a service + +To add a service to an existing subdomain: + +1. Locate the subdomain block (or the domain root) in the viewer. +2. Click the **+** button on the subdomain heading, or use the **Add a service** action. +3. Pick the service type from the selector. The list adapts to what already exists on that subdomain (for instance, you cannot add two conflicting services). +4. Fill in the form for the chosen service, then save. + +![The service type selector](happydomain-modal-service-selector.webp) + +## Inspecting a service + +Click a service to open the **details panel** that slides in from the right. It shows: + +- A description of the service type and any comment you set. +- The concrete DNS records the service produces. +- The propagation status (when the change was last published). +- Any health checks attached to that service (see {{% relref "checks" %}}). + +From this panel you can also adjust the **default TTL** of the service, edit it, or delete it. + +![The service details panel](happydomain-offcanva-service-details.webp) + +## Editing a service + +1. Open the service details panel, then click **Edit this service**; or use the pencil button shown on simple services such as aliases. +2. happyDomain opens the full editing form for the service. +3. Make your changes and save. The viewer refreshes to reflect them. + +## Deleting a service + +1. Open the service details panel. +2. Click **Delete this service**. + +The service and all the records it generated are removed from your working copy of the zone. + +{{% notice style="warning" title="Some services cannot be removed" icon="triangle-exclamation" %}} +The origin service of a zone (the one carrying the SOA and the authoritative name servers) is essential and cannot be deleted from the editor. +{{% /notice %}} + +For aliases (CNAME) and reverse pointers (PTR), a dedicated delete button is available directly on the subdomain heading. + +## Aliases + +When a subdomain holds services, you can attach an **alias** to it using the link button on its heading. The alias makes another name resolve to this subdomain. + +## Next steps + +None of the above changes anything at your hosting provider yet. When you are happy with your edits: + +- Review what will change, then send the changes; see {{% relref "publish-changes" %}}. + +You can also re-import the live zone, or import/export it as a standard zone file: see {{% relref "import-export" %}}. diff --git a/content/pages/domain-abstract/index.fr.md b/content/pages/domain-abstract/index.fr.md new file mode 100644 index 0000000..1938afd --- /dev/null +++ b/content/pages/domain-abstract/index.fr.md @@ -0,0 +1,106 @@ +--- +date: 2020-12-09T18:12:45+01:00 +title: "Utiliser l'éditeur de zone" +weight: 900 +description: "Visualiser, ajouter, modifier et supprimer les enregistrements et services de votre zone, regroupés par sous-domaine" +--- + +L'éditeur de zone est l'écran principal pour travailler sur un domaine. Il présente le contenu de votre zone regroupé par sous-domaine, et vous permet d'ajouter, modifier et supprimer les services et enregistrements qui composent votre zone, sans rien changer chez votre hébergeur tant que vous n'avez pas décidé de [publier vos changements]({{% relref "publish-changes" %}}). + +## Disposition de l'éditeur + +Lorsque vous ouvrez un domaine, l'écran est divisé en deux parties : + +- À gauche, une **barre latérale** liste tous les sous-domaines de la zone. Elle donne aussi accès aux actions concernant l'ensemble du domaine (historique, journal d'audit, contrôles, WHOIS, import/export, etc.). +- À droite, le **Visualiseur de zone** affiche le contenu de la zone, un bloc par sous-domaine. + +![L'éditeur de zone d'happyDomain, avec la barre latérale des sous-domaines et le visualiseur de zone](happydomain-abstract-zone-records.webp) + +Tout en haut de la barre latérale se trouvent le bouton **Ajouter un sous-domaine** et un menu en forme d'engrenage regroupant les autres actions. Le bouton servant à transmettre vos changements à votre hébergeur (« Diffuser mes changements ») est également accessible depuis cet écran ; voyez [cette page]({{% relref "publish-changes" %}}) pour les détails. + +{{% notice style="info" title="Rien n'est envoyé automatiquement" icon="cloud" %}} +Chaque modification que vous faites dans l'éditeur est conservée localement dans happyDomain. Elle n'est transmise à votre hébergeur que lorsque vous la publiez explicitement. +{{% /notice %}} + +## Parcourir la zone + +La zone est organisée **par sous-domaine**. La racine du domaine apparaît en premier (affichée avec le nom de domaine seul), suivie de chaque sous-domaine. Les sous-domaines intermédiaires qui ne portent aucun service sont tout de même affichés, signalés par une icône en pointillés, afin que vous puissiez toujours voir l'arborescence complète. + +- Cliquez sur le titre d'un sous-domaine pour le **déplier ou le replier** et révéler les services qu'il contient. +- Lorsqu'un bloc est replié, un badge indique combien de services il contient ; survolez-le pour obtenir un aperçu rapide. +- Utilisez la **barre latérale** pour accéder directement à un sous-domaine : elle reflète la liste et fait défiler le visualiseur jusqu'au bloc correspondant. + +Les alias pointant vers un sous-domaine apparaissent à côté de son titre, sous forme d'un badge « + N alias ». + + + +## Enregistrements et services + +Par défaut, happyDomain ne vous présente pas une liste brute d'enregistrements DNS. Il regroupe au contraire les enregistrements liés en **services**, des objets de plus haut niveau plus simples à appréhender (un serveur de courrier, un site web, une délégation, etc.). Chaque service se déploie en montrant les enregistrements concrets qu'il génère. + +Si vous préférez travailler directement avec les enregistrements individuels, vous pouvez changer le mode d'affichage de la zone dans [vos préférences]({{% relref "settings" %}}). L'éditeur propose alors un bouton **Ajouter un enregistrement** au lieu d'**Ajouter un service**. + +## Ajouter un sous-domaine + +1. Cliquez sur **Ajouter un sous-domaine** en haut de la barre latérale. +2. Saisissez le nom du sous-domaine à créer (relatif à votre domaine). +3. happyDomain vous propose ensuite d'ajouter immédiatement un premier service sur ce sous-domaine. + +Un sous-domaine n'existe réellement qu'à partir du moment où il porte au moins un service : les deux étapes sont donc enchaînées. + +![La fenêtre d'ajout d'un sous-domaine](happydomain-modal-new-subdomain.webp) + +## Ajouter un service + +Pour ajouter un service à un sous-domaine existant : + +1. Repérez le bloc du sous-domaine (ou la racine du domaine) dans le visualiseur. +2. Cliquez sur le bouton **+** présent sur le titre du sous-domaine, ou utilisez l'action **Ajouter un service**. +3. Choisissez le type de service dans le sélecteur. La liste s'adapte à ce qui existe déjà sur ce sous-domaine (par exemple, vous ne pouvez pas ajouter deux services en conflit). +4. Remplissez le formulaire du service choisi, puis enregistrez. + +![Le sélecteur de type de service](happydomain-modal-service-selector.webp) + +## Inspecter un service + +Cliquez sur un service pour ouvrir le **panneau de détails** qui apparaît par la droite. Il présente : + +- Une description du type de service et le commentaire éventuel que vous avez défini. +- Les enregistrements DNS concrets que le service produit. +- L'état de propagation (date de la dernière publication de la modification). +- Les contrôles de santé éventuellement rattachés à ce service (voyez {{% relref "checks" %}}). + +Depuis ce panneau, vous pouvez aussi ajuster le **TTL par défaut** du service, le modifier ou le supprimer. + +![Le panneau de détails d'un service](happydomain-offcanva-service-details.webp) + +## Modifier un service + +1. Ouvrez le panneau de détails du service, puis cliquez sur **Modifier ce service** ; ou utilisez le bouton crayon affiché sur les services simples comme les alias. +2. happyDomain ouvre le formulaire d'édition complet du service. +3. Effectuez vos changements et enregistrez. Le visualiseur se met à jour pour les refléter. + +## Supprimer un service + +1. Ouvrez le panneau de détails du service. +2. Cliquez sur **Supprimer ce service**. + +Le service et tous les enregistrements qu'il générait sont retirés de votre copie de travail de la zone. + +{{% notice style="warning" title="Certains services ne peuvent pas être supprimés" icon="triangle-exclamation" %}} +Le service d'origine d'une zone (celui qui porte le SOA et les serveurs de noms faisant autorité) est essentiel et ne peut pas être supprimé depuis l'éditeur. +{{% /notice %}} + +Pour les alias (CNAME) et les pointeurs inverses (PTR), un bouton de suppression dédié est disponible directement sur le titre du sous-domaine. + +## Alias + +Lorsqu'un sous-domaine porte des services, vous pouvez lui rattacher un **alias** à l'aide du bouton en forme de lien présent sur son titre. L'alias fait pointer un autre nom vers ce sous-domaine. + +## Et ensuite + +Aucune des opérations ci-dessus ne change quoi que ce soit chez votre hébergeur pour l'instant. Lorsque vos modifications vous conviennent : + +- Examinez ce qui va changer, puis envoyez les changements ; voyez {{% relref "publish-changes" %}}. + +Vous pouvez aussi réimporter la zone en ligne, ou [l'importer / l'exporter sous forme de fichier de zone standard]({{% relref "import-export" %}}). diff --git a/content/pages/domain-availability.en.md b/content/pages/domain-availability.en.md new file mode 100644 index 0000000..ec64590 --- /dev/null +++ b/content/pages/domain-availability.en.md @@ -0,0 +1,87 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Domain availability & lookups +author: nemunaire +weight: 1800 +description: "Check whether a domain is available for registration, and inspect any domain with the WHOIS and DNS resolver tools" +--- + +happyDomain bundles a few diagnostic tools that work on any domain name, whether or not you manage it in happyDomain. They let you check if a name is available for registration, look up its registration details (WHOIS), and query its DNS records directly (resolver). + +## Availability checker + +The **Availability** page lets you keep an eye on one or more domain names you would like to register, and be told as soon as one becomes available. + + + +### Watching a domain + +To start watching a name: + +1. Type the domain you are interested in (for example `mydomain.example`) in the input at the top of the page. +2. Click **Add**. + +The name is added to your watch list and an immediate check is launched in the background, so you do not have to wait for the next automatic check to see its current state. + +### Reading the status + +Each watched domain shows a badge reflecting the result of the last check: + +| Badge | Meaning | +|-------|---------| +| **Available** | The name appears to be free and can probably be registered. | +| **Registered** | The name is already taken. | +| _(error message)_ | The check could not be completed (for example the extension is unsupported, or the registry could not be reached). | +| **Never checked** | No result is available yet. | + +The time of the last check is displayed next to the status. + +### Rechecking and removing + +- Click **Check now** next to a domain to trigger a fresh check immediately. A spinner is shown while the check runs in the background, and the status updates automatically once it finishes. +- Click the trash icon to stop watching a domain. A confirmation is asked before removal. + +{{% notice style="tip" title="Availability is a best effort" icon="lightbulb" %}} +The availability result is only an indication. Some extensions cannot be checked reliably, and a name that appears free may still be reserved or blocked at registration time. Always confirm with a registrar before counting on a name. +{{% /notice %}} + + +## WHOIS lookup + +The **WHOIS** tool shows the public registration information of a domain: its registrar, important dates and current status. + + + +Enter a domain name and run the lookup. happyDomain then displays a clear summary of the collected information: + +- **Status**: the registration statuses returned for the domain (for example `active`, `clientTransferProhibited`, a `hold` state, etc.), shown as colour-coded badges. +- **Creation date** and **Expiration date**: when the domain was first registered and when its registration is due to expire. The expiration is accompanied by a progress bar and a countdown, which turns orange then red as the date approaches. +- **Registrar**: the company through which the domain is registered, with a link to its website when available. +- **Nameservers**: the authoritative nameservers declared for the domain. + +If the name is not registered, a message tells you the domain was not found. If the lookup itself fails, the error is shown. + +{{% notice style="info" title="WHOIS and the availability checker" icon="circle-info" %}} +The availability checker relies on the same underlying registration data as the WHOIS lookup. If you want the full registration picture for a name, use the WHOIS tool; if you simply want to know whether a name is free (and be notified later), add it to your availability watch list. +{{% /notice %}} + + +## DNS resolver + +The **DNS resolver** lets you query the live DNS of any domain, exactly as it is published on the Internet right now. This is handy to confirm that a change has propagated, or to inspect a domain you do not manage. + + + +Enter a domain name and run the query. By default, every record type is requested (`ANY`). Open the **Advanced** options to refine the query: + +- **Field (record type)**: restrict the query to a single record type (`A`, `AAAA`, `MX`, `TXT`, etc.). +- **Resolver**: choose which DNS resolver to send the query to. Several well-known public resolvers are offered, and you can pick **Custom** to enter the address of any resolver you want to test against. +- **Show DNSSEC records**: include the DNSSEC-related records (`RRSIG`, `NSEC`, `NSEC3`) in the results, which are hidden by default. + +If you manage domains in happyDomain, their names are suggested as you type the domain to query. + +Results are grouped by record type, and each entry shows its fields together with its TTL. When the domain exists but has no record of the requested type, a message says so explicitly. + +{{% notice style="tip" title="Resolver vs. your zone in happyDomain" icon="lightbulb" %}} +The resolver shows what is **currently published** by the authoritative servers, which may differ from a draft zone you are editing in happyDomain until you [publish your changes]({{% relref "publish-changes" %}}). +{{% /notice %}} diff --git a/content/pages/domain-availability.fr.md b/content/pages/domain-availability.fr.md new file mode 100644 index 0000000..02c54ac --- /dev/null +++ b/content/pages/domain-availability.fr.md @@ -0,0 +1,86 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Disponibilité et recherches de domaines +weight: 1800 +description: "Vérifier si un domaine est disponible à l'enregistrement, et inspecter n'importe quel domaine grâce aux outils WHOIS et résolveur DNS" +--- + +happyDomain embarque quelques outils de diagnostic qui fonctionnent sur n'importe quel nom de domaine, qu'il soit ou non géré dans happyDomain. Ils permettent de vérifier si un nom est disponible à l'enregistrement, de consulter ses informations d'enregistrement (WHOIS), et d'interroger directement ses enregistrements DNS (résolveur). + +## Vérificateur de disponibilité + +La page **Disponibilité** vous permet de surveiller un ou plusieurs noms de domaine que vous souhaiteriez enregistrer, et d'être prévenu dès que l'un d'eux devient disponible. + + + +### Surveiller un domaine + +Pour commencer à surveiller un nom : + +1. Saisissez le domaine qui vous intéresse (par exemple `mondomaine.example`) dans le champ situé en haut de la page. +2. Cliquez sur **Ajouter**. + +Le nom est ajouté à votre liste de surveillance et une première vérification est lancée immédiatement en arrière-plan, afin de ne pas avoir à attendre la prochaine vérification automatique pour connaître son état actuel. + +### Lire le statut + +Chaque domaine surveillé affiche un badge qui reflète le résultat de la dernière vérification : + +| Badge | Signification | +|-------|---------------| +| **Disponible** | Le nom semble libre et peut probablement être enregistré. | +| **Enregistré** | Le nom est déjà pris. | +| _(message d'erreur)_ | La vérification n'a pas pu aboutir (par exemple l'extension n'est pas prise en charge, ou le registre n'a pas pu être contacté). | +| **Jamais vérifié** | Aucun résultat n'est encore disponible. | + +La date de la dernière vérification est indiquée à côté du statut. + +### Revérifier et supprimer + +- Cliquez sur **Vérifier maintenant** à côté d'un domaine pour déclencher immédiatement une nouvelle vérification. Une animation est affichée pendant que le contrôle s'exécute en arrière-plan, et le statut se met à jour automatiquement une fois terminé. +- Cliquez sur l'icône de corbeille pour cesser de surveiller un domaine. Une confirmation est demandée avant la suppression. + +{{% notice style="tip" title="La disponibilité reste indicative" icon="lightbulb" %}} +Le résultat de disponibilité n'est qu'une indication. Certaines extensions ne peuvent pas être vérifiées de manière fiable, et un nom qui semble libre peut tout de même être réservé ou bloqué au moment de l'enregistrement. Confirmez toujours auprès d'un bureau d'enregistrement avant de compter sur un nom. +{{% /notice %}} + + +## Recherche WHOIS + +L'outil **WHOIS** affiche les informations publiques d'enregistrement d'un domaine : son bureau d'enregistrement, ses dates importantes et son statut actuel. + + + +Saisissez un nom de domaine puis lancez la recherche. happyDomain affiche alors un résumé clair des informations collectées : + +- **Statut** : les statuts d'enregistrement renvoyés pour le domaine (par exemple `active`, `clientTransferProhibited`, un état `hold`, etc.), présentés sous forme de badges colorés. +- **Date de création** et **Date d'expiration** : la date du premier enregistrement du domaine et celle à laquelle son enregistrement doit expirer. L'expiration est accompagnée d'une barre de progression et d'un compte à rebours, qui passe à l'orange puis au rouge à l'approche de l'échéance. +- **Bureau d'enregistrement** : l'organisme auprès duquel le domaine est enregistré, avec un lien vers son site lorsqu'il est disponible. +- **Serveurs de noms** : les serveurs de noms faisant autorité déclarés pour le domaine. + +Si le nom n'est pas enregistré, un message vous indique que le domaine est introuvable. Si la recherche elle-même échoue, l'erreur est affichée. + +{{% notice style="info" title="WHOIS et vérificateur de disponibilité" icon="circle-info" %}} +Le vérificateur de disponibilité s'appuie sur les mêmes données d'enregistrement que la recherche WHOIS. Si vous souhaitez la vue complète de l'enregistrement d'un nom, utilisez l'outil WHOIS ; si vous voulez simplement savoir si un nom est libre (et être prévenu ultérieurement), ajoutez-le à votre liste de surveillance de disponibilité. +{{% /notice %}} + + +## Résolveur DNS + +Le **résolveur DNS** vous permet d'interroger le DNS en direct de n'importe quel domaine, exactement tel qu'il est publié sur Internet en cet instant. C'est pratique pour confirmer qu'une modification s'est bien propagée, ou pour inspecter un domaine que vous ne gérez pas. + + + +Saisissez un nom de domaine puis lancez la requête. Par défaut, tous les types d'enregistrement sont demandés (`ANY`). Ouvrez les options **Avancées** pour affiner la requête : + +- **Champ (type d'enregistrement)** : restreignez la requête à un seul type d'enregistrement (`A`, `AAAA`, `MX`, `TXT`, etc.). +- **Résolveur** : choisissez le résolveur DNS auquel envoyer la requête. Plusieurs résolveurs publics réputés sont proposés, et vous pouvez sélectionner **Personnalisé** pour saisir l'adresse du résolveur de votre choix. +- **Afficher les enregistrements DNSSEC** : inclure les enregistrements liés à DNSSEC (`RRSIG`, `NSEC`, `NSEC3`) dans les résultats, masqués par défaut. + +Si vous gérez des domaines dans happyDomain, leurs noms vous sont suggérés au fur et à mesure que vous saisissez le domaine à interroger. + +Les résultats sont regroupés par type d'enregistrement, et chaque entrée affiche ses champs ainsi que son TTL. Lorsque le domaine existe mais ne possède aucun enregistrement du type demandé, un message l'indique explicitement. + +{{% notice style="tip" title="Résolveur et votre zone dans happyDomain" icon="lightbulb" %}} +Le résolveur montre ce qui est **actuellement publié** par les serveurs faisant autorité, ce qui peut différer d'une zone en cours d'édition dans happyDomain tant que vous n'avez pas [publié vos modifications]({{% relref "publish-changes" %}}). +{{% /notice %}} diff --git a/content/pages/domain-history.en.md b/content/pages/domain-history.en.md index 88753d8..7165ce7 100644 --- a/content/pages/domain-history.en.md +++ b/content/pages/domain-history.en.md @@ -1,7 +1,43 @@ --- date: 2025-06-15T11:06:00+02:00 title: "View change history" -weight: 40 +weight: 1500 --- Every time you [publish changes]({{% relref "publish-changes" %}}) with happyDomain, they are recorded in a log. This log allows you to easily retrieve the status of your domains as they were previously deployed, and to see when you made each change. + +## Opening the history + +From your domain's page, open the **History** entry in the menu. happyDomain displays every recorded version of the zone, from the most recent at the top to the oldest at the bottom. + + + +To keep the list readable, versions are grouped by month. A heading marks the beginning of each month so you can quickly locate a change by its time period. + +## Reading a version + +Each version is identified by the moment it was last modified, along with the avatar and email address of the author who made the change. + +Three dates may be shown for a version: + +- **Published on**: when this version was deployed to your DNS provider. A version without this date was saved but never published. +- **Committed on**: when the version was committed (saved as a definitive state of the zone). +- **Modified on**: when the version was last edited. + +If a message was attached when the changes were published, it appears below the dates, much like a commit message in version control. + +## Viewing the zone at a given time + +To inspect the full content of the zone as it was for a given version, click the eye button next to its date. happyDomain opens that version in read-only mode, so you can browse all the records exactly as they were at that moment. + +## Comparing two versions + +Under each version (except the oldest one), the **View differences** section lets you compare it with the version that immediately precedes it. + + + +Expand the section to reveal the changes: added records, deleted records, and modified records are highlighted, so you can see at a glance what each publication changed. The most recent comparison is expanded automatically when you open the page. + +{{% notice style="info" title="No history yet?" %}} +A domain only builds up a history once you start publishing changes to it. If you have just imported a domain, its history will fill in as you make and publish your first modifications. +{{% /notice %}} diff --git a/content/pages/domain-history.fr.md b/content/pages/domain-history.fr.md index 08f97b3..81a629f 100644 --- a/content/pages/domain-history.fr.md +++ b/content/pages/domain-history.fr.md @@ -1,7 +1,43 @@ --- date: 2025-06-15T11:06:00+02:00 title: "Voir l'historique des changements" -weight: 40 +weight: 1500 --- À chaque fois que vous [publiez des modifications]({{% relref "publish-changes" %}}) avec happyDomain, celles-ci sont enregistrées dans un journal. Ce journal vous permet de retrouver facilement l'état de vos domaines tels qu'ils étaient déployés précédemment, et de voir quand vous avez fait chaque modification. + +## Ouvrir l'historique + +Depuis la page de votre domaine, ouvrez l'entrée **Historique** dans le menu. happyDomain affiche toutes les versions enregistrées de la zone, de la plus récente en haut à la plus ancienne en bas. + + + +Pour garder la liste lisible, les versions sont regroupées par mois. Un en-tête marque le début de chaque mois, ce qui vous permet de retrouver rapidement une modification d'après sa période. + +## Lire une version + +Chaque version est identifiée par le moment de sa dernière modification, accompagné de l'avatar et de l'adresse électronique de l'auteur qui l'a effectuée. + +Trois dates peuvent être affichées pour une version : + +- **Publiée le** : le moment où cette version a été déployée chez votre fournisseur DNS. Une version sans cette date a été enregistrée, mais jamais publiée. +- **Enregistrée le** : le moment où la version a été figée (sauvegardée comme un état définitif de la zone). +- **Dernière modification le** : le moment où la version a été modifiée pour la dernière fois. + +Si un message a été associé lors de la publication des changements, il apparaît sous les dates, à la manière d'un message de commit dans un gestionnaire de versions. + +## Voir la zone à un instant donné + +Pour examiner le contenu complet de la zone tel qu'il était pour une version donnée, cliquez sur le bouton en forme d'œil situé à côté de sa date. happyDomain ouvre cette version en lecture seule, ce qui vous permet de parcourir tous les enregistrements exactement tels qu'ils étaient à ce moment. + +## Comparer deux versions + +Sous chaque version (sauf la plus ancienne), la section **Voir les changements** vous permet de la comparer avec la version qui la précède immédiatement. + + + +Dépliez la section pour révéler les modifications : les enregistrements ajoutés, supprimés et modifiés sont mis en évidence, ce qui vous permet de voir d'un coup d'œil ce que chaque publication a changé. La comparaison la plus récente est dépliée automatiquement à l'ouverture de la page. + +{{% notice style="info" title="Pas encore d'historique ?" %}} +Un domaine ne se constitue un historique qu'à partir du moment où vous commencez à y publier des changements. Si vous venez d'importer un domaine, son historique se remplira au fur et à mesure que vous effectuerez et publierez vos premières modifications. +{{% /notice %}} diff --git a/content/pages/domain-new.en.md b/content/pages/domain-new.en.md index 738330e..e371071 100644 --- a/content/pages/domain-new.en.md +++ b/content/pages/domain-new.en.md @@ -2,7 +2,7 @@ date: 2021-01-12T21:38:49+02:00 title: Import a domain author: Frederic -weight: 20 +weight: 800 --- Importing a domain into happyDomain does not make happyDomain the owner of your domain. This action does not involve any changes to your usual hosting provider. happyDomain will contact your hosting provider or server to check which services are currently registered. diff --git a/content/pages/domain-new.fr.md b/content/pages/domain-new.fr.md index 78b3e0f..00d091f 100644 --- a/content/pages/domain-new.fr.md +++ b/content/pages/domain-new.fr.md @@ -1,7 +1,7 @@ --- date: 2020-12-09T18:12:45+01:00 title: Importer un domaine -weight: 20 +weight: 800 --- Importer un domaine dans happyDomain ne rend pas happyDomain propriétaire de votre domaine. Cette action n'implique aucune modification auprès de votre hébergeur habituel. happyDomain va communiquer avec votre hébergeur ou votre serveur afin de consulter les services qui sont actuellement enregistrés. diff --git a/content/pages/domains/_index.en.md b/content/pages/domains/_index.en.md index 6170d54..fc6a1c8 100644 --- a/content/pages/domains/_index.en.md +++ b/content/pages/domains/_index.en.md @@ -4,14 +4,17 @@ title: Centralize your domains author: Frederic aliases: home -weight: 10 +weight: 300 --- +happyDomain provides you with a unified graphical interface with modern features, regardless of where your domain names are hosted. They can be on a DNS server (PowerDNS, bind, knot, ...) of your own, or with one or several providers (around 50 are currently supported). + + ## Your domains The home page presents the list of all the domains managed by happyDomain, whatever their host: -![The domains managed by happyDomain](domain-list.png) +![The domains managed by happyDomain](domain-list.webp) Click one of the domains to start [make changes]({{% relref "domain-abstract" %}}) (add a sub-domain, add a service, ...). @@ -20,7 +23,7 @@ Click one of the domains to start [make changes]({{% relref "domain-abstract" %} On the right, you can see the list of the different hosting providers for your: -The hosters of your domains](hosters-list.png) +![The hosters of your domains](providers-list.webp) You can [add new host]({{% relref "provider-new-choice" %}}) by clicking on the + button in the table header. @@ -28,7 +31,7 @@ Clicking on a row in this table will filter the list of domains to show only dom You will also see, if the host allows you to list the domains that belong to you, the domains that you can add to happyDomain: -![Domain filtering according to the hosting provider](hoster-ovh.png) +![Domain filtering according to the hosting provider](filtered-by-provider.webp) To view the entire list again, simply click on the selected host again. @@ -37,19 +40,19 @@ To view the entire list again, simply click on the selected host again. If you find an error or no longer need a hosting provider, click on the ... on the line of the host concerned. You will then be able to choose between [update information]({{% relref "provider-update" %}}) or delete the host: -![Modify or delete a hosting](hoster-edit.png) +![Modify or delete a hosting](provider-menu.webp) Note that you will not be able to remove the host as long as domains referring to it exist in the list on the left. ## Add a domain -You have a new domain you want to manage in happyDomain? Start by entering its name in the field below the list. You will then be guided to the [to choose the host] screen ({{% relref "domain-new" %}}). +You have a new domain you want to manage in happyDomain? Start by entering its name in the field above the list. You will then be guided to the screen [to choose the host]({{% relref "domain-new" %}}). -![Location to add a domain that is not listed](new-domain.png) +![Location to add a domain that is not listed](new-domain.webp) -The field does not show when a host is selected on the right. Unless this host does not allow to list: +Some DNS providers allows you to create a domain directly in their database, even if it was not already registered. First, you'll need to select the right provider. You'll see a dedicated "Create on" button. -![Special case of addition for authoritative DNS servers](hoster-self.png) +![Some provider will permit to create a domain](create-domain-on-provider.webp) -In this case, validating the field will automatically search for the new domain with the selected host, as indicated by the message just above the field. +Some providers could charge you for this action, so pay attention if this implies to realy buy the domain. diff --git a/content/pages/domains/_index.fr.md b/content/pages/domains/_index.fr.md index 932d3fb..160c5f4 100644 --- a/content/pages/domains/_index.fr.md +++ b/content/pages/domains/_index.fr.md @@ -3,7 +3,7 @@ date: 2020-12-09T18:12:45+01:00 title: Regrouper vos domaines aliases: home -weight: 10 +weight: 300 --- happyDomain vous apporte une interface graphique unifiée et avec des fonctionnalités modernes quelque soit l'endroit où sont hébergés vos noms de domaine. Ils peuvent être sur un serveur DNS (PowerDNS, bind, knot, ...) qui vous est propre, ou bien chez un ou plusieurs hébergeurs (une 50aine sont supportés à l'heure actuelle). @@ -13,7 +13,7 @@ happyDomain vous apporte une interface graphique unifiée et avec des fonctionna La page d'accueil présente la liste de l'ensemble des domaines gérés par happyDomain, quelque soit leur hébergeur : -![Les domaines gérés par happyDomain](domain-list.png) +![Les domaines gérés par happyDomain](domain-list.webp) Cliquez sur l'un des domaines pour commencer à [y apporter des modifications]({{% relref "domain-abstract" %}}) (ajouter un sous-domaine, ajouter un service, ...). @@ -22,7 +22,7 @@ Cliquez sur l'un des domaines pour commencer à [y apporter des modifications]({ Sur la droite, vous voyez la liste des différents hébergeurs de vos domaines : -![Les hébergeurs de vos domaines](hosters-list.png) +![Les hébergeurs de vos domaines](providers-list.webp) Vous pouvez [ajouter un nouvel hébergeur]({{% relref "provider-new-choice" %}}) en cliquant sur le bouton +, présent dans l'en-tête du tableau. @@ -30,7 +30,7 @@ En cliquant sur une ligne de ce tableau, vous filtrerez la liste des domaines po Vous verrez aussi, si l'hébergeur permet de lister les domaines qui vous appartiennent, les domaines que vous pouvez ajouter à happyDomain : -![Filtrage des domaines en fonction de l'hébergeur](hoster-ovh.png) +![Filtrage des domaines en fonction de l'hébergeur](filtered-by-provider.webp) Pour afficher à nouveau la liste dans son intégralité, recliquez simplement sur l'hébergeur qui est sélectionné. @@ -39,7 +39,7 @@ Pour afficher à nouveau la liste dans son intégralité, recliquez simplement s Si vous constatez une erreur ou n'avez plus besoin d'un hébergeur, cliquez sur les ... sur la ligne de l'hébergeur concerné. Vous aurez alors la possibilité de choisir entre [mettre à jour les informations]({{% relref "provider-update" %}}) ou supprimer l'hébergeur : -![Modification ou suppression d'un hébergeur](hoster-edit.png) +![Modification ou suppression d'un hébergeur](provider-menu.webp) Notez que vous ne pourrez pas supprimer l'hébergeur tant que des domaines y faisant référence existeront dans la liste de gauche. @@ -48,10 +48,10 @@ Notez que vous ne pourrez pas supprimer l'hébergeur tant que des domaines y fai Vous avez un nouveau domaine que vous souhaitez gérer dans happyDomain ? Commencez par entrer son nom dans le champ présent sous la liste. Vous serez ensuite guidé vers l'écran [permettant de choisir l'hébergeur]({{% relref "domain-new" %}}). -![Emplacement pour ajouter un domaine qui n'est pas listé](new-domain.png) +![Emplacement pour ajouter un domaine qui n'est pas listé](new-domain.webp) -Le champ n'apparaît pas lorsqu'un hébergeur est sélectionné à droite. Sauf si cet hébergeur ne permet pas de lister les domaines : +Certains hébergeurs DNS vous permettent de créer un domaine directement dans leur base de données, même s'il n'était pas déjà enregistré. Vous devrez d'abord sélectionner le bon hébergeur. Vous verrez alors un bouton « Créer sur » dédié. -![Cas particulier d'ajout pour les serveurs DNS autoritaire](hoster-self.png) +![Certains hébergeurs permettent de créer un domaine](create-domain-on-provider.webp) -Dans ce cas, la validation du champ recherchera automatiquement le nouveau domaine auprès de l'hébergeur sélectionné, comme l'indique le message juste au dessus du champ. +Certains hébergeurs peuvent vous facturer cette action, soyez donc attentif si cela implique d'acheter réellement le domaine. diff --git a/content/pages/domains/create-domain-on-provider.webp b/content/pages/domains/create-domain-on-provider.webp new file mode 100644 index 0000000..b7bff7b Binary files /dev/null and b/content/pages/domains/create-domain-on-provider.webp differ diff --git a/content/pages/domains/domain-list.png b/content/pages/domains/domain-list.png deleted file mode 100644 index 640ad10..0000000 Binary files a/content/pages/domains/domain-list.png and /dev/null differ diff --git a/content/pages/domains/domain-list.webp b/content/pages/domains/domain-list.webp new file mode 100644 index 0000000..87d12df Binary files /dev/null and b/content/pages/domains/domain-list.webp differ diff --git a/content/pages/domains/filtered-by-provider.webp b/content/pages/domains/filtered-by-provider.webp new file mode 100644 index 0000000..e38da4e Binary files /dev/null and b/content/pages/domains/filtered-by-provider.webp differ diff --git a/content/pages/domains/hoster-edit.png b/content/pages/domains/hoster-edit.png deleted file mode 100644 index 797156f..0000000 Binary files a/content/pages/domains/hoster-edit.png and /dev/null differ diff --git a/content/pages/domains/hoster-ovh.png b/content/pages/domains/hoster-ovh.png deleted file mode 100644 index 0988ad2..0000000 Binary files a/content/pages/domains/hoster-ovh.png and /dev/null differ diff --git a/content/pages/domains/hoster-self.png b/content/pages/domains/hoster-self.png deleted file mode 100644 index ac66177..0000000 Binary files a/content/pages/domains/hoster-self.png and /dev/null differ diff --git a/content/pages/domains/hosters-list.png b/content/pages/domains/hosters-list.png deleted file mode 100644 index f7179b4..0000000 Binary files a/content/pages/domains/hosters-list.png and /dev/null differ diff --git a/content/pages/domains/new-domain.png b/content/pages/domains/new-domain.png deleted file mode 100644 index cbebda6..0000000 Binary files a/content/pages/domains/new-domain.png and /dev/null differ diff --git a/content/pages/domains/new-domain.webp b/content/pages/domains/new-domain.webp new file mode 100644 index 0000000..1f08cae Binary files /dev/null and b/content/pages/domains/new-domain.webp differ diff --git a/content/pages/domains/provider-menu.webp b/content/pages/domains/provider-menu.webp new file mode 100644 index 0000000..d8faf66 Binary files /dev/null and b/content/pages/domains/provider-menu.webp differ diff --git a/content/pages/domains/providers-list.webp b/content/pages/domains/providers-list.webp new file mode 100644 index 0000000..d53f47e Binary files /dev/null and b/content/pages/domains/providers-list.webp differ diff --git a/content/pages/import-export/happydomain-export-zone.webp b/content/pages/import-export/happydomain-export-zone.webp new file mode 100644 index 0000000..780aba2 Binary files /dev/null and b/content/pages/import-export/happydomain-export-zone.webp differ diff --git a/content/pages/import-export/happydomain-modal-import-zone.webp b/content/pages/import-export/happydomain-modal-import-zone.webp new file mode 100644 index 0000000..6ec9693 Binary files /dev/null and b/content/pages/import-export/happydomain-modal-import-zone.webp differ diff --git a/content/pages/import-export/index.en.md b/content/pages/import-export/index.en.md new file mode 100644 index 0000000..b098082 --- /dev/null +++ b/content/pages/import-export/index.en.md @@ -0,0 +1,63 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: "Importing and exporting a zone" +author: nemunaire +weight: 1600 +description: "Bring an existing zone file into happyDomain, or export your zone in standard BIND format" +--- + +happyDomain can exchange your zone with the rest of the DNS world using the standard zone file format (the well-known BIND format). You can **import** a zone file to populate your working copy, and **export** the current zone to read it, copy it, or keep it elsewhere. + +These actions are available from the gear menu at the top of the zone editor sidebar. + +## Re-importing the live zone + +Before working with files, it is worth knowing that you can always pull the **current** zone back from your provider. In the gear menu, choose **Retrieve the current zone**. + +This contacts your hosting provider, reads the zone as it stands right now, and refreshes your working copy from it. Use it when the zone may have been changed outside happyDomain, or to start again from a clean state. + +{{% notice style="warning" title="This replaces unpublished edits" icon="triangle-exclamation" %}} +Re-importing the live zone fetches the provider's version. Any local change you had not yet published may be superseded, so review your pending changes first (see {{% relref "publish-changes" %}}) if you want to keep them. +{{% /notice %}} + +## Importing a zone file + +To load a zone from a standard zone file: + +1. Open the gear menu in the sidebar and choose the **upload / import a zone** action. +2. A dialog opens with two tabs: + - **From text** -- paste the content of a zone file directly into the text area. + - **From a zone file** -- select a file from your computer. +3. Click the upload button to send it. + +![The import zone dialog, with the "From text" and "From a zone file" tabs](happydomain-modal-import-zone.webp) + +happyDomain parses the zone file, recognises the records, and groups them back into services in your working copy. As with every other edit, the imported content stays local until you publish it. + +{{% notice style="info" title="Standard format" icon="circle-info" %}} +The expected format is the standard textual zone file, the same one BIND and most DNS tools use. A line such as `@ 4269 IN SOA root ns 2042070136 ...` is a typical example of what you can paste. +{{% /notice %}} + +## Exporting / viewing the zone + +To obtain your zone as a standard zone file: + +1. Open the gear menu and choose **View my zone**. +2. happyDomain renders the current zone in standard BIND format, with syntax highlighting. +3. Use the **Copy to clipboard** button to grab the whole file in one click. + +![The zone displayed in standard BIND format, with syntax highlighting and a copy-to-clipboard button](happydomain-export-zone.webp) + +This view always reflects the zone you are currently looking at. If you are browsing a past version from the {{% relref "domain-history" %}}, the export shows that historical version, which is handy for comparing or restoring an earlier state. + +## Typical workflows + +- **Migrating from another tool**: export the zone from your previous tool as a zone file, then import it here with **From a zone file**. +- **Keeping a backup**: open **View my zone** and copy the content somewhere safe. +- **Bulk editing**: export, edit the file in your favourite editor, then re-import the result. + +## After importing + +Importing only changes your working copy. To make it effective at your provider: + +1. Review the resulting diff and publish the changes (see {{% relref "publish-changes" %}}). diff --git a/content/pages/import-export/index.fr.md b/content/pages/import-export/index.fr.md new file mode 100644 index 0000000..7884b6b --- /dev/null +++ b/content/pages/import-export/index.fr.md @@ -0,0 +1,63 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: "Importer et exporter une zone" +author: nemunaire +weight: 1600 +description: "Importer un fichier de zone existant dans happyDomain, ou exporter votre zone au format BIND standard" +--- + +happyDomain peut échanger votre zone avec le reste du monde DNS en utilisant le format de fichier de zone standard (le célèbre format BIND). Vous pouvez **importer** un fichier de zone pour alimenter votre copie de travail, et **exporter** la zone actuelle pour la lire, la copier ou la conserver ailleurs. + +Ces actions sont accessibles depuis le menu en forme d'engrenage situé en haut de la barre latérale de l'éditeur de zone. + +## Réimporter la zone en ligne + +Avant de travailler avec des fichiers, il est utile de savoir que vous pouvez toujours récupérer la zone **actuelle** auprès de votre hébergeur. Dans le menu engrenage, choisissez « Récupérer la zone actuelle ». + +Cette action contacte votre hébergeur, lit la zone telle qu'elle est en ce moment, et rafraîchit votre copie de travail à partir d'elle. Utilisez-la lorsque la zone a pu être modifiée en dehors de happyDomain, ou pour repartir d'un état propre. + +{{% notice style="warning" title="Cela remplace les modifications non publiées" icon="triangle-exclamation" %}} +Réimporter la zone en ligne récupère la version de l'hébergeur. Tout changement local que vous n'aviez pas encore publié peut être écrasé : examinez donc d'abord [vos changements en attente]({{% relref "publish-changes" %}}) si vous souhaitez les conserver. +{{% /notice %}} + +## Importer un fichier de zone + +Pour charger une zone à partir d'un fichier de zone standard : + +1. Ouvrez le menu engrenage de la barre latérale et choisissez l'action d'import de zone. +2. Une fenêtre s'ouvre avec deux onglets : + - **Depuis du texte** : collez le contenu d'un fichier de zone directement dans la zone de saisie. + - **Depuis un fichier de zone** : sélectionnez un fichier sur votre ordinateur. +3. Cliquez sur le bouton d'envoi pour le transmettre. + +![La fenêtre d'import de zone, avec les onglets « Depuis du texte » et « Depuis un fichier de zone »](happydomain-modal-import-zone.webp) + +happyDomain analyse le fichier de zone, reconnaît les enregistrements et les regroupe à nouveau en services dans votre copie de travail. Comme pour toute autre modification, le contenu importé reste local tant que vous ne l'avez pas publié. + +{{% notice style="info" title="Format standard" icon="circle-info" %}} +Le format attendu est le fichier de zone textuel standard, le même que celui qu'utilisent BIND et la plupart des outils DNS. Une ligne telle que `@ 4269 IN SOA root ns 2042070136 ...` est un exemple typique de ce que vous pouvez coller. +{{% /notice %}} + +## Exporter / visualiser la zone + +Pour obtenir votre zone sous forme de fichier de zone standard : + +1. Ouvrez le menu engrenage et choisissez « Voir ma zone ». +2. happyDomain affiche la zone actuelle au format BIND standard, avec coloration syntaxique. +3. Utilisez le bouton **Copier dans le presse-papier** pour récupérer le fichier entier en un clic. + +![La zone affichée au format BIND standard, avec coloration syntaxique et un bouton de copie dans le presse-papier](happydomain-export-zone.webp) + +Cette vue reflète toujours la zone que vous consultez actuellement. Si vous parcourez une version passée depuis l'[historique]({{% relref "domain-history" %}}), l'export montre cette version historique, ce qui est pratique pour comparer ou restaurer un état antérieur. + +## Cas d'usage typiques + +- **Migrer depuis un autre outil** : exportez la zone de votre outil précédent sous forme de fichier de zone, puis importez-la ici avec « Depuis un fichier de zone ». +- **Conserver une sauvegarde** : ouvrez « Voir ma zone » et copiez le contenu dans un endroit sûr. +- **Édition en masse** : exportez, modifiez le fichier dans votre éditeur favori, puis réimportez le résultat. + +## Après un import + +Un import ne modifie que votre copie de travail. Pour le rendre effectif chez votre hébergeur : + +1. Examinez le différentiel obtenu, puis [publiez les changements]({{% relref "publish-changes" %}}). diff --git a/content/pages/login/happydomain-forget-password-page.webp b/content/pages/login/happydomain-forget-password-page.webp new file mode 100644 index 0000000..c559b3b Binary files /dev/null and b/content/pages/login/happydomain-forget-password-page.webp differ diff --git a/content/pages/login/happydomain-login-page.webp b/content/pages/login/happydomain-login-page.webp new file mode 100644 index 0000000..00bd09e Binary files /dev/null and b/content/pages/login/happydomain-login-page.webp differ diff --git a/content/pages/login/index.en.md b/content/pages/login/index.en.md new file mode 100644 index 0000000..57e3b96 --- /dev/null +++ b/content/pages/login/index.en.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Log in +author: nemunaire +weight: 200 +description: "Sign in to happyDomain and recover a forgotten password" +--- + +Once you have [created an account]({{% relref "signup" %}}) and validated your email address, you can sign in to access your domains. + +## Signing in + +On the login page, enter the email address and password you chose at registration, then click **Go**. + +![The happyDomain login page](happydomain-login-page.webp) + +If the credentials are correct, you are taken to your dashboard. If they are not, an error message is displayed: double-check your address and password and try again. + +{{% notice style="info" title="Repeated attempts" icon="shield" %}} +For security reasons, the server may ask you to complete an anti-bot challenge (captcha) after a few failed attempts, or temporarily rate-limit further tries. Wait a moment, then retry. +{{% /notice %}} + +### Signing in with an external provider + +When the server is configured for it, an additional button lets you sign in through an external identity provider (for example Google, GitLab, GitHub, Microsoft or Apple). Click it to be redirected to that provider and authenticate there. + +## Forgotten password + +If you no longer remember your password, click **Forgotten password?** below the login form. + +![The happyDomain forgotten password page](happydomain-forget-password-page.webp) + +Enter the email address of your account and click **Send the recovery link**. If an account matches, a message containing a recovery link is sent to that address. + +Open the link from your mailbox to reach the account recovery form, where you can set a new password: + +1. Type your **new password** (it must meet the same strength requirements as at sign-up). +2. Retype it in the **confirmation** field. +3. Click **Redefine my password**. + +Once the password is redefined, you are redirected to the login page to sign in with your new credentials. + +{{% notice style="warning" title="Servers without email" icon="triangle-exclamation" %}} +On instances that run without a mail service, password recovery is not available: clicking **Forgotten password?** displays a notice inviting you to contact the server administrator to reset your password. +{{% /notice %}} diff --git a/content/pages/login/index.fr.md b/content/pages/login/index.fr.md new file mode 100644 index 0000000..7491ac7 --- /dev/null +++ b/content/pages/login/index.fr.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Se connecter +weight: 200 +description: "Connectez-vous à happyDomain et récupérez un mot de passe oublié" +--- + +Une fois votre [compte créé]({{% relref "signup" %}}) et votre adresse e-mail validée, vous pouvez vous connecter pour accéder à vos domaines. + +## Se connecter + +Sur la page de connexion, saisissez l'adresse e-mail et le mot de passe choisis lors de l'inscription, puis cliquez sur « C'est parti ». + +![La page de connexion d'happyDomain](happydomain-login-page.webp) + +Si les identifiants sont corrects, vous arrivez sur votre tableau de bord. Sinon, un message d'erreur s'affiche : vérifiez votre adresse et votre mot de passe, puis réessayez. + +{{% notice style="info" title="Tentatives répétées" icon="shield" %}} +Pour des raisons de sécurité, le serveur peut vous demander de compléter une vérification anti-robot (captcha) après plusieurs échecs, ou limiter temporairement les nouvelles tentatives. Patientez un instant, puis réessayez. +{{% /notice %}} + +### Se connecter avec un fournisseur externe + +Lorsque le serveur est configuré pour cela, un bouton supplémentaire permet de se connecter via un fournisseur d'identité externe (par exemple Google, GitLab, GitHub, Microsoft ou Apple). Cliquez dessus pour être redirigé vers ce fournisseur et vous y authentifier. + +## Mot de passe oublié + +Si vous ne vous souvenez plus de votre mot de passe, cliquez sur « Mot de passe oublié ? » sous le formulaire de connexion. + +![La page de récupération de mot de passe d'happyDomain](happydomain-forget-password-page.webp) + +Saisissez l'adresse e-mail de votre compte, puis cliquez sur « Envoyer le lien de récupération ». Si un compte correspond, un message contenant un lien de récupération est envoyé à cette adresse. + +Ouvrez le lien depuis votre messagerie pour accéder au formulaire de récupération de compte, où vous pourrez définir un nouveau mot de passe : + +1. Saisissez votre **nouveau mot de passe** (il doit respecter les mêmes exigences de robustesse qu'à l'inscription). +2. Ressaisissez-le dans le champ de **confirmation**. +3. Cliquez sur « Redéfinir mon mot de passe ». + +Une fois le mot de passe redéfini, vous êtes redirigé vers la page de connexion pour vous identifier avec vos nouveaux identifiants. + +{{% notice style="warning" title="Serveurs sans e-mail" icon="triangle-exclamation" %}} +Sur les instances fonctionnant sans service de messagerie, la récupération de mot de passe n'est pas disponible : cliquer sur « Mot de passe oublié ? » affiche un message vous invitant à contacter l'administrateur du serveur pour réinitialiser votre mot de passe. +{{% /notice %}} diff --git a/content/pages/me.en.md b/content/pages/me.en.md deleted file mode 100644 index 60d36c7..0000000 --- a/content/pages/me.en.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -date: 2021-01-12T21:38:49+02:00 -title: "Set up your profile" -author: Frederic -weight: 40 ---- - -You access this page by clicking on the top menu "My Account" link. - -## Account Settings - -The screen is divided into three parts. The first one will allow you to change the settings related to your account: such as the language of the interface or the way the contextual help is displayed. - - -## Change password - -The second part of the screen allows you to change the password. - - -## Change account email address - -It is currently not possible to change the email address of your account. We invite you to contact us if you wish to change it. - - -## Delete your account - -The last part of the page allows you to delete your happyDomain account. - -Once the deletion is validated, your account will no longer be accessible and all data belonging to you will be deleted shortly after, during a regular database cleanup. - -From the moment you delete your account, your domains will continue to respond according to the last update you made on happyDomain. The deletion will not affect the distributed data. diff --git a/content/pages/me.fr.md b/content/pages/me.fr.md deleted file mode 100644 index d5ae27f..0000000 --- a/content/pages/me.fr.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -date: 2020-12-10T10:26:54+01:00 -title: "Paramétrer son profil" -weight: 40 ---- - -Vous accédez à cette page en cliquant sur le lien « Mon compte » dans le menu en haut. - -## Paramètres du compte - -L'écran est divisé en 3 parties. La première va vous permettre de modifier les paramètres liés à votre compte : tel que la langue de l'interface ou la manière dont l'aide contextuelle est affichée. - - -## Changer de mot de passe - -La seconde partie de l'écran vous permet de changer de mot de passe. - - -## Changer l'adresse électronique de compte - -Il n'est pour l'instant pas possible de changer l'adresse électronique de votre compte. Nous vous invitons à nous contacter si vous souhaitez la changer. - - -## Supprimer son compte - -La dernière partie de la page vous permet de supprimer votre compte happyDomain. - -Une fois la suppression validée, votre compte ne sera plus accessible et l'ensemble des données vous appartenant sera supprimé peu de temps après, lors d'un nettoyage régulier de la base de données. - -À partir du moment où vous supprimez votre compte, vos domaines continueront de répondre selon la dernière mise à jour que vous avez effectué sur happyDomain. La suppression n'affectera pas les données distribuées. diff --git a/content/pages/notifications.en.md b/content/pages/notifications.en.md new file mode 100644 index 0000000..9406e8c --- /dev/null +++ b/content/pages/notifications.en.md @@ -0,0 +1,116 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Notifications +author: nemunaire +weight: 2300 +description: "Receive alerts when your monitoring checks change state, and configure where and when those alerts are delivered" +--- + +happyDomain can notify you when something changes on your domains. Notifications are driven by the [monitoring & checks]({{% relref "checks" %}}) system: whenever a checker changes status (for example from **OK** to **Warning**, or back to **OK** after a problem), happyDomain can deliver an alert to the channels you have configured. + +You manage notifications from the **Notifications** page in your account settings. It is organised into three tabs: **Channels**, **Preferences** and **History**. + + + + +## What triggers a notification + +Notifications are tied to your checkers. happyDomain watches the status reported by each check and sends a notification when: + +- a check **degrades** to (or beyond) a severity you care about, for example reaching **Warning**, **Critical** or **Error**; +- a check **recovers**, returning to a healthy state, if you have asked to be notified of recoveries. + +Each notification therefore describes a status transition (the previous status and the new status) for a given target. Which transitions reach you, and through which channels, is entirely controlled by your **preferences** (see below). + + +## Channels + +A **channel** is a destination where notifications are sent. Open the **Channels** tab to manage them. + +To add one, click **Add**, choose a **Type**, give it a **Name** (so you can recognise it later) and fill in the type-specific fields. A channel can be **enabled** or disabled with a switch without deleting it. + +happyDomain offers the following channel types out of the box: + +### Email + +Sends notifications to an email address. + +- **Email address**: the recipient. If left empty, the notification is sent to your account's email address. + +### Webhook + +Sends an HTTP request to a URL of your choice, which is useful to integrate happyDomain with chat tools, automation platforms or your own services. + +- **Webhook URL** (required): the endpoint that will receive the notification. +- **Webhook headers**: optional custom HTTP headers (name/value pairs) to add to the request, for example an authorization header. +- **Webhook secret**: an optional secret used to sign the request so the receiver can verify it really comes from happyDomain. + +### UnifiedPush + +Delivers push notifications to your devices through a [UnifiedPush](https://unifiedpush.org/) distributor. + +- **UnifiedPush endpoint** (required): the endpoint URL provided by your UnifiedPush application. + +{{% notice style="info" title="Other channel types" icon="circle-info" %}} +The list of available types depends on what the instance administrator has enabled. For types that happyDomain does not provide a dedicated form for, the editor falls back to a raw JSON configuration field. +{{% /notice %}} + +### Testing a channel + +Once a channel is created and enabled, use the **send/test** button next to it to deliver a test notification. This confirms the configuration works before relying on it for real alerts. + + + + +## Preferences + +Channels say *where* notifications go; **preferences** say *what* gets sent and *when*. Open the **Preferences** tab and click **Add** to create a rule. + +A preference combines the following settings: + +### Scope + +Choose how broadly the rule applies: + +- **Global**: applies to all your domains and services. +- **Domain**: applies to a single domain you select. +- **Service**: applies to a specific service (you select the domain and provide the service identifier). + +### Channels + +Select one or more of your configured channels to receive the notifications matching this preference. If you have no channels yet, create one first in the **Channels** tab. + +### Minimum status + +Pick the lowest severity that should trigger a notification. The available levels, in increasing severity, are **OK**, **Info**, **Warning**, **Critical** and **Error**. Only status changes that reach this level (or higher) are notified. For example, choosing **Warning** means you are alerted on Warning, Critical and Error, but not on purely informational changes. + +### Notify on recovery + +When enabled, you also receive a notification when a previously degraded check returns to a healthy state, so you know when a problem has been resolved. + +### Quiet hours + +Optionally define a period during which notifications are held back, for instance overnight. Set a **start** hour and an **end** hour (0 to 23). When quiet hours are active, alerts raised within that window are not sent immediately. + +### Enabled + +Each preference can be turned on or off with a switch, letting you temporarily suspend a rule without deleting it. + + + +{{% notice style="tip" title="Start simple" icon="lightbulb" %}} +A common setup is a single **Global** preference, pointing at one channel, with a minimum status of **Warning** and recovery notifications enabled. You can later add more specific per-domain or per-service rules as your needs grow. +{{% /notice %}} + + +## History + +The **History** tab lists the notifications happyDomain has attempted to send. For each entry you can see: + +- the target concerned; +- the status transition (previous status → new status); +- whether delivery **succeeded** or **failed** (with the error message when it failed). + +Use **Load more** to page back through older entries. This view is the place to check why an expected alert did not reach you, for example a channel misconfiguration causing repeated failures. + + diff --git a/content/pages/notifications.fr.md b/content/pages/notifications.fr.md new file mode 100644 index 0000000..6161a03 --- /dev/null +++ b/content/pages/notifications.fr.md @@ -0,0 +1,115 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Notifications +weight: 2300 +description: "Recevoir des alertes lorsque vos contrôles de supervision changent d'état, et configurer où et quand ces alertes sont délivrées" +--- + +happyDomain peut vous prévenir lorsque quelque chose change sur vos domaines. Les notifications reposent sur le système de [supervision et contrôles]({{% relref "checks" %}}) : chaque fois qu'un contrôle change de statut (par exemple de **OK** à **Avertissement**, ou un retour à **OK** après un problème), happyDomain peut envoyer une alerte vers les canaux que vous avez configurés. + +Vous gérez les notifications depuis la page **Notifications** des paramètres de votre compte. Elle s'organise en trois onglets : **Canaux**, **Préférences** et **Historique**. + + + + +## Ce qui déclenche une notification + +Les notifications sont liées à vos contrôles. happyDomain surveille le statut rapporté par chaque contrôle et envoie une notification lorsque : + +- un contrôle **se dégrade** jusqu'à (ou au-delà d') une gravité qui vous importe, par exemple en atteignant **Avertissement**, **Critique** ou **Erreur** ; +- un contrôle **se rétablit**, en revenant à un état sain, si vous avez demandé à être prévenu des rétablissements. + +Chaque notification décrit donc une transition de statut (l'ancien statut et le nouveau) pour une cible donnée. Les transitions qui vous parviennent, et par quels canaux, sont entièrement déterminées par vos **préférences** (voir ci-dessous). + + +## Canaux + +Un **canal** est une destination vers laquelle les notifications sont envoyées. Ouvrez l'onglet **Canaux** pour les gérer. + +Pour en ajouter un, cliquez sur **Ajouter**, choisissez un **Type**, donnez-lui un **Nom** (afin de le reconnaître par la suite) et renseignez les champs propres à ce type. Un canal peut être **activé** ou désactivé à l'aide d'un interrupteur, sans avoir à le supprimer. + +happyDomain propose les types de canaux suivants d'origine : + +### E-mail + +Envoie les notifications à une adresse e-mail. + +- **Adresse e-mail** : le destinataire. Si le champ est laissé vide, la notification est envoyée à l'adresse e-mail de votre compte. + +### Webhook + +Envoie une requête HTTP vers une URL de votre choix, ce qui est utile pour intégrer happyDomain à des outils de discussion, des plateformes d'automatisation ou vos propres services. + +- **URL du webhook** (obligatoire) : le point d'accès qui recevra la notification. +- **En-têtes du webhook** : des en-têtes HTTP personnalisés facultatifs (paires nom/valeur) à ajouter à la requête, par exemple un en-tête d'autorisation. +- **Secret du webhook** : un secret facultatif servant à signer la requête, afin que le destinataire puisse vérifier qu'elle provient bien de happyDomain. + +### UnifiedPush + +Délivre des notifications push sur vos appareils via un distributeur [UnifiedPush](https://unifiedpush.org/). + +- **Point d'accès UnifiedPush** (obligatoire) : l'URL du point d'accès fournie par votre application UnifiedPush. + +{{% notice style="info" title="Autres types de canaux" icon="circle-info" %}} +La liste des types disponibles dépend de ce que l'administrateur de l'instance a activé. Pour les types pour lesquels happyDomain ne propose pas de formulaire dédié, l'éditeur bascule sur un champ de configuration JSON brut. +{{% /notice %}} + +### Tester un canal + +Une fois un canal créé et activé, utilisez le bouton d'envoi/test situé à côté de lui pour délivrer une notification de test. Cela confirme que la configuration fonctionne avant de compter dessus pour de vraies alertes. + + + + +## Préférences + +Les canaux indiquent *où* vont les notifications ; les **préférences** indiquent *quoi* est envoyé et *quand*. Ouvrez l'onglet **Préférences** puis cliquez sur **Ajouter** pour créer une règle. + +Une préférence combine les réglages suivants : + +### Portée + +Choisissez l'étendue d'application de la règle : + +- **Globale** : s'applique à l'ensemble de vos domaines et services. +- **Domaine** : s'applique à un seul domaine que vous sélectionnez. +- **Service** : s'applique à un service précis (vous sélectionnez le domaine et fournissez l'identifiant du service). + +### Canaux + +Sélectionnez un ou plusieurs de vos canaux configurés pour recevoir les notifications correspondant à cette préférence. Si vous n'avez pas encore de canal, créez-en un d'abord dans l'onglet **Canaux**. + +### Statut minimum + +Choisissez la gravité la plus basse qui doit déclencher une notification. Les niveaux disponibles, par gravité croissante, sont **OK**, **Info**, **Avertissement**, **Critique** et **Erreur**. Seuls les changements de statut qui atteignent ce niveau (ou un niveau supérieur) sont notifiés. Par exemple, choisir **Avertissement** signifie que vous êtes alerté pour les états Avertissement, Critique et Erreur, mais pas pour les changements purement informatifs. + +### Notifier le rétablissement + +Lorsque cette option est activée, vous recevez également une notification quand un contrôle auparavant dégradé revient à un état sain, afin de savoir qu'un problème a été résolu. + +### Heures calmes + +Vous pouvez définir une période durant laquelle les notifications sont retenues, par exemple la nuit. Indiquez une heure de **début** et une heure de **fin** (de 0 à 23). Lorsque les heures calmes sont actives, les alertes survenant dans cette plage ne sont pas envoyées immédiatement. + +### Activée + +Chaque préférence peut être activée ou désactivée à l'aide d'un interrupteur, ce qui permet de suspendre temporairement une règle sans la supprimer. + + + +{{% notice style="tip" title="Commencez simplement" icon="lightbulb" %}} +Une configuration courante consiste en une unique préférence **Globale**, pointant vers un canal, avec un statut minimum d'**Avertissement** et les notifications de rétablissement activées. Vous pourrez ensuite ajouter des règles plus spécifiques par domaine ou par service au fur et à mesure de vos besoins. +{{% /notice %}} + + +## Historique + +L'onglet **Historique** liste les notifications que happyDomain a tenté d'envoyer. Pour chaque entrée, vous pouvez voir : + +- la cible concernée ; +- la transition de statut (ancien statut → nouveau statut) ; +- si l'envoi a **réussi** ou **échoué** (avec le message d'erreur en cas d'échec). + +Utilisez **Charger plus** pour remonter dans les entrées plus anciennes. Cette vue est l'endroit où vérifier pourquoi une alerte attendue ne vous est pas parvenue, par exemple un canal mal configuré provoquant des échecs répétés. + + diff --git a/content/pages/provider-features.en.md b/content/pages/provider-features.en.md new file mode 100644 index 0000000..bf21c0c --- /dev/null +++ b/content/pages/provider-features.en.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Provider features +author: nemunaire +weight: 700 +description: "Compare what each DNS provider supports with the provider feature matrix" +--- + +Not every DNS provider supports the same set of capabilities. Some can list the domains in your account automatically, others handle only the most common record types, and a few support more specialised records such as `CAA` or `TLSA`. The **Supported providers** page presents this information as a single comparison table so you can pick the right provider, or understand why a given [service]({{% relref "services" %}}) is unavailable for one of your domains. + +## Reading the feature matrix + +The page lists every provider happyDomain integrates with, one per row, with its logo and name. Each column corresponds to a capability, and the cell shows whether that provider supports it: + +- a green check mark means the capability **is supported**; +- a red cross means it **is not supported**. + + + +The table scrolls horizontally if it is wider than your screen, and the header row stays visible while you scroll, so you can always tell which capability each column refers to. + +## The capabilities + +The matrix compares the following capabilities: + +| Column | Meaning | +|--------|---------| +| **Supported providers** | The provider can automatically list the domains in your account, so you can import them without typing each name. When unsupported, you add domains manually. | +| **Common types** | The provider supports the everyday record types (such as `A`, `AAAA`, `MX`, `TXT`, `CNAME`). This is what most domains need. | +| **CAA** | Support for `CAA` records, which declare the certificate authorities allowed to issue certificates for your domain. | +| **OPENPGPKEY** | Support for `OPENPGPKEY` records, used to publish OpenPGP public keys in DNS. | +| **PTR** | Support for `PTR` records, used mainly for reverse DNS (mapping an IP address back to a name). | +| **SRV** | Support for `SRV` records, which advertise the location of a service (port and host) for protocols that rely on them. | +| **SSHFP** | Support for `SSHFP` records, which publish SSH host key fingerprints in DNS. | +| **TLSA** | Support for `TLSA` records, used by DANE to bind a certificate to a name. | + +{{% notice style="info" title="Why this matters" icon="circle-info" %}} +When you add a [service]({{% relref "services" %}}) to a subdomain, happyDomain only offers the service types your provider can actually publish. If a service you expect is greyed out, the feature matrix is the place to confirm whether the underlying record type is supported by that provider. +{{% /notice %}} + +## Choosing a provider + +If you are still deciding where to host your DNS, use this page to make sure the provider you have in mind covers the record types you need. A provider that supports the **Common types** is enough for most websites and email setups; the specialised columns matter only if you rely on the corresponding features (DANE, reverse DNS, SSH fingerprints, and so on). + +Once you have picked a provider, head over to [add it]({{% relref "provider-new-choice" %}}) to happyDomain. diff --git a/content/pages/provider-features.fr.md b/content/pages/provider-features.fr.md new file mode 100644 index 0000000..a10ffc6 --- /dev/null +++ b/content/pages/provider-features.fr.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Fonctionnalités des fournisseurs +weight: 700 +description: "Comparer ce que prend en charge chaque hébergeur DNS grâce à la matrice des fonctionnalités" +--- + +Tous les hébergeurs DNS ne prennent pas en charge les mêmes capacités. Certains savent lister automatiquement les domaines de votre compte, d'autres ne gèrent que les types d'enregistrements les plus courants, et quelques-uns prennent en charge des enregistrements plus spécialisés comme `CAA` ou `TLSA`. La page **Fournisseurs supportés** présente ces informations sous la forme d'un unique tableau comparatif, afin de vous aider à choisir le bon hébergeur, ou à comprendre pourquoi un [service]({{% relref "services" %}}) donné n'est pas disponible pour l'un de vos domaines. + +## Lire la matrice des fonctionnalités + +La page liste tous les hébergeurs avec lesquels happyDomain s'intègre, un par ligne, avec son logo et son nom. Chaque colonne correspond à une capacité, et la cellule indique si l'hébergeur la prend en charge : + +- une coche verte signifie que la capacité **est prise en charge** ; +- une croix rouge signifie qu'elle **n'est pas prise en charge**. + + + +Le tableau défile horizontalement s'il est plus large que votre écran, et la ligne d'en-tête reste visible pendant le défilement : vous savez ainsi toujours à quelle capacité se rapporte chaque colonne. + +## Les capacités + +La matrice compare les capacités suivantes : + +| Colonne | Signification | +|---------|---------------| +| **Fournisseurs supportés** | L'hébergeur sait lister automatiquement les domaines de votre compte, ce qui vous permet de les importer sans saisir chaque nom. Lorsque ce n'est pas pris en charge, vous ajoutez les domaines manuellement. | +| **Types courants** | L'hébergeur prend en charge les types d'enregistrements du quotidien (comme `A`, `AAAA`, `MX`, `TXT`, `CNAME`). C'est ce dont la plupart des domaines ont besoin. | +| **CAA** | Prise en charge des enregistrements `CAA`, qui déclarent les autorités de certification autorisées à émettre des certificats pour votre domaine. | +| **OPENPGPKEY** | Prise en charge des enregistrements `OPENPGPKEY`, utilisés pour publier des clés publiques OpenPGP dans le DNS. | +| **PTR** | Prise en charge des enregistrements `PTR`, utilisés principalement pour le DNS inverse (associer une adresse IP à un nom). | +| **SRV** | Prise en charge des enregistrements `SRV`, qui annoncent l'emplacement d'un service (port et hôte) pour les protocoles qui s'appuient dessus. | +| **SSHFP** | Prise en charge des enregistrements `SSHFP`, qui publient les empreintes des clés d'hôte SSH dans le DNS. | +| **TLSA** | Prise en charge des enregistrements `TLSA`, utilisés par DANE pour lier un certificat à un nom. | + +{{% notice style="info" title="Pourquoi c'est important" icon="circle-info" %}} +Lorsque vous ajoutez un [service]({{% relref "services" %}}) à un sous-domaine, happyDomain ne propose que les types de services que votre hébergeur peut réellement publier. Si un service que vous attendiez apparaît grisé, la matrice des fonctionnalités est l'endroit où vérifier si le type d'enregistrement sous-jacent est pris en charge par cet hébergeur. +{{% /notice %}} + +## Choisir un hébergeur + +Si vous hésitez encore sur l'endroit où héberger votre DNS, servez-vous de cette page pour vous assurer que l'hébergeur envisagé couvre les types d'enregistrements dont vous avez besoin. Un hébergeur qui prend en charge les **types courants** suffit pour la plupart des sites web et des configurations de messagerie ; les colonnes spécialisées ne comptent que si vous utilisez les fonctionnalités correspondantes (DANE, DNS inverse, empreintes SSH, etc.). + +Une fois votre hébergeur choisi, rendez-vous sur la page pour l'[ajouter]({{% relref "provider-new-choice" %}}) à happyDomain. diff --git a/content/pages/provider-list/_index.en.md b/content/pages/provider-list/_index.en.md index 09801ab..5a8ed80 100644 --- a/content/pages/provider-list/_index.en.md +++ b/content/pages/provider-list/_index.en.md @@ -5,7 +5,7 @@ title: List your name providers aliases: hosters source-list -weight: 15 +weight: 400 --- You can access this page by clicking on the the top menu link "The hosts of my domains". @@ -14,9 +14,9 @@ You can access this page by clicking on the the top menu link "The hosts of my d This page shows only the list of registries and domain hosts you have added to your account, and [allows you to add more]({{% relref "provider-new-choice" %}}). -![The hosters of your domains](hosters-list.png) +![The hosters of your domains](providers-list.webp) You can add a new host by clicking on the "+" button at the top of the page. -By clicking on a row of the table, you will access the parameters used by happyDomain to contact this host. +By clicking on a row of the table, you will access [the parameters used by happyDomain to contact this host]({{% relref "provider-update" %}}). This is where you'll be able to modify the name you gave to this host, and where you'll be able to modify the access parameters. diff --git a/content/pages/provider-list/_index.fr.md b/content/pages/provider-list/_index.fr.md index 009acb4..dadfc46 100644 --- a/content/pages/provider-list/_index.fr.md +++ b/content/pages/provider-list/_index.fr.md @@ -4,18 +4,18 @@ title: Lister vos hébergeurs de noms aliases: hosters source-list -weight: 15 +weight: 400 --- -Vous accédez à cette page en cliquant sur le lien « Les hôtes de mes domaines » dans le menu en haut. +Vous accédez à cette page en cliquant sur le lien « Les hébergeurs de mes domaines » dans le menu en haut. ## Vos registres et hébergeurs de domaines Cette page montre uniquement la liste des registres et des hébergeurs de domaines que vous avez ajouté à votre compte, et [vous permet d'en ajouter]({{% relref "provider-new-choice" %}}). -![Les hébergeurs de vos domaines](hosters-list.png) +![Les hébergeurs de vos domaines](providers-list.webp) Vous pouvez ajouter un nouvel hébergeur en cliquant sur le bouton +, présent en haut de la page. -En cliquant sur une ligne du tableau, vous accéderez aux paramètres qu'utilise happyDomain pour contacter cet hébergeur. +En cliquant sur une ligne du tableau, vous accéderez aux [paramètres qu'utilise happyDomain pour contacter cet hébergeur]({{% relref "provider-update" %}}). C'est là que vous allez pouvoir modifier le nom que vous avez donné à cet hébergeur, et que vous pourrez modifier les paramètres d'accès. diff --git a/content/pages/provider-list/hosters-list.png b/content/pages/provider-list/hosters-list.png deleted file mode 100644 index 9f12e22..0000000 Binary files a/content/pages/provider-list/hosters-list.png and /dev/null differ diff --git a/content/pages/provider-list/providers-list.webp b/content/pages/provider-list/providers-list.webp new file mode 100644 index 0000000..df7d1ee Binary files /dev/null and b/content/pages/provider-list/providers-list.webp differ diff --git a/content/pages/provider-new-choice/_index.en.md b/content/pages/provider-new-choice/_index.en.md index 85df56f..f2d38a3 100644 --- a/content/pages/provider-new-choice/_index.en.md +++ b/content/pages/provider-new-choice/_index.en.md @@ -4,7 +4,7 @@ author: Frederic title: Add a provider aliases: source-new-choice -weight: 17 +weight: 500 --- You access this screen by clicking on the ["My domain providers"]({{% relref "provider-list" %}}) link in the top menu, then by clicking on the "+ Add a new domain host" button. diff --git a/content/pages/provider-new-choice/_index.fr.md b/content/pages/provider-new-choice/_index.fr.md index 7a01108..fc59dc4 100644 --- a/content/pages/provider-new-choice/_index.fr.md +++ b/content/pages/provider-new-choice/_index.fr.md @@ -3,7 +3,7 @@ date: 2020-12-09T18:12:45+01:00 title: Ajouter un hébergeur aliases: source-new-choice -weight: 17 +weight: 500 --- Vous accédez à cet écran en cliquant sur le lien [« Les hébergeurs de mes domaines »]({{% relref "provider-list" %}}) dans le menu en haut, puis en cliquant sur le bouton « + Ajouter un nouvel hébergeur de domaines ». diff --git a/content/pages/provider-update.en.md b/content/pages/provider-update.en.md index c1ad54f..46698ff 100644 --- a/content/pages/provider-update.en.md +++ b/content/pages/provider-update.en.md @@ -5,7 +5,7 @@ title: Hosting provider settings aliases: source-new-state source-update -weight: 19 +weight: 600 --- You access this screen either: diff --git a/content/pages/provider-update.fr.md b/content/pages/provider-update.fr.md index 8ea360b..9cd216c 100644 --- a/content/pages/provider-update.fr.md +++ b/content/pages/provider-update.fr.md @@ -4,7 +4,7 @@ title: Paramètres de l'hébergeur aliases: source-new-state source-update -weight: 19 +weight: 600 --- Vous accédez à cet écran soit : diff --git a/content/pages/publish-changes.en.md b/content/pages/publish-changes.en.md deleted file mode 100644 index f99c5a2..0000000 --- a/content/pages/publish-changes.en.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -date: 2025-06-15T11:08:00+02:00 -title: "Publish modifications" -weight: 40 ---- - -When you make a change in happyDomain, it is not directly passed on to your host or server. - -Once you've made all the changes you wish to be propagated, click on the “Distribute my changes” button. - -A window will open showing exactly which concrete changes will be passed on to your host or server. - -If at this stage you don't want to apply all the changes, you can uncheck some of them. - -Don't forget to enter a message in the appropriate field: this message will be recorded in your log. -Later, when you need to see what changes you've made, it might be simpler to read “Changing host from Wordpress to Alwaysdata” rather than trying to interpret IP changes, ... diff --git a/content/pages/publish-changes.fr.md b/content/pages/publish-changes.fr.md deleted file mode 100644 index f42830f..0000000 --- a/content/pages/publish-changes.fr.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -date: 2025-06-15T11:08:00+02:00 -title: "Publier des modifications" -weight: 40 ---- - -Lorsque vous effectuez un changement dans happyDomain, celui-ci n'est pas directement répercuté auprès de votre hébergeur ou de votre serveur. - -Une fois que vous avez fait toutes les modifications que vous souhaitez voir propagées, cliquez sur le bouton « Diffuser mes changements ». - -Une fenêtre va s'ouvrir montrant précisément quelle modifications concrètes seront répercutées auprès de votre hébergeur ou de votre serveur. - -Si à ce stade vous ne voulez pas appliquer tous les changements, vous pouvez en décocher certains. - -N'oubliez pas d'indiquer un message dans le champs prévu à cet effet : ce message sera consigné dans votre journal. -Plus tard, lorsque vous aurez besoin de voir quelles ont été vos modifications, cela pourrait s'avérer plus simple de lire « Changement d'hébergeur de Wordpress vers Alwaysdata » plutôt que de chercher à interpréter les changements d'IP, ... diff --git a/content/pages/publish-changes/happydomain-modal-diff-view.webp b/content/pages/publish-changes/happydomain-modal-diff-view.webp new file mode 100644 index 0000000..c8465c3 Binary files /dev/null and b/content/pages/publish-changes/happydomain-modal-diff-view.webp differ diff --git a/content/pages/publish-changes/happydomain-publish-changes-button.webp b/content/pages/publish-changes/happydomain-publish-changes-button.webp new file mode 100644 index 0000000..7ac54fc Binary files /dev/null and b/content/pages/publish-changes/happydomain-publish-changes-button.webp differ diff --git a/content/pages/publish-changes/index.en.md b/content/pages/publish-changes/index.en.md new file mode 100644 index 0000000..9575dad --- /dev/null +++ b/content/pages/publish-changes/index.en.md @@ -0,0 +1,68 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: "Publishing changes" +author: nemunaire +weight: 1300 +description: "Review the diff of your pending changes, choose exactly which ones to apply, and publish them to your provider" +--- + +When you make a change in happyDomain, it is not sent to your hosting provider straight away. Your edits accumulate in a working copy, and nothing reaches your provider until you decide to publish. Before that happens, happyDomain lets you review the exact list of changes that your edits produce, fine-tune what will be applied, and record a message for your history. + +## Opening the diff + +In the zone editor, the **Publish my changes** button shows a small counter with the number of pending changes detected for your zone. Click it to open the review window. + +![The Publish my changes button with its pending-changes counter](happydomain-publish-changes-button.webp) + +happyDomain computes the difference between the zone as it currently lives at your provider and the working copy you have been editing. If everything is already in sync, you will simply see a message telling you there is nothing to apply. + +## Understanding the diff + +Each line of the diff describes one concrete correction, written in a human-readable form and colour-coded by its nature: + +| Colour | Meaning | +|--------|---------| +| **Green** | An addition (a record being created) | +| **Red** | A deletion (a record being removed) | +| **Yellow** | A modification (an existing record being changed) | +| **Blue** | Another kind of change (for example a reordering or provider-specific operation) | + +At the bottom of the window, a **summary** recaps how many additions, deletions and modifications are currently selected. + +![The diff window listing colour-coded changes with their summary](happydomain-modal-diff-view.webp) + +## Selecting which changes to apply + +Every line in the diff has a checkbox. By default the changes are listed for your review, and you decide which ones to keep: + +- **Uncheck** any change you do not want to apply right now. It stays in your working copy and will reappear next time. +- Keep checked only the changes you are confident about. + +This is useful when you have made several unrelated edits but only want to publish some of them, or when you want to roll out a sensitive change separately. + +The summary and the apply button update live to reflect your current selection. If nothing is selected, the apply button stays disabled. + +## Writing a commit message + +Before applying, enter a message in the **What's changed?** field. This message is recorded in your history alongside the changes. + +{{% notice style="tip" title="Describe the intent, not the IPs" icon="lightbulb" %}} +The diff describes the technical operations, but your message is what makes your history readable later on. When you need to look back at what you did, "Move mail to a new provider" is far easier to understand than re-deriving meaning from a list of IP changes. +{{% /notice %}} + +## A confirmation step for safety + +Depending on your [account preferences]({{% relref "settings" %}}), happyDomain may show an extra confirmation screen after you choose to apply: + +- It asks your provider to **prepare** the corrections, then shows you exactly how many operations the provider will actually run for your selection. +- If that number differs from what you selected (for instance because a change was already applied, or the provider expands one change into several), a warning is displayed so you can double-check before confirming. + +You can configure whether this confirmation appears always, never, or only when the prepared corrections do not match your selection. + + + +## After publishing + +Once you confirm, happyDomain sends the selected changes to your provider and records the operation, with your message, in the domain's log. From there you can review past deployments at any time, and roll back to an earlier state if needed; see {{% relref "domain-history" %}}. + +To inspect the resulting zone itself rather than the diff, or to keep a copy as a standard zone file, see {{% relref "import-export" %}}. diff --git a/content/pages/publish-changes/index.fr.md b/content/pages/publish-changes/index.fr.md new file mode 100644 index 0000000..0d06459 --- /dev/null +++ b/content/pages/publish-changes/index.fr.md @@ -0,0 +1,68 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: "Publier des modifications" +author: nemunaire +weight: 1300 +description: "Examiner le différentiel de vos changements en attente, choisir précisément ceux à appliquer, et les publier chez votre hébergeur" +--- + +Lorsque vous effectuez un changement dans happyDomain, celui-ci n'est pas immédiatement répercuté auprès de votre hébergeur. Vos modifications s'accumulent dans une copie de travail, et rien n'est transmis à votre hébergeur tant que vous n'avez pas décidé de publier. Avant cela, happyDomain vous permet d'examiner la liste exacte des changements produits par vos modifications, d'ajuster finement ce qui sera appliqué, et de consigner un message dans votre historique. + +## Ouvrir le différentiel + +Dans l'éditeur de zone, le bouton « Diffuser mes changements » affiche un petit compteur indiquant le nombre de changements en attente détectés pour votre zone. Cliquez dessus pour ouvrir la fenêtre de relecture. + +![Le bouton « Diffuser mes changements » avec son compteur de changements en attente](happydomain-publish-changes-button.webp) + +happyDomain calcule la différence entre la zone telle qu'elle existe actuellement chez votre hébergeur et la copie de travail que vous avez éditée. Si tout est déjà synchronisé, un message vous indiquera simplement qu'il n'y a rien à appliquer. + +## Comprendre le différentiel + +Chaque ligne du différentiel décrit une correction concrète, formulée de façon lisible et colorée selon sa nature : + +| Couleur | Signification | +|---------|---------------| +| **Vert** | Un ajout (un enregistrement créé) | +| **Rouge** | Une suppression (un enregistrement retiré) | +| **Jaune** | Une modification (un enregistrement existant modifié) | +| **Bleu** | Un autre type de changement (par exemple un réordonnancement ou une opération propre à l'hébergeur) | + +En bas de la fenêtre, un **résumé** récapitule le nombre d'ajouts, de suppressions et de modifications actuellement sélectionnés. + +![La fenêtre du différentiel listant les changements colorés avec leur résumé](happydomain-modal-diff-view.webp) + +## Choisir les changements à appliquer + +Chaque ligne du différentiel comporte une case à cocher. Par défaut, les changements sont listés pour votre relecture, et c'est vous qui décidez lesquels conserver : + +- **Décochez** tout changement que vous ne souhaitez pas appliquer maintenant. Il reste dans votre copie de travail et réapparaîtra la prochaine fois. +- Ne laissez cochés que les changements dont vous êtes sûr. + +C'est utile lorsque vous avez fait plusieurs modifications sans rapport entre elles mais ne voulez en publier qu'une partie, ou lorsque vous souhaitez déployer un changement sensible séparément. + +Le résumé et le bouton d'application se mettent à jour en direct selon votre sélection. Si rien n'est sélectionné, le bouton d'application reste désactivé. + +## Rédiger un message de validation + +Avant d'appliquer, saisissez un message dans le champ « Qu'est-ce qui a changé ? ». Ce message est consigné dans votre historique aux côtés des changements. + +{{% notice style="tip" title="Décrivez l'intention, pas les adresses IP" icon="lightbulb" %}} +Le différentiel décrit les opérations techniques, mais c'est votre message qui rendra votre historique lisible plus tard. Lorsque vous aurez besoin de revoir ce que vous avez fait, « Déplacement du courrier vers un nouvel hébergeur » est bien plus facile à comprendre que de reconstituer le sens à partir d'une liste de changements d'IP. +{{% /notice %}} + +## Une étape de confirmation par sécurité + +Selon les [préférences de votre compte]({{% relref "settings" %}}), happyDomain peut afficher un écran de confirmation supplémentaire après que vous avez choisi d'appliquer : + +- Il demande à votre hébergeur de **préparer** les corrections, puis vous montre exactement combien d'opérations l'hébergeur exécutera réellement pour votre sélection. +- Si ce nombre diffère de ce que vous avez sélectionné (par exemple parce qu'un changement était déjà appliqué, ou parce que l'hébergeur décompose un changement en plusieurs), un avertissement s'affiche pour que vous puissiez vérifier avant de confirmer. + +Vous pouvez configurer si cette confirmation apparaît toujours, jamais, ou uniquement lorsque les corrections préparées ne correspondent pas à votre sélection. + + + +## Après la publication + +Une fois que vous confirmez, happyDomain envoie les changements sélectionnés à votre hébergeur et consigne l'opération, avec votre message, dans le journal du domaine. Vous pouvez ensuite consulter les déploiements passés à tout moment, et [revenir à un état antérieur]({{% relref "domain-history" %}}) si besoin. + +Pour inspecter la zone résultante elle-même plutôt que le différentiel, ou pour en conserver une copie sous forme de fichier de zone standard, consultez la page [Importer et exporter]({{% relref "import-export" %}}). diff --git a/content/pages/quotas.en.md b/content/pages/quotas.en.md new file mode 100644 index 0000000..55ec957 --- /dev/null +++ b/content/pages/quotas.en.md @@ -0,0 +1,40 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Quotas & limits +author: nemunaire +weight: 2400 +description: "Understand the limits an administrator may set on your account, and what happens when one is reached" +--- + +A happyDomain instance can apply **quotas** to each account. Quotas are limits set by the person running the instance (the administrator), not by you. They exist mainly to keep a shared instance fair and to avoid overloading the servers, and they apply above all to the [monitoring & checks]({{% relref "checks" %}}) system. + +{{% notice style="info" title="Quotas are managed by the administrator" icon="circle-info" %}} +Quotas are **read-only** for regular users. There is no screen in your account where you can view or change your own quota: they are configured server-side and adjusted only through the administration interface. If a limit is getting in your way, the right course of action is to contact the administrator of your instance. +{{% /notice %}} + + +## What quotas can cover + +On a default happyDomain instance, quotas relate to how the monitoring scheduler works for your account. An administrator may set, per account or instance-wide: + +- **Maximum checks per day**: a cap on how many checker executions are run automatically for you each day. Once the cap is reached, further scheduled checks wait until the next day. +- **Result retention**: how long the results of your checks are kept before old executions are automatically cleaned up. +- **Inactivity pause**: after a period without logging in, the scheduler may stop running your automatic checks until you sign in again. This keeps the instance from spending resources on abandoned accounts. +- **Scheduling pause**: an administrator can entirely pause automatic scheduling for an account. + +Each of these can be left at the instance default, set to a specific value for your account, or explicitly made unlimited, at the administrator's discretion. + +{{% notice style="tip" title="No fixed limit on the number of domains" icon="lightbulb" %}} +On a standard happyDomain instance, the quota system does not impose a built-in cap on the number of domains you can manage. If a particular instance does restrict this, it is a policy of that instance; ask its administrator for the details that apply to you. +{{% /notice %}} + + +## What you see when a limit is reached + +Quotas mostly act in the background. You will not usually see a quota screen; instead you notice their effects: + +- **Automatic checks stop running**: if your daily check cap is reached, or your account is in an inactivity or scheduling pause, scheduled checks simply do not run until the condition clears. You can still trigger a check **manually** from the [checks]({{% relref "checks#running-a-check-manually" %}}) interface. +- **Older results disappear**: with a retention limit, executions older than the allowed age are removed during routine cleanup, so the history only goes back so far. +- **An action is refused**: where an operation would exceed a limit, the interface shows an error message explaining what went wrong. + +If you are unsure whether a behaviour is caused by a quota, or you need a limit raised, contact the administrator of your instance. diff --git a/content/pages/quotas.fr.md b/content/pages/quotas.fr.md new file mode 100644 index 0000000..76c7500 --- /dev/null +++ b/content/pages/quotas.fr.md @@ -0,0 +1,39 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Quotas et limites +weight: 2400 +description: "Comprendre les limites qu'un administrateur peut appliquer à votre compte, et ce qu'il se passe lorsque l'une d'elles est atteinte" +--- + +Une instance happyDomain peut appliquer des **quotas** à chaque compte. Les quotas sont des limites définies par la personne qui administre l'instance (l'administrateur), et non par vous. Ils servent principalement à préserver l'équité sur une instance partagée et à éviter de surcharger les serveurs ; ils concernent avant tout le système de [supervision et contrôles]({{% relref "checks" %}}). + +{{% notice style="info" title="Les quotas sont gérés par l'administrateur" icon="circle-info" %}} +Les quotas sont en **lecture seule** pour les utilisateurs ordinaires. Il n'existe aucun écran dans votre compte permettant de consulter ou de modifier votre propre quota : ils sont configurés côté serveur et ne sont ajustés qu'au travers de l'interface d'administration. Si une limite vous gêne, la bonne démarche consiste à contacter l'administrateur de votre instance. +{{% /notice %}} + + +## Ce que les quotas peuvent couvrir + +Sur une instance happyDomain par défaut, les quotas portent sur le fonctionnement du planificateur de supervision pour votre compte. Un administrateur peut définir, par compte ou pour l'ensemble de l'instance : + +- **Nombre maximal de contrôles par jour** : un plafond sur le nombre d'exécutions de contrôles lancées automatiquement pour vous chaque jour. Une fois ce plafond atteint, les contrôles planifiés suivants attendent le lendemain. +- **Conservation des résultats** : la durée pendant laquelle les résultats de vos contrôles sont conservés avant que les anciennes exécutions ne soient automatiquement nettoyées. +- **Pause pour inactivité** : après une période sans connexion, le planificateur peut cesser d'exécuter vos contrôles automatiques jusqu'à votre prochaine connexion. Cela évite que l'instance ne dépense des ressources pour des comptes abandonnés. +- **Pause de planification** : un administrateur peut entièrement suspendre la planification automatique d'un compte. + +Chacun de ces réglages peut rester à la valeur par défaut de l'instance, être fixé à une valeur particulière pour votre compte, ou être explicitement rendu illimité, à la discrétion de l'administrateur. + +{{% notice style="tip" title="Pas de limite fixe sur le nombre de domaines" icon="lightbulb" %}} +Sur une instance happyDomain standard, le système de quotas n'impose pas de plafond intégré sur le nombre de domaines que vous pouvez gérer. Si une instance particulière restreint ce point, il s'agit d'une politique propre à cette instance ; demandez à son administrateur les détails qui vous concernent. +{{% /notice %}} + + +## Ce que vous voyez lorsqu'une limite est atteinte + +Les quotas agissent surtout en arrière-plan. Vous ne verrez généralement pas d'écran de quota ; vous en constatez plutôt les effets : + +- **Les contrôles automatiques cessent de s'exécuter** : si votre plafond quotidien de contrôles est atteint, ou si votre compte est en pause pour inactivité ou de planification, les contrôles planifiés ne s'exécutent simplement plus tant que la condition persiste. Vous pouvez toujours déclencher un contrôle **manuellement** depuis l'interface des [contrôles]({{% relref "checks#lancer-une-vérification-manuellement" %}}). +- **Les anciens résultats disparaissent** : avec une limite de conservation, les exécutions plus anciennes que la durée autorisée sont supprimées lors du nettoyage régulier, si bien que l'historique ne remonte que jusqu'à un certain point. +- **Une action est refusée** : lorsqu'une opération dépasserait une limite, l'interface affiche un message d'erreur expliquant ce qui n'a pas fonctionné. + +Si vous ne savez pas si un comportement est dû à un quota, ou si vous avez besoin qu'une limite soit relevée, contactez l'administrateur de votre instance. diff --git a/content/pages/services/happydomain-abstract-zone-records.webp b/content/pages/services/happydomain-abstract-zone-records.webp new file mode 100644 index 0000000..bdb5aa2 Binary files /dev/null and b/content/pages/services/happydomain-abstract-zone-records.webp differ diff --git a/content/pages/services/happydomain-modal-service-selector.webp b/content/pages/services/happydomain-modal-service-selector.webp new file mode 100644 index 0000000..c1a6164 Binary files /dev/null and b/content/pages/services/happydomain-modal-service-selector.webp differ diff --git a/content/pages/services/index.en.md b/content/pages/services/index.en.md new file mode 100644 index 0000000..d670d2a --- /dev/null +++ b/content/pages/services/index.en.md @@ -0,0 +1,86 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Services +author: nemunaire +weight: 1200 +description: "Understand how happyDomain turns raw DNS records into high-level services, and how to add one to a subdomain" +--- + +happyDomain does not ask you to think in terms of individual DNS records. Instead, it groups the records that belong together into a single, meaningful **service**: a mailbox, a website, a delegation, a CAA policy, and so on. This is the foundation of the [abstract view]({{% relref "domain-abstract" %}}) of your zone. + +## What is a service? + +A service is a higher-level object that hides the complexity of one or several DNS records behind a clear, purpose-driven form. + +For example, instead of editing a raw `MX` record, a couple of `A`/`AAAA` records and an `SPF` `TXT` record separately, you fill in a single **email** service. happyDomain takes care of generating the right records, with the right names and the right syntax. + +Each service belongs to a family: + +- **Services** (abstract): the recommended, human-friendly objects (email, website, CAA, delegation, ...). They map to one or more records automatically. +- **Providers**: services tied to a specific third party that publishes its own helper (for example a hosted service that needs a predefined set of records). +- **Raw DNS resources**: a fallback that lets you add a single record (`A`, `TXT`, `SRV`, ...) directly, when no abstract service fits your need. + +{{% notice style="info" title="Why services instead of records?" icon="lightbulb" %}} +Working with services means you do not have to remember the exact record types, their order, or their syntax. happyDomain validates your input and generates valid DNS for you, which greatly reduces the risk of a misconfiguration. +{{% /notice %}} + +## The service view of a subdomain + +When you open a domain, each subdomain is displayed as a list of the services attached to it. A subdomain can hold several services at once: for instance the apex (`@`) of a domain often carries an email service, a website service and a CAA policy together. + +![A subdomain showing several services in the zone editor](happydomain-abstract-zone-records.webp) + +From this view you can: + +- **Add** a new service to the subdomain. +- **Edit** an existing service to change its values. +- **Delete** a service you no longer need. + +All these changes are staged locally and only applied to your provider when you publish them. See the [abstract view]({{% relref "domain-abstract" %}}) for how editing and propagation work. + +## Adding a service to a subdomain + +To attach a new service, start from the subdomain where you want it (see [Subdomains]({{% relref "subdomains" %}}) for navigating the zone), then follow these steps. + +### 1. Open the service selector + +Click the **Add service** action on the subdomain. A selector opens, listing every service type you can add. + +![The service selector modal](happydomain-modal-service-selector.webp) + +The selector is organised in tabs so you can narrow down the list: + +- **All**: every available service type. +- **Services**: the abstract, high-level services (recommended). +- **Providers**: services specific to a provider. +- **Raw DNS resources**: a single record type when you need full control. + +You can also type in the search box at the top to filter the list by name. Pressing Enter selects the first available match. + +{{% notice style="tip" title="Greyed-out entries" icon="circle-info" %}} +Some service types may appear disabled. This happens when the service cannot be added in the current context: for example because your DNS provider does not support the underlying record type, or because that service already exists on this subdomain and only one instance is allowed. Hover over a disabled entry to see the reason. +{{% /notice %}} + +### 2. Choose the service type + +Select the service that matches what you want to publish. happyDomain knows which record types your provider supports, so only the relevant choices are offered. To check what a given provider can handle, see the [Provider features]({{% relref "provider-features" %}}) page. + +### 3. Fill in the service form + +happyDomain then presents a form tailored to the chosen service. Each field corresponds to a meaningful piece of information (a target host, a priority, a public key, a policy value, ...) rather than to raw record syntax. + + + +Fill in the fields, then confirm to add the service to the subdomain. + +### 4. Review the generated records + +Once the form is validated, happyDomain converts your input into the corresponding DNS records and adds them to the staged zone. You can review them in the [abstract view]({{% relref "domain-abstract" %}}) before publishing your changes to your provider. + +## Trying services without an account + +happyDomain also offers a public **record generator** where you can build and preview the DNS records produced by a service without signing in. Pick a service type, enter a domain name, fill in the form, and the generated zone-file entries are displayed instantly. + +This is a handy way to discover how a given service maps to actual DNS records, or to grab a record you will paste elsewhere. + + diff --git a/content/pages/services/index.fr.md b/content/pages/services/index.fr.md new file mode 100644 index 0000000..fee647e --- /dev/null +++ b/content/pages/services/index.fr.md @@ -0,0 +1,85 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Services +weight: 1200 +description: "Comprendre comment happyDomain transforme les enregistrements DNS bruts en services de haut niveau, et comment en ajouter un à un sous-domaine" +--- + +happyDomain ne vous demande pas de raisonner en termes d'enregistrements DNS individuels. À la place, il regroupe les enregistrements qui vont ensemble au sein d'un unique **service** porteur de sens : une messagerie, un site web, une délégation, une politique CAA, etc. C'est le fondement de la [vue abstraite]({{% relref "domain-abstract" %}}) de votre zone. + +## Qu'est-ce qu'un service ? + +Un service est un objet de plus haut niveau qui masque la complexité d'un ou de plusieurs enregistrements DNS derrière un formulaire clair, orienté usage. + +Par exemple, au lieu d'éditer séparément un enregistrement `MX`, quelques enregistrements `A`/`AAAA` et un enregistrement `SPF` de type `TXT`, vous remplissez un seul service **messagerie**. happyDomain se charge de générer les bons enregistrements, avec les bons noms et la bonne syntaxe. + +Chaque service appartient à une famille : + +- **Services** (abstraits) : les objets recommandés, pensés pour les humains (messagerie, site web, CAA, délégation, etc.). Ils se traduisent automatiquement en un ou plusieurs enregistrements. +- **Fournisseurs** : des services liés à un acteur tiers précis qui publie son propre assistant (par exemple un service hébergé nécessitant un ensemble d'enregistrements prédéfini). +- **Ressources DNS brutes** : une solution de repli qui vous permet d'ajouter directement un enregistrement unique (`A`, `TXT`, `SRV`, etc.), lorsqu'aucun service abstrait ne correspond à votre besoin. + +{{% notice style="info" title="Pourquoi des services plutôt que des enregistrements ?" icon="lightbulb" %}} +Travailler avec des services vous évite d'avoir à mémoriser les types d'enregistrements exacts, leur ordre ou leur syntaxe. happyDomain valide votre saisie et génère du DNS correct à votre place, ce qui réduit fortement le risque d'erreur de configuration. +{{% /notice %}} + +## La vue par services d'un sous-domaine + +Lorsque vous ouvrez un domaine, chaque sous-domaine est présenté sous la forme d'une liste des services qui lui sont rattachés. Un sous-domaine peut accueillir plusieurs services à la fois : par exemple, la racine (`@`) d'un domaine porte souvent à la fois un service de messagerie, un service de site web et une politique CAA. + +![Un sous-domaine affichant plusieurs services dans l'éditeur de zone](happydomain-abstract-zone-records.webp) + +Depuis cette vue, vous pouvez : + +- **Ajouter** un nouveau service au sous-domaine ; +- **Modifier** un service existant pour en changer les valeurs ; +- **Supprimer** un service dont vous n'avez plus besoin. + +Toutes ces modifications sont préparées localement et ne sont appliquées chez votre hébergeur qu'au moment de leur publication. Consultez la [vue abstraite]({{% relref "domain-abstract" %}}) pour comprendre le fonctionnement de l'édition et de la propagation. + +## Ajouter un service à un sous-domaine + +Pour rattacher un nouveau service, placez-vous sur le sous-domaine où vous le souhaitez (voir [Sous-domaines]({{% relref "subdomains" %}}) pour naviguer dans la zone), puis suivez ces étapes. + +### 1. Ouvrir le sélecteur de services + +Cliquez sur l'action **Ajouter un service** du sous-domaine. Un sélecteur s'ouvre, listant tous les types de services que vous pouvez ajouter. + +![La fenêtre de sélection des services](happydomain-modal-service-selector.webp) + +Le sélecteur est organisé en onglets pour vous aider à restreindre la liste : + +- **Tous** : tous les types de services disponibles. +- **Services** : les services abstraits de haut niveau (recommandé). +- **Fournisseurs** : les services spécifiques à un fournisseur. +- **Ressources DNS brutes** : un type d'enregistrement unique, lorsque vous avez besoin d'un contrôle total. + +Vous pouvez également saisir un terme dans le champ de recherche, en haut, pour filtrer la liste par nom. Appuyer sur Entrée sélectionne le premier résultat disponible. + +{{% notice style="tip" title="Entrées grisées" icon="circle-info" %}} +Certains types de services peuvent apparaître désactivés. Cela se produit lorsque le service ne peut pas être ajouté dans le contexte actuel : par exemple parce que votre hébergeur DNS ne prend pas en charge le type d'enregistrement sous-jacent, ou parce que ce service existe déjà sur ce sous-domaine et qu'une seule instance est autorisée. Survolez une entrée désactivée pour en connaître la raison. +{{% /notice %}} + +### 2. Choisir le type de service + +Sélectionnez le service correspondant à ce que vous souhaitez publier. happyDomain connaît les types d'enregistrements pris en charge par votre hébergeur : seuls les choix pertinents vous sont donc proposés. Pour savoir ce qu'un hébergeur donné sait gérer, consultez la page [Fonctionnalités des fournisseurs]({{% relref "provider-features" %}}). + +### 3. Remplir le formulaire du service + +happyDomain présente alors un formulaire adapté au service choisi. Chaque champ correspond à une information porteuse de sens (un hôte cible, une priorité, une clé publique, une valeur de politique, etc.) plutôt qu'à de la syntaxe d'enregistrement brute. + + + +Renseignez les champs, puis validez pour ajouter le service au sous-domaine. + +### 4. Vérifier les enregistrements générés + +Une fois le formulaire validé, happyDomain convertit votre saisie en enregistrements DNS correspondants et les ajoute à la zone en préparation. Vous pouvez les vérifier dans la [vue abstraite]({{% relref "domain-abstract" %}}) avant de publier vos modifications chez votre hébergeur. + +## Essayer les services sans compte + +happyDomain propose également un **générateur d'enregistrements** public qui vous permet de construire et de prévisualiser les enregistrements DNS produits par un service sans être connecté. Choisissez un type de service, saisissez un nom de domaine, remplissez le formulaire : les entrées de fichier de zone générées s'affichent instantanément. + +C'est un moyen pratique de découvrir comment un service donné se traduit en véritables enregistrements DNS, ou de récupérer un enregistrement à coller ailleurs. + + diff --git a/content/pages/settings.en.md b/content/pages/settings.en.md new file mode 100644 index 0000000..d5e1a70 --- /dev/null +++ b/content/pages/settings.en.md @@ -0,0 +1,76 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Your account and settings +author: nemunaire +weight: 2000 +description: "Manage your happyDomain account and tailor the interface: language, field hints, confirmation, zone view, password and account deletion" +aliases: + me +--- + +happyDomain lets you manage your account and tailor how the interface behaves. Your preferences are saved with your account, so you find them again on every device you connect from. + +You reach this page from the **My Account** link in the top menu. Each option is described below. + + + +## Language + +Choose the language used throughout the interface. The list contains every language currently available in your happyDomain instance. Changing it takes effect as soon as you save. + +## Field hints + +Form fields often come with a short help text. This setting controls how that help is displayed: + +- **Hide** -- no help text is shown. +- **Tooltip near field** -- the help appears as a tooltip when you hover the field. +- **Under field when focused** -- the help appears below the field, but only while you are editing it. +- **Under field, always** -- the help is permanently displayed below each field. + +Pick the level of guidance that suits your familiarity with DNS. + +## Confirmation before applying + +When you publish changes to your DNS provider, happyDomain can show a confirmation step beforehand. This setting decides when: + +- **Ask on unexpected differences** -- the confirmation appears only when the changes differ from what was expected. +- **Always ask** -- a confirmation is always shown before applying. +- **Never ask, overwrite on publish** -- changes are applied directly, without a confirmation step. + +See [Publishing changes]({{% relref "publish-changes" %}}) for the full publication workflow. + +## Zone view layout + +Choose how a domain's zone is displayed: + +- **Grid view (easiest)** -- the most visual and approachable layout. +- **List view (fastest)** -- a compact list, quicker to scan. +- **List with records (advanced)** -- a list that also exposes the underlying DNS records, for advanced users. + +## Show DNS record types + +This switch shows the resource record type (A, MX, CNAME, etc.) associated with each service. It is meant for users who are already familiar with DNS and want to see the technical record types behind the friendly service names. + +## Newsletter + +The option to receive news about future improvements is proposed when you [create your account]({{% relref "signup" %}}). To change your subscription afterwards, refer to the unsubscribe link included in the messages you receive. + +## Saving + +When your preferences are set, click **Save settings**. A confirmation message appears and the new settings take effect immediately, including a language change if you made one. + +## Change password + +A dedicated part of the page lets you change the password of your account. + +## Change account email address + +It is currently not possible to change the email address of your account. We invite you to contact us if you wish to change it. + +## Delete your account + +The last part of the page allows you to delete your happyDomain account. + +Once the deletion is validated, your account will no longer be accessible and all data belonging to you will be deleted shortly after, during a regular database cleanup. + +From the moment you delete your account, your domains will continue to respond according to the last update you made on happyDomain. The deletion will not affect the distributed data. diff --git a/content/pages/settings.fr.md b/content/pages/settings.fr.md new file mode 100644 index 0000000..08b0c91 --- /dev/null +++ b/content/pages/settings.fr.md @@ -0,0 +1,75 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Votre compte et vos réglages +weight: 2000 +description: "Gérez votre compte happyDomain et personnalisez l'interface : langue, aide des champs, confirmation, affichage des zones, mot de passe et suppression du compte" +aliases: + me +--- + +happyDomain vous permet de gérer votre compte et d'ajuster le comportement de l'interface. Vos préférences sont enregistrées avec votre compte ; vous les retrouvez ainsi sur chaque appareil depuis lequel vous vous connectez. + +Vous accédez à cette page en cliquant sur le lien « Mon compte » dans le menu en haut. Chaque option est décrite ci-dessous. + + + +## Langue + +Choisissez la langue utilisée dans toute l'interface. La liste contient toutes les langues actuellement disponibles sur votre instance happyDomain. Le changement prend effet dès l'enregistrement. + +## Aide des champs + +Les champs des formulaires sont souvent accompagnés d'un court texte d'aide. Ce réglage détermine la façon dont cette aide s'affiche : + +- **Masquer** : aucun texte d'aide n'est affiché. +- **Infobulle près du champ** : l'aide apparaît sous forme d'infobulle au survol du champ. +- **Sous le champ lors de la saisie** : l'aide apparaît sous le champ, mais uniquement pendant que vous le modifiez. +- **Sous le champ, en permanence** : l'aide reste affichée sous chaque champ. + +Choisissez le niveau d'accompagnement adapté à votre aisance avec le DNS. + +## Confirmation avant application + +Lorsque vous publiez des modifications chez votre fournisseur DNS, happyDomain peut afficher une étape de confirmation au préalable. Ce réglage décide du moment : + +- **Demander en cas de différences inattendues** : la confirmation n'apparaît que lorsque les modifications diffèrent de ce qui était attendu. +- **Toujours demander** : une confirmation est systématiquement affichée avant l'application. +- **Ne jamais demander, écraser à la publication** : les modifications sont appliquées directement, sans étape de confirmation. + +Consultez [Publier ses modifications]({{% relref "publish-changes" %}}) pour le déroulé complet de la publication. + +## Affichage des zones + +Choisissez la façon dont la zone d'un domaine est présentée : + +- **Vue en grille (le plus simple)** : la présentation la plus visuelle et la plus accessible. +- **Vue en liste (le plus rapide)** : une liste compacte, plus rapide à parcourir. +- **Liste avec enregistrements (avancé)** : une liste qui expose également les enregistrements DNS sous-jacents, pour les utilisateurs avancés. + +## Afficher les types d'enregistrements DNS + +Cet interrupteur affiche le type d'enregistrement (A, MX, CNAME, etc.) associé à chaque service. Il s'adresse aux personnes déjà familières du DNS qui souhaitent voir les types techniques derrière les noms de services simplifiés. + +## Lettre d'information + +L'option permettant de recevoir les nouvelles des prochaines améliorations vous est proposée lors de la [création de votre compte]({{% relref "signup" %}}). Pour modifier ensuite votre abonnement, référez-vous au lien de désinscription présent dans les messages que vous recevez. + +## Enregistrement + +Une fois vos préférences définies, cliquez sur « Enregistrer les réglages ». Un message de confirmation apparaît et les nouveaux réglages prennent effet immédiatement, y compris un changement de langue si vous en avez effectué un. + +## Changer de mot de passe + +Une partie dédiée de la page vous permet de changer le mot de passe de votre compte. + +## Changer l'adresse électronique de compte + +Il n'est pour l'instant pas possible de changer l'adresse électronique de votre compte. Nous vous invitons à nous contacter si vous souhaitez la changer. + +## Supprimer son compte + +La dernière partie de la page vous permet de supprimer votre compte happyDomain. + +Une fois la suppression validée, votre compte ne sera plus accessible et l'ensemble des données vous appartenant sera supprimé peu de temps après, lors d'un nettoyage régulier de la base de données. + +À partir du moment où vous supprimez votre compte, vos domaines continueront de répondre selon la dernière mise à jour que vous avez effectué sur happyDomain. La suppression n'affectera pas les données distribuées. diff --git a/content/pages/signup.en.md b/content/pages/signup.en.md new file mode 100644 index 0000000..4989b52 --- /dev/null +++ b/content/pages/signup.en.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Create an account +author: nemunaire +weight: 100 +description: "Sign up for a happyDomain account and validate your email address" +--- + +Before you can manage your domains, you need a happyDomain account. Creating one takes less than two minutes and only requires an email address and a password. + +## Filling in the sign-up form + +From the home page, follow the link to register, then fill in the form: + + + +- **Email address** -- this address identifies you on the platform and is used to contact you for security-related operations (password recovery, important notices). It must contain a valid `@`. +- **Password** -- choose a strong password (see below). +- **Password confirmation** -- retype the exact same password to avoid typos. +- **Keep me informed of future big improvements** -- an optional checkbox to subscribe to the project newsletter. Leave it unchecked if you do not wish to receive these updates. + +The interface language you are currently using is automatically recorded with your account, so the emails you receive will be in that language. + +{{% notice style="tip" title="Password requirements" icon="key" %}} +A password is accepted only if it contains at least 8 characters, including at least one uppercase letter, one lowercase letter and one digit. It must also contain a special character, or be at least 11 characters long. +{{% /notice %}} + +Some servers display an anti-bot challenge (captcha) below the form. If so, complete it before submitting. + +When everything is filled in correctly, click **Sign up!**. + +## Validating your email address + +On most servers, an email is sent to the address you provided right after registration. Open your mailbox and click the validation link it contains to activate your account. + + + +If you did not receive the message (check your spam folder first), you can request a new one from the email validation page by entering your address again and clicking **Send again**. + +{{% notice style="info" title="Servers without email" icon="circle-info" %}} +Some happyDomain instances run without an email service. On these servers, no validation message is sent: your account is usable immediately and you can [log in]({{% relref "login" %}}) right away. +{{% /notice %}} + +Once your address is validated, you are redirected to the [login page]({{% relref "login" %}}) where you can sign in with your new credentials. diff --git a/content/pages/signup.fr.md b/content/pages/signup.fr.md new file mode 100644 index 0000000..7cbc804 --- /dev/null +++ b/content/pages/signup.fr.md @@ -0,0 +1,43 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Créer un compte +weight: 100 +description: "Inscrivez-vous sur happyDomain et validez votre adresse e-mail" +--- + +Avant de pouvoir gérer vos domaines, il vous faut un compte happyDomain. Sa création prend moins de deux minutes et ne demande qu'une adresse e-mail et un mot de passe. + +## Remplir le formulaire d'inscription + +Depuis la page d'accueil, suivez le lien d'inscription, puis remplissez le formulaire : + + + +- **Adresse e-mail** : cette adresse vous identifie sur la plateforme et sert à vous contacter pour les opérations liées à la sécurité (récupération de mot de passe, informations importantes). Elle doit contenir un `@` valide. +- **Mot de passe** : choisissez un mot de passe robuste (voir ci-dessous). +- **Confirmation du mot de passe** : ressaisissez exactement le même mot de passe afin d'éviter toute faute de frappe. +- **Tenez-moi informé des prochaines grandes améliorations** : une case à cocher facultative pour vous abonner à la lettre d'information du projet. Laissez-la décochée si vous ne souhaitez pas recevoir ces nouvelles. + +La langue de l'interface que vous utilisez est automatiquement enregistrée avec votre compte ; les e-mails que vous recevrez seront ainsi dans cette langue. + +{{% notice style="tip" title="Exigences du mot de passe" icon="key" %}} +Un mot de passe n'est accepté que s'il contient au moins 8 caractères, dont au moins une majuscule, une minuscule et un chiffre. Il doit en outre contenir un caractère spécial, ou bien faire au moins 11 caractères. +{{% /notice %}} + +Certains serveurs affichent une vérification anti-robot (captcha) sous le formulaire. Le cas échéant, complétez-la avant de valider. + +Lorsque tout est correctement renseigné, cliquez sur « Inscrivez-vous ! ». + +## Valider votre adresse e-mail + +Sur la plupart des serveurs, un e-mail est envoyé à l'adresse indiquée juste après l'inscription. Ouvrez votre messagerie et cliquez sur le lien de validation qu'il contient pour activer votre compte. + + + +Si vous n'avez pas reçu le message (vérifiez d'abord votre dossier de courrier indésirable), vous pouvez en demander un nouveau depuis la page de validation : saisissez à nouveau votre adresse, puis cliquez sur « Renvoyer ». + +{{% notice style="info" title="Serveurs sans e-mail" icon="circle-info" %}} +Certaines instances happyDomain fonctionnent sans service de messagerie. Sur ces serveurs, aucun message de validation n'est envoyé : votre compte est utilisable immédiatement et vous pouvez [vous connecter]({{% relref "login" %}}) sans attendre. +{{% /notice %}} + +Une fois votre adresse validée, vous êtes redirigé vers la [page de connexion]({{% relref "login" %}}) où vous pourrez vous identifier avec vos nouveaux identifiants. diff --git a/content/pages/subdomains/happydomain-abstract-zone-records.webp b/content/pages/subdomains/happydomain-abstract-zone-records.webp new file mode 100644 index 0000000..bdb5aa2 Binary files /dev/null and b/content/pages/subdomains/happydomain-abstract-zone-records.webp differ diff --git a/content/pages/subdomains/happydomain-modal-new-subdomain.webp b/content/pages/subdomains/happydomain-modal-new-subdomain.webp new file mode 100644 index 0000000..4541b75 Binary files /dev/null and b/content/pages/subdomains/happydomain-modal-new-subdomain.webp differ diff --git a/content/pages/subdomains/index.en.md b/content/pages/subdomains/index.en.md new file mode 100644 index 0000000..6028177 --- /dev/null +++ b/content/pages/subdomains/index.en.md @@ -0,0 +1,66 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Subdomains +author: nemunaire +weight: 1100 +description: "Navigate and manage the subdomains of a domain: the subdomain list, the tree view, and how to create a new subdomain path" +--- + +A domain is rarely flat: it is made of a root (the apex, written `@`) and a hierarchy of subdomains such as `www`, `mail`, or `blog.staging`. happyDomain presents this hierarchy in a clear, navigable way so you can quickly find and manage each part of your zone. + +## The subdomain list + +When you open a domain, the left sidebar shows the list of subdomains for the currently selected zone version. Each entry is displayed as a path relative to the domain, with the apex shown as the domain name itself. + +![The sidebar listing the subdomains of the domain](happydomain-abstract-zone-records.webp) + +The list behaves like a table of contents: + +- It is **indented** to reflect the hierarchy: a subdomain is shifted to the right according to its depth in the tree, so `blog.staging` appears nested under `staging`. +- Clicking an entry **scrolls** the main panel to the corresponding subdomain. +- As you scroll through the zone, the sidebar **highlights** the subdomain you are currently looking at and follows along automatically. + +Intermediate levels that do not carry any service of their own are still shown, so the tree remains coherent and easy to read. (For reverse zones, only the actual entries are listed.) + +## Managing a subdomain + +Each subdomain in the main panel groups the [services]({{% relref "services" %}}) attached to it. From there you can add, edit, or remove services. Adding a service to an existing subdomain is covered in detail in [Services]({{% relref "services#adding-a-service-to-a-subdomain" %}}). + +## Creating a new subdomain path + +To create a brand-new subdomain (one that does not exist yet in your zone), use the **Add a subdomain** action at the top of the sidebar. + + + +### 1. Enter the subdomain name + +A dialog opens asking for the new subdomain to create under your domain. Type the name **relative to the domain**: for example, enter `www` to create `www.example.com`, or `blog.staging` to create a nested path in one step. + +![The new-subdomain creation dialog](happydomain-modal-new-subdomain.webp) + +The name is validated as you type. You only need to provide the part to the left of your domain name; happyDomain appends the domain for you. + +{{% notice style="tip" title="Apex and nested paths" icon="sitemap" %}} +Leave the field empty (or use `@`) to target the domain apex itself. You can also create several levels at once by typing a dotted path such as `a.b.c`: the intermediate levels are created as needed. +{{% /notice %}} + +### 2. Add a first service + +Creating a subdomain only makes sense if it carries at least one service, so happyDomain chains directly into the service selector once you confirm the name. Pick the service type and fill in its form exactly as described in [Services]({{% relref "services" %}}). + +The new subdomain then appears in the sidebar and in the main panel, with the service you just added. + +{{% notice style="info" title="Changes are staged" icon="circle-info" %}} +Creating a subdomain and its service does not contact your DNS provider immediately. Like every other change, it is staged locally and only sent to your provider when you publish the zone. See the [abstract view]({{% relref "domain-abstract" %}}) for how to review and apply your changes. +{{% /notice %}} + +## Other domain actions + +Next to the **Add a subdomain** button, a menu gives access to domain-wide actions, including: + +- viewing the [history]({{% relref "domain-history" %}}) of zone versions; +- consulting the audit log of changes; +- configuring [checks]({{% relref "checks" %}}) for the domain; +- running a WHOIS lookup; +- viewing or re-importing the zone, or uploading a zone file; +- removing the domain from happyDomain. diff --git a/content/pages/subdomains/index.fr.md b/content/pages/subdomains/index.fr.md new file mode 100644 index 0000000..df2a608 --- /dev/null +++ b/content/pages/subdomains/index.fr.md @@ -0,0 +1,65 @@ +--- +date: 2026-06-10T12:00:00+02:00 +title: Sous-domaines +weight: 1100 +description: "Naviguer et gérer les sous-domaines d'un domaine : la liste des sous-domaines, la vue en arbre et la création d'un nouveau sous-domaine" +--- + +Un domaine est rarement plat : il se compose d'une racine (l'apex, noté `@`) et d'une hiérarchie de sous-domaines tels que `www`, `mail` ou `blog.staging`. happyDomain présente cette hiérarchie de façon claire et navigable, afin que vous puissiez retrouver et gérer rapidement chaque partie de votre zone. + +## La liste des sous-domaines + +Lorsque vous ouvrez un domaine, la barre latérale de gauche affiche la liste des sous-domaines pour la version de zone sélectionnée. Chaque entrée est présentée sous la forme d'un chemin relatif au domaine, l'apex étant affiché sous la forme du nom de domaine lui-même. + +![La barre latérale listant les sous-domaines du domaine](happydomain-abstract-zone-records.webp) + +Cette liste se comporte comme une table des matières : + +- elle est **indentée** pour refléter la hiérarchie : un sous-domaine est décalé vers la droite en fonction de sa profondeur dans l'arbre, si bien que `blog.staging` apparaît imbriqué sous `staging` ; +- cliquer sur une entrée **fait défiler** le panneau principal jusqu'au sous-domaine correspondant ; +- au fil de votre défilement dans la zone, la barre latérale **met en évidence** le sous-domaine que vous consultez et suit automatiquement votre position. + +Les niveaux intermédiaires qui ne portent aucun service propre restent affichés, de sorte que l'arbre demeure cohérent et facile à lire. (Pour les zones inverses, seules les entrées réelles sont listées.) + +## Gérer un sous-domaine + +Dans le panneau principal, chaque sous-domaine regroupe les [services]({{% relref "services" %}}) qui lui sont rattachés. Vous pouvez y ajouter, modifier ou supprimer des services. L'ajout d'un service à un sous-domaine existant est détaillé dans la page [Services]({{% relref "services#ajouter-un-service-à-un-sous-domaine" %}}). + +## Créer un nouveau sous-domaine + +Pour créer un sous-domaine entièrement nouveau (qui n'existe pas encore dans votre zone), utilisez l'action **Ajouter un sous-domaine**, en haut de la barre latérale. + + + +### 1. Saisir le nom du sous-domaine + +Une fenêtre s'ouvre et vous demande le nouveau sous-domaine à créer sous votre domaine. Saisissez le nom **relatif au domaine** : par exemple, entrez `www` pour créer `www.example.com`, ou `blog.staging` pour créer un chemin imbriqué en une seule fois. + +![La fenêtre de création d'un sous-domaine](happydomain-modal-new-subdomain.webp) + +Le nom est validé au fur et à mesure de la saisie. Vous n'avez besoin de fournir que la partie située à gauche de votre nom de domaine ; happyDomain ajoute le domaine pour vous. + +{{% notice style="tip" title="Apex et chemins imbriqués" icon="sitemap" %}} +Laissez le champ vide (ou utilisez `@`) pour viser la racine du domaine elle-même. Vous pouvez aussi créer plusieurs niveaux d'un coup en saisissant un chemin avec des points, comme `a.b.c` : les niveaux intermédiaires sont créés au besoin. +{{% /notice %}} + +### 2. Ajouter un premier service + +Créer un sous-domaine n'a de sens que s'il porte au moins un service : happyDomain enchaîne donc directement avec le sélecteur de services dès que vous confirmez le nom. Choisissez le type de service et remplissez son formulaire exactement comme décrit dans la page [Services]({{% relref "services" %}}). + +Le nouveau sous-domaine apparaît alors dans la barre latérale et dans le panneau principal, avec le service que vous venez d'ajouter. + +{{% notice style="info" title="Les modifications sont préparées" icon="circle-info" %}} +Créer un sous-domaine et son service ne contacte pas immédiatement votre hébergeur DNS. Comme toute autre modification, l'opération est préparée localement et n'est envoyée à votre hébergeur qu'au moment de la publication de la zone. Consultez la [vue abstraite]({{% relref "domain-abstract" %}}) pour savoir comment vérifier et appliquer vos modifications. +{{% /notice %}} + +## Autres actions sur le domaine + +À côté du bouton **Ajouter un sous-domaine**, un menu donne accès aux actions concernant l'ensemble du domaine, notamment : + +- consulter l'[historique]({{% relref "domain-history" %}}) des versions de la zone ; +- consulter le journal d'audit des modifications ; +- configurer les [vérifications]({{% relref "checks" %}}) du domaine ; +- effectuer une recherche WHOIS ; +- afficher ou réimporter la zone, ou téléverser un fichier de zone ; +- retirer le domaine de happyDomain. diff --git a/content/pages/tools-client.en.md b/content/pages/tools-client.en.md index 2ed133d..5bdffab 100644 --- a/content/pages/tools-client.en.md +++ b/content/pages/tools-client.en.md @@ -2,7 +2,7 @@ date: 2021-01-12T21:38:49+02:00 author: Frederic title: Test a domain -weight: 50 +weight: 1900 --- Please, help us to write this Documentation page diff --git a/content/pages/tools-client.fr.md b/content/pages/tools-client.fr.md index 146ecf4..0be1d6a 100644 --- a/content/pages/tools-client.fr.md +++ b/content/pages/tools-client.fr.md @@ -1,7 +1,7 @@ --- date: 2020-12-10T10:26:54+01:00 title: Tester un domaine -weight: 50 +weight: 1900 --- Documentation à faire diff --git a/content/reference/checkers/_index.en.md b/content/reference/checkers/_index.en.md new file mode 100644 index 0000000..d79534f --- /dev/null +++ b/content/reference/checkers/_index.en.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +title: Checkers +author: nemunaire +archetype: chapter +weight: 35 +aliases: + checkers +--- + +Checkers are the building blocks of happyDomain's monitoring system. Each one collects data about a domain, a zone or a service, evaluates it against a set of rules, and reports a clear status (OK, Warning, Critical or Error). + +This chapter documents every checker shipped with happyDomain: what it verifies, the scope it applies to, the options you can tune, and the rules it evaluates. For the day-to-day workflow of configuring, scheduling and reading checks in the interface, see {{< relref "/pages/checks" >}}. + +## Scopes + +Every checker declares the scope it operates on: + +- **Domain-level** — concerns the domain itself, independent of its DNS records (registration status, expiry, transfer lock…). +- **Zone-level** — needs the full zone content (DNSSEC validation, delegation consistency…). +- **Service-level** — targets a specific service published on a subdomain (HTTP, TLS, ping…), and is configured from that service's own **Checks** tab. + +## Statuses + +Checkers report one of the following statuses, in order of severity: + +| Status | Meaning | +|--------|---------| +| **OK** | Everything is within acceptable parameters | +| **Info** | Informational finding, no action needed | +| **Warning** | A threshold is approaching; attention recommended | +| **Critical** | A threshold has been exceeded; action required | +| **Error** | The check itself failed (collection error, bad configuration) | +| **Unknown** | The check could not determine a result | + +{{% children %}} diff --git a/content/reference/checkers/_index.fr.md b/content/reference/checkers/_index.fr.md new file mode 100644 index 0000000..ce12857 --- /dev/null +++ b/content/reference/checkers/_index.fr.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +title: Vérificateurs +author: nemunaire +archetype: chapter +weight: 35 +aliases: + checkers +--- + +Les vérificateurs sont les briques de base du système de surveillance de happyDomain. Chacun collecte des données sur un domaine, une zone ou un service, les évalue selon un ensemble de règles, puis rapporte un état clair (OK, Avertissement, Critique ou Erreur). + +Ce chapitre documente chaque vérificateur fourni avec happyDomain : ce qu'il contrôle, la portée à laquelle il s'applique, les options que vous pouvez régler et les règles qu'il évalue. Pour le fonctionnement au quotidien (configuration, planification et lecture des résultats dans l'interface), consultez {{< relref "/pages/checks" >}}. + +## Portées + +Chaque vérificateur déclare la portée sur laquelle il opère : + +- **Niveau domaine** : concerne le domaine lui-même, indépendamment de ses enregistrements DNS (statut d'enregistrement, expiration, verrou de transfert...). +- **Niveau zone** : nécessite le contenu complet de la zone (validation DNSSEC, cohérence de la délégation...). +- **Niveau service** : cible un service précis publié sur un sous-domaine (HTTP, TLS, ping...), et se configure depuis l'onglet **Vérifications** de ce service. + +## États + +Les vérificateurs rapportent l'un des états suivants, par ordre de gravité : + +| État | Signification | +|------|---------------| +| **OK** | Tout se situe dans les paramètres acceptables | +| **Info** | Information utile, aucune action requise | +| **Avertissement** | Un seuil est sur le point d'être atteint ; attention recommandée | +| **Critique** | Un seuil a été dépassé ; action requise | +| **Erreur** | La vérification elle-même a échoué (erreur de collecte, mauvaise configuration) | +| **Inconnu** | La vérification n'a pas pu déterminer de résultat | + +{{% children %}} diff --git a/content/reference/checkers/alias.en.md b/content/reference/checkers/alias.en.md new file mode 100644 index 0000000..7d83b00 --- /dev/null +++ b/content/reference/checkers/alias.en.md @@ -0,0 +1,49 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Alias chain +description: "Walks a CNAME/DNAME/ALIAS chain and validates hop count, TTLs, target resolvability, apex coexistence and DNSSEC signing." +weight: 130 +--- + +The **CNAME / DNAME / ALIAS chain** checker follows the alias chain of a name and verifies that it resolves cleanly: no loops, not too many hops, sane TTLs, a resolvable final target, no forbidden record coexistence, and a properly signed CNAME RRset when the zone uses DNSSEC. + +This is a **service-level** checker: it runs on a `CNAME` (or special CNAME) service and is configured from that service's own **Checks** tab. Starting from the queried name it locates the zone apex, walks each CNAME/DNAME hop, and finally resolves the chain's target to A/AAAA records. + +## What it checks + +Each rule emits a finding code. Some severities are softened by the options below. + +| Rule | What it verifies / flags | Severity | +|------|--------------------------|----------| +| `apex_lookup` | The zone apex (SOA) for the queried name can be located. | Critical | +| `chain_loop` | A CNAME/DNAME cycle in the resolution chain. | Critical | +| `chain_length` | The chain exceeds **Maximum chain length** hops. | Critical | +| `chain_query_error` | A DNS query fails while walking the chain (network error, timeout). | Warning | +| `chain_rcode` | A non-NOERROR response code mid-chain or on the final A/AAAA lookup. | Critical (mid-chain) / Warning (final) | +| `hop_ttl` | A CNAME/DNAME hop has a TTL below **Minimum target TTL**. | Warning | +| `cname_at_apex` | A CNAME exists at the zone apex, conflicting with SOA/NS (RFC 1912 §2.4). | Critical / Warning | +| `apex_flattening` | A/AAAA coexist with SOA/NS at the apex without a CNAME (provider-side ALIAS/ANAME flattening). | Info | +| `cname_coexistence` | Other RRsets (beyond A/AAAA) coexist at a CNAME owner, violating RFC 1034 §3.6.2 / RFC 2181 §10.1. | Critical / Warning at apex | +| `cname_dnssec` | The zone is DNSSEC-signed but the CNAME RRset lacks an RRSIG. | Critical | +| `target_resolvable` | The final target of the chain has no A or AAAA record. | Critical | +| `multiple_records` | An owner in the chain carries more than one CNAME/DNAME record (malformed). | Critical | + +{{% notice style="info" title="Why a CNAME at the apex is a problem" %}} +A CNAME owner may carry no other record type, but the zone apex must always hold SOA and NS records. The two requirements are mutually exclusive, so a CNAME at the apex is invalid (RFC 1912 §2.4). Some providers work around this with server-side ALIAS/ANAME "flattening" that publishes plain A/AAAA at the apex; the `apex_flattening` rule recognises that pattern as intentional when **Recognize ALIAS/ANAME flattening** is enabled. +{{% /notice %}} + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Maximum chain length | Above this number of hops the chain is reported as critical. | `8` | +| Minimum target TTL | Hops with a TTL below this threshold (seconds) are flagged as a warning. | `60` | +| Allow CNAME at apex | When enabled, a CNAME at a zone apex and its coexistence violations are downgraded to warnings. RFC 1912 forbids this, so leaving it off is strongly recommended. | `false` | +| Recognize ALIAS/ANAME flattening | When enabled, providers serving A/AAAA at the apex (ALIAS/ANAME pseudo-records) are recognised as intentional and excused from coexistence violations. | `true` | + +## In happyDomain + +Add the CNAME service to the subdomain, then enable this checker from that service's **Checks** tab. See {{< relref "/pages/checks" >}} for configuring and scheduling checks. The parent domain and subdomain are filled in automatically. + +Related checkers: {{< relref "/reference/checkers/dangling" >}} watches for alias targets that have become unregistered or NXDOMAIN, and {{< relref "/reference/checkers/ptr" >}} covers the reverse-DNS side. diff --git a/content/reference/checkers/alias.fr.md b/content/reference/checkers/alias.fr.md new file mode 100644 index 0000000..2613785 --- /dev/null +++ b/content/reference/checkers/alias.fr.md @@ -0,0 +1,49 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Chaîne d'alias +description: "Parcourt une chaîne CNAME/DNAME/ALIAS et valide le nombre de sauts, les TTL, la résolvabilité de la cible, la coexistence à l'apex et la signature DNSSEC." +weight: 130 +--- + +Le vérificateur **Chaîne CNAME / DNAME / ALIAS** suit la chaîne d'alias d'un nom et vérifie qu'elle se résout proprement : pas de boucle, pas trop de sauts, des TTL raisonnables, une cible finale résolvable, aucune coexistence d'enregistrements interdite et un RRset CNAME correctement signé lorsque la zone utilise DNSSEC. + +Il s'agit d'un vérificateur de **niveau service** : il s'exécute sur un service `CNAME` (ou CNAME spécial) et se configure depuis l'onglet **Vérifications** de ce service. À partir du nom interrogé, il localise l'apex de la zone, parcourt chaque saut CNAME/DNAME, puis résout la cible de la chaîne vers des enregistrements A/AAAA. + +## Ce qui est vérifié + +Chaque règle émet un code de constat. Certaines sévérités sont atténuées par les options ci-dessous. + +| Règle | Ce qui est vérifié ou signalé | Sévérité | +|-------|-------------------------------|----------| +| `apex_lookup` | L'apex de la zone (SOA) du nom interrogé peut être localisé. | Critique | +| `chain_loop` | Un cycle CNAME/DNAME dans la chaîne de résolution. | Critique | +| `chain_length` | La chaîne dépasse le nombre de sauts de **Longueur maximale de chaîne**. | Critique | +| `chain_query_error` | Une requête DNS échoue pendant le parcours de la chaîne (erreur réseau, délai dépassé). | Avertissement | +| `chain_rcode` | Un code de réponse autre que NOERROR en milieu de chaîne ou sur la résolution A/AAAA finale. | Critique (milieu) / Avertissement (final) | +| `hop_ttl` | Un saut CNAME/DNAME a un TTL inférieur à **TTL minimal de la cible**. | Avertissement | +| `cname_at_apex` | Un CNAME existe à l'apex de la zone, en conflit avec SOA/NS (RFC 1912 §2.4). | Critique / Avertissement | +| `apex_flattening` | Des A/AAAA coexistent avec SOA/NS à l'apex sans CNAME (aplatissement ALIAS/ANAME côté hébergeur). | Info | +| `cname_coexistence` | D'autres RRset (au-delà de A/AAAA) coexistent chez un propriétaire CNAME, en violation des RFC 1034 §3.6.2 / RFC 2181 §10.1. | Critique / Avertissement à l'apex | +| `cname_dnssec` | La zone est signée DNSSEC mais le RRset CNAME ne possède pas de RRSIG. | Critique | +| `target_resolvable` | La cible finale de la chaîne n'a aucun enregistrement A ni AAAA. | Critique | +| `multiple_records` | Un propriétaire de la chaîne porte plus d'un enregistrement CNAME/DNAME (malformé). | Critique | + +{{% notice style="info" title="Pourquoi un CNAME à l'apex pose problème" %}} +Un propriétaire de CNAME ne peut porter aucun autre type d'enregistrement, mais l'apex de la zone doit toujours contenir des enregistrements SOA et NS. Ces deux exigences sont incompatibles : un CNAME à l'apex est donc invalide (RFC 1912 §2.4). Certains hébergeurs contournent cela par un aplatissement ALIAS/ANAME côté serveur qui publie de simples A/AAAA à l'apex ; la règle `apex_flattening` reconnaît ce motif comme intentionnel lorsque l'option **Reconnaître l'aplatissement ALIAS/ANAME** est activée. +{{% /notice %}} + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Longueur maximale de chaîne | Au-delà de ce nombre de sauts, la chaîne est rapportée comme critique. | `8` | +| TTL minimal de la cible | Les sauts dont le TTL est inférieur à ce seuil (en secondes) sont signalés comme avertissement. | `60` | +| Autoriser un CNAME à l'apex | Lorsqu'activée, un CNAME à l'apex d'une zone et ses violations de coexistence sont rétrogradés en avertissements. La RFC 1912 l'interdit : il est fortement recommandé de laisser cette option désactivée. | `false` | +| Reconnaître l'aplatissement ALIAS/ANAME | Lorsqu'activée, les hébergeurs servant des A/AAAA à l'apex (pseudo-enregistrements ALIAS/ANAME) sont reconnus comme intentionnels et dispensés des violations de coexistence. | `true` | + +## Dans happyDomain + +Ajoutez le service CNAME au sous-domaine, puis activez ce vérificateur depuis l'onglet **Vérifications** de ce service. Consultez {{< relref "/pages/checks" >}} pour configurer et planifier les vérifications. Le domaine parent et le sous-domaine sont renseignés automatiquement. + +Vérificateurs apparentés : {{< relref "/reference/checkers/dangling" >}} surveille les cibles d'alias devenues non enregistrées ou NXDOMAIN, et {{< relref "/reference/checkers/ptr" >}} couvre le versant DNS inverse. diff --git a/content/reference/checkers/authoritative-consistency.en.md b/content/reference/checkers/authoritative-consistency.en.md new file mode 100644 index 0000000..e17684f --- /dev/null +++ b/content/reference/checkers/authoritative-consistency.en.md @@ -0,0 +1,51 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Authoritative consistency +description: "Probes every authoritative name server of a zone and verifies they agree with each other and with the parent on NS, SOA, reachability, EDNS0 and authoritativeness." +weight: 80 +--- + +The **Authoritative consistency** checker probes every authoritative name server of a zone and verifies that they agree — with one another and with the parent delegation. Where the {{< relref "/reference/checkers/delegation" >}} checker focuses on the parent/child hand-off, this checker concentrates on the *apex itself*: do all the servers serve the same `NS` and `SOA`, are they all reachable over UDP and TCP, do they support EDNS0, do they answer authoritatively, and how fast do they respond? + +This checker is **service-level**: it targets an *Origin* or *NS-only Origin* service (`abstract.Origin`, `abstract.NSOnlyOrigin`) and is configured from that service's **Checks** tab. + +## What it checks + +Each rule emits a finding code. Several severities depend on the options below. + +| Finding code | Default severity | Condition | +|---|---|---| +| `authoritative_consistency_no_ns` | Critical | No name servers could be discovered (declared list empty and parent query returned nothing). | +| `authoritative_consistency_too_few_ns` | Warning | Fewer name servers declared than `minNameServers` (RFC 1034 recommends at least 2). | +| `authoritative_consistency_parent_query_failed` | Warning | The parent delegation query failed (network error, REFUSED…). | +| `authoritative_consistency_parent_drift` | Warning | The parent's `NS` RRset does not match the `NS` declared in the service. | +| `authoritative_consistency_ns_unresolvable` | Critical | A declared name server has no `A` or `AAAA` record. | +| `authoritative_consistency_ns_udp_failed` | Critical | A name server did not answer any SOA query over UDP/53. | +| `authoritative_consistency_ns_tcp_failed` | Critical with `requireTCP`, else Warning | A name server did not answer over TCP/53 (required by RFC 7766 and DNSSEC). | +| `authoritative_consistency_lame` | Critical | A name server answered without the AA bit for the zone (lame delegation). | +| `authoritative_consistency_no_soa` | Critical | A name server is authoritative but returned no `SOA`. | +| `authoritative_consistency_edns_unsupported` | Warning | A name server drops or mishandles EDNS0 queries (RFC 6891). | +| `authoritative_consistency_slow_ns` | Info | A name server's response time exceeded `latencyThresholdMs`. | +| `authoritative_consistency_serial_drift` | Warning | Authoritative servers disagree on the `SOA` serial (zone not fully propagated). | +| `authoritative_consistency_serial_stale_vs_saved` | Warning | The serial saved in happyDomain is newer than what the servers publish (likely un-pushed change). | +| `authoritative_consistency_serial_ahead_of_saved` | Info | The servers publish a serial newer than the saved one (out-of-band change). | +| `authoritative_consistency_soa_fields_drift` | Warning | Servers disagree on `SOA` fields (MNAME, RNAME, refresh, retry, expire, minimum). | +| `authoritative_consistency_ns_rrset_drift` | Warning | Servers disagree on the `NS` RRset they publish at the apex. | +| `authoritative_consistency_ns_rrset_mismatch_config` | Warning | The published `NS` RRset does not match the `NS` declared in the service. | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| `requireTCP` | When enabled, a server that fails over TCP is critical (otherwise warning). TCP/53 is required by RFC 7766 and DNSSEC. | `true` | +| `checkEDNS` | Probe each name server for EDNS0 (RFC 6891). Servers that mishandle EDNS0 break DNSSEC and large answers. | `true` | +| `checkLatency` | Measure response time of every name server and warn on slow responders. | `true` | +| `latencyThresholdMs` | Response times above this value trigger a slow-server warning. | `500` | +| `useParentNS` | Query the parent for the delegation `NS` RRset and compare it to the service's declared name servers. | `true` | +| `warnOnStaleSaved` | Warn when the saved `SOA` serial is newer than what authoritative servers publish. | `true` | +| `minNameServers` | Below this count, a warning is emitted (RFC 1034 recommends at least 2). | `2` | + +## In happyDomain + +Enable the Authoritative consistency checker from the **Checks** tab of an Origin service. See {{< relref "/pages/checks" >}} for the full workflow. To compare what *recursive resolvers around the world* see against the authoritative answer, pair it with {{< relref "/reference/checkers/resolver-propagation" >}}. diff --git a/content/reference/checkers/authoritative-consistency.fr.md b/content/reference/checkers/authoritative-consistency.fr.md new file mode 100644 index 0000000..c5d186e --- /dev/null +++ b/content/reference/checkers/authoritative-consistency.fr.md @@ -0,0 +1,51 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Cohérence des serveurs faisant autorité +description: "Sonde chaque serveur faisant autorité d'une zone et vérifie qu'ils s'accordent entre eux et avec le parent sur les NS, le SOA, la joignabilité, EDNS0 et l'autorité." +weight: 80 +--- + +Le vérificateur **Cohérence des serveurs faisant autorité** sonde chaque serveur faisant autorité d'une zone et vérifie qu'ils s'accordent, entre eux et avec la délégation parente. Là où le vérificateur {{< relref "/reference/checkers/delegation" >}} se concentre sur le passage de relais parent/enfant, celui-ci porte sur l'*apex lui-même* : tous les serveurs servent-ils les mêmes `NS` et `SOA`, sont-ils tous joignables en UDP et en TCP, prennent-ils en charge EDNS0, répondent-ils de façon autoritaire, et à quelle vitesse répondent-ils ? + +Ce vérificateur s'applique au niveau du **service** : il cible un service d'origine ou d'origine NS-seule (`abstract.Origin`, `abstract.NSOnlyOrigin`) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +Chaque règle émet un code de constat. Plusieurs sévérités dépendent des options ci-dessous. + +| Code de constat | Sévérité par défaut | Condition | +|---|---|---| +| `authoritative_consistency_no_ns` | Critique | Aucun serveur de noms n'a pu être découvert (liste déclarée vide et requête parente sans réponse). | +| `authoritative_consistency_too_few_ns` | Avertissement | Moins de serveurs déclarés que `minNameServers` (la RFC 1034 recommande au moins 2). | +| `authoritative_consistency_parent_query_failed` | Avertissement | La requête de délégation parente a échoué (erreur réseau, REFUSED, etc.). | +| `authoritative_consistency_parent_drift` | Avertissement | Le RRset `NS` du parent ne correspond pas aux `NS` déclarés dans le service. | +| `authoritative_consistency_ns_unresolvable` | Critique | Un serveur de noms déclaré n'a aucun enregistrement `A` ni `AAAA`. | +| `authoritative_consistency_ns_udp_failed` | Critique | Un serveur de noms n'a répondu à aucune requête SOA en UDP/53. | +| `authoritative_consistency_ns_tcp_failed` | Critique avec `requireTCP`, sinon avertissement | Un serveur de noms n'a pas répondu en TCP/53 (exigé par la RFC 7766 et par DNSSEC). | +| `authoritative_consistency_lame` | Critique | Un serveur de noms a répondu sans le bit AA pour la zone (délégation boiteuse). | +| `authoritative_consistency_no_soa` | Critique | Un serveur fait autorité mais n'a renvoyé aucun `SOA`. | +| `authoritative_consistency_edns_unsupported` | Avertissement | Un serveur ignore ou gère mal les requêtes EDNS0 (RFC 6891). | +| `authoritative_consistency_slow_ns` | Info | Le temps de réponse d'un serveur a dépassé `latencyThresholdMs`. | +| `authoritative_consistency_serial_drift` | Avertissement | Les serveurs divergent sur le numéro de série `SOA` (zone non entièrement propagée). | +| `authoritative_consistency_serial_stale_vs_saved` | Avertissement | Le numéro de série enregistré dans happyDomain est plus récent que celui publié (changement probablement non poussé). | +| `authoritative_consistency_serial_ahead_of_saved` | Info | Les serveurs publient un numéro de série plus récent que celui enregistré (changement hors bande). | +| `authoritative_consistency_soa_fields_drift` | Avertissement | Les serveurs divergent sur les champs `SOA` (MNAME, RNAME, refresh, retry, expire, minimum). | +| `authoritative_consistency_ns_rrset_drift` | Avertissement | Les serveurs divergent sur le RRset `NS` qu'ils publient à l'apex. | +| `authoritative_consistency_ns_rrset_mismatch_config` | Avertissement | Le RRset `NS` publié ne correspond pas aux `NS` déclarés dans le service. | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| `requireTCP` | Si activé, un serveur défaillant en TCP est critique (sinon avertissement). TCP/53 est exigé par la RFC 7766 et par DNSSEC. | `true` | +| `checkEDNS` | Sonde chaque serveur de noms pour EDNS0 (RFC 6891). Les serveurs qui gèrent mal EDNS0 cassent DNSSEC et les grandes réponses. | `true` | +| `checkLatency` | Mesure le temps de réponse de chaque serveur et avertit en cas de lenteur. | `true` | +| `latencyThresholdMs` | Les temps de réponse au-delà de cette valeur déclenchent un avertissement de lenteur. | `500` | +| `useParentNS` | Interroge le parent pour le RRset `NS` de délégation et le compare aux serveurs de noms déclarés dans le service. | `true` | +| `warnOnStaleSaved` | Avertit lorsque le numéro de série `SOA` enregistré est plus récent que celui publié par les serveurs faisant autorité. | `true` | +| `minNameServers` | En dessous de ce nombre, un avertissement est émis (la RFC 1034 recommande au moins 2). | `2` | + +## Dans happyDomain + +Activez le vérificateur Cohérence des serveurs faisant autorité depuis l'onglet **Vérifications** d'un service d'origine. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet. Pour comparer ce que voient les *résolveurs récursifs à travers le monde* à la réponse faisant autorité, associez-le à {{< relref "/reference/checkers/resolver-propagation" >}}. diff --git a/content/reference/checkers/blacklist.en.md b/content/reference/checkers/blacklist.en.md new file mode 100644 index 0000000..52bc277 --- /dev/null +++ b/content/reference/checkers/blacklist.en.md @@ -0,0 +1,35 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Blacklist (DNSBL) +description: "Checks whether a domain is currently listed on widely-used reputation systems: DNS-based domain blocklists, downloaded phishing/malware feeds, and threat-intelligence APIs." +weight: 320 +--- + +The **Blacklist & reputation** checker flags whether a domain is currently listed on widely-used reputation systems. It queries a range of sources in parallel and produces a diagnosis-first HTML report whose "Action required" section lists the most impactful listings with a per-operator removal procedure. + +**Scope:** domain-level. The check targets the domain name itself, independent of its DNS records, and is enabled from the domain's checks view. + +## What it checks + +Each configured source contributes its own per-source rule; a listing on any of them raises the domain's status. The sources fall into three families: + +- **DNS-based domain blocklists (DBL/RHSBL)** — queried over DNS, no API key required: Spamhaus DBL, SURBL multi, URIBL multi, NordSpam DBL, SpamEatingMonkey Fresh, Tiopan DBL, SORBS RHSBL, plus any extra DNSBL zones an administrator adds. +- **Downloaded phishing/malware feeds** — fetched and cached in memory: OpenPhish public feed, PhishTank, Botvrij.eu, Disconnect.me, OISD, and a Quad9 secure-DNS comparison. +- **Threat-intelligence HTTPS lookups** — requiring an API key configured by an administrator: Google Safe Browsing, abuse.ch URLhaus / ThreatFox / MalwareBazaar, VirusTotal v3, AlienVault OTX, Pulsedive, Criminal IP. + +When a DNSBL query is refused (many public resolvers are blocked by DBL operators) or an API quota is exhausted, the source is surfaced as a Warning so it does not pollute the OK status. A multi-vendor source such as VirusTotal reports Critical when at least one vendor flags the domain as malicious, and Warning when it is only suspicious. + +## Options + +The only domain-level option is the target itself: + +| Option | Meaning | Default | +|--------|---------|---------| +| Domain name (`domain_name`) | The domain to look up. Auto-filled from the domain. | (from domain) | + +All source selection and credentials are configured per source. Most sources are toggled on or off (and API keys supplied) at the **administrator** level; a subset of the downloaded-feed sources default to on and can be toggled by the user. See the source's own documentation for which sources need an API key and how to obtain one. + +## In happyDomain + +This is a domain-level checker: enable it from the domain's checks view. Listings often reflect a compromise; treat a positive result as a signal to audit the host and rotate credentials, then follow the per-operator delisting links shown in the report. For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/blacklist.fr.md b/content/reference/checkers/blacklist.fr.md new file mode 100644 index 0000000..bc9e176 --- /dev/null +++ b/content/reference/checkers/blacklist.fr.md @@ -0,0 +1,35 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Liste noire (DNSBL) +description: "Vérifie si un domaine est actuellement listé sur des systèmes de réputation répandus : listes noires de domaines basées sur le DNS, flux de phishing/malware téléchargés et API de renseignement sur les menaces." +weight: 320 +--- + +Le vérificateur **Liste noire et réputation** signale si un domaine est actuellement listé sur des systèmes de réputation répandus. Il interroge en parallèle une série de sources et produit un rapport HTML orienté diagnostic dont la section « Action requise » liste les inscriptions les plus impactantes avec une procédure de retrait propre à chaque opérateur. + +**Portée** : niveau domaine. La vérification cible le nom de domaine lui-même, indépendamment de ses enregistrements DNS, et s'active depuis la vue des vérifications du domaine. + +## Ce qu'il vérifie + +Chaque source configurée contribue à sa propre règle ; une inscription sur l'une d'elles élève le statut du domaine. Les sources se répartissent en trois familles : + +- **Listes noires de domaines basées sur le DNS (DBL/RHSBL)** : interrogées via DNS, sans clé d'API : Spamhaus DBL, SURBL multi, URIBL multi, NordSpam DBL, SpamEatingMonkey Fresh, Tiopan DBL, SORBS RHSBL, ainsi que toute zone DNSBL supplémentaire ajoutée par un administrateur. +- **Flux de phishing/malware téléchargés** : récupérés et mis en cache en mémoire : flux public OpenPhish, PhishTank, Botvrij.eu, Disconnect.me, OISD et une comparaison avec le DNS sécurisé Quad9. +- **Recherches HTTPS de renseignement sur les menaces** : nécessitant une clé d'API configurée par un administrateur : Google Safe Browsing, abuse.ch URLhaus / ThreatFox / MalwareBazaar, VirusTotal v3, AlienVault OTX, Pulsedive, Criminal IP. + +Lorsqu'une requête DNSBL est refusée (de nombreux résolveurs publics sont bloqués par les opérateurs de DBL) ou qu'un quota d'API est épuisé, la source est rapportée comme avertissement afin de ne pas polluer le statut OK. Une source multi-fournisseurs comme VirusTotal rapporte « critique » lorsqu'au moins un fournisseur signale le domaine comme malveillant, et « avertissement » lorsqu'il est seulement suspect. + +## Options + +La seule option de niveau domaine est la cible elle-même : + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Nom de domaine (`domain_name`) | Le domaine à rechercher. Rempli automatiquement depuis le domaine. | (depuis le domaine) | + +La sélection des sources et les identifiants se configurent source par source. La plupart des sources s'activent ou se désactivent (et leurs clés d'API se renseignent) au niveau **administrateur** ; un sous-ensemble des flux téléchargés est activé par défaut et peut être basculé par l'utilisateur. Voir la documentation de chaque source pour savoir lesquelles nécessitent une clé d'API et comment l'obtenir. + +## Dans happyDomain + +C'est un vérificateur de niveau domaine : activez-le depuis la vue des vérifications du domaine. Les inscriptions reflètent souvent une compromission ; traitez un résultat positif comme un signal pour auditer l'hôte et renouveler les identifiants, puis suivez les liens de retrait propres à chaque opérateur indiqués dans le rapport. Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/caa.en.md b/content/reference/checkers/caa.en.md new file mode 100644 index 0000000..03b9ff2 --- /dev/null +++ b/content/reference/checkers/caa.en.md @@ -0,0 +1,42 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: CAA +description: "Cross-references the TLS certificates observed on a domain against its CAA issue/issuewild policy to detect unauthorized issuance." +weight: 150 +--- + +The **CAA Compliance** checker verifies that the TLS certificates actually deployed on a domain were issued by a Certification Authority that the domain's `CAA` records authorize. A `CAA` (Certification Authority Authorization) record lets a domain declare which CAs may issue certificates for it; this checker confirms reality matches that policy. + +This is a **service-level** checker: it runs on a `CAA` policy service. It performs **no network probes of its own** — it reads the parsed CAA policy from the service body and the TLS certificates observed by the {{< relref "/reference/checkers/dane" >}} / `checker-tls` family, then maps each observed issuer to its CAA identifier domain using the Common CA Database (CCADB). + +## What it checks + +A single rule, `caa_compliance`, loads the zone's CAA `issue` / `issuewild` policy, gathers every TLS probe observed on the target, resolves each certificate's issuer (by Authority Key Identifier, falling back to the issuer Distinguished Name) against the embedded CCADB "CAA Identifiers" mapping, and compares the result against the allow list. + +| Outcome | Meaning | Status | +|---------|---------|--------| +| `caa_ok` | Every observed issuer is authorized by the CAA policy. | OK | +| `caa_no_tls` | No TLS probes related to this target have been published yet. | Unknown | +| `caa_not_authorized` | CCADB mapped an observed issuer to a domain the policy does not list. | Critical | +| `caa_issuance_disallowed` | The policy contains `CAA 0 issue ";"` (issuance explicitly forbidden) but a certificate was still observed. | Critical | +| `caa_issuer_unknown` | CCADB has no mapping for the observed issuer (AKI + DN). | Info | + +{{% notice style="info" title="Eventual consistency with TLS probes" %}} +The `caa_no_tls` state is a normal steady state, not an error: until `checker-tls` has probed an endpoint on the target and published a certificate, the CAA checker has nothing to compare against and reports **Unknown**. Once probes arrive, the check resolves on its next run. The `caa_issuer_unknown` outcome means the CA simply isn't in the current CCADB snapshot; the fix is to file a CCADB update, not to change your zone. +{{% /notice %}} + +The issuer-to-CAA-domain mapping comes from an embedded snapshot of CCADB's "CAA Identifiers (V2)" report. Refreshing it only requires re-embedding a newer CSV and recompiling — no code change and no network dependency at build time. + +## Options + +This checker has no user-tunable options. Both inputs are filled in automatically: + +| Option | Meaning | +|--------|---------| +| Domain | The domain being checked (auto-filled, required). | +| Service | The CAA policy service body (auto-filled). | + +## In happyDomain + +Add the CAA policy service to the relevant subdomain (usually the apex), then enable this checker from that service's **Checks** tab. See {{< relref "/pages/checks" >}} for configuring and scheduling checks. For the comparison to produce a verdict, a TLS-probing checker such as {{< relref "/reference/checkers/dane" >}} (or the standalone `checker-tls`) must have observed certificates on the target. diff --git a/content/reference/checkers/caa.fr.md b/content/reference/checkers/caa.fr.md new file mode 100644 index 0000000..a0b51d3 --- /dev/null +++ b/content/reference/checkers/caa.fr.md @@ -0,0 +1,42 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: CAA +description: "Recoupe les certificats TLS observés sur un domaine avec sa politique CAA issue/issuewild pour détecter les émissions non autorisées." +weight: 150 +--- + +Le vérificateur **Conformité CAA** vérifie que les certificats TLS réellement déployés sur un domaine ont été émis par une autorité de certification que les enregistrements `CAA` du domaine autorisent. Un enregistrement `CAA` (Certification Authority Authorization) permet à un domaine de déclarer quelles autorités de certification peuvent émettre des certificats pour lui ; ce vérificateur confirme que la réalité correspond à cette politique. + +Il s'agit d'un vérificateur de **niveau service** : il s'exécute sur un service de politique `CAA`. Il n'effectue **aucune sonde réseau** : il lit la politique CAA déjà analysée dans le corps du service et les certificats TLS observés par la famille {{< relref "/reference/checkers/dane" >}} / `checker-tls`, puis associe chaque émetteur observé à son domaine d'identifiant CAA à l'aide de la base de données Common CA Database (CCADB). + +## Ce qui est vérifié + +Une seule règle, `caa_compliance`, charge la politique CAA `issue` / `issuewild` de la zone, rassemble chaque sonde TLS observée sur la cible, résout l'émetteur de chaque certificat (par Authority Key Identifier, avec repli sur le Distinguished Name de l'émetteur) à l'aide du mappage « CAA Identifiers » embarqué de CCADB, puis compare le résultat à la liste d'autorisations. + +| Résultat | Signification | Statut | +|----------|---------------|--------| +| `caa_ok` | Chaque émetteur observé est autorisé par la politique CAA. | OK | +| `caa_no_tls` | Aucune sonde TLS liée à cette cible n'a encore été publiée. | Inconnu | +| `caa_not_authorized` | CCADB a associé un émetteur observé à un domaine que la politique ne liste pas. | Critique | +| `caa_issuance_disallowed` | La politique contient `CAA 0 issue ";"` (émission explicitement interdite) mais un certificat a tout de même été observé. | Critique | +| `caa_issuer_unknown` | CCADB n'a aucun mappage pour l'émetteur observé (AKI + DN). | Info | + +{{% notice style="info" title="Cohérence à terme avec les sondes TLS" %}} +L'état `caa_no_tls` est un état stable normal, pas une erreur : tant que `checker-tls` n'a pas sondé un point d'accès sur la cible ni publié de certificat, le vérificateur CAA n'a rien à comparer et rapporte **Inconnu**. Dès que les sondes arrivent, la vérification se résout à son exécution suivante. Le résultat `caa_issuer_unknown` signifie simplement que l'autorité n'est pas dans l'instantané CCADB courant ; le correctif consiste à soumettre une mise à jour à CCADB, pas à modifier votre zone. +{{% /notice %}} + +Le mappage émetteur vers domaine CAA provient d'un instantané embarqué du rapport « CAA Identifiers (V2) » de CCADB. Le rafraîchir ne demande que de ré-embarquer un CSV plus récent et de recompiler : aucun changement de code ni dépendance réseau à la compilation. + +## Options + +Ce vérificateur n'a aucune option réglable par l'utilisateur. Ses deux entrées sont renseignées automatiquement : + +| Option | Signification | +|--------|---------------| +| Domaine | Le domaine vérifié (renseigné automatiquement, requis). | +| Service | Le corps du service de politique CAA (renseigné automatiquement). | + +## Dans happyDomain + +Ajoutez le service de politique CAA au sous-domaine concerné (généralement l'apex), puis activez ce vérificateur depuis l'onglet **Vérifications** de ce service. Consultez {{< relref "/pages/checks" >}} pour configurer et planifier les vérifications. Pour que la comparaison produise un verdict, un vérificateur de sonde TLS comme {{< relref "/reference/checkers/dane" >}} (ou le `checker-tls` autonome) doit avoir observé des certificats sur la cible. diff --git a/content/reference/checkers/dane.en.md b/content/reference/checkers/dane.en.md new file mode 100644 index 0000000..b175912 --- /dev/null +++ b/content/reference/checkers/dane.en.md @@ -0,0 +1,48 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: DANE / TLSA +description: "Matches a service's TLSA records against the certificate chain actually presented by each endpoint, per RFC 6698." +weight: 160 +--- + +The **DANE / TLSA** checker verifies that the `TLSA` records published for a service correctly pin the TLS certificate that the matching endpoint actually presents. DANE (DNS-based Authentication of Named Entities) lets a domain bind a certificate or public key to a name through DNS, secured by DNSSEC; this checker confirms the binding holds. + +This is a **service-level** checker: it runs on a `TLSAs` service. It groups the declared TLSA records by `(port, proto, base)`, publishes one TLS endpoint discovery entry per endpoint so `checker-tls` probes it, then matches each TLSA against the observed certificate chain following RFC 6698. + +## What it checks + +| Rule | What it verifies / flags | Severity | +|------|--------------------------|----------| +| `dane.has_records` | At least one TLSA record is declared on the service. | — | +| `dane.dnssec_validated` | The TLSA records were fetched via a DNSSEC-validating resolver (AD bit set). | — | +| `dane.probe_available` | A TLS probe is available for every DANE endpoint so the chain can be compared. | — | +| `dane.handshake_ok` | The TLS handshake succeeds on every DANE endpoint. | — | +| `dane.records_match_chain` | At least one TLSA record matches the certificate chain presented by each endpoint. | — | +| `dane.pkix_chain_valid` | When usages 0 or 1 are published, the chain also validates against system trust roots. | — | +| `dane.usage_coherent` | Flags TLSA records whose declared usage does not match the chain slot they actually hash (e.g. usage 3 matching an intermediate). | — | + +### How the TLSA fields are interpreted + +- **Usage 0 (PKIX-TA) / 1 (PKIX-EE)** — the TLSA must match *and* the chain must validate against the public PKIX trust roots. +- **Usage 2 (DANE-TA) / 3 (DANE-EE)** — the TLSA itself acts as the trust anchor; PKIX validity is informational. +- **Selector** 0 (full certificate) or 1 (Subject Public Key Info), and **matching type** 0 (full) / 1 (SHA-256) / 2 (SHA-512), are matched against the chain slot implied by the usage. + +{{% notice style="info" title="DANE relies on DNSSEC" %}} +DANE is only trustworthy when the TLSA records are served from a DNSSEC-signed zone and validated by the resolver. The `dane.dnssec_validated` rule checks that the records arrived with the AD (Authenticated Data) bit set; without DNSSEC, a TLSA record could be forged and the whole binding is meaningless. +{{% /notice %}} + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Probe timeout (ms) | Forwarded to `checker-tls` as the per-endpoint TLS probe timeout. | `checker-tls` default | +| STARTTLS override | A map keyed by `"/"` overriding the STARTTLS application used when probing. Common STARTTLS ports (25, 110, 143, 389, 587, 5222, 5269) are auto-mapped; set this only for non-standard ports. | (auto) | + +The domain, subdomain and TLSAs service are filled in automatically. + +## In happyDomain + +Add the TLSA service to the subdomain, then enable this checker from that service's **Checks** tab. See {{< relref "/pages/checks" >}} for configuring and scheduling checks. The checker publishes its endpoints for `checker-tls` to probe, so allow a probe cycle before the first match result appears. + +Related checker: {{< relref "/reference/checkers/caa" >}} verifies, on the same certificates, that the issuing CA was authorized by the domain's CAA policy. diff --git a/content/reference/checkers/dane.fr.md b/content/reference/checkers/dane.fr.md new file mode 100644 index 0000000..0f5b8bd --- /dev/null +++ b/content/reference/checkers/dane.fr.md @@ -0,0 +1,48 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: DANE / TLSA +description: "Compare les enregistrements TLSA d'un service à la chaîne de certificats réellement présentée par chaque point d'accès, selon la RFC 6698." +weight: 160 +--- + +Le vérificateur **DANE / TLSA** vérifie que les enregistrements `TLSA` publiés pour un service épinglent correctement le certificat TLS que le point d'accès correspondant présente réellement. DANE (DNS-based Authentication of Named Entities) permet à un domaine de lier un certificat ou une clé publique à un nom via le DNS, sécurisé par DNSSEC ; ce vérificateur confirme que la liaison tient. + +Il s'agit d'un vérificateur de **niveau service** : il s'exécute sur un service `TLSAs`. Il regroupe les enregistrements TLSA déclarés par `(port, proto, base)`, publie une entrée de découverte de point d'accès TLS par point d'accès afin que `checker-tls` le sonde, puis compare chaque TLSA à la chaîne de certificats observée selon la RFC 6698. + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié ou signalé | Sévérité | +|-------|-------------------------------|----------| +| `dane.has_records` | Au moins un enregistrement TLSA est déclaré sur le service. | variable | +| `dane.dnssec_validated` | Les enregistrements TLSA ont été récupérés via un résolveur validant DNSSEC (bit AD positionné). | variable | +| `dane.probe_available` | Une sonde TLS est disponible pour chaque point d'accès DANE afin de comparer la chaîne. | variable | +| `dane.handshake_ok` | La poignée de main TLS réussit sur chaque point d'accès DANE. | variable | +| `dane.records_match_chain` | Au moins un enregistrement TLSA correspond à la chaîne de certificats présentée par chaque point d'accès. | variable | +| `dane.pkix_chain_valid` | Lorsque les usages 0 ou 1 sont publiés, la chaîne se valide aussi face aux racines de confiance du système. | variable | +| `dane.usage_coherent` | Signale les TLSA dont l'usage déclaré ne correspond pas à l'emplacement de chaîne qu'ils hachent réellement (par exemple un usage 3 correspondant à un intermédiaire). | variable | + +### Interprétation des champs TLSA + +- **Usage 0 (PKIX-TA) / 1 (PKIX-EE)** : le TLSA doit correspondre *et* la chaîne doit se valider face aux racines de confiance PKIX publiques. +- **Usage 2 (DANE-TA) / 3 (DANE-EE)** : le TLSA fait lui-même office d'ancre de confiance ; la validité PKIX est informative. +- Le **sélecteur** 0 (certificat complet) ou 1 (Subject Public Key Info), et le **type de correspondance** 0 (complet) / 1 (SHA-256) / 2 (SHA-512), sont comparés à l'emplacement de chaîne impliqué par l'usage. + +{{% notice style="info" title="DANE repose sur DNSSEC" %}} +DANE n'est digne de confiance que si les enregistrements TLSA proviennent d'une zone signée DNSSEC et sont validés par le résolveur. La règle `dane.dnssec_validated` vérifie que les enregistrements sont arrivés avec le bit AD (Authenticated Data) positionné ; sans DNSSEC, un enregistrement TLSA pourrait être falsifié et toute la liaison perd son sens. +{{% /notice %}} + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Délai de sonde (ms) | Transmis à `checker-tls` comme délai d'expiration de la sonde TLS par point d'accès. | défaut de `checker-tls` | +| Surcharge STARTTLS | Une table indexée par `"/"` surchargeant l'application STARTTLS utilisée lors de la sonde. Les ports STARTTLS courants (25, 110, 143, 389, 587, 5222, 5269) sont associés automatiquement ; ne renseignez ceci que pour des ports non standard. | (auto) | + +Le domaine, le sous-domaine et le service TLSAs sont renseignés automatiquement. + +## Dans happyDomain + +Ajoutez le service TLSA au sous-domaine, puis activez ce vérificateur depuis l'onglet **Vérifications** de ce service. Consultez {{< relref "/pages/checks" >}} pour configurer et planifier les vérifications. Le vérificateur publie ses points d'accès pour que `checker-tls` les sonde : laissez donc passer un cycle de sonde avant l'apparition du premier résultat de correspondance. + +Vérificateur apparenté : {{< relref "/reference/checkers/caa" >}} vérifie, sur les mêmes certificats, que l'autorité émettrice était bien autorisée par la politique CAA du domaine. diff --git a/content/reference/checkers/dangling.en.md b/content/reference/checkers/dangling.en.md new file mode 100644 index 0000000..b05ca15 --- /dev/null +++ b/content/reference/checkers/dangling.en.md @@ -0,0 +1,42 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Dangling records +description: "Scans a zone for CNAME/MX/SRV/NS records whose targets resolve to NXDOMAIN or whose external domain has expired and could be re-registered." +weight: 140 +--- + +The **Dangling subdomains** checker scans a zone for pointer records (`CNAME`, `MX`, `SRV`, `NS`) whose targets have gone stale: they resolve to NXDOMAIN, or their external registrable domain has expired, is in `pendingDelete`, or was recently re-registered. This is the subdomain-takeover attack class popularised in 2017, where institutions ended up serving hostile content from CNAMEs pointing at decommissioned third-party services after attackers re-registered the lapsed targets. + +This is a **zone-level** checker: it needs the full zone content and runs a single pass over it, consolidating findings by owner rather than producing one result per record. + +## What it checks + +The checker walks every service in the working zone and extracts pointer records from `CNAME`, special CNAME, `MX`, unknown `SRV` and orphan (bare `NS`/`CNAME`/`MX`) bodies. For each `(owner, type, target)` triple it classifies the target as in-zone or external (relative to the zone's registrable domain), performs a single time-bounded DNS resolution to detect immediate breakage, and publishes a discovery entry so a companion `domain_expiry` checker can run RDAP/WHOIS on external targets. + +It emits one finding per impacted owner, ranked by descending severity: + +| Signal | Severity | Source | +|--------|----------|--------| +| Target NXDOMAIN | Critical | Local DNS resolution | +| Target SERVFAIL | Warning | Local DNS resolution | +| Target NOERROR with empty answer | Info | Local DNS resolution | +| Registrable domain expired | Critical | `whois` related observation | +| Registrable status `pendingDelete` / `redemptionPeriod` | Critical | `whois` related observation | +| Registrable domain registered within the last 90 days | Warning | `whois` related observation | + +{{% notice style="info" title="WHOIS signals need a companion checker" %}} +The DNS-resolution signals (NXDOMAIN, SERVFAIL, empty answer) work on their own. The WHOIS-driven signals (expired, `pendingDelete`, recently registered) only fire when the host's `domain_expiry` checker subscribes to this checker's external-target discovery entries and publishes a per-target `whois` observation. Without that wiring, the checker still works as a DNS-only dangling detector. +{{% /notice %}} + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Skip live DNS resolution | When set, the checker only reports the static structure of pointer records (offline analysis), without resolving targets. | `false` | + +## In happyDomain + +Enable this checker on the domain from the {{< relref "/pages/checks" >}} view; the domain name and zone content are filled in automatically. Because it is zone-scoped, it runs over the whole zone in a single pass. + +Related checkers: {{< relref "/reference/checkers/alias" >}} validates the structure of individual alias chains, and {{< relref "/reference/checkers/domain-expiry" >}} watches your own domains' expiry — the same WHOIS machinery that powers this checker's external-target signals. diff --git a/content/reference/checkers/dangling.fr.md b/content/reference/checkers/dangling.fr.md new file mode 100644 index 0000000..17ea1db --- /dev/null +++ b/content/reference/checkers/dangling.fr.md @@ -0,0 +1,42 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Enregistrements orphelins +description: "Analyse une zone à la recherche d'enregistrements CNAME/MX/SRV/NS dont la cible renvoie NXDOMAIN ou dont le domaine externe a expiré et pourrait être ré-enregistré." +weight: 140 +--- + +Le vérificateur **Sous-domaines orphelins** analyse une zone à la recherche d'enregistrements pointeurs (`CNAME`, `MX`, `SRV`, `NS`) dont les cibles sont devenues obsolètes : elles renvoient NXDOMAIN, ou leur domaine enregistrable externe a expiré, est en `pendingDelete`, ou a été ré-enregistré récemment. C'est la classe d'attaques par prise de contrôle de sous-domaine popularisée en 2017, où des institutions ont fini par servir du contenu hostile depuis des CNAME pointant vers des services tiers désaffectés, après que des attaquants eurent ré-enregistré les cibles libérées. + +Il s'agit d'un vérificateur de **niveau zone** : il nécessite le contenu complet de la zone et la parcourt en une seule passe, consolidant les constats par propriétaire plutôt que de produire un résultat par enregistrement. + +## Ce qui est vérifié + +Le vérificateur parcourt chaque service de la zone de travail et extrait les enregistrements pointeurs des corps `CNAME`, CNAME spécial, `MX`, `SRV` inconnu et orphelin (enregistrements `NS`/`CNAME`/`MX` nus). Pour chaque triplet `(propriétaire, type, cible)`, il classe la cible comme interne ou externe à la zone (par rapport au domaine enregistrable de la zone), effectue une résolution DNS unique et bornée dans le temps pour détecter une rupture immédiate, et publie une entrée de découverte afin qu'un vérificateur `domain_expiry` compagnon puisse lancer une requête RDAP/WHOIS sur les cibles externes. + +Il émet un constat par propriétaire concerné, classé par sévérité décroissante : + +| Signal | Sévérité | Source | +|--------|----------|--------| +| Cible NXDOMAIN | Critique | Résolution DNS locale | +| Cible SERVFAIL | Avertissement | Résolution DNS locale | +| Cible NOERROR avec réponse vide | Info | Résolution DNS locale | +| Domaine enregistrable expiré | Critique | Observation `whois` apparentée | +| Statut enregistrable `pendingDelete` / `redemptionPeriod` | Critique | Observation `whois` apparentée | +| Domaine enregistrable créé au cours des 90 derniers jours | Avertissement | Observation `whois` apparentée | + +{{% notice style="info" title="Les signaux WHOIS nécessitent un vérificateur compagnon" %}} +Les signaux issus de la résolution DNS (NXDOMAIN, SERVFAIL, réponse vide) fonctionnent seuls. Les signaux issus du WHOIS (expiré, `pendingDelete`, créé récemment) ne se déclenchent que lorsque le vérificateur `domain_expiry` de l'hôte s'abonne aux entrées de découverte de cibles externes de ce vérificateur et publie une observation `whois` par cible. Sans ce câblage, le vérificateur fonctionne tout de même comme un détecteur d'orphelins basé uniquement sur le DNS. +{{% /notice %}} + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Ignorer la résolution DNS en direct | Lorsqu'elle est activée, le vérificateur ne rapporte que la structure statique des enregistrements pointeurs (analyse hors ligne), sans résoudre les cibles. | `false` | + +## Dans happyDomain + +Activez ce vérificateur sur le domaine depuis la vue {{< relref "/pages/checks" >}} ; le nom de domaine et le contenu de la zone sont renseignés automatiquement. Étant de niveau zone, il s'exécute sur l'ensemble de la zone en une seule passe. + +Vérificateurs apparentés : {{< relref "/reference/checkers/alias" >}} valide la structure des chaînes d'alias individuelles, et {{< relref "/reference/checkers/domain-expiry" >}} surveille l'expiration de vos propres domaines, avec la même mécanique WHOIS qui alimente les signaux de cibles externes de ce vérificateur. diff --git a/content/reference/checkers/dav.en.md b/content/reference/checkers/dav.en.md new file mode 100644 index 0000000..6760a7e --- /dev/null +++ b/content/reference/checkers/dav.en.md @@ -0,0 +1,48 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: CalDAV / CardDAV +description: "Discovers and probes a domain's CalDAV and CardDAV servers: well-known/SRV discovery, HTTPS reachability, advertised DAV capabilities, and (with credentials) the authenticated principal, home-set, collections and REPORT flow." +weight: 240 +--- + +The **CalDAV** and **CardDAV** checkers verify that a domain's calendar (RFC 4791) and contacts (RFC 6352) servers are discoverable, reachable, and correctly advertise the WebDAV extensions that clients rely on. They are two distinct checkers sharing the same logic: `caldav` attaches to a *CalDAV* service (`abstract.CalDAV`), `carddav` to a *CardDAV* service (`abstract.CardDAV`). The only behavioural difference is the required DAV capability (`calendar-access` vs `addressbook`) and a CalDAV-only scheduling check. + +Both checkers are **service-level**: they target the corresponding service published on a subdomain and are configured from that service's own **Checks** tab. Discovery follows RFC 6764: the checker resolves a context URL from `/.well-known/{caldav,carddav}` and from `_caldavs._tcp` / `_carddavs._tcp` SRV records (with an optional `path=` TXT hint), then probes that endpoint. + +When no credentials are supplied, only the anonymous phase runs (discovery, transport, OPTIONS). Supplying a username and password unlocks the authenticated phase: principal discovery, home-set, collection enumeration and the REPORT probe. + +{{% notice style="info" title="TLS posture is out of scope" %}} +These checkers confirm only that an HTTPS session can be established to the context URL. Certificate validation (chain, hostname, expiry, ciphers) is deliberately left to the dedicated TLS checker. See {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | Conditions | +|---|---|---| +| `dav_discovery` | A context URL resolves via `/.well-known` or SRV. | **Critical** if no context URL can be resolved. **Warning** when `/.well-known` returns `200` instead of a `301`/`302` redirect (legal but many clients won't follow it). **Info** when the URL was resolved via SRV but `/.well-known` is broken. | +| `dav_transport` | The HTTPS connection to the context URL is reachable. | **Critical** if the connection fails. | +| `dav_options` | An HTTP `OPTIONS` request advertises the required DAV capability (`calendar-access` for CalDAV, `addressbook` for CardDAV) and the `PROPFIND`/`REPORT` methods. | **Critical** if OPTIONS fails or the capability is missing. **Warning** if the `Allow` header lacks `PROPFIND` or `REPORT`. | +| `dav_principal` | The current-user principal URL is discovered via authenticated `PROPFIND`. | **Critical** on failure. **Unknown** when no credentials are supplied (phase skipped). | +| `dav_home_set` | The calendar/addressbook home-set is discovered from the principal. | **Critical** on failure. **Unknown** when skipped. | +| `dav_collections` | Calendar/addressbook collections enumerate and expose their properties (supported component set, supported address data, display name…). | **Critical** on failure. **Warning** if the home-set is empty. **Unknown** when skipped. | +| `dav_report` | The server accepts a minimal `calendar-query` / `addressbook-query` `REPORT` against the first collection. | **Critical** on failure. **Warning** if the query returns an unexpected response. **Unknown** when skipped. | +| `caldav_scheduling` | *(CalDAV only)* When `calendar-schedule` is advertised, the principal exposes `schedule-inbox-URL` and `schedule-outbox-URL`. | **Warning** if advertised but the URLs are missing or the probe fails. **Info** when scheduling is not advertised. **Unknown** when skipped. | + +The HTML report surfaces the most common misconfigurations as callouts: `/.well-known` returning `200`, no SRV and no well-known (service unreachable), a plaintext SRV record without a secure counterpart, a server not advertising the required DAV class, and the authenticated phase being skipped for lack of credentials. + +## Options + +Both checkers accept the same options. + +| Option | Meaning | Default | +|---|---|---| +| Username | Optional. Supplying credentials unlocks the authenticated checks (principal, home-set, collections, REPORT probe). | *(empty)* | +| Password or token | Optional. Paired with the username for HTTP Basic authentication. | *(empty)* | +| Explicit context URL | Optional. Bypasses `/.well-known` and SRV discovery; use for servers with a non-standard layout. | *(empty)* | +| Domain name | The domain to probe (auto-filled from the service scope). | *(auto)* | +| Timeout (seconds) | Per-request HTTP timeout. | `10` | + +## In happyDomain + +Enable the CalDAV or CardDAV checker from the **Checks** tab of a CalDAV or CardDAV service. The domain name is filled in automatically; add credentials only if you want the authenticated collection and REPORT checks to run. See {{< relref "/pages/checks" >}} for the full workflow, and {{< relref "/reference/checkers/tls" >}} for the certificate posture of the same endpoints. diff --git a/content/reference/checkers/dav.fr.md b/content/reference/checkers/dav.fr.md new file mode 100644 index 0000000..51cf53d --- /dev/null +++ b/content/reference/checkers/dav.fr.md @@ -0,0 +1,48 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: CalDAV / CardDAV +description: "Découvre et sonde les serveurs CalDAV et CardDAV d'un domaine : découverte via well-known/SRV, accessibilité HTTPS, capacités DAV annoncées et (avec des identifiants) le parcours authentifié principal, home-set, collections et REPORT." +weight: 240 +--- + +Les vérificateurs **CalDAV** et **CardDAV** vérifient que les serveurs de calendrier (RFC 4791) et de contacts (RFC 6352) d'un domaine sont découvrables, accessibles, et annoncent correctement les extensions WebDAV sur lesquelles s'appuient les clients. Il s'agit de deux vérificateurs distincts partageant la même logique : `caldav` s'attache à un service *CalDAV* (`abstract.CalDAV`), `carddav` à un service *CardDAV* (`abstract.CardDAV`). La seule différence de comportement porte sur la capacité DAV requise (`calendar-access` contre `addressbook`) et sur une vérification de planification propre à CalDAV. + +Les deux vérificateurs sont de **niveau service** : ils ciblent le service correspondant publié sur un sous-domaine et se configurent depuis l'onglet **Vérifications** de ce service. La découverte suit la RFC 6764 : le vérificateur résout une URL de contexte à partir de `/.well-known/{caldav,carddav}` et des enregistrements SRV `_caldavs._tcp` / `_carddavs._tcp` (avec un indice TXT `path=` facultatif), puis sonde ce point d'accès. + +Lorsqu'aucun identifiant n'est fourni, seule la phase anonyme s'exécute (découverte, transport, OPTIONS). Fournir un nom d'utilisateur et un mot de passe déverrouille la phase authentifiée : découverte du principal, home-set, énumération des collections et sonde REPORT. + +{{% notice style="info" title="La posture TLS est hors périmètre" %}} +Ces vérificateurs confirment uniquement qu'une session HTTPS peut être établie vers l'URL de contexte. La validation du certificat (chaîne, nom d'hôte, expiration, algorithmes) est volontairement laissée au vérificateur TLS dédié. Consultez {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | Conditions | +|---|---|---| +| `dav_discovery` | Une URL de contexte se résout via `/.well-known` ou SRV. | **Critique** si aucune URL de contexte ne peut être résolue. **Avertissement** quand `/.well-known` renvoie `200` au lieu d'une redirection `301`/`302` (légal mais beaucoup de clients ne la suivent pas). **Info** quand l'URL a été résolue via SRV mais que `/.well-known` est cassé. | +| `dav_transport` | La connexion HTTPS vers l'URL de contexte est accessible. | **Critique** si la connexion échoue. | +| `dav_options` | Une requête HTTP `OPTIONS` annonce la capacité DAV requise (`calendar-access` pour CalDAV, `addressbook` pour CardDAV) et les méthodes `PROPFIND`/`REPORT`. | **Critique** si OPTIONS échoue ou si la capacité manque. **Avertissement** si l'en-tête `Allow` ne contient pas `PROPFIND` ou `REPORT`. | +| `dav_principal` | L'URL du principal de l'utilisateur courant est découverte via un `PROPFIND` authentifié. | **Critique** en cas d'échec. **Inconnu** si aucun identifiant n'est fourni (phase ignorée). | +| `dav_home_set` | Le home-set calendrier/carnet d'adresses est découvert depuis le principal. | **Critique** en cas d'échec. **Inconnu** si ignoré. | +| `dav_collections` | Les collections calendrier/carnet d'adresses s'énumèrent et exposent leurs propriétés (jeu de composants pris en charge, données d'adresse prises en charge, nom affiché...). | **Critique** en cas d'échec. **Avertissement** si le home-set est vide. **Inconnu** si ignoré. | +| `dav_report` | Le serveur accepte une requête `REPORT` minimale (`calendar-query` / `addressbook-query`) sur la première collection. | **Critique** en cas d'échec. **Avertissement** si la requête renvoie une réponse inattendue. **Inconnu** si ignoré. | +| `caldav_scheduling` | *(CalDAV uniquement)* Lorsque `calendar-schedule` est annoncé, le principal expose `schedule-inbox-URL` et `schedule-outbox-URL`. | **Avertissement** si annoncé mais que les URL manquent ou que la sonde échoue. **Info** quand la planification n'est pas annoncée. **Inconnu** si ignoré. | + +Le rapport HTML met en avant les erreurs de configuration les plus courantes sous forme d'encarts : `/.well-known` renvoyant `200`, absence de SRV et de well-known (service inaccessible), un enregistrement SRV en clair sans équivalent sécurisé, un serveur n'annonçant pas la classe DAV requise, et la phase authentifiée ignorée faute d'identifiants. + +## Options + +Les deux vérificateurs acceptent les mêmes options. + +| Option | Signification | Défaut | +|---|---|---| +| Nom d'utilisateur | Facultatif. Fournir des identifiants déverrouille les vérifications authentifiées (principal, home-set, collections, sonde REPORT). | *(vide)* | +| Mot de passe ou jeton | Facultatif. Associé au nom d'utilisateur pour l'authentification HTTP Basic. | *(vide)* | +| URL de contexte explicite | Facultatif. Contourne la découverte `/.well-known` et SRV ; à utiliser pour les serveurs à la disposition non standard. | *(vide)* | +| Nom de domaine | Le domaine à sonder (renseigné automatiquement depuis la portée du service). | *(auto)* | +| Délai d'attente (secondes) | Délai d'attente HTTP par requête. | `10` | + +## Dans happyDomain + +Activez le vérificateur CalDAV ou CardDAV depuis l'onglet **Vérifications** d'un service CalDAV ou CardDAV. Le nom de domaine est renseigné automatiquement ; ajoutez des identifiants uniquement si vous souhaitez exécuter les vérifications authentifiées des collections et de REPORT. Consultez {{< relref "/pages/checks" >}} pour le fonctionnement complet, et {{< relref "/reference/checkers/tls" >}} pour la posture des certificats de ces mêmes points d'accès. diff --git a/content/reference/checkers/delegation.en.md b/content/reference/checkers/delegation.en.md new file mode 100644 index 0000000..abb098d --- /dev/null +++ b/content/reference/checkers/delegation.en.md @@ -0,0 +1,69 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Delegation +description: "Audits a zone's delegation: NS consistency between parent and child, glue correctness, DS/DNSKEY hand-off, reachability and authoritativeness of each delegated server." +weight: 70 +--- + +The **Delegation** checker audits how a zone is delegated from its parent. It cross-examines the parent zone and the child name servers to confirm that the hand-off is coherent: that the parent and child agree on the `NS` set, that glue records are correct, that the DNSSEC `DS`/`DNSKEY` chain lines up, and that every delegated server is reachable and actually authoritative for the zone. + +This checker is **service-level**: it targets a *Delegation* service (`abstract.Delegation`) published on a subdomain, and is configured from that service's own **Checks** tab. + +## What it checks + +Each rule emits a stable finding `code` so results can be matched deterministically. + +### Name-server count and parent discovery + +| Finding code | What it verifies | +|---|---| +| `delegation_too_few_ns` | The zone declares at least `minNameServers` `NS` records (RFC 1034 recommends ≥ 2). | +| `delegation_no_parent_ns` | The parent zone and its authoritative name servers can be discovered. | +| `delegation_parent_query_failed` | Each parent name server answers the `NS` query for the delegated zone. | +| `delegation_parent_tcp_failed` | Each parent name server is reachable over TCP (RFC 7766). | + +### NS and glue at the parent + +| Finding code | What it verifies | +|---|---| +| `delegation_ns_mismatch` | The `NS` RRset at the parent matches the `NS` set declared by the service. | +| `delegation_missing_glue` | In-bailiwick name servers have glue (`A`/`AAAA`) at the parent. | +| `delegation_unnecessary_glue` | Out-of-bailiwick name servers do not carry unnecessary glue. | + +### DNSSEC hand-off + +| Finding code | What it verifies | +|---|---| +| `delegation_ds_query_failed` | The `DS` RRset can be queried from the parent name servers. | +| `delegation_ds_mismatch` | The `DS` RRset at the parent matches the `DS` set declared by the service. | +| `delegation_ds_missing` | `DS` records are present at the parent when DNSSEC is expected (gated by `requireDS`). | +| `delegation_ds_rrsig_invalid` | The `DS` RRset is covered by a valid `RRSIG` at the parent. | +| `delegation_dnskey_query_failed` | The `DNSKEY` RRset can be queried from each child name server. | +| `delegation_dnskey_no_match` | At least one child `DNSKEY` matches a `DS` digest published at the parent. | + +### Child reachability and authoritativeness + +| Finding code | What it verifies | +|---|---| +| `delegation_ns_unresolvable` | Each declared name server name resolves to at least one address. | +| `delegation_unreachable` | Each child name server answers DNS queries on its advertised addresses. | +| `delegation_lame` | Each child name server is authoritative for the zone (no lame delegation). | +| `delegation_no_authoritative_answer` | Each child name server sets the AA flag in its answers for the zone. | +| `delegation_tcp_failed` | Each child name server answers over TCP (gated by `requireTCP`). | +| `delegation_soa_serial_drift` | The `SOA` serial is consistent across all child name servers. | +| `delegation_ns_drift` | The `NS` RRset returned by each child matches the `NS` RRset at the parent. | +| `delegation_glue_mismatch` | Glue addresses at the child match those at the parent (gated by `allowGlueMismatch`). | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| `requireDS` | When enabled, missing `DS` records at the parent are treated as critical (otherwise informational). | `false` | +| `requireTCP` | When enabled, name servers that fail to answer over TCP are reported as critical (otherwise warning). | `true` | +| `minNameServers` | Below this count, the delegation is reported as a warning (RFC 1034 recommends at least 2). | `2` | +| `allowGlueMismatch` | When disabled, glue/address mismatches between parent and child are reported as critical. | `false` | + +## In happyDomain + +Enable the Delegation checker from the **Checks** tab of a Delegation service. See {{< relref "/pages/checks" >}} for the full workflow. For consistency *between* the authoritative servers of the apex itself (rather than the parent/child hand-off), see {{< relref "/reference/checkers/authoritative-consistency" >}}; for the DNSSEC hygiene of the signed zone, see {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/checkers/delegation.fr.md b/content/reference/checkers/delegation.fr.md new file mode 100644 index 0000000..4760002 --- /dev/null +++ b/content/reference/checkers/delegation.fr.md @@ -0,0 +1,69 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Délégation +description: "Audite la délégation d'une zone : cohérence des NS entre parent et enfant, exactitude des glue, passage de relais DS/DNSKEY, joignabilité et autorité de chaque serveur délégué." +weight: 70 +--- + +Le vérificateur **Délégation** audite la façon dont une zone est déléguée depuis son parent. Il confronte la zone parente et les serveurs de noms enfants pour confirmer la cohérence du passage de relais : le parent et l'enfant s'accordent sur l'ensemble des `NS`, les enregistrements de glue sont corrects, la chaîne DNSSEC `DS`/`DNSKEY` est alignée, et chaque serveur délégué est joignable et réellement faisant autorité pour la zone. + +Ce vérificateur s'applique au niveau du **service** : il cible un service de délégation (`abstract.Delegation`) publié sur un sous-domaine, et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +Chaque règle émet un `code` de constat stable, afin que les résultats puissent être appariés de façon déterministe. + +### Nombre de serveurs de noms et découverte du parent + +| Code de constat | Ce qui est vérifié | +|---|---| +| `delegation_too_few_ns` | La zone déclare au moins `minNameServers` enregistrements `NS` (la RFC 1034 recommande ≥ 2). | +| `delegation_no_parent_ns` | La zone parente et ses serveurs faisant autorité peuvent être découverts. | +| `delegation_parent_query_failed` | Chaque serveur de noms parent répond à la requête `NS` pour la zone déléguée. | +| `delegation_parent_tcp_failed` | Chaque serveur de noms parent est joignable en TCP (RFC 7766). | + +### NS et glue au parent + +| Code de constat | Ce qui est vérifié | +|---|---| +| `delegation_ns_mismatch` | Le RRset `NS` au parent correspond à l'ensemble `NS` déclaré par le service. | +| `delegation_missing_glue` | Les serveurs de noms dans le bailliage disposent de glue (`A`/`AAAA`) au parent. | +| `delegation_unnecessary_glue` | Les serveurs de noms hors bailliage ne portent pas de glue superflue. | + +### Passage de relais DNSSEC + +| Code de constat | Ce qui est vérifié | +|---|---| +| `delegation_ds_query_failed` | Le RRset `DS` peut être interrogé auprès des serveurs de noms parents. | +| `delegation_ds_mismatch` | Le RRset `DS` au parent correspond à l'ensemble `DS` déclaré par le service. | +| `delegation_ds_missing` | Des enregistrements `DS` sont présents au parent lorsque DNSSEC est attendu (conditionné par `requireDS`). | +| `delegation_ds_rrsig_invalid` | Le RRset `DS` est couvert par un `RRSIG` valide au parent. | +| `delegation_dnskey_query_failed` | Le RRset `DNSKEY` peut être interrogé auprès de chaque serveur de noms enfant. | +| `delegation_dnskey_no_match` | Au moins un `DNSKEY` enfant correspond à un condensat `DS` publié au parent. | + +### Joignabilité et autorité des serveurs enfants + +| Code de constat | Ce qui est vérifié | +|---|---| +| `delegation_ns_unresolvable` | Chaque nom de serveur déclaré se résout en au moins une adresse. | +| `delegation_unreachable` | Chaque serveur de noms enfant répond aux requêtes DNS sur ses adresses annoncées. | +| `delegation_lame` | Chaque serveur de noms enfant fait autorité pour la zone (pas de délégation boiteuse). | +| `delegation_no_authoritative_answer` | Chaque serveur de noms enfant positionne le drapeau AA dans ses réponses pour la zone. | +| `delegation_tcp_failed` | Chaque serveur de noms enfant répond en TCP (conditionné par `requireTCP`). | +| `delegation_soa_serial_drift` | Le numéro de série `SOA` est cohérent entre tous les serveurs de noms enfants. | +| `delegation_ns_drift` | Le RRset `NS` renvoyé par chaque enfant correspond au RRset `NS` au parent. | +| `delegation_glue_mismatch` | Les adresses de glue chez l'enfant correspondent à celles du parent (conditionné par `allowGlueMismatch`). | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| `requireDS` | Si activé, l'absence de `DS` au parent est traitée comme critique (sinon informative). | `false` | +| `requireTCP` | Si activé, les serveurs de noms qui ne répondent pas en TCP sont signalés comme critiques (sinon en avertissement). | `true` | +| `minNameServers` | En dessous de ce nombre, la délégation est signalée en avertissement (la RFC 1034 recommande au moins 2). | `2` | +| `allowGlueMismatch` | Si désactivé, les divergences de glue/adresses entre parent et enfant sont signalées comme critiques. | `false` | + +## Dans happyDomain + +Activez le vérificateur Délégation depuis l'onglet **Vérifications** d'un service de délégation. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet. Pour la cohérence *entre* les serveurs faisant autorité de l'apex lui-même (plutôt que le passage de relais parent/enfant), voyez {{< relref "/reference/checkers/authoritative-consistency" >}} ; pour l'hygiène DNSSEC de la zone signée, voyez {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/checkers/dnssec.en.md b/content/reference/checkers/dnssec.en.md new file mode 100644 index 0000000..8c29c65 --- /dev/null +++ b/content/reference/checkers/dnssec.en.md @@ -0,0 +1,80 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: DNSSEC validation +description: "Audits the operational hygiene of a signed zone: algorithms, key sizes, signature freshness, NSEC/NSEC3 parameters and per-name-server consistency." +weight: 60 +--- + +The **DNSSEC** checker audits the *operational hygiene* of a signed zone. It does not re-validate the cryptographic chain of trust end to end (that work is delegated to a dedicated DNSViz-based checker); instead it focuses on the policy and day-to-day operational aspects of signing: which algorithms and key sizes are in use, whether signatures are fresh and valid, how negative answers are denied (NSEC vs NSEC3), and whether every authoritative server serves a consistent view. + +This checker is **domain-level**: it operates on the zone apex. From a bootstrap recursive resolver it discovers the apex name servers and looks up the parent `DS`, then queries each authoritative server directly. + +## What it checks + +The checker evaluates the following rules. Several of them are governed by the options described further down. + +### Chain and key material + +| Rule | Verifies | Severity | +|---|---|---| +| `dnssec_zone_signed` | The parent advertises a `DS` but the apex serves no `DNSKEY` (a broken signed zone). | Critical | +| `dnssec_dnskey_consistent` | Every authoritative server returns the same `DNSKEY` RRset. | Critical | +| `dnssec_dnskey_query_ok` | Every authoritative server answered the `DNSKEY` query. | Critical | +| `dnssec_ksk_present` | At least one `DNSKEY` carries the SEP bit (a Key Signing Key). | Critical | +| `dnssec_dnskey_count` | Warns when too many `DNSKEY`s are published, inflating responses and amplification potential. | Warning | + +### Algorithms and key strength + +| Rule | Verifies | Severity | +|---|---|---| +| `dnssec_algorithm_allowed` | No `DNSKEY` uses a forbidden algorithm or one outside the allowed list. | Critical | +| `dnssec_algorithm_modern` | Recommends ECDSAP256SHA256 (13) or Ed25519 (15) over RSA. | Warning | +| `dnssec_rsa_keysize` | RSA `DNSKEY`s reach the minimum modulus size. | Critical | + +### Signatures + +| Rule | Verifies | Severity | +|---|---|---| +| `dnssec_rrsig_present_dnskey` | The `DNSKEY` RRset is signed. | Critical | +| `dnssec_rrsig_present_soa` | The `SOA` RRset is signed. | Critical | +| `dnssec_rrsig_validity_window` | Every observed `RRSIG` is currently within its inception/expiration window. | Critical | +| `dnssec_rrsig_freshness` | Pre-emptive alert when `RRSIG`s are close to expiring (catches stuck signers). | Critical | + +### Denial of existence (NSEC / NSEC3) + +| Rule | Verifies | Severity | +|---|---|---| +| `dnssec_denial_uses_nsec3` | Warns when the zone uses bare NSEC, which makes the zone walkable (RFC 5155 / RFC 7129). | Warning | +| `dnssec_nsec3_iterations` | `NSEC3PARAM.Iterations` is at most the configured ceiling (RFC 9276 §3.1 recommends 0). | Critical | +| `dnssec_nsec3_salt_empty` | `NSEC3PARAM.SaltLength` is 0 (RFC 9276 §3.1: a salt buys no measurable protection). | Warning | +| `dnssec_nsec3_optout_only_when_signed_delegations` | Informational note when the OPT-OUT flag is set in a leaf zone. | Info | +| `dnssec_denial_consistent` | Every authoritative server uses the same denial-of-existence scheme. | Warning | + +### TTL hygiene + +| Rule | Verifies | Severity | +|---|---|---| +| `dnssec_dnskey_ttl_min` | Warns when the `DNSKEY` TTL is too short to be useful for caching. | Warning | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| `nsec3IterationsMax` | RFC 9276 §3.1 ceiling on `NSEC3PARAM.Iterations`. Raise only if your signer cannot publish 0 yet. | `0` | +| `nsec3IterationsSeverity` | Severity when iterations exceed the ceiling. Set `crit` to enforce RFC 9276 strictly. | `warn` | +| `signatureFreshness` | Warn when the closest `RRSIG` expires in fewer than this many days. | `7` | +| `signatureFreshnessCrit` | Critical when the closest `RRSIG` expires in fewer than this many days. | `1` | +| `minRSAKeySize` | Minimum acceptable RSA modulus size, in bits. | `2048` | +| `requireSEP` | Require at least one `DNSKEY` with the SEP bit (KSK). | `true` | +| `dnskeyTTLMin` | Minimum `DNSKEY` TTL, in seconds; shorter TTLs hurt cacheability. | `3600` | + +The administrator can also set a bootstrap `resolver` (`host:port`) used to discover the apex name servers and look up the parent `DS`; it defaults to `/etc/resolv.conf`. + +{{% notice style="info" title="What this checker does not do" %}} +The DNSSEC checker does not verify the full cryptographic chain of trust from the root. For that end-to-end validation, use the DNSViz-based checker. This checker complements it by catching policy and operational problems (weak algorithms, expiring signatures, NSEC walkability) that a chain validation alone would not surface. +{{% /notice %}} + +## In happyDomain + +Enable the DNSSEC checker on a domain from its **Checks** view. See {{< relref "/pages/checks" >}} for the full workflow of adding, scheduling and reading checks. For delegation-side `DS`/`DNSKEY` hand-off, see the {{< relref "/reference/checkers/delegation" >}} checker. diff --git a/content/reference/checkers/dnssec.fr.md b/content/reference/checkers/dnssec.fr.md new file mode 100644 index 0000000..933acfd --- /dev/null +++ b/content/reference/checkers/dnssec.fr.md @@ -0,0 +1,80 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Validation DNSSEC +description: "Audite l'hygiène opérationnelle d'une zone signée : algorithmes, taille des clés, fraîcheur des signatures, paramètres NSEC/NSEC3 et cohérence entre serveurs." +weight: 60 +--- + +Le vérificateur **DNSSEC** audite l'*hygiène opérationnelle* d'une zone signée. Il ne revalide pas de bout en bout la chaîne de confiance cryptographique (cette tâche est confiée à un vérificateur dédié fondé sur DNSViz) : il se concentre sur les aspects de politique et d'exploitation au quotidien de la signature, à savoir les algorithmes et tailles de clés utilisés, la validité et la fraîcheur des signatures, le mode de déni d'existence (NSEC ou NSEC3) et la cohérence de la vue servie par chaque serveur faisant autorité. + +Ce vérificateur s'applique au niveau du **domaine** : il opère sur l'apex de la zone. À partir d'un résolveur récursif d'amorçage, il découvre les serveurs de noms de l'apex et interroge le `DS` parent, puis questionne directement chaque serveur faisant autorité. + +## Ce qu'il vérifie + +Le vérificateur évalue les règles suivantes. Plusieurs d'entre elles sont pilotées par les options décrites plus bas. + +### Chaîne et matériel de clés + +| Règle | Vérifie | Sévérité | +|---|---|---| +| `dnssec_zone_signed` | Le parent annonce un `DS` mais l'apex ne sert aucun `DNSKEY` (zone signée cassée). | Critique | +| `dnssec_dnskey_consistent` | Tous les serveurs faisant autorité renvoient le même RRset `DNSKEY`. | Critique | +| `dnssec_dnskey_query_ok` | Tous les serveurs faisant autorité ont répondu à la requête `DNSKEY`. | Critique | +| `dnssec_ksk_present` | Au moins un `DNSKEY` porte le bit SEP (clé de signature de clé, KSK). | Critique | +| `dnssec_dnskey_count` | Avertit lorsque trop de `DNSKEY` sont publiés, ce qui gonfle les réponses et le potentiel d'amplification. | Avertissement | + +### Algorithmes et robustesse des clés + +| Règle | Vérifie | Sévérité | +|---|---|---| +| `dnssec_algorithm_allowed` | Aucun `DNSKEY` n'utilise un algorithme interdit ou hors de la liste autorisée. | Critique | +| `dnssec_algorithm_modern` | Recommande ECDSAP256SHA256 (13) ou Ed25519 (15) plutôt que RSA. | Avertissement | +| `dnssec_rsa_keysize` | Les `DNSKEY` RSA atteignent la taille de module minimale. | Critique | + +### Signatures + +| Règle | Vérifie | Sévérité | +|---|---|---| +| `dnssec_rrsig_present_dnskey` | Le RRset `DNSKEY` est signé. | Critique | +| `dnssec_rrsig_present_soa` | Le RRset `SOA` est signé. | Critique | +| `dnssec_rrsig_validity_window` | Chaque `RRSIG` observé est dans sa fenêtre d'inception/expiration. | Critique | +| `dnssec_rrsig_freshness` | Alerte anticipée lorsque les `RRSIG` approchent de l'expiration (détecte les signeurs bloqués). | Critique | + +### Déni d'existence (NSEC / NSEC3) + +| Règle | Vérifie | Sévérité | +|---|---|---| +| `dnssec_denial_uses_nsec3` | Avertit lorsque la zone utilise NSEC nu, ce qui la rend parcourable (RFC 5155 / RFC 7129). | Avertissement | +| `dnssec_nsec3_iterations` | `NSEC3PARAM.Iterations` ne dépasse pas le plafond configuré (la RFC 9276 §3.1 recommande 0). | Critique | +| `dnssec_nsec3_salt_empty` | `NSEC3PARAM.SaltLength` vaut 0 (RFC 9276 §3.1 : un sel n'apporte aucune protection mesurable). | Avertissement | +| `dnssec_nsec3_optout_only_when_signed_delegations` | Note informative lorsque le drapeau OPT-OUT est positionné dans une zone feuille. | Info | +| `dnssec_denial_consistent` | Tous les serveurs faisant autorité utilisent le même schéma de déni d'existence. | Avertissement | + +### Hygiène des TTL + +| Règle | Vérifie | Sévérité | +|---|---|---| +| `dnssec_dnskey_ttl_min` | Avertit lorsque le TTL des `DNSKEY` est trop court pour être utile au cache. | Avertissement | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| `nsec3IterationsMax` | Plafond RFC 9276 §3.1 sur `NSEC3PARAM.Iterations`. À relever uniquement si votre signeur ne sait pas encore publier 0. | `0` | +| `nsec3IterationsSeverity` | Sévérité lorsque les itérations dépassent le plafond. Mettre `crit` pour appliquer strictement la RFC 9276. | `warn` | +| `signatureFreshness` | Avertit lorsque le `RRSIG` le plus proche expire dans moins de ce nombre de jours. | `7` | +| `signatureFreshnessCrit` | Critique lorsque le `RRSIG` le plus proche expire dans moins de ce nombre de jours. | `1` | +| `minRSAKeySize` | Taille de module RSA minimale acceptable, en bits. | `2048` | +| `requireSEP` | Exige au moins un `DNSKEY` portant le bit SEP (KSK). | `true` | +| `dnskeyTTLMin` | TTL minimal des `DNSKEY`, en secondes ; des TTL plus courts nuisent à la mise en cache. | `3600` | + +L'administrateur peut également définir un résolveur d'amorçage (`resolver`, au format `host:port`) servant à découvrir les serveurs de noms de l'apex et à interroger le `DS` parent ; sa valeur par défaut est `/etc/resolv.conf`. + +{{% notice style="info" title="Ce que ce vérificateur ne fait pas" %}} +Le vérificateur DNSSEC ne vérifie pas l'intégralité de la chaîne de confiance cryptographique depuis la racine. Pour cette validation de bout en bout, utilisez le vérificateur fondé sur DNSViz. Le présent vérificateur le complète en détectant les problèmes de politique et d'exploitation (algorithmes faibles, signatures expirantes, NSEC parcourable) qu'une validation de chaîne seule ne révélerait pas. +{{% /notice %}} + +## Dans happyDomain + +Activez le vérificateur DNSSEC sur un domaine depuis sa vue **Vérifications**. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet de l'ajout, de la planification et de la lecture des vérifications. Pour le passage de relais `DS`/`DNSKEY` côté délégation, voyez le vérificateur {{< relref "/reference/checkers/delegation" >}}. diff --git a/content/reference/checkers/dnsviz.en.md b/content/reference/checkers/dnsviz.en.md new file mode 100644 index 0000000..2aeef53 --- /dev/null +++ b/content/reference/checkers/dnsviz.en.md @@ -0,0 +1,54 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: DNSViz +description: "Run DNSViz against a domain and walk the whole DNSSEC chain from the root down to the leaf, surfacing every error and warning at the exact zone where it occurs." +weight: 340 +--- + +The **DNSViz** checker (named *DNSSEC (DNSViz)* in happyDomain) assesses a domain's DNSSEC validation chain by driving [DNSViz](https://github.com/dnsviz/dnsviz). It analyses the queried name **and every ancestor up to the root**, so a recursive DNSSEC failure can be located at the exact level, and the exact record, where it broke. + +This checker is **domain-level**: it concerns the domain and its delegation chain rather than a single service. + +## How it works + +DNSViz is run externally (a Python tool packaged alongside the checker), and happyDomain delegates collection to that endpoint. For each run it effectively performs: + +``` +dnsviz probe -A . | dnsviz grok -t +``` + +Every link of the chain (root → TLD → intermediates → leaf) is listed explicitly so the full analysis appears in the report. `dnsviz grok` is given a BIND-format DNSKEY trust anchor for the root zone; without it, the root has no parent to chain against and stays classified at the DNS level (`NOERROR`) instead of DNSSEC `SECURE`. + +The output is parsed: per-zone errors and warnings are walked out of the nested record tree and turned into individual states tagged with the JSON path where they were found. A curated catalog of common DNSSEC failures (broken chain, expired RRSIG, DS digest mismatch, deprecated algorithm…) is matched against the findings to drive a "Fix these first" section in the HTML report. + +{{% notice style="info" title="Scope" %}} +This checker reports exactly what DNSViz reports. NSEC/NSEC3 zone-walk hardening and NSEC3PARAM iteration policy (RFC 9276) are out of scope here and handled by the dedicated DNSSEC checker — see {{< relref "/reference/checkers/dnssec" >}}. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | +|---|---| +| `dnsviz_overall_status` | DNSViz status of the queried domain (SECURE / INSECURE / BOGUS / INDETERMINATE). | +| `dnsviz_per_zone_status` | One state per zone in the chain (root, TLD, intermediates, leaf). | +| `dnsviz_zone_errors` | Every error reported by DNSViz, scoped to the zone where it was found. | +| `dnsviz_zone_warnings` | Every warning reported by DNSViz, scoped to the zone where it was found. | +| `dnsviz_common_failures` | Pattern-matches the findings against a catalog of common DNSSEC failures. | + +Statuses map as follows: `SECURE` → OK; `BOGUS` → Critical; `INDETERMINATE` → Warning; `INSECURE`, `NON_EXISTENT` and a plain `NOERROR` (resolves but unsigned) → Info. + +## Options + +| Option | Meaning | Default | +|---|---|---| +| Probe timeout (`probeTimeoutSeconds`, admin) | Hard timeout for the `dnsviz probe` invocation; the recursive walk can be slow on some zones. | 120 | +| Domain name (`domain_name`) | Domain to analyse. | auto-filled | + +The DNSViz runtime itself requires `dnsviz` on the host's `PATH` and a BIND-format root DNSKEY trust anchor file (auto-detected from the system's `dnssec-root` / `dns-root-data` package, or pointed at explicitly). The packaged container image bundles these so the trust anchor is in place out of the box. + +## In happyDomain + +Enable this checker for the domain from the **Checks** view. See {{< relref "/pages/checks" >}} for scheduling and reading checks. + +DNSViz and {{< relref "/reference/checkers/dnssec" >}} are complementary: DNSViz validates the end-to-end chain, while the DNSSEC checker covers NSEC/NSEC3 hardening. A second opinion on the same chain is available from {{< relref "/reference/checkers/zonemaster" >}}. diff --git a/content/reference/checkers/dnsviz.fr.md b/content/reference/checkers/dnsviz.fr.md new file mode 100644 index 0000000..e2dec18 --- /dev/null +++ b/content/reference/checkers/dnsviz.fr.md @@ -0,0 +1,54 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: DNSViz +description: "Lance DNSViz sur un domaine et parcourt toute la chaîne DNSSEC, de la racine jusqu'à la feuille, en faisant remonter chaque erreur et avertissement à la zone exacte où il survient." +weight: 340 +--- + +Le vérificateur **DNSViz** (nommé *DNSSEC (DNSViz)* dans happyDomain) évalue la chaîne de validation DNSSEC d'un domaine en pilotant [DNSViz](https://github.com/dnsviz/dnsviz). Il analyse le nom interrogé **et chacun de ses ancêtres jusqu'à la racine**, de sorte qu'un échec DNSSEC récursif peut être localisé au niveau exact, et à l'enregistrement exact, où il s'est produit. + +Ce vérificateur s'applique au **niveau domaine** : il concerne le domaine et sa chaîne de délégation plutôt qu'un service isolé. + +## Fonctionnement + +DNSViz est exécuté en externe (un outil Python empaqueté avec le vérificateur), et happyDomain délègue la collecte à ce point d'accès. Chaque exécution revient à effectuer : + +``` +dnsviz probe -A . | dnsviz grok -t +``` + +Chaque maillon de la chaîne (racine, TLD, intermédiaires, feuille) est listé explicitement afin que l'analyse complète apparaisse dans le rapport. `dnsviz grok` reçoit une ancre de confiance DNSKEY au format BIND pour la zone racine ; sans elle, la racine n'a pas de parent auquel se rattacher et reste classée au niveau DNS (`NOERROR`) au lieu de `SECURE` au sens DNSSEC. + +La sortie est analysée : les erreurs et avertissements par zone sont extraits de l'arbre d'enregistrements imbriqués et transformés en états individuels, étiquetés du chemin JSON où ils ont été trouvés. Un catalogue d'échecs DNSSEC courants (chaîne rompue, RRSIG expirée, condensat DS incohérent, algorithme déprécié) est confronté aux constats pour alimenter une section « Fix these first » du rapport HTML. + +{{% notice style="info" title="Périmètre" %}} +Ce vérificateur rapporte exactement ce que DNSViz rapporte. Le durcissement contre le parcours de zone NSEC/NSEC3 et la politique d'itérations NSEC3PARAM (RFC 9276) sont hors périmètre ici et traités par le vérificateur DNSSEC dédié : voir {{< relref "/reference/checkers/dnssec" >}}. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | +|---|---| +| `dnsviz_overall_status` | Statut DNSViz du domaine interrogé (SECURE / INSECURE / BOGUS / INDETERMINATE). | +| `dnsviz_per_zone_status` | Un état par zone de la chaîne (racine, TLD, intermédiaires, feuille). | +| `dnsviz_zone_errors` | Chaque erreur rapportée par DNSViz, rattachée à la zone où elle a été trouvée. | +| `dnsviz_zone_warnings` | Chaque avertissement rapporté par DNSViz, rattaché à la zone où il a été trouvé. | +| `dnsviz_common_failures` | Confronte les constats à un catalogue d'échecs DNSSEC courants. | + +Les statuts sont projetés ainsi : `SECURE` vers OK ; `BOGUS` vers Critique ; `INDETERMINATE` vers Avertissement ; `INSECURE`, `NON_EXISTENT` et un simple `NOERROR` (résout mais non signé) vers Info. + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Délai de sondage (`probeTimeoutSeconds`, admin) | Délai maximal pour l'appel à `dnsviz probe` ; le parcours récursif peut être lent sur certaines zones. | 120 | +| Nom de domaine (`domain_name`) | Domaine à analyser. | prérempli | + +L'environnement d'exécution de DNSViz nécessite quant à lui la présence de `dnsviz` dans le `PATH` de l'hôte et un fichier d'ancre de confiance DNSKEY racine au format BIND (détecté automatiquement à partir du paquet système `dnssec-root` / `dns-root-data`, ou indiqué explicitement). L'image conteneur fournie embarque ces éléments, de sorte que l'ancre de confiance est en place d'emblée. + +## Dans happyDomain + +Activez ce vérificateur pour le domaine depuis la vue **Vérifications**. Voir {{< relref "/pages/checks" >}} pour la planification et la lecture des vérifications. + +DNSViz et {{< relref "/reference/checkers/dnssec" >}} sont complémentaires : DNSViz valide la chaîne de bout en bout, tandis que le vérificateur DNSSEC couvre le durcissement NSEC/NSEC3. Un second avis sur la même chaîne est disponible auprès de {{< relref "/reference/checkers/zonemaster" >}}. diff --git a/content/reference/checkers/domain-availability.en.md b/content/reference/checkers/domain-availability.en.md new file mode 100644 index 0000000..ef7c1e7 --- /dev/null +++ b/content/reference/checkers/domain-availability.en.md @@ -0,0 +1,33 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Domain availability +description: "Notifies you when a watched domain name becomes available for registration." +weight: 40 +--- + +The **Domain availability** checker watches a domain name you do *not* own and notifies you the moment it becomes available for registration. It is the counterpart of {{< relref "/reference/checkers/domain-expiry" >}}: instead of protecting a domain you hold, it lets you grab one as soon as it lapses. + +This is a **domain-level** checker: registration status is determined from the registry through a WHOIS/RDAP lookup. A domain is considered available when the registry reports that it does not exist. + +## What it checks + +A single rule, `domain_availability_check`, reports whether the watched domain is still registered or has become free. + +| Status | Condition | +|--------|-----------| +| **Critical** | The domain is now available for registration | +| **OK** | The domain is still registered (the registrar and expiry date are reported when known) | +| **Error** | The availability lookup failed | + +{{% notice style="info" title="Why available is reported as Critical" %}} +The status is intentionally inverted compared with the usual convention. Reporting *Critical* when the domain becomes available makes the registered → available transition cross the notification threshold, so you are alerted exactly once when the domain frees up. +{{% /notice %}} + +## Options + +This checker has no user-tunable options. The watched domain name is supplied automatically. + +## In happyDomain + +Unlike the other domain-level checkers, **Domain availability** is not scheduled on the domains you manage. It is driven by the dedicated availability-watch list. See {{< relref "/pages/domain-availability" >}} for how to add a domain to watch, and {{< relref "/pages/checks" >}} for the general checks workflow. diff --git a/content/reference/checkers/domain-availability.fr.md b/content/reference/checkers/domain-availability.fr.md new file mode 100644 index 0000000..35977d3 --- /dev/null +++ b/content/reference/checkers/domain-availability.fr.md @@ -0,0 +1,33 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Disponibilité du domaine +description: "Vous notifie lorsqu'un nom de domaine surveillé devient disponible à l'enregistrement." +weight: 40 +--- + +Le vérificateur **Disponibilité du domaine** surveille un nom de domaine que vous ne possédez pas et vous notifie dès qu'il devient disponible à l'enregistrement. C'est le pendant de {{< relref "/reference/checkers/domain-expiry" >}} : au lieu de protéger un domaine que vous détenez, il vous permet d'en saisir un dès qu'il se libère. + +Il s'agit d'un vérificateur de **niveau domaine** : l'état d'enregistrement est déterminé auprès du registre via une requête WHOIS/RDAP. Un domaine est considéré comme disponible lorsque le registre indique qu'il n'existe pas. + +## Ce qui est vérifié + +Une seule règle, `domain_availability_check`, indique si le domaine surveillé est toujours enregistré ou s'il s'est libéré. + +| Statut | Condition | +|--------|-----------| +| **Critique** | Le domaine est désormais disponible à l'enregistrement | +| **OK** | Le domaine est toujours enregistré (le bureau d'enregistrement et la date d'expiration sont rapportés lorsqu'ils sont connus) | +| **Erreur** | La requête de disponibilité a échoué | + +{{% notice style="info" title="Pourquoi la disponibilité est rapportée comme Critique" %}} +Le statut est volontairement inversé par rapport à la convention habituelle. Rapporter *Critique* lorsque le domaine devient disponible fait franchir le seuil de notification à la transition enregistré → disponible, de sorte que vous êtes alerté exactement une fois lorsque le domaine se libère. +{{% /notice %}} + +## Options + +Ce vérificateur ne propose aucune option configurable. Le nom de domaine surveillé est fourni automatiquement. + +## Dans happyDomain + +Contrairement aux autres vérificateurs de niveau domaine, **Disponibilité du domaine** n'est pas planifié sur les domaines que vous gérez. Il est piloté par la liste dédiée de surveillance de disponibilité. Consultez {{< relref "/pages/domain-availability" >}} pour savoir comment ajouter un domaine à surveiller, et {{< relref "/pages/checks" >}} pour le fonctionnement général des vérifications. diff --git a/content/reference/checkers/domain-contact.en.md b/content/reference/checkers/domain-contact.en.md new file mode 100644 index 0000000..c945f6a --- /dev/null +++ b/content/reference/checkers/domain-contact.en.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Domain contacts +description: "Verifies that the registered domain contacts (registrant, admin, tech) match the values you expect, with detection of privacy-protected records." +weight: 30 +--- + +The **Domain contacts** checker compares the contact information registered for a domain (registrant, administrative and technical contacts) against the values you expect. An unexpected change to a contact, especially the registrant, can be an early sign of a hijack or of an administrative mistake. + +This is a **domain-level** checker: the contact data is read from the registry through a WHOIS/RDAP lookup. Many registries redact contact fields for privacy; this checker detects redaction and reports it rather than treating it as a mismatch. + +## What it checks + +A single rule, `domain_contact_check`, evaluates each contact role you selected and emits one result per role. + +| Status | Condition | +|--------|-----------| +| **OK** | The role's contact matches every expected value provided | +| **Warning** | A field does not match the expected value, or the role is missing from the record | +| **Info** | The contact is privacy-protected (redacted) so it cannot be compared | +| **Unknown** | No expected value is configured, or no role is selected (nothing to check) | +| **Error** | The WHOIS/RDAP lookup failed | + +Comparisons are case-insensitive and exact. Redaction is detected from common markers in the contact fields such as *redacted*, *privacy*, *withheld*, *not disclosed*, *data protected*, *contact privacy* and *whoisguard*. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Expected registrant name | If set, the configured roles must report this exact name (case-insensitive). | *(empty)* | +| Expected organization | If set, the configured roles must report this exact organization (case-insensitive). | *(empty)* | +| Expected email | If set, the configured roles must report this exact email (case-insensitive). | *(empty)* | +| Contact roles to check | Comma-separated list of roles among `registrant`, `admin`, `tech`. | `registrant` | + +{{% notice style="info" title="At least one expected value is required" %}} +If none of the expected name, organization or email is set, the checker has nothing to compare and reports an *Unknown* status. Set at least one expected value for the check to be meaningful. +{{% /notice %}} + +## In happyDomain + +Enable this checker from the domain's **Checks** view; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The domain name is filled in automatically. + +This checker complements {{< relref "/reference/checkers/domain-expiry" >}} and {{< relref "/reference/checkers/domain-lock" >}}, which together keep the registration of a domain under watch. diff --git a/content/reference/checkers/domain-contact.fr.md b/content/reference/checkers/domain-contact.fr.md new file mode 100644 index 0000000..220892f --- /dev/null +++ b/content/reference/checkers/domain-contact.fr.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Contacts du domaine +description: "Vérifie que les contacts enregistrés du domaine (titulaire, administratif, technique) correspondent aux valeurs attendues, avec détection des enregistrements protégés par confidentialité." +weight: 30 +--- + +Le vérificateur **Contacts du domaine** compare les informations de contact enregistrées pour un domaine (contacts titulaire, administratif et technique) aux valeurs que vous attendez. Une modification inattendue d'un contact, en particulier le titulaire, peut être un signe précoce de détournement ou d'une erreur administrative. + +Il s'agit d'un vérificateur de **niveau domaine** : les données de contact sont lues auprès du registre via une requête WHOIS/RDAP. De nombreux registres masquent les champs de contact pour des raisons de confidentialité ; ce vérificateur détecte ce masquage et le signale au lieu de le traiter comme une divergence. + +## Ce qui est vérifié + +Une seule règle, `domain_contact_check`, évalue chaque rôle de contact sélectionné et émet un résultat par rôle. + +| Statut | Condition | +|--------|-----------| +| **OK** | Le contact du rôle correspond à chaque valeur attendue fournie | +| **Avertissement** | Un champ ne correspond pas à la valeur attendue, ou le rôle est absent de l'enregistrement | +| **Info** | Le contact est protégé par confidentialité (masqué) et ne peut donc pas être comparé | +| **Inconnu** | Aucune valeur attendue n'est configurée, ou aucun rôle n'est sélectionné (rien à vérifier) | +| **Erreur** | La requête WHOIS/RDAP a échoué | + +Les comparaisons sont exactes et insensibles à la casse. Le masquage est détecté à partir de marqueurs courants dans les champs de contact comme *redacted*, *privacy*, *withheld*, *not disclosed*, *data protected*, *contact privacy* et *whoisguard*. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Nom du titulaire attendu | Si renseigné, les rôles configurés doivent rapporter ce nom exact (insensible à la casse). | *(vide)* | +| Organisation attendue | Si renseignée, les rôles configurés doivent rapporter cette organisation exacte (insensible à la casse). | *(vide)* | +| Adresse e-mail attendue | Si renseignée, les rôles configurés doivent rapporter cette adresse exacte (insensible à la casse). | *(vide)* | +| Rôles de contact à vérifier | Liste de rôles séparés par des virgules parmi `registrant`, `admin`, `tech`. | `registrant` | + +{{% notice style="info" title="Au moins une valeur attendue est nécessaire" %}} +Si ni le nom, ni l'organisation, ni l'adresse e-mail attendus ne sont renseignés, le vérificateur n'a rien à comparer et rapporte un statut *Inconnu*. Renseignez au moins une valeur attendue pour que la vérification ait du sens. +{{% /notice %}} + +## Dans happyDomain + +Activez ce vérificateur depuis la vue **Vérifications** du domaine ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. Le nom de domaine est renseigné automatiquement. + +Ce vérificateur complète {{< relref "/reference/checkers/domain-expiry" >}} et {{< relref "/reference/checkers/domain-lock" >}}, qui ensemble gardent l'enregistrement d'un domaine sous surveillance. diff --git a/content/reference/checkers/domain-expiry.en.md b/content/reference/checkers/domain-expiry.en.md new file mode 100644 index 0000000..3aa9559 --- /dev/null +++ b/content/reference/checkers/domain-expiry.en.md @@ -0,0 +1,43 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Domain expiry +description: "Warns when a domain name is approaching its registration expiry date." +weight: 10 +--- + +The **Domain expiry** checker watches the registration expiry date of a domain name and warns you before it lapses. Letting a domain expire can mean losing it to another registrant, so this is one of the most important domain-level checks. + +This is a **domain-level** checker: it concerns the domain registration itself, not its DNS records. The expiry date is obtained from the registry through a WHOIS/RDAP lookup, together with the registrar name. + +## What it checks + +A single rule, `domain_expiry_check`, compares the number of days remaining until expiry against two thresholds and reports the corresponding status. + +| Status | Condition | +|--------|-----------| +| **Critical** | Days remaining ≤ critical threshold | +| **Warning** | Days remaining ≤ warning threshold (but above critical) | +| **OK** | Days remaining above the warning threshold | +| **Error** | The WHOIS/RDAP lookup failed or no expiry date is available | + +The message always reports how many days remain until expiry, regardless of status. + +The checker also exposes a metric, `domain_expiry_days_remaining`, labelled with the registrar, so the time left can be tracked over time. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Warning threshold (days) | Days before expiry at which a warning is raised. Must be positive. | 30 | +| Critical threshold (days) | Days before expiry at which a critical alert is raised. Must be positive. | 7 | + +{{% notice style="info" title="Critical must be lower than warning" %}} +The critical threshold must be strictly smaller than the warning threshold. happyDomain rejects a configuration where `critical_days` is greater than or equal to `warning_days`. +{{% /notice %}} + +## In happyDomain + +Enable this checker from the domain's **Checks** view; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The domain name is filled in automatically. + +For the inverse situation, watching a domain you do *not* yet own so you can register it once it lapses, see the {{< relref "/reference/checkers/domain-availability" >}} checker and {{< relref "/pages/domain-availability" >}}. Related domain-level checkers include {{< relref "/reference/checkers/domain-lock" >}} and {{< relref "/reference/checkers/domain-contact" >}}. diff --git a/content/reference/checkers/domain-expiry.fr.md b/content/reference/checkers/domain-expiry.fr.md new file mode 100644 index 0000000..c858e3a --- /dev/null +++ b/content/reference/checkers/domain-expiry.fr.md @@ -0,0 +1,43 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Expiration du domaine +description: "Avertit lorsqu'un nom de domaine approche de sa date d'expiration." +weight: 10 +--- + +Le vérificateur **Expiration du domaine** surveille la date d'expiration de l'enregistrement d'un nom de domaine et vous avertit avant qu'elle ne soit dépassée. Laisser un domaine expirer peut conduire à le perdre au profit d'un autre titulaire : c'est l'une des vérifications les plus importantes au niveau du domaine. + +Il s'agit d'un vérificateur de **niveau domaine** : il concerne l'enregistrement du domaine lui-même, et non ses enregistrements DNS. La date d'expiration est obtenue auprès du registre via une requête WHOIS/RDAP, en même temps que le nom du bureau d'enregistrement. + +## Ce qui est vérifié + +Une seule règle, `domain_expiry_check`, compare le nombre de jours restant avant l'expiration à deux seuils et rapporte le statut correspondant. + +| Statut | Condition | +|--------|-----------| +| **Critique** | Jours restants ≤ seuil critique | +| **Avertissement** | Jours restants ≤ seuil d'avertissement (mais au-dessus du critique) | +| **OK** | Jours restants au-dessus du seuil d'avertissement | +| **Erreur** | La requête WHOIS/RDAP a échoué ou aucune date d'expiration n'est disponible | + +Le message indique toujours le nombre de jours restant avant l'expiration, quel que soit le statut. + +Le vérificateur expose également une métrique, `domain_expiry_days_remaining`, étiquetée avec le bureau d'enregistrement, afin de suivre l'évolution du temps restant. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Seuil d'avertissement (jours) | Nombre de jours avant l'expiration déclenchant un avertissement. Doit être positif. | 30 | +| Seuil critique (jours) | Nombre de jours avant l'expiration déclenchant une alerte critique. Doit être positif. | 7 | + +{{% notice style="info" title="Le critique doit être inférieur à l'avertissement" %}} +Le seuil critique doit être strictement inférieur au seuil d'avertissement. happyDomain refuse une configuration où `critical_days` est supérieur ou égal à `warning_days`. +{{% /notice %}} + +## Dans happyDomain + +Activez ce vérificateur depuis la vue **Vérifications** du domaine ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. Le nom de domaine est renseigné automatiquement. + +Pour la situation inverse, surveiller un domaine que vous ne possédez pas encore afin de l'enregistrer dès qu'il se libère, consultez le vérificateur {{< relref "/reference/checkers/domain-availability" >}} et {{< relref "/pages/domain-availability" >}}. Les vérificateurs de niveau domaine apparentés incluent {{< relref "/reference/checkers/domain-lock" >}} et {{< relref "/reference/checkers/domain-contact" >}}. diff --git a/content/reference/checkers/domain-lock.en.md b/content/reference/checkers/domain-lock.en.md new file mode 100644 index 0000000..f08793f --- /dev/null +++ b/content/reference/checkers/domain-lock.en.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Domain transfer lock +description: "Verifies that a domain carries the expected EPP lock statuses that protect it against unauthorized transfers or changes." +weight: 20 +--- + +The **Domain transfer lock** checker verifies that a domain carries the EPP status codes that protect it against unauthorized transfers, updates or deletions. A locked domain (for example one bearing `clientTransferProhibited`) cannot be transferred away without first removing the lock, which is a key defence against domain hijacking. + +This is a **domain-level** checker: the status codes are read from the registry through a WHOIS/RDAP lookup, not from the zone's DNS records. + +## What it checks + +A single rule, `domain_lock_check`, compares the EPP status codes reported by the registry against the list of statuses you require. + +| Status | Condition | +|--------|-----------| +| **OK** | Every required status is present on the domain | +| **Critical** | One or more required statuses are missing (the missing codes are listed) | +| **Unknown** | No required status is configured (nothing to check) | +| **Error** | The WHOIS/RDAP lookup failed | + +Comparison is tolerant of formatting: spaces, dashes and underscores are ignored and case does not matter, so `clientTransferProhibited`, `client-transfer-prohibited` and `client transfer prohibited` are all treated as equal. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Required lock statuses | Comma-separated list of EPP status codes that must be present on the domain (for example `clientTransferProhibited`, `clientUpdateProhibited`, `clientDeleteProhibited`). At least one code must be supplied. | `clientTransferProhibited` | + +## In happyDomain + +Enable this checker from the domain's **Checks** view; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The domain name is filled in automatically. + +This checker pairs naturally with {{< relref "/reference/checkers/domain-expiry" >}} and {{< relref "/reference/checkers/domain-contact" >}} to keep the registration of a domain under control. diff --git a/content/reference/checkers/domain-lock.fr.md b/content/reference/checkers/domain-lock.fr.md new file mode 100644 index 0000000..b218bf6 --- /dev/null +++ b/content/reference/checkers/domain-lock.fr.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Verrou de transfert du domaine +description: "Vérifie qu'un domaine porte les statuts de verrouillage EPP attendus, qui le protègent contre les transferts ou modifications non autorisés." +weight: 20 +--- + +Le vérificateur **Verrou de transfert du domaine** vérifie qu'un domaine porte les codes de statut EPP qui le protègent contre les transferts, modifications ou suppressions non autorisés. Un domaine verrouillé (par exemple portant `clientTransferProhibited`) ne peut pas être transféré sans que le verrou soit d'abord retiré, ce qui constitue une défense essentielle contre le détournement de domaine. + +Il s'agit d'un vérificateur de **niveau domaine** : les codes de statut sont lus auprès du registre via une requête WHOIS/RDAP, et non dans les enregistrements DNS de la zone. + +## Ce qui est vérifié + +Une seule règle, `domain_lock_check`, compare les codes de statut EPP rapportés par le registre à la liste des statuts que vous exigez. + +| Statut | Condition | +|--------|-----------| +| **OK** | Tous les statuts requis sont présents sur le domaine | +| **Critique** | Un ou plusieurs statuts requis sont absents (les codes manquants sont listés) | +| **Inconnu** | Aucun statut requis n'est configuré (rien à vérifier) | +| **Erreur** | La requête WHOIS/RDAP a échoué | + +La comparaison tolère les différences de format : les espaces, tirets et tirets bas sont ignorés et la casse n'a pas d'importance. Ainsi `clientTransferProhibited`, `client-transfer-prohibited` et `client transfer prohibited` sont tous considérés comme équivalents. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Statuts de verrouillage requis | Liste de codes de statut EPP séparés par des virgules qui doivent être présents sur le domaine (par exemple `clientTransferProhibited`, `clientUpdateProhibited`, `clientDeleteProhibited`). Au moins un code doit être fourni. | `clientTransferProhibited` | + +## Dans happyDomain + +Activez ce vérificateur depuis la vue **Vérifications** du domaine ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. Le nom de domaine est renseigné automatiquement. + +Ce vérificateur se combine naturellement avec {{< relref "/reference/checkers/domain-expiry" >}} et {{< relref "/reference/checkers/domain-contact" >}} pour garder la maîtrise de l'enregistrement d'un domaine. diff --git a/content/reference/checkers/email-autoconfig.en.md b/content/reference/checkers/email-autoconfig.en.md new file mode 100644 index 0000000..3302e6a --- /dev/null +++ b/content/reference/checkers/email-autoconfig.en.md @@ -0,0 +1,57 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Mail autoconfiguration +description: "Verify that a domain publishes discoverable mail-client configuration through Thunderbird autoconfig, Microsoft Autodiscover and RFC 6186 SRV records." +weight: 220 +--- + +The **Mail Autoconfiguration** checker verifies that mail clients can automatically discover how to connect to your mail servers. When autoconfiguration is published correctly, a user only types their email address and password, and their client (Thunderbird, Outlook, mobile mail apps…) finds the right IMAP/POP and SMTP hosts, ports and security settings on its own. + +This checker is **service-level**: it applies to the mail-autoconfiguration and RFC 6186 services of a domain. For each run it probes the discovery mechanisms used by real-world clients: + +- **Thunderbird autoconfig** (Bucksch draft): `https://autoconfig./mail/config-v1.1.xml` as the primary URL, with the `https:///.well-known/autoconfig/...` apex fallback, an optional plain-HTTP variant, the Mozilla ISPDB fallback, and MX-parent fallbacks. +- **Microsoft Autodiscover** (POX): `https://autodiscover./autodiscover/autodiscover.xml`. +- **RFC 6186 SRV records**: `_imaps`, `_imap`, `_pop3s`, `_pop3`, `_submissions`, `_submission`, `_autodiscover`. +- **MX resolution**, for context and MX-based discovery. + +It parses every response, cross-checks the servers advertised by the different sources, and produces an HTML report with paste-ready remediation snippets for the most common failure modes. + +## What it checks + +| Rule | What it verifies | Severity on failure | +|---|---|---| +| `autoconfig_presence` | At least one autoconfiguration discovery method answers for the domain. | Critical | +| `autoconfig_preferred_endpoint` | The primary URL `https://autoconfig./mail/config-v1.1.xml` is reachable and serves a valid clientConfig. | Warning | +| `autoconfig_tls` | Autoconfig endpoints are served over HTTPS with a valid TLS certificate. | Critical | +| `autoconfig_server_encryption` | Servers advertised by autoconfig use SSL or STARTTLS and a non-cleartext authentication method. | Critical | +| `autoconfig_consistency` | Hostnames and ports reported by autoconfig, Autodiscover and SRV records agree with each other. | Warning | +| `autoconfig_srv_records` | RFC 6186 SRV records complement the autoconfig XML. | Warning | +| `autoconfig_autodiscover` | Whether Microsoft Autodiscover (POX) responds on the domain. | Warning | + +When a check fails, the report's "Fix this first" section provides ready-to-copy snippets: a sample `config-v1.1.xml` and its canonical URLs when nothing is published, a nudge to add the `autoconfig.` subdomain when only `.well-known` answers, an HTTPS redirect hint, a certificate-coverage hint, a port cheat-sheet for plaintext servers (SSL 993/465, STARTTLS 143/587), and a ready-to-paste SRV zone excerpt. + +## Options + +### Per user + +| Option | Meaning | Default | +|---|---|---| +| Local-part used in probes (`probeEmail`) | Local part sent in the autoconfig URL query string (before `@`). Most servers ignore it. | `test` | +| HTTP timeout (`httpTimeout`) | Per-request timeout, in seconds, when probing endpoints. | 8 | +| Try Mozilla ISPDB fallback (`tryISPDB`) | When the domain publishes no autoconfig file, also query Mozilla's public Thunderbird ISPDB. | true | +| Allow plain-HTTP fallback probe (`tryHTTPAutoconfig`) | Also probe the plain-HTTP variant of `autoconfig.` (optional in the draft); useful to spot HTTP-only providers. | false | +| Probe Microsoft Autodiscover (`tryAutodiscoverPost`) | Probe the Exchange/Outlook Autodiscover endpoints. Disable to check only the Thunderbird flow. | true | + +### Admin + +| Option | Meaning | Default | +|---|---|---| +| Mozilla ISPDB base URL (`ispdbURL`) | Base URL of Mozilla's autoconfig fallback database. | `https://autoconfig.thunderbird.net/v1.1/` | +| User-Agent used in probes (`userAgent`) | User-Agent announced in every probe request. | `happyDomain-autoconfig/1.0 (+https://happydomain.org)` | + +## In happyDomain + +Enable this checker from the **Checks** tab of the relevant mail-autoconfiguration service. See {{< relref "/pages/checks" >}} for scheduling and reading checks. + +This checker is the natural companion to a full mail setup: see {{< relref "/reference/services/email" >}} for the MX, SPF, DKIM and DMARC services that govern how mail is delivered and authenticated. diff --git a/content/reference/checkers/email-autoconfig.fr.md b/content/reference/checkers/email-autoconfig.fr.md new file mode 100644 index 0000000..8b3a241 --- /dev/null +++ b/content/reference/checkers/email-autoconfig.fr.md @@ -0,0 +1,57 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Autoconfiguration de la messagerie +description: "Vérifie qu'un domaine publie une configuration de messagerie découvrable via l'autoconfig Thunderbird, l'Autodiscover Microsoft et les enregistrements SRV de la RFC 6186." +weight: 220 +--- + +Le vérificateur d'**autoconfiguration de la messagerie** s'assure que les clients de messagerie peuvent découvrir automatiquement comment se connecter à vos serveurs de courriel. Lorsque l'autoconfiguration est publiée correctement, l'utilisateur saisit seulement son adresse et son mot de passe, et son client (Thunderbird, Outlook, applications mobiles) trouve de lui-même les bons hôtes IMAP/POP et SMTP, les ports et les réglages de sécurité. + +Ce vérificateur s'applique au **niveau service** : il concerne les services d'autoconfiguration de messagerie et de RFC 6186 d'un domaine. À chaque exécution, il sonde les mécanismes de découverte utilisés par les clients réels : + +- **Autoconfig Thunderbird** (brouillon Bucksch) : `https://autoconfig./mail/config-v1.1.xml` comme URL primaire, avec le repli sur l'apex `https:///.well-known/autoconfig/...`, une variante optionnelle en HTTP simple, le repli sur l'ISPDB de Mozilla et les replis via le parent MX. +- **Autodiscover Microsoft** (POX) : `https://autodiscover./autodiscover/autodiscover.xml`. +- **Enregistrements SRV de la RFC 6186** : `_imaps`, `_imap`, `_pop3s`, `_pop3`, `_submissions`, `_submission`, `_autodiscover`. +- **Résolution MX**, pour le contexte et la découverte fondée sur les MX. + +Il analyse chaque réponse, recoupe les serveurs annoncés par les différentes sources et produit un rapport HTML accompagné d'extraits de correction prêts à coller pour les défauts les plus courants. + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | Sévérité en cas d'échec | +|---|---|---| +| `autoconfig_presence` | Au moins une méthode de découverte d'autoconfiguration répond pour le domaine. | Critique | +| `autoconfig_preferred_endpoint` | L'URL primaire `https://autoconfig./mail/config-v1.1.xml` est joignable et sert un clientConfig valide. | Avertissement | +| `autoconfig_tls` | Les points d'accès d'autoconfig sont servis en HTTPS avec un certificat TLS valide. | Critique | +| `autoconfig_server_encryption` | Les serveurs annoncés par l'autoconfig utilisent SSL ou STARTTLS et une méthode d'authentification non en clair. | Critique | +| `autoconfig_consistency` | Les noms d'hôtes et ports rapportés par l'autoconfig, l'Autodiscover et les SRV concordent entre eux. | Avertissement | +| `autoconfig_srv_records` | Les enregistrements SRV de la RFC 6186 complètent le XML d'autoconfig. | Avertissement | +| `autoconfig_autodiscover` | Si l'Autodiscover Microsoft (POX) répond sur le domaine. | Avertissement | + +En cas d'échec, la section « Fix this first » du rapport fournit des extraits prêts à copier : un exemple de `config-v1.1.xml` et ses URL canoniques lorsque rien n'est publié, une incitation à ajouter le sous-domaine `autoconfig.` lorsque seul `.well-known` répond, une redirection vers HTTPS, un rappel sur la couverture du certificat, un aide-mémoire de ports pour les serveurs en clair (SSL 993/465, STARTTLS 143/587) et un extrait de zone SRV prêt à coller. + +## Options + +### Par utilisateur + +| Option | Signification | Défaut | +|---|---|---| +| Partie locale des sondes (`probeEmail`) | Partie locale envoyée dans la chaîne de requête de l'URL d'autoconfig (avant le `@`). La plupart des serveurs l'ignorent. | `test` | +| Délai HTTP (`httpTimeout`) | Délai par requête, en secondes, lors du sondage des points d'accès. | 8 | +| Tenter le repli ISPDB de Mozilla (`tryISPDB`) | Lorsque le domaine ne publie aucun fichier d'autoconfig, interroger aussi l'ISPDB public de Mozilla. | true | +| Autoriser le repli HTTP simple (`tryHTTPAutoconfig`) | Sonder aussi la variante en HTTP simple de `autoconfig.` (optionnelle dans le brouillon) ; utile pour repérer les fournisseurs encore en HTTP. | false | +| Sonder l'Autodiscover Microsoft (`tryAutodiscoverPost`) | Sonder les points d'accès Autodiscover Exchange/Outlook. À désactiver pour ne vérifier que le flux Thunderbird. | true | + +### Admin + +| Option | Signification | Défaut | +|---|---|---| +| URL de base de l'ISPDB Mozilla (`ispdbURL`) | URL de base de la base de repli d'autoconfig de Mozilla. | `https://autoconfig.thunderbird.net/v1.1/` | +| User-Agent des sondes (`userAgent`) | User-Agent annoncé dans chaque requête de sondage. | `happyDomain-autoconfig/1.0 (+https://happydomain.org)` | + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** du service d'autoconfiguration de messagerie concerné. Voir {{< relref "/pages/checks" >}} pour la planification et la lecture des vérifications. + +Ce vérificateur est le compagnon naturel d'une configuration de messagerie complète : voir {{< relref "/reference/services/email" >}} pour les services MX, SPF, DKIM et DMARC qui régissent la remise et l'authentification du courrier. diff --git a/content/reference/checkers/email-keys.en.md b/content/reference/checkers/email-keys.en.md new file mode 100644 index 0000000..167cca6 --- /dev/null +++ b/content/reference/checkers/email-keys.en.md @@ -0,0 +1,86 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Mail keys (DKIM / OpenPGP) +description: "Validate DNS-published OpenPGP keys (OPENPGPKEY) and S/MIME certificates (SMIMEA) used for end-to-end mail encryption, including their DNSSEC authentication." +weight: 230 +--- + +The **Mail keys** checker (named *OPENPGPKEY & SMIMEA* in happyDomain) validates the cryptographic keys a domain publishes in DNS so that correspondents can encrypt mail to its users. It covers two DANE-style record types: + +- **`OPENPGPKEY`** ([RFC 7929](https://www.rfc-editor.org/rfc/rfc7929)) — an individual user's OpenPGP public key, published under an owner-hashed name below `._openpgpkey.`. +- **`SMIMEA`** ([RFC 8162](https://www.rfc-editor.org/rfc/rfc8162)) — a user's S/MIME certificate, published under an owner-hashed name below `._smimecert.`. + +This checker is **service-level**: it applies to the OpenPGP and S/MIME services of a subdomain and runs a comprehensive test suite, then renders an HTML report whose top block points to the fix for the most common failure scenarios. + +{{% notice style="info" title="Publication and structure, not cryptographic trust" %}} +This checker validates DNS publication and the structure and metadata of the keys it finds. It does **not** cryptographically verify them: OpenPGP signatures (self-signatures, third-party certifications) are not verified, and S/MIME chains are not built or validated against any trust anchor (no CRL/OCSP). Authenticity of the records themselves is delegated to a validating resolver via the DNSSEC `AD` flag. Treat a green report as "the record is well-formed and DNSSEC-signed", not as "the key is trustworthy". +{{% /notice %}} + +## What it checks + +### DNS and DNSSEC + +| Rule | What it verifies | Severity | +|---|---|---| +| `dns_query_failed` | The DNS lookup for the record succeeds. | Critical | +| `dns_no_record` | A record is published at the expected owner name. | Critical | +| `dns_record_mismatch` | The record returned by DNS matches the service-declared record. | Warning | +| `dnssec_not_validated` | The record is authenticated by DNSSEC (`AD` flag set). | Critical (Warning if DNSSEC not required) | +| `owner_hash_mismatch` | The owner-name first label equals `hex(sha256(username))[:28]`. | Critical | + +### OpenPGP (`OPENPGPKEY`) + +| Rule | What it verifies | Severity | +|---|---|---| +| `pgp_parse_error` | The record decodes as a valid OpenPGP key. | Critical | +| `pgp_primary_revoked` | The primary key carries no revocation signature. | Critical | +| `pgp_primary_expired` | The primary key has not passed its self-signature expiry. | Critical | +| `pgp_primary_expiring_soon` | The primary key does not expire within the configured window. | Warning | +| `pgp_weak_algorithm` | No legacy algorithm (DSA/ElGamal) is used. | Warning | +| `pgp_weak_key_size` | RSA keys meet the minimum 2048-bit size (3072+ preferred). | Critical | +| `pgp_no_encryption_subkey` | At least one active key advertises encryption capability. | Critical | +| `pgp_no_identity` | The key carries at least one self-signed User ID. | Warning | +| `pgp_uid_mismatch` | At least one UID references ``. | Info | +| `pgp_multiple_entities` | The record carries a single OpenPGP entity (RFC 7929). | Warning | +| `pgp_record_too_large` | The record stays below 4 KiB to fit typical UDP answers. | Warning | + +### S/MIME (`SMIMEA`) + +| Rule | What it verifies | Severity | +|---|---|---| +| `smimea_bad_usage` | The usage field is 0, 1, 2 or 3. | Critical | +| `smimea_bad_selector` | The selector field is 0 (Cert) or 1 (SPKI). | Critical | +| `smimea_bad_match_type` | The matching type is 0 (Full), 1 (SHA-256) or 2 (SHA-512). | Critical | +| `smimea_cert_parse_error` | The record decodes as a valid X.509 certificate or SPKI. | Critical | +| `smimea_cert_not_yet_valid` | The certificate's `NotBefore` is in the past. | Critical | +| `smimea_cert_expired` | The certificate's `NotAfter` is in the future. | Critical | +| `smimea_cert_expiring_soon` | The certificate does not expire within the configured window. | Warning | +| `smimea_no_email_protection_eku` | The certificate advertises the `emailProtection` EKU. | Critical (Warning if not required) | +| `smimea_missing_key_usage` | The certificate carries `digitalSignature` and/or `keyEncipherment` key usage. | Warning | +| `smimea_weak_signature_algorithm` | The certificate is not signed with a deprecated algorithm (MD2/MD5/SHA-1). | Critical | +| `smimea_weak_key_size` | RSA keys meet the minimum 2048-bit size (3072+ preferred). | Critical | +| `smimea_self_signed` | Flags self-signed certificates paired with PKIX-EE (usage 1). | Info | +| `smimea_email_mismatch` | At least one email SAN begins with `@`. | Info | +| `smimea_hash_only` | Notes that matching types 1/2 transport only a digest, preventing certificate inspection. | Info | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| DNS resolver (`resolver`) | Validating resolver to query (comma-separated list accepted). Empty uses the system resolver. | (system) | +| `certExpiryWarnDays` | Window, in days, for the `expiring_soon` warnings (PGP and S/MIME). | 30 | +| `requireDNSSEC` | When false, a missing `AD` flag is a Warning instead of Critical. | true | +| `requireEmailProtection` | When false, a missing `emailProtection` EKU is a Warning instead of Critical. | true | + +The domain origin, subdomain, service and service type are auto-filled by happyDomain. + +{{% notice style="info" title="Query a validating resolver" %}} +Because record authenticity is delegated to DNSSEC, run this checker against a resolver you trust to perform DNSSEC validation, so the `AD` flag reflects a real validation. +{{% /notice %}} + +## In happyDomain + +Enable this checker from the **Checks** tab of the relevant OpenPGP or S/MIME service. See {{< relref "/pages/checks" >}} for the general workflow. + +These records share their security model with DNSSEC: to confirm your zone's signing chain is itself sound, see {{< relref "/reference/checkers/dnssec" >}}. For the surrounding mail configuration, see {{< relref "/reference/services/email" >}}. diff --git a/content/reference/checkers/email-keys.fr.md b/content/reference/checkers/email-keys.fr.md new file mode 100644 index 0000000..f6707a5 --- /dev/null +++ b/content/reference/checkers/email-keys.fr.md @@ -0,0 +1,86 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Clés de messagerie (DKIM / OpenPGP) +description: "Valide les clés OpenPGP (OPENPGPKEY) et les certificats S/MIME (SMIMEA) publiés dans le DNS pour le chiffrement de bout en bout du courrier, ainsi que leur authentification DNSSEC." +weight: 230 +--- + +Le vérificateur de **clés de messagerie** (nommé *OPENPGPKEY & SMIMEA* dans happyDomain) valide les clés cryptographiques qu'un domaine publie dans le DNS afin que ses correspondants puissent chiffrer le courrier destiné à ses utilisateurs. Il couvre deux types d'enregistrements de style DANE : + +- **`OPENPGPKEY`** ([RFC 7929](https://www.rfc-editor.org/rfc/rfc7929)) : la clé publique OpenPGP d'un utilisateur, publiée sous un nom haché du propriétaire, sous `._openpgpkey.`. +- **`SMIMEA`** ([RFC 8162](https://www.rfc-editor.org/rfc/rfc8162)) : le certificat S/MIME d'un utilisateur, publié sous un nom haché du propriétaire, sous `._smimecert.`. + +Ce vérificateur s'applique au **niveau service** : il concerne les services OpenPGP et S/MIME d'un sous-domaine, exécute une suite de tests complète, puis produit un rapport HTML dont le bloc supérieur pointe vers la correction des défauts les plus courants. + +{{% notice style="info" title="Publication et structure, pas confiance cryptographique" %}} +Ce vérificateur valide la publication DNS ainsi que la structure et les métadonnées des clés qu'il trouve. Il ne les vérifie pas cryptographiquement : les signatures OpenPGP (auto-signatures, certifications par des tiers) ne sont pas vérifiées, et les chaînes S/MIME ne sont ni construites ni validées par rapport à une ancre de confiance (pas de CRL/OCSP). L'authenticité des enregistrements eux-mêmes est déléguée à un résolveur validant via le drapeau DNSSEC `AD`. Considérez un rapport vert comme « l'enregistrement est bien formé et signé par DNSSEC », et non comme « la clé est digne de confiance ». +{{% /notice %}} + +## Ce qui est vérifié + +### DNS et DNSSEC + +| Règle | Ce qui est vérifié | Sévérité | +|---|---|---| +| `dns_query_failed` | La requête DNS de l'enregistrement aboutit. | Critique | +| `dns_no_record` | Un enregistrement est publié au nom de propriétaire attendu. | Critique | +| `dns_record_mismatch` | L'enregistrement renvoyé par le DNS correspond à celui déclaré par le service. | Avertissement | +| `dnssec_not_validated` | L'enregistrement est authentifié par DNSSEC (drapeau `AD` posé). | Critique (Avertissement si DNSSEC non exigé) | +| `owner_hash_mismatch` | Le premier label du nom de propriétaire vaut `hex(sha256(username))[:28]`. | Critique | + +### OpenPGP (`OPENPGPKEY`) + +| Règle | Ce qui est vérifié | Sévérité | +|---|---|---| +| `pgp_parse_error` | L'enregistrement se décode en une clé OpenPGP valide. | Critique | +| `pgp_primary_revoked` | La clé primaire ne porte aucune signature de révocation. | Critique | +| `pgp_primary_expired` | La clé primaire n'a pas dépassé l'expiration de son auto-signature. | Critique | +| `pgp_primary_expiring_soon` | La clé primaire n'expire pas dans la fenêtre configurée. | Avertissement | +| `pgp_weak_algorithm` | Aucun algorithme ancien (DSA/ElGamal) n'est employé. | Avertissement | +| `pgp_weak_key_size` | Les clés RSA respectent la taille minimale de 2048 bits (3072+ préférée). | Critique | +| `pgp_no_encryption_subkey` | Au moins une clé active annonce une capacité de chiffrement. | Critique | +| `pgp_no_identity` | La clé porte au moins un identifiant utilisateur auto-signé. | Avertissement | +| `pgp_uid_mismatch` | Au moins un UID référence ``. | Info | +| `pgp_multiple_entities` | L'enregistrement porte une seule entité OpenPGP (RFC 7929). | Avertissement | +| `pgp_record_too_large` | L'enregistrement reste sous 4 Kio pour tenir dans une réponse UDP typique. | Avertissement | + +### S/MIME (`SMIMEA`) + +| Règle | Ce qui est vérifié | Sévérité | +|---|---|---| +| `smimea_bad_usage` | Le champ usage vaut 0, 1, 2 ou 3. | Critique | +| `smimea_bad_selector` | Le champ sélecteur vaut 0 (Cert) ou 1 (SPKI). | Critique | +| `smimea_bad_match_type` | Le type de correspondance vaut 0 (Full), 1 (SHA-256) ou 2 (SHA-512). | Critique | +| `smimea_cert_parse_error` | L'enregistrement se décode en un certificat X.509 ou un SPKI valide. | Critique | +| `smimea_cert_not_yet_valid` | Le `NotBefore` du certificat est dans le passé. | Critique | +| `smimea_cert_expired` | Le `NotAfter` du certificat est dans le futur. | Critique | +| `smimea_cert_expiring_soon` | Le certificat n'expire pas dans la fenêtre configurée. | Avertissement | +| `smimea_no_email_protection_eku` | Le certificat annonce l'EKU `emailProtection`. | Critique (Avertissement si non exigé) | +| `smimea_missing_key_usage` | Le certificat porte l'usage de clé `digitalSignature` et/ou `keyEncipherment`. | Avertissement | +| `smimea_weak_signature_algorithm` | Le certificat n'est pas signé avec un algorithme déprécié (MD2/MD5/SHA-1). | Critique | +| `smimea_weak_key_size` | Les clés RSA respectent la taille minimale de 2048 bits (3072+ préférée). | Critique | +| `smimea_self_signed` | Signale les certificats auto-signés associés à PKIX-EE (usage 1). | Info | +| `smimea_email_mismatch` | Au moins un SAN courriel commence par `@`. | Info | +| `smimea_hash_only` | Note que les types de correspondance 1/2 ne transportent qu'un condensat, empêchant l'inspection du certificat. | Info | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Résolveur DNS (`resolver`) | Résolveur validant à interroger (liste séparée par des virgules acceptée). Vide : résolveur système. | (système) | +| `certExpiryWarnDays` | Fenêtre, en jours, des avertissements `expiring_soon` (PGP et S/MIME). | 30 | +| `requireDNSSEC` | Si faux, un drapeau `AD` absent devient un Avertissement plutôt qu'un Critique. | true | +| `requireEmailProtection` | Si faux, une EKU `emailProtection` absente devient un Avertissement plutôt qu'un Critique. | true | + +L'origine de la zone, le sous-domaine, le service et le type de service sont préremplis par happyDomain. + +{{% notice style="info" title="Interrogez un résolveur validant" %}} +L'authenticité des enregistrements étant déléguée au DNSSEC, exécutez ce vérificateur contre un résolveur en qui vous avez confiance pour effectuer la validation DNSSEC, afin que le drapeau `AD` reflète une validation réelle. +{{% /notice %}} + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** du service OpenPGP ou S/MIME concerné. Voir {{< relref "/pages/checks" >}} pour le fonctionnement général. + +Ces enregistrements partagent leur modèle de sécurité avec le DNSSEC : pour confirmer que la chaîne de signature de votre zone est elle-même saine, voir {{< relref "/reference/checkers/dnssec" >}}. Pour la configuration de messagerie environnante, voir {{< relref "/reference/services/email" >}}. diff --git a/content/reference/checkers/external-expiry.en.md b/content/reference/checkers/external-expiry.en.md new file mode 100644 index 0000000..e91a8a0 --- /dev/null +++ b/content/reference/checkers/external-expiry.en.md @@ -0,0 +1,38 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: External-reference expiry +description: "Retrieves the WHOIS/RDAP registration facts for the external domains your zone points to, so their expiry can be evaluated." +weight: 50 +--- + +The **External-reference expiry** checker looks up the registration facts of the *external* domains your zone refers to. When a record points at a name you do not own (a `CNAME` to a third-party service, an `MX` to an external provider, an `NS` delegation…), the safety of your zone depends on that external domain staying registered. If it expires and is re-registered by someone else, the pointer can be hijacked. + +This is a **zone-level** checker: it enumerates the external targets discovered in the zone and performs one WHOIS/RDAP lookup per distinct registrable domain. Targets sharing the same registrable domain reuse a single lookup, and lookups run with a bounded concurrency so a large zone does not overwhelm the registry. + +## What it checks + +This checker is primarily a **collector**. It gathers per-target WHOIS facts (registrable name, expiry date, creation date, registrar, status) and publishes them for the *dangling-reference* checker, which is where the actionable verdicts about expiration, redemption or recent re-registration are emitted. + +Its own rule, `external_whois_collected`, reports only how the collection went: + +| Status | Condition | +|--------|-----------| +| **OK** | WHOIS was collected for every external target | +| **Info** | Some lookups succeeded and some failed (a partial result), or no external target was reported at all | +| **Warning** | The WHOIS lookup failed for *all* external targets | +| **Error** | The external WHOIS observation could not be read | + +{{% notice style="info" title="Verdicts live in the dangling-reference checker" %}} +This checker does not decide whether an external domain is dangerously close to expiry. It only retrieves the facts. The expiry, redemption and re-registration verdicts are surfaced by the companion dangling-reference checker, which consumes the facts collected here. +{{% /notice %}} + +## Options + +This checker has no user-tunable options. The list of external targets is supplied automatically from the zone's discovered references. + +## In happyDomain + +Enable this checker from the zone's **Checks** view; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The discovery of external targets is automatic. + +For the registration of the domains you own directly, see {{< relref "/reference/checkers/domain-expiry" >}}. diff --git a/content/reference/checkers/external-expiry.fr.md b/content/reference/checkers/external-expiry.fr.md new file mode 100644 index 0000000..630f72a --- /dev/null +++ b/content/reference/checkers/external-expiry.fr.md @@ -0,0 +1,38 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Expiration des références externes +description: "Récupère les informations d'enregistrement WHOIS/RDAP des domaines externes vers lesquels pointe votre zone, afin d'évaluer leur expiration." +weight: 50 +--- + +Le vérificateur **Expiration des références externes** récupère les informations d'enregistrement des domaines *externes* auxquels votre zone fait référence. Lorsqu'un enregistrement pointe vers un nom que vous ne possédez pas (un `CNAME` vers un service tiers, un `MX` vers un prestataire externe, une délégation `NS`, etc.), la sûreté de votre zone dépend du maintien de l'enregistrement de ce domaine externe. S'il expire et qu'il est ré-enregistré par quelqu'un d'autre, le pointeur peut être détourné. + +Il s'agit d'un vérificateur de **niveau zone** : il énumère les cibles externes découvertes dans la zone et effectue une requête WHOIS/RDAP par domaine enregistrable distinct. Les cibles partageant le même domaine enregistrable réutilisent une seule requête, et les requêtes s'exécutent avec une concurrence limitée afin qu'une zone volumineuse ne sature pas le registre. + +## Ce qui est vérifié + +Ce vérificateur est avant tout un **collecteur**. Il rassemble les informations WHOIS par cible (nom enregistrable, date d'expiration, date de création, bureau d'enregistrement, statuts) et les publie pour le vérificateur de *références orphelines*, où sont émis les verdicts exploitables sur l'expiration, la période de rédemption ou un ré-enregistrement récent. + +Sa propre règle, `external_whois_collected`, ne rapporte que le déroulement de la collecte : + +| Statut | Condition | +|--------|-----------| +| **OK** | Le WHOIS a été collecté pour toutes les cibles externes | +| **Info** | Certaines requêtes ont réussi et d'autres ont échoué (résultat partiel), ou aucune cible externe n'a été signalée | +| **Avertissement** | La requête WHOIS a échoué pour *toutes* les cibles externes | +| **Erreur** | L'observation WHOIS externe n'a pas pu être lue | + +{{% notice style="info" title="Les verdicts se trouvent dans le vérificateur de références orphelines" %}} +Ce vérificateur ne décide pas si un domaine externe est dangereusement proche de l'expiration. Il se contente d'en récupérer les informations. Les verdicts d'expiration, de rédemption et de ré-enregistrement sont produits par le vérificateur de références orphelines associé, qui consomme les informations collectées ici. +{{% /notice %}} + +## Options + +Ce vérificateur ne propose aucune option configurable. La liste des cibles externes est fournie automatiquement à partir des références découvertes dans la zone. + +## Dans happyDomain + +Activez ce vérificateur depuis la vue **Vérifications** de la zone ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. La découverte des cibles externes est automatique. + +Pour l'enregistrement des domaines que vous possédez directement, consultez {{< relref "/reference/checkers/domain-expiry" >}}. diff --git a/content/reference/checkers/happydeliver.en.md b/content/reference/checkers/happydeliver.en.md new file mode 100644 index 0000000..0dbeff1 --- /dev/null +++ b/content/reference/checkers/happydeliver.en.md @@ -0,0 +1,85 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Outbound deliverability (happyDeliver) +description: "Send a real test message from your domain to a happyDeliver instance and grade how well it would be delivered to a real inbox." +weight: 210 +--- + +The **Outbound deliverability** checker (named *Outbound deliverability (via happyDeliver)* in happyDomain) measures how a message sent **from your domain** would actually fare on its way to a recipient's inbox. Rather than inspecting DNS records in isolation, it drives an external [happyDeliver](https://git.nemunai.re/happyDomain/happyDeliver) instance to perform an end-to-end test. + +This checker is **service-level**: it is attached to a service (typically the mail configuration of a subdomain) and needs SMTP credentials to send the test message on your behalf. + +## How it works + +For each run, the checker: + +1. Allocates a fresh recipient address on the configured happyDeliver instance. +2. Sends a **real test email** from the tested domain to that address, using the SMTP submission server and credentials you provide. +3. Polls happyDeliver until the message has been received and analysed. +4. Stores happyDeliver's report and exposes one score per section as a metric. + +happyDeliver grades the message across several sections (DNS, authentication, spam filters, blacklists, headers, content) and computes an overall score. The checker turns each section into a rule. + +{{% notice style="info" title="An external happyDeliver instance is required" %}} +This checker does nothing on its own: it needs a reachable happyDeliver instance, identified by its API URL and bearer token. Those are usually configured once by the administrator and can be overridden per domain. +{{% /notice %}} + +## What it checks + +Each section rule compares happyDeliver's score for that section against a configurable minimum. The check is **Critical** when the score falls below the minimum, otherwise **OK**. + +| Rule | What it verifies | Default minimum | +|---|---|---| +| `happydeliver.score.overall` | happyDeliver's Overall score | 70 | +| `happydeliver.score.dns` | DNS configuration score | 70 | +| `happydeliver.score.authentication` | Authentication score (SPF / DKIM / DMARC) | 80 | +| `happydeliver.score.spam` | Spam-filter score | 70 | +| `happydeliver.score.blacklist` | Blacklist score | 90 | +| `happydeliver.score.header` | Header score | 70 | +| `happydeliver.score.content` | Content score | 60 | + +A separate `happydeliver.lifecycle` rule reports the outcome of the run itself: **OK** when the message was analysed, **Critical** when the test address could not be allocated, the message could not be sent, or happyDeliver returned a wait/fetch/parse error, and **Warning** when the message was not analysed before the timeout elapsed. + +Each section minimum can be tuned through its own `min_score_
` rule option in the happyDomain interface. + +## Options + +### Sending (per domain) + +| Option | Meaning | Default | +|---|---|---| +| Sending SMTP host (`smtp_host`) | Hostname or IP of the submission server used to send the test email. **Required.** | (none) | +| Sending SMTP port (`smtp_port`) | Submission port (587 for STARTTLS, 465 for implicit TLS, 25 for plain). | 587 | +| SMTP username (`smtp_username`) | Username for the submission server (omit for anonymous submission). | (none) | +| SMTP password (`smtp_password`) | Password for the submission server. | (none) | +| TLS mode (`smtp_tls`) | How to negotiate TLS: `starttls`, `tls`, or `none`. | `starttls` | +| From address (`from_address`) | Address used in the `From` header; must belong to the tested domain. | `no-reply@` | + +### Message content (per domain) + +| Option | Meaning | Default | +|---|---|---| +| Subject (`subject_override`) | Override the default test subject. | (built-in) | +| Plain-text body (`body_text_override`) | Override the default plain-text body. | (built-in) | +| HTML body (`body_html_override`) | Override the default HTML body. | (built-in) | + +### Timing (per domain) + +| Option | Meaning | Default | +|---|---|---| +| Wait timeout (`wait_timeout`) | Seconds to wait for happyDeliver to receive and analyse the message. | 900 | +| Poll interval (`poll_interval`) | Seconds between status polls (clamped to the 2–60 range). | 5 | + +### Instance (admin, overridable per domain) + +| Option | Meaning | Default | +|---|---|---| +| happyDeliver instance URL (`happydeliver_url`) | Base URL of the happyDeliver API. | (admin) | +| happyDeliver API token (`happydeliver_token`) | Bearer token for the happyDeliver API. | (admin) | + +## In happyDomain + +Enable this checker from the service's **Checks** tab and provide the SMTP submission details so happyDomain can send the test message. See {{< relref "/pages/checks" >}} for the general workflow of scheduling and reading checks. + +Because deliverability depends heavily on your anti-spoofing posture, pair this checker with a well-configured {{< relref "/reference/services/email" >}} setup (SPF, DKIM and DMARC). For the DNSSEC half of your domain's trust chain, see {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/checkers/happydeliver.fr.md b/content/reference/checkers/happydeliver.fr.md new file mode 100644 index 0000000..9096924 --- /dev/null +++ b/content/reference/checkers/happydeliver.fr.md @@ -0,0 +1,85 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Délivrabilité sortante (happyDeliver) +description: "Envoie un véritable message de test depuis votre domaine vers une instance happyDeliver et évalue la qualité de sa délivrabilité jusqu'à une boîte de réception réelle." +weight: 210 +--- + +Le vérificateur de **délivrabilité sortante** (nommé *Outbound deliverability (via happyDeliver)* dans happyDomain) mesure le sort que connaîtrait un message envoyé **depuis votre domaine** sur le chemin de la boîte de réception du destinataire. Au lieu d'examiner les enregistrements DNS isolément, il pilote une instance externe [happyDeliver](https://git.nemunai.re/happyDomain/happyDeliver) pour réaliser un test de bout en bout. + +Ce vérificateur s'applique au **niveau service** : il est rattaché à un service (typiquement la configuration de messagerie d'un sous-domaine) et a besoin d'identifiants SMTP pour envoyer le message de test en votre nom. + +## Fonctionnement + +À chaque exécution, le vérificateur : + +1. Alloue une adresse de réception neuve sur l'instance happyDeliver configurée. +2. Envoie un **véritable courriel de test** depuis le domaine testé vers cette adresse, en utilisant le serveur de soumission SMTP et les identifiants que vous fournissez. +3. Interroge happyDeliver jusqu'à ce que le message ait été reçu et analysé. +4. Conserve le rapport de happyDeliver et expose le score de chaque section sous forme de métrique. + +happyDeliver note le message sur plusieurs sections (DNS, authentification, filtres anti-spam, listes noires, en-têtes, contenu) et calcule un score global. Le vérificateur transforme chaque section en une règle. + +{{% notice style="info" title="Une instance happyDeliver externe est requise" %}} +Ce vérificateur ne fait rien seul : il lui faut une instance happyDeliver accessible, identifiée par l'URL de son API et un jeton d'authentification. Ceux-ci sont en général configurés une fois par l'administrateur et peuvent être redéfinis par domaine. +{{% /notice %}} + +## Ce qui est vérifié + +Chaque règle de section compare le score happyDeliver de cette section à un minimum configurable. La vérification est **Critique** lorsque le score passe sous le minimum, sinon **OK**. + +| Règle | Ce qui est vérifié | Minimum par défaut | +|---|---|---| +| `happydeliver.score.overall` | Score global de happyDeliver | 70 | +| `happydeliver.score.dns` | Score de configuration DNS | 70 | +| `happydeliver.score.authentication` | Score d'authentification (SPF / DKIM / DMARC) | 80 | +| `happydeliver.score.spam` | Score des filtres anti-spam | 70 | +| `happydeliver.score.blacklist` | Score des listes noires | 90 | +| `happydeliver.score.header` | Score des en-têtes | 70 | +| `happydeliver.score.content` | Score du contenu | 60 | + +Une règle distincte, `happydeliver.lifecycle`, rapporte le déroulement de l'exécution elle-même : **OK** lorsque le message a été analysé, **Critique** lorsque l'adresse de test n'a pu être allouée, que le message n'a pu être envoyé, ou que happyDeliver a renvoyé une erreur d'attente, de récupération ou d'analyse, et **Avertissement** lorsque le message n'a pas été analysé avant l'expiration du délai. + +Chaque minimum de section se règle via son option de règle `min_score_
` dans l'interface de happyDomain. + +## Options + +### Envoi (par domaine) + +| Option | Signification | Défaut | +|---|---|---| +| Serveur SMTP d'envoi (`smtp_host`) | Nom d'hôte ou IP du serveur de soumission utilisé pour envoyer le courriel de test. **Obligatoire.** | (aucun) | +| Port SMTP d'envoi (`smtp_port`) | Port de soumission (587 pour STARTTLS, 465 pour TLS implicite, 25 pour le texte clair). | 587 | +| Identifiant SMTP (`smtp_username`) | Identifiant du serveur de soumission (à omettre pour une soumission anonyme). | (aucun) | +| Mot de passe SMTP (`smtp_password`) | Mot de passe du serveur de soumission. | (aucun) | +| Mode TLS (`smtp_tls`) | Mode de négociation TLS : `starttls`, `tls` ou `none`. | `starttls` | +| Adresse d'expéditeur (`from_address`) | Adresse utilisée dans l'en-tête `From` ; elle doit appartenir au domaine testé. | `no-reply@` | + +### Contenu du message (par domaine) + +| Option | Signification | Défaut | +|---|---|---| +| Sujet (`subject_override`) | Remplace le sujet de test par défaut. | (intégré) | +| Corps texte (`body_text_override`) | Remplace le corps texte par défaut. | (intégré) | +| Corps HTML (`body_html_override`) | Remplace le corps HTML par défaut. | (intégré) | + +### Temporisation (par domaine) + +| Option | Signification | Défaut | +|---|---|---| +| Délai d'attente (`wait_timeout`) | Secondes d'attente pour que happyDeliver reçoive et analyse le message. | 900 | +| Intervalle d'interrogation (`poll_interval`) | Secondes entre deux interrogations de statut (borné à la plage 2 à 60). | 5 | + +### Instance (admin, redéfinissable par domaine) + +| Option | Signification | Défaut | +|---|---|---| +| URL de l'instance happyDeliver (`happydeliver_url`) | URL de base de l'API happyDeliver. | (admin) | +| Jeton d'API happyDeliver (`happydeliver_token`) | Jeton d'authentification de l'API happyDeliver. | (admin) | + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** du service et fournissez les détails de soumission SMTP afin que happyDomain puisse envoyer le message de test. Voir {{< relref "/pages/checks" >}} pour le fonctionnement général de la planification et de la lecture des vérifications. + +La délivrabilité dépendant fortement de votre posture anti-usurpation, associez ce vérificateur à une configuration {{< relref "/reference/services/email" >}} bien réglée (SPF, DKIM et DMARC). Pour la partie DNSSEC de la chaîne de confiance de votre domaine, voir {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/checkers/http.en.md b/content/reference/checkers/http.en.md new file mode 100644 index 0000000..5e0e2d1 --- /dev/null +++ b/content/reference/checkers/http.en.md @@ -0,0 +1,54 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: HTTP / HTTPS +description: "Probes a web server over HTTP and HTTPS and evaluates reachability, the redirect chain, and the full battery of HTTP security response headers and cookie hygiene rules." +weight: 180 +--- + +The **HTTP / HTTPS** checker probes the web server declared by a *Server* service over plain HTTP (port 80) and HTTPS (port 443), then evaluates a battery of independent rules on the responses: reachability, the HTTP→HTTPS redirect chain, and the modern set of HTTP security headers (HSTS, CSP, frame options, cross-origin isolation…) along with cookie hygiene. + +**Scope:** service-level. It attaches to services of type `abstract.Server` (a subdomain that publishes `A`/`AAAA` records) and is configured from that service's **Checks** tab. + +Deep TLS and certificate analysis is intentionally delegated to the {{< relref "/reference/checkers/tls" >}} checker; this checker relies on TLS only as a transport. + +## What it checks + +| Rule | Verifies | Severity | +|------|----------|----------| +| `http.tcp_reachable` | Every probed IP accepts an HTTP connection on port 80. | Critical | +| `https.tcp_reachable` | Every probed IP accepts an HTTPS connection on port 443. | Critical | +| `http.https_redirect` | Plain HTTP redirects to an HTTPS URL on the same host. | Warning | +| `http.redirect_chain` | The redirect chain has no loops, excessive length, or scheme downgrades. | Warning | +| `http.redirect_permanence` | HTTP→HTTPS upgrade uses 301 or 308 (permanent) rather than 302/307. | Warning | +| `http.hsts` | Presence and quality of the Strict-Transport-Security header on HTTPS. | Warning | +| `http.csp` | Presence and quality of the Content-Security-Policy header on HTTPS. | Warning | +| `http.x_frame_options` | Responses set X-Frame-Options or a CSP `frame-ancestors` directive. | Warning | +| `http.x_content_type_options` | Responses set `X-Content-Type-Options: nosniff`. | Warning | +| `http.x_xss_protection` | Reports the legacy X-XSS-Protection header value (CSP is the proper replacement). | Info | +| `http.referrer_policy` | Responses set a privacy-preserving Referrer-Policy header. | Warning | +| `http.permissions_policy` | The Permissions-Policy header restricts powerful APIs (camera, microphone, geolocation…). | Warning | +| `http.coop` | The Cross-Origin-Opener-Policy header is set for cross-origin process isolation. | Warning | +| `http.coep` | The Cross-Origin-Embedder-Policy header is set (required with COOP for cross-origin isolation). | Warning | +| `http.corp` | The Cross-Origin-Resource-Policy header restricts cross-origin embedding. | Warning | +| `http.cookie_flags` | Cookies set over HTTPS use the Secure, HttpOnly and SameSite attributes. | Warning | +| `http.cookie_prefixes` | Cookies using the `__Secure-` / `__Host-` prefixes meet the RFC 6265bis constraints. | Warning | +| `http.cookie_size` | Flags Set-Cookie lines exceeding the 4096-byte minimum browsers must support. | Warning | +| `http.sri` | Reports cross-origin script/style tags missing Subresource Integrity attributes. | Warning | +| `http.security_txt` | Reports whether `/.well-known/security.txt` (RFC 9116) is published. | Warning | + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Per-request timeout (ms) (`probeTimeoutMs`) | Maximum time allowed for a single HTTP/HTTPS request. | 10000 | +| Max redirects to follow (`maxRedirects`) | Stop following redirects after this many hops. | 5 | +| User-Agent (`userAgent`) | User-Agent header sent with every request. | `happyDomain-checker-http/1.0` | +| Require HTTPS (`requireHTTPS`) | Plain HTTP must redirect to HTTPS. | true | +| Require HSTS (`requireHSTS`) | HTTPS responses must include a Strict-Transport-Security header. | true | +| Min HSTS max-age (days) (`minHSTSMaxAgeDays`) | Minimum acceptable HSTS max-age, in days. | 180 | +| Require Content-Security-Policy (`requireCSP`) | HTTPS responses must include a Content-Security-Policy header. | false | + +## In happyDomain + +This is a service-level checker: configure it from the **Checks** tab of the *Server* service on the relevant subdomain. For deep certificate posture, add the {{< relref "/reference/checkers/tls" >}} checker as well. For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/http.fr.md b/content/reference/checkers/http.fr.md new file mode 100644 index 0000000..d9131b7 --- /dev/null +++ b/content/reference/checkers/http.fr.md @@ -0,0 +1,54 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: HTTP / HTTPS +description: "Sonde un serveur web en HTTP et HTTPS et évalue l'accessibilité, la chaîne de redirections, ainsi que l'ensemble des en-têtes de sécurité HTTP et des règles d'hygiène des cookies." +weight: 180 +--- + +Le vérificateur **HTTP / HTTPS** sonde le serveur web déclaré par un service « Serveur » en HTTP simple (port 80) et en HTTPS (port 443), puis évalue une série de règles indépendantes sur les réponses : accessibilité, chaîne de redirections HTTP vers HTTPS et ensemble moderne des en-têtes de sécurité HTTP (HSTS, CSP, options de cadre, isolation inter-origines, etc.), ainsi que l'hygiène des cookies. + +**Portée** : niveau service. Il s'attache aux services de type `abstract.Server` (un sous-domaine publiant des enregistrements `A`/`AAAA`) et se configure depuis l'onglet **Vérifications** de ce service. + +L'analyse approfondie du TLS et des certificats est volontairement déléguée au vérificateur {{< relref "/reference/checkers/tls" >}} ; ce vérificateur ne s'appuie sur TLS que comme transport. + +## Ce qu'il vérifie + +| Règle | Vérifie | Sévérité | +|-------|---------|----------| +| `http.tcp_reachable` | Chaque IP sondée accepte une connexion HTTP sur le port 80. | Critique | +| `https.tcp_reachable` | Chaque IP sondée accepte une connexion HTTPS sur le port 443. | Critique | +| `http.https_redirect` | Le HTTP simple redirige vers une URL HTTPS sur le même hôte. | Avertissement | +| `http.redirect_chain` | La chaîne de redirections est sans boucle, sans longueur excessive ni rétrogradation de schéma. | Avertissement | +| `http.redirect_permanence` | La bascule HTTP vers HTTPS utilise 301 ou 308 (permanent) plutôt que 302/307. | Avertissement | +| `http.hsts` | Présence et qualité de l'en-tête Strict-Transport-Security en HTTPS. | Avertissement | +| `http.csp` | Présence et qualité de l'en-tête Content-Security-Policy en HTTPS. | Avertissement | +| `http.x_frame_options` | Les réponses définissent X-Frame-Options ou une directive CSP `frame-ancestors`. | Avertissement | +| `http.x_content_type_options` | Les réponses définissent `X-Content-Type-Options: nosniff`. | Avertissement | +| `http.x_xss_protection` | Rapporte la valeur de l'en-tête hérité X-XSS-Protection (CSP est le remplaçant adéquat). | Info | +| `http.referrer_policy` | Les réponses définissent un en-tête Referrer-Policy respectueux de la vie privée. | Avertissement | +| `http.permissions_policy` | L'en-tête Permissions-Policy restreint les API sensibles (caméra, microphone, géolocalisation, etc.). | Avertissement | +| `http.coop` | L'en-tête Cross-Origin-Opener-Policy est défini pour l'isolation de processus inter-origines. | Avertissement | +| `http.coep` | L'en-tête Cross-Origin-Embedder-Policy est défini (requis avec COOP pour l'isolation inter-origines). | Avertissement | +| `http.corp` | L'en-tête Cross-Origin-Resource-Policy restreint l'inclusion inter-origines. | Avertissement | +| `http.cookie_flags` | Les cookies posés en HTTPS utilisent les attributs Secure, HttpOnly et SameSite. | Avertissement | +| `http.cookie_prefixes` | Les cookies utilisant les préfixes `__Secure-` / `__Host-` respectent les contraintes RFC 6265bis. | Avertissement | +| `http.cookie_size` | Signale les lignes Set-Cookie dépassant les 4096 octets que les navigateurs doivent supporter au minimum. | Avertissement | +| `http.sri` | Rapporte les balises script/style inter-origines dépourvues d'attributs Subresource Integrity. | Avertissement | +| `http.security_txt` | Indique si `/.well-known/security.txt` (RFC 9116) est publié. | Avertissement | + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Délai par requête (ms) (`probeTimeoutMs`) | Temps maximal alloué à une requête HTTP/HTTPS. | 10000 | +| Nombre maximal de redirections (`maxRedirects`) | Arrête de suivre les redirections au-delà de ce nombre de sauts. | 5 | +| User-Agent (`userAgent`) | En-tête User-Agent envoyé à chaque requête. | `happyDomain-checker-http/1.0` | +| Exiger HTTPS (`requireHTTPS`) | Le HTTP simple doit rediriger vers HTTPS. | true | +| Exiger HSTS (`requireHSTS`) | Les réponses HTTPS doivent inclure un en-tête Strict-Transport-Security. | true | +| max-age HSTS minimal (jours) (`minHSTSMaxAgeDays`) | Valeur max-age HSTS minimale acceptable, en jours. | 180 | +| Exiger Content-Security-Policy (`requireCSP`) | Les réponses HTTPS doivent inclure un en-tête Content-Security-Policy. | false | + +## Dans happyDomain + +C'est un vérificateur de niveau service : configurez-le depuis l'onglet **Vérifications** du service « Serveur » sur le sous-domaine concerné. Pour la posture détaillée des certificats, ajoutez aussi le vérificateur {{< relref "/reference/checkers/tls" >}}. Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/kerberos.en.md b/content/reference/checkers/kerberos.en.md new file mode 100644 index 0000000..5f16d06 --- /dev/null +++ b/content/reference/checkers/kerberos.en.md @@ -0,0 +1,49 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Kerberos +description: "Audits a Kerberos realm from its DNS records: SRV layout, KDC/kadmin/kpasswd reachability, an anonymous AS-REQ probe (realm, enctypes, pre-auth, clock skew), and an optional authenticated round-trip." +weight: 260 +--- + +The **Kerberos** checker audits a Kerberos realm starting from its DNS records. From the realm name (derived in uppercase from the domain) and the SRV records grouped under the *Kerberos* service, it runs a series of **anonymous probes** and, when credentials are supplied, an optional **authenticated round-trip** — giving a combined picture of the realm's availability and security posture. + +This checker is **service-level**: it targets a *Kerberos* service (`abstract.Kerberos`) published on a subdomain and is configured from that service's own **Checks** tab. It inspects the SRV layout (`_kerberos._tcp`, `_kerberos._udp`, `_kerberos-master._tcp`, `_kerberos-adm._tcp`, `_kpasswd._tcp`, `_kpasswd._udp`), forward-resolves every SRV target (A + AAAA), tests TCP reachability of each KDC/kadmin/kpasswd host and UDP reachability of the KDC via a real AS-REQ. The anonymous AS-REQ probe confirms the realm, reads the supported enctypes from `ETYPE-INFO2`, detects a PKINIT hint (`PA-PK-AS-REQ`) and measures clock skew. + +{{% notice style="info" title="Credentials are forwarded to the KDC" %}} +When a principal and password are supplied, they are used once to obtain a TGT and then a TGS-REQ for the target service; they are forwarded to the KDC over the network and are never stored by the checker. Leave them blank to run anonymous probes only. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | Severity | +|---|---|---| +| `kerberos.srv_present` | At least one `_kerberos._tcp` / `_kerberos._udp` SRV record is published for the realm. | Critical | +| `kerberos.kdc_reachable` | At least one KDC endpoint (TCP/UDP 88) accepts a connection. | Critical | +| `kerberos.as_probe` | The anonymous AS-REQ probe received a sane reply (`KRB-ERROR` or `AS-REP`). | Critical | +| `kerberos.realm_match` | The KDC answers for the expected realm name. | Critical | +| `kerberos.preauth_required` | Flags KDCs that return an `AS-REP` without requiring pre-authentication (AS-REP roasting exposure). | Warning | +| `kerberos.clock_skew` | The KDC clock is within tolerance of the checker's clock. | Critical | +| `kerberos.enctypes` | Reviews the encryption types advertised by the KDC, flagging DES/RC4-only configurations. | Critical | +| `kerberos.kadmin_reachable` | Flags kadmin endpoints published via SRV but not reachable. | Warning | +| `kerberos.kpasswd_reachable` | Flags kpasswd endpoints published via SRV but not reachable. | Warning | +| `kerberos.auth_tgt` | The supplied principal/password can obtain a TGT (only runs when credentials are supplied). | Critical | +| `kerberos.auth_tgs` | A TGS-REQ succeeds for the supplied target service (only runs when credentials and a target service are supplied). | Warning | + +The HTML report surfaces the most common misconfigurations with a direct remediation hint: no SRV records (publish `_kerberos._tcp.REALM. SRV …`), an SRV target with no A/AAAA, port 88 unreachable (open TCP+UDP 88), clock skew above the maximum (run ntpd/chrony), weak-enctype-only realms (switch to `aes256-cts-hmac-sha1-96`), the wrong realm in the reply, and AS-REP roasting exposure (enable `requires_preauth`). + +## Options + +| Option | Meaning | Default | +|---|---|---| +| Kerberos realm | DNS domain advertising the realm (auto-filled from the service scope; the realm name is derived in uppercase). Required. | *(auto)* | +| Principal | Optional. Supply to run an authenticated round-trip; leave blank for anonymous probes only. | *(empty)* | +| Password | Optional, secret. Password for the principal above; used once per run and never stored. | *(empty)* | +| Service to request (TGS) | Optional. SPN requested via TGS-REQ once a TGT is acquired. Defaults to `krbtgt` (realm self-test). | *(empty)* | +| Per-probe timeout (seconds) | Timeout for each probe. | `5` | +| Require strong enctypes | When enabled, realms advertising only DES/RC4 are flagged as Critical. | `true` | +| Max tolerated clock skew (seconds) | Default Kerberos tolerance is 300 s; tighter values surface drift earlier. | `300` | + +## In happyDomain + +Enable the Kerberos checker from the **Checks** tab of a Kerberos service. The realm domain is filled in automatically; supply a principal and password only if you want the authenticated TGT/TGS round-trip to run. See {{< relref "/pages/checks" >}} for the full workflow. diff --git a/content/reference/checkers/kerberos.fr.md b/content/reference/checkers/kerberos.fr.md new file mode 100644 index 0000000..6f482a6 --- /dev/null +++ b/content/reference/checkers/kerberos.fr.md @@ -0,0 +1,49 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Kerberos +description: "Audite un royaume Kerberos à partir de ses enregistrements DNS : disposition SRV, accessibilité KDC/kadmin/kpasswd, sonde AS-REQ anonyme (royaume, enctypes, pré-authentification, dérive d'horloge) et aller-retour authentifié facultatif." +weight: 260 +--- + +Le vérificateur **Kerberos** audite un royaume Kerberos à partir de ses enregistrements DNS. À partir du nom du royaume (dérivé en majuscules depuis le domaine) et des enregistrements SRV regroupés sous le service *Kerberos*, il exécute une série de **sondes anonymes** et, lorsque des identifiants sont fournis, un **aller-retour authentifié** facultatif, ce qui donne une vue combinée de la disponibilité et de la posture de sécurité du royaume. + +Il s'agit d'un vérificateur de **niveau service** : il cible un service *Kerberos* (`abstract.Kerberos`) publié sur un sous-domaine et se configure depuis l'onglet **Vérifications** de ce service. Il inspecte la disposition SRV (`_kerberos._tcp`, `_kerberos._udp`, `_kerberos-master._tcp`, `_kerberos-adm._tcp`, `_kpasswd._tcp`, `_kpasswd._udp`), résout en avant chaque cible SRV (A + AAAA), teste l'accessibilité TCP de chaque hôte KDC/kadmin/kpasswd et l'accessibilité UDP du KDC via un véritable AS-REQ. La sonde AS-REQ anonyme confirme le royaume, lit les enctypes pris en charge depuis `ETYPE-INFO2`, détecte un indice PKINIT (`PA-PK-AS-REQ`) et mesure la dérive d'horloge. + +{{% notice style="info" title="Les identifiants sont transmis au KDC" %}} +Lorsqu'un principal et un mot de passe sont fournis, ils servent une fois à obtenir un TGT puis à effectuer un TGS-REQ pour le service cible ; ils sont transmis au KDC sur le réseau et ne sont jamais stockés par le vérificateur. Laissez-les vides pour n'exécuter que les sondes anonymes. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | Gravité | +|---|---|---| +| `kerberos.srv_present` | Au moins un enregistrement SRV `_kerberos._tcp` / `_kerberos._udp` est publié pour le royaume. | Critique | +| `kerberos.kdc_reachable` | Au moins un point d'accès KDC (TCP/UDP 88) accepte une connexion. | Critique | +| `kerberos.as_probe` | La sonde AS-REQ anonyme a reçu une réponse cohérente (`KRB-ERROR` ou `AS-REP`). | Critique | +| `kerberos.realm_match` | Le KDC répond pour le nom de royaume attendu. | Critique | +| `kerberos.preauth_required` | Signale les KDC qui renvoient un `AS-REP` sans exiger de pré-authentification (exposition à l'AS-REP roasting). | Avertissement | +| `kerberos.clock_skew` | L'horloge du KDC est dans la tolérance par rapport à celle du vérificateur. | Critique | +| `kerberos.enctypes` | Examine les types de chiffrement annoncés par le KDC, signalant les configurations limitées à DES/RC4. | Critique | +| `kerberos.kadmin_reachable` | Signale les points d'accès kadmin publiés via SRV mais inaccessibles. | Avertissement | +| `kerberos.kpasswd_reachable` | Signale les points d'accès kpasswd publiés via SRV mais inaccessibles. | Avertissement | +| `kerberos.auth_tgt` | Le principal/mot de passe fourni peut obtenir un TGT (ne s'exécute que si des identifiants sont fournis). | Critique | +| `kerberos.auth_tgs` | Un TGS-REQ réussit pour le service cible fourni (ne s'exécute que si des identifiants et un service cible sont fournis). | Avertissement | + +Le rapport HTML met en avant les erreurs de configuration les plus courantes avec une piste de remédiation directe : absence d'enregistrements SRV (publier `_kerberos._tcp.REALM. SRV …`), une cible SRV sans A/AAAA, le port 88 inaccessible (ouvrir TCP+UDP 88), une dérive d'horloge au-dessus du maximum (lancer ntpd/chrony), des royaumes limités aux enctypes faibles (passer à `aes256-cts-hmac-sha1-96`), un mauvais royaume dans la réponse, et l'exposition à l'AS-REP roasting (activer `requires_preauth`). + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Royaume Kerberos | Domaine DNS annonçant le royaume (renseigné automatiquement depuis la portée du service ; le nom du royaume est dérivé en majuscules). Obligatoire. | *(auto)* | +| Principal | Facultatif. À fournir pour exécuter un aller-retour authentifié ; laissez vide pour n'exécuter que les sondes anonymes. | *(vide)* | +| Mot de passe | Facultatif, secret. Mot de passe du principal ci-dessus ; utilisé une fois par exécution et jamais stocké. | *(vide)* | +| Service à demander (TGS) | Facultatif. SPN demandé via TGS-REQ une fois un TGT obtenu. Par défaut `krbtgt` (auto-test du royaume). | *(vide)* | +| Délai d'attente par sonde (secondes) | Délai d'attente pour chaque sonde. | `5` | +| Exiger des enctypes forts | Lorsqu'activé, les royaumes n'annonçant que DES/RC4 sont signalés comme Critique. | `true` | +| Dérive d'horloge maximale tolérée (secondes) | La tolérance Kerberos par défaut est de 300 s ; des valeurs plus strictes font apparaître la dérive plus tôt. | `300` | + +## Dans happyDomain + +Activez le vérificateur Kerberos depuis l'onglet **Vérifications** d'un service Kerberos. Le domaine du royaume est renseigné automatiquement ; fournissez un principal et un mot de passe uniquement si vous souhaitez exécuter l'aller-retour authentifié TGT/TGS. Consultez {{< relref "/pages/checks" >}} pour le fonctionnement complet. diff --git a/content/reference/checkers/ldap.en.md b/content/reference/checkers/ldap.en.md new file mode 100644 index 0000000..085ccad --- /dev/null +++ b/content/reference/checkers/ldap.en.md @@ -0,0 +1,51 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: LDAP +description: "Probes a domain's LDAP directory end-to-end: SRV discovery, transport encryption (StartTLS / LDAPS), RootDSE introspection, anonymous exposure, plaintext-bind refusal, and optional authenticated bind." +weight: 250 +--- + +The **LDAP** checker probes a domain's LDAP directory deployment from end to end. Starting from SRV discovery (`_ldap._tcp`, `_ldaps._tcp`), it tests reachability of every endpoint, confirms an encrypted channel is available (StartTLS per RFC 2830 or implicit TLS on port 636), introspects the RootDSE, looks for anonymous information disclosure, verifies the directory refuses cleartext binds, and — when credentials are supplied — performs an authenticated bind over TLS with an optional read test on a base DN. + +This checker is **service-level**: it targets an *LDAP* service (`abstract.LDAP`) published on a subdomain and is configured from that service's own **Checks** tab. For each transport it probes `_ldap._tcp` (falling back to port 389) and `_ldaps._tcp` (falling back to port 636), testing each resolved A/AAAA address per IP family. + +{{% notice style="info" title="TLS posture is folded in, not duplicated" %}} +The LDAP checker confirms only that a TLS session can be established, recording the negotiated version and cipher for context. Each probed endpoint is published as a `tls.endpoint.v1` discovery entry so the dedicated TLS checker can verify the certificate chain, hostname match and expiry. Those findings are folded back onto the LDAP service page through the `ldap.tls_quality` rule — a bad certificate on an LDAP endpoint shows up here, not only in a separate TLS view. See {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | Severity | +|---|---|---| +| `ldap.has_srv` | `_ldap._tcp` / `_ldaps._tcp` SRV records are published and resolvable. | Warning | +| `ldap.endpoint_reachable` | Every discovered LDAP endpoint accepts a TCP connection. | Critical | +| `ldap.has_encrypted_transport` | At least one reachable endpoint offers an encrypted channel (LDAPS or StartTLS). | Critical | +| `ldap.starttls_supported` | StartTLS is offered and the upgrade succeeds on every reachable plain LDAP endpoint. | Critical | +| `ldap.ldaps_handshake` | The direct TLS handshake succeeds on every LDAPS endpoint. | Critical | +| `ldap.starttls_on_ldaps` | Flags servers that needlessly advertise StartTLS on the implicit-TLS LDAPS port. | Info | +| `ldap.ipv6_reachable` | At least one endpoint is reachable over IPv6. | Info | +| `ldap.refuses_plain_bind` | The directory refuses authentication over a cleartext channel (`confidentialityRequired`, resultCode 13, per RFC 4513 §5.1.2). | Critical | +| `ldap.anonymous_search_blocked` | Flags directories that allow an anonymous `baseObject` search of the naming context (information disclosure). | Warning | +| `ldap.rootdse_readable` | The RootDSE is readable over TLS and advertises naming contexts. | Warning | +| `ldap.sasl_mechanisms` | Reviews `supportedSASLMechanisms`: presence of strong mechanisms (SCRAM-*, EXTERNAL, GSSAPI), absence of password-equivalent ones (PLAIN/LOGIN only). | Warning | +| `ldap.protocol_version` | Flags servers that still advertise the deprecated LDAPv2 protocol. | Warning | +| `ldap.bind_credentials` | The supplied bind credentials are accepted by the directory (only runs when `bind_dn` is set). | Critical | +| `ldap.base_dn_read` | The bound account can read the supplied base DN (only runs when `base_dn` is set and the bind succeeded). | Critical | +| `ldap.tls_quality` | Folds the downstream TLS checker findings (certificate chain, hostname match, expiry) onto the LDAP service. | Critical | + +The HTML report leads with the most common failures and includes server-specific remediation (OpenLDAP `olcSecurity`, 389-ds `require_tls`…): no encrypted endpoint reachable, StartTLS missing on 389, a StartTLS handshake that fails, a cleartext bind accepted on 389, an LDAPS handshake that fails, anonymous search exposing the DIT, PLAIN/LOGIN-only SASL, lingering LDAPv2, and rejected bind credentials. + +## Options + +| Option | Meaning | Default | +|---|---|---| +| Domain | The directory's domain (auto-filled from the service scope). Required. | *(auto)* | +| Per-endpoint timeout (seconds) | Connection/probe timeout for each endpoint. | `10` | +| Bind DN | Optional. DN to bind as; used only when a bind password is also set, and only over a TLS-protected channel. | *(empty)* | +| Bind password | Optional, secret. The password is not persisted in the observation payload and is never sent over cleartext. | *(empty)* | +| Base DN (read test) | Optional. After a successful bind, a `baseObject` search on this DN confirms the account has read access. Falls back to an anonymous `baseObject` search when no bind DN is supplied. | *(empty)* | + +## In happyDomain + +Enable the LDAP checker from the **Checks** tab of an LDAP service. The domain is filled in automatically; supply a bind DN and password only if you want the authenticated bind and base-DN read tests to run. See {{< relref "/pages/checks" >}} for the full workflow, and {{< relref "/reference/checkers/tls" >}} for the certificate posture of the same endpoints. diff --git a/content/reference/checkers/ldap.fr.md b/content/reference/checkers/ldap.fr.md new file mode 100644 index 0000000..552c273 --- /dev/null +++ b/content/reference/checkers/ldap.fr.md @@ -0,0 +1,51 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: LDAP +description: "Sonde l'annuaire LDAP d'un domaine de bout en bout : découverte SRV, chiffrement du transport (StartTLS / LDAPS), introspection RootDSE, exposition anonyme, refus du bind en clair et bind authentifié facultatif." +weight: 250 +--- + +Le vérificateur **LDAP** sonde le déploiement LDAP d'un domaine de bout en bout. À partir de la découverte SRV (`_ldap._tcp`, `_ldaps._tcp`), il teste l'accessibilité de chaque point d'accès, confirme qu'un canal chiffré est disponible (StartTLS selon la RFC 2830 ou TLS implicite sur le port 636), introspecte le RootDSE, recherche une divulgation d'information anonyme, vérifie que l'annuaire refuse les binds en clair et, lorsque des identifiants sont fournis, effectue un bind authentifié sur TLS avec un test de lecture facultatif sur un DN de base. + +Il s'agit d'un vérificateur de **niveau service** : il cible un service *LDAP* (`abstract.LDAP`) publié sur un sous-domaine et se configure depuis l'onglet **Vérifications** de ce service. Pour chaque transport, il sonde `_ldap._tcp` (repli sur le port 389) et `_ldaps._tcp` (repli sur le port 636), en testant chaque adresse A/AAAA résolue par famille d'adresses. + +{{% notice style="info" title="La posture TLS est intégrée, pas dupliquée" %}} +Le vérificateur LDAP confirme uniquement qu'une session TLS peut être établie, en enregistrant la version et l'algorithme négociés à titre de contexte. Chaque point d'accès sondé est publié comme entrée de découverte `tls.endpoint.v1` afin que le vérificateur TLS dédié puisse vérifier la chaîne de certificats, la correspondance du nom d'hôte et l'expiration. Ces constats sont réintégrés sur la page du service LDAP via la règle `ldap.tls_quality` : un certificat défectueux sur un point d'accès LDAP apparaît ici, et pas seulement dans une vue TLS distincte. Consultez {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | Gravité | +|---|---|---| +| `ldap.has_srv` | Les enregistrements SRV `_ldap._tcp` / `_ldaps._tcp` sont publiés et résolvables. | Avertissement | +| `ldap.endpoint_reachable` | Chaque point d'accès LDAP découvert accepte une connexion TCP. | Critique | +| `ldap.has_encrypted_transport` | Au moins un point d'accès accessible propose un canal chiffré (LDAPS ou StartTLS). | Critique | +| `ldap.starttls_supported` | StartTLS est proposé et la bascule réussit sur chaque point d'accès LDAP en clair accessible. | Critique | +| `ldap.ldaps_handshake` | La poignée de main TLS directe réussit sur chaque point d'accès LDAPS. | Critique | +| `ldap.starttls_on_ldaps` | Signale les serveurs qui annoncent inutilement StartTLS sur le port LDAPS à TLS implicite. | Info | +| `ldap.ipv6_reachable` | Au moins un point d'accès est accessible en IPv6. | Info | +| `ldap.refuses_plain_bind` | L'annuaire refuse l'authentification sur un canal en clair (`confidentialityRequired`, resultCode 13, selon la RFC 4513 §5.1.2). | Critique | +| `ldap.anonymous_search_blocked` | Signale les annuaires qui autorisent une recherche `baseObject` anonyme du contexte de nommage (divulgation d'information). | Avertissement | +| `ldap.rootdse_readable` | Le RootDSE est lisible sur TLS et annonce des contextes de nommage. | Avertissement | +| `ldap.sasl_mechanisms` | Examine `supportedSASLMechanisms` : présence de mécanismes forts (SCRAM-*, EXTERNAL, GSSAPI), absence de mécanismes équivalents à un mot de passe (PLAIN/LOGIN seuls). | Avertissement | +| `ldap.protocol_version` | Signale les serveurs qui annoncent encore le protocole LDAPv2 déprécié. | Avertissement | +| `ldap.bind_credentials` | Les identifiants de bind fournis sont acceptés par l'annuaire (ne s'exécute que si `bind_dn` est défini). | Critique | +| `ldap.base_dn_read` | Le compte authentifié peut lire le DN de base fourni (ne s'exécute que si `base_dn` est défini et que le bind a réussi). | Critique | +| `ldap.tls_quality` | Réintègre les constats du vérificateur TLS aval (chaîne de certificats, correspondance du nom d'hôte, expiration) sur le service LDAP. | Critique | + +Le rapport HTML commence par les défaillances les plus courantes et inclut une remédiation propre à chaque serveur (`olcSecurity` sous OpenLDAP, `require_tls` sous 389-ds...) : aucun point d'accès chiffré accessible, StartTLS absent sur 389, une poignée de main StartTLS qui échoue, un bind en clair accepté sur 389, une poignée de main LDAPS qui échoue, une recherche anonyme exposant le DIT, un SASL limité à PLAIN/LOGIN, un LDAPv2 résiduel, et des identifiants de bind rejetés. + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Domaine | Le domaine de l'annuaire (renseigné automatiquement depuis la portée du service). Obligatoire. | *(auto)* | +| Délai d'attente par point d'accès (secondes) | Délai de connexion/sonde pour chaque point d'accès. | `10` | +| Bind DN | Facultatif. DN avec lequel se connecter ; utilisé uniquement si un mot de passe de bind est aussi défini, et seulement sur un canal protégé par TLS. | *(vide)* | +| Mot de passe de bind | Facultatif, secret. Le mot de passe n'est pas conservé dans la charge d'observation et n'est jamais transmis en clair. | *(vide)* | +| DN de base (test de lecture) | Facultatif. Après un bind réussi, une recherche `baseObject` sur ce DN confirme que le compte dispose d'un accès en lecture. Repli sur une recherche `baseObject` anonyme si aucun bind DN n'est fourni. | *(vide)* | + +## Dans happyDomain + +Activez le vérificateur LDAP depuis l'onglet **Vérifications** d'un service LDAP. Le domaine est renseigné automatiquement ; fournissez un bind DN et un mot de passe uniquement si vous souhaitez exécuter les tests de bind authentifié et de lecture du DN de base. Consultez {{< relref "/pages/checks" >}} pour le fonctionnement complet, et {{< relref "/reference/checkers/tls" >}} pour la posture des certificats de ces mêmes points d'accès. diff --git a/content/reference/checkers/legacy-records.en.md b/content/reference/checkers/legacy-records.en.md new file mode 100644 index 0000000..f8879f5 --- /dev/null +++ b/content/reference/checkers/legacy-records.en.md @@ -0,0 +1,35 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Legacy records +description: "Scans a zone for DNS record types deprecated by the IETF and reports each one with its RFC reference and a migration suggestion." +weight: 330 +--- + +The **Legacy DNS record types** checker scans a zone for record types the IETF has deprecated, and reports every occurrence with the relevant RFC reference and a concrete migration suggestion. Deprecated types clutter a zone and, in a few cases, are silently ignored by modern resolvers — so cleaning them up keeps the zone both tidy and unambiguous. + +This is a **zone-level** checker: it walks every service in the working zone in a single pass and consolidates findings by record type, so the report shows one picture rather than one result per record. + +## What it checks + +A single rule, `legacy_records`, inspects each orphan record body for a deprecated type and groups the findings by severity. The default rule status is critical (the worst severity present bubbles to the top of the report). + +| Severity | Record types | Why | +|----------|--------------|-----| +| Critical | `KEY`, `SIG`, `NXT` | RFC 3755: superseded by DNSKEY / RRSIG / NSEC; modern validators ignore them. | +| Warning | `SPF`, `A6`, `MD`, `MF` | RFC 7208 / RFC 6563 / RFC 973: replaced by TXT, AAAA, MX. | +| Info | `WKS`, `MB`, `MG`, `MR`, `MINFO`, `NULL`, `GPOS`, `NSAP`, `NSAP-PTR`, `X25`, `ISDN`, `RT`, `ATMA`, `EID`, `NIMLOC`, `SINK`, `NINFO`, `RKEY` | Experimental or historical (RFC 1035, 1183, 1706, 1712…); safe to delete. | + +For each detected type the report names every owner where it appears, the RFC reason, the suggested replacement, and a concrete "how to fix" instruction. A clean zone produces a single OK state with the scan count; parse errors encountered during the scan are surfaced in a separate "skipped" section so a silent skip never masquerades as a clean pass. + +{{% notice style="info" title="The SPF record type, not the SPF policy" %}} +The `SPF` *record type* (RFC 4408) was deprecated by RFC 7208 in favour of publishing the SPF policy in a `TXT` record. This checker flags the obsolete `SPF` record type, not your SPF policy itself — which remains valid and necessary when published as a `TXT` record. +{{% /notice %}} + +## Options + +This checker has no user-tunable options. The domain name and zone content are filled in automatically. + +## In happyDomain + +Enable this checker on the domain from the {{< relref "/pages/checks" >}} view; it runs over the whole zone in a single pass and needs no configuration. Use its findings as a clean-up checklist: each card tells you which record type to remove and what, if anything, to publish instead. diff --git a/content/reference/checkers/legacy-records.fr.md b/content/reference/checkers/legacy-records.fr.md new file mode 100644 index 0000000..659d330 --- /dev/null +++ b/content/reference/checkers/legacy-records.fr.md @@ -0,0 +1,35 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Enregistrements obsolètes +description: "Analyse une zone à la recherche de types d'enregistrements DNS dépréciés par l'IETF et signale chacun avec sa référence RFC et une suggestion de migration." +weight: 330 +--- + +Le vérificateur **Types d'enregistrements DNS obsolètes** analyse une zone à la recherche de types d'enregistrements dépréciés par l'IETF, et signale chaque occurrence avec la référence RFC pertinente et une suggestion de migration concrète. Les types dépréciés encombrent une zone et, dans quelques cas, sont silencieusement ignorés par les résolveurs modernes : les nettoyer garde la zone à la fois propre et sans ambiguïté. + +Il s'agit d'un vérificateur de **niveau zone** : il parcourt chaque service de la zone de travail en une seule passe et consolide les constats par type d'enregistrement, afin que le rapport présente une vue d'ensemble plutôt qu'un résultat par enregistrement. + +## Ce qui est vérifié + +Une seule règle, `legacy_records`, inspecte le corps de chaque enregistrement orphelin à la recherche d'un type déprécié et regroupe les constats par sévérité. Le statut par défaut de la règle est critique (la pire sévérité présente remonte en tête du rapport). + +| Sévérité | Types d'enregistrement | Pourquoi | +|----------|------------------------|----------| +| Critique | `KEY`, `SIG`, `NXT` | RFC 3755 : remplacés par DNSKEY / RRSIG / NSEC ; les validateurs modernes les ignorent. | +| Avertissement | `SPF`, `A6`, `MD`, `MF` | RFC 7208 / RFC 6563 / RFC 973 : remplacés par TXT, AAAA, MX. | +| Info | `WKS`, `MB`, `MG`, `MR`, `MINFO`, `NULL`, `GPOS`, `NSAP`, `NSAP-PTR`, `X25`, `ISDN`, `RT`, `ATMA`, `EID`, `NIMLOC`, `SINK`, `NINFO`, `RKEY` | Expérimentaux ou historiques (RFC 1035, 1183, 1706, 1712, etc.) ; suppression sans danger. | + +Pour chaque type détecté, le rapport nomme chaque propriétaire où il apparaît, la raison RFC, le remplacement suggéré et une instruction concrète de correction. Une zone propre produit un unique état OK avec le décompte de l'analyse ; les erreurs d'analyse rencontrées pendant le balayage sont exposées dans une section « ignorés » distincte, afin qu'un saut silencieux ne se fasse jamais passer pour un passage propre. + +{{% notice style="info" title="Le type d'enregistrement SPF, pas la politique SPF" %}} +Le *type d'enregistrement* `SPF` (RFC 4408) a été déprécié par la RFC 7208 au profit de la publication de la politique SPF dans un enregistrement `TXT`. Ce vérificateur signale le type d'enregistrement `SPF` obsolète, et non votre politique SPF elle-même, qui reste valide et nécessaire lorsqu'elle est publiée dans un enregistrement `TXT`. +{{% /notice %}} + +## Options + +Ce vérificateur n'a aucune option réglable par l'utilisateur. Le nom de domaine et le contenu de la zone sont renseignés automatiquement. + +## Dans happyDomain + +Activez ce vérificateur sur le domaine depuis la vue {{< relref "/pages/checks" >}} ; il s'exécute sur l'ensemble de la zone en une seule passe et ne nécessite aucune configuration. Utilisez ses constats comme une liste de nettoyage : chaque carte vous indique le type d'enregistrement à supprimer et ce qu'il convient, le cas échéant, de publier à la place. diff --git a/content/reference/checkers/matrix-federation.en.md b/content/reference/checkers/matrix-federation.en.md new file mode 100644 index 0000000..4dbb80d --- /dev/null +++ b/content/reference/checkers/matrix-federation.en.md @@ -0,0 +1,34 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Matrix federation +description: "Verifies that a Matrix homeserver federates correctly, using the Matrix Federation Tester." +weight: 300 +--- + +The **Matrix federation** checker verifies that a Matrix homeserver is correctly set up to federate with the rest of the Matrix network. It delegates the actual probing to a [Matrix Federation Tester](https://federationtester.matrix.org/) instance, stores the full report as an observation, and renders a rich HTML summary covering connections, certificates, well-known delegation and DNS/SRV resolution. + +This is a **service-level** checker. It applies to services of type **Matrix** (instant messaging) and is configured from that service's own **Checks** tab. + +## What it checks + +| Rule | What it verifies | Severity | +|------|------------------|----------| +| `matrix.connection_reachable` | Every discovered federation endpoint accepts an inbound connection. | Critical | +| `matrix.federation_ok` | The overall federation status reported by the Matrix Federation Tester. | Critical | +| `matrix.srv_records` | The Matrix SRV lookup (`_matrix-fed._tcp` / `_matrix._tcp`) succeeded or was legitimately skipped. | Critical | +| `matrix.tls_checks` | The TLS posture on every reachable federation endpoint (certificate chain, hostname, Ed25519 key). | Critical | +| `matrix.version` | The homeserver answers `/_matrix/federation/v1/version` with its name and version. | Warning | +| `matrix.well_known` | `/.well-known/matrix/server`, when published, is valid and points at the declared `server_name`. | Critical | + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Matrix domain | The Matrix `server_name` to test. Filled in automatically from the service. | `matrix.org` | + +An additional **admin-level** option, `federationTesterServer`, sets the URL template of the Federation Tester instance to query. It is configured by the happyDomain operator, not per check, and defaults to `https://federationtester.matrix.org/api/report?server_name=%s`. + +## In happyDomain + +Enable this checker from the **Checks** tab of a Matrix service; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The Matrix domain is filled in automatically from the service. diff --git a/content/reference/checkers/matrix-federation.fr.md b/content/reference/checkers/matrix-federation.fr.md new file mode 100644 index 0000000..79e8641 --- /dev/null +++ b/content/reference/checkers/matrix-federation.fr.md @@ -0,0 +1,34 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Fédération Matrix +description: "Vérifie qu'un serveur Matrix fédère correctement, à l'aide du Matrix Federation Tester." +weight: 300 +--- + +Le vérificateur **Fédération Matrix** vérifie qu'un serveur Matrix (homeserver) est correctement configuré pour fédérer avec le reste du réseau Matrix. Il délègue le sondage proprement dit à une instance du [Matrix Federation Tester](https://federationtester.matrix.org/), stocke le rapport complet sous forme d'observation, et produit un résumé HTML détaillé couvrant les connexions, les certificats, la délégation well-known et la résolution DNS/SRV. + +Il s'agit d'un vérificateur de **niveau service**. Il s'applique aux services de type **Matrix** (messagerie instantanée) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qui est vérifié + +| Règle | Ce qu'elle vérifie | Sévérité | +|-------|--------------------|----------| +| `matrix.connection_reachable` | Chaque point d'accès de fédération découvert accepte une connexion entrante. | Critique | +| `matrix.federation_ok` | Le statut global de fédération rapporté par le Matrix Federation Tester. | Critique | +| `matrix.srv_records` | La résolution SRV Matrix (`_matrix-fed._tcp` / `_matrix._tcp`) a réussi ou a été légitimement ignorée. | Critique | +| `matrix.tls_checks` | La posture TLS sur chaque point d'accès de fédération joignable (chaîne de certificats, nom d'hôte, clé Ed25519). | Critique | +| `matrix.version` | Le serveur répond à `/_matrix/federation/v1/version` avec son nom et sa version. | Avertissement | +| `matrix.well_known` | `/.well-known/matrix/server`, lorsqu'il est publié, est valide et pointe vers le `server_name` déclaré. | Critique | + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Domaine Matrix | Le `server_name` Matrix à tester. Renseigné automatiquement depuis le service. | `matrix.org` | + +Une option supplémentaire de **niveau administrateur**, `federationTesterServer`, définit le modèle d'URL de l'instance du Federation Tester à interroger. Elle est configurée par l'opérateur happyDomain, et non par vérification, et vaut par défaut `https://federationtester.matrix.org/api/report?server_name=%s`. + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** d'un service Matrix ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. Le domaine Matrix est renseigné automatiquement depuis le service. diff --git a/content/reference/checkers/ns-restrictions.en.md b/content/reference/checkers/ns-restrictions.en.md new file mode 100644 index 0000000..7fcab49 --- /dev/null +++ b/content/reference/checkers/ns-restrictions.en.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Name-server restrictions +description: "Probes every authoritative name server of a zone to confirm it is properly locked down: zone transfers refused, no open recursion, and RFC 8482 handling of ANY." +weight: 90 +--- + +The **Name-server restrictions** checker verifies that the authoritative name servers of a zone are properly locked down. For each declared name server it resolves the host name, then runs a set of DNS probes against every returned IPv4 and IPv6 address (IPv6 targets are skipped gracefully when the host has no IPv6 connectivity). The goal is to catch common misconfigurations that leak data or turn a name server into an abuse vector: open zone transfers, open recursion, and unbounded `ANY` responses. + +This checker is **service-level**: it targets an *Origin* or *NS-only Origin* service (`abstract.Origin`, `abstract.NSOnlyOrigin`) and is configured from that service's **Checks** tab. + +## What it checks + +Each rule emits one finding per probed name-server address, with a stable `code`. + +| Rule | Verifies | Severity on failure | +|---|---|---| +| `ns_resolution` | Every NS host name declared in the delegation resolves to at least one IP address. | Critical | +| `ns_axfr_refused` | `AXFR` zone transfers are refused by every authoritative name server. | Critical | +| `ns_ixfr_refused` | `IXFR` zone transfers are refused by every authoritative name server. | Warning | +| `ns_no_recursion` | Authoritative name servers do not advertise recursion (RA bit unset). | Warning | +| `ns_any_handled` | `ANY` queries are handled per RFC 8482 (HINFO or a minimal answer rather than the full zone contents). | Warning | +| `ns_is_authoritative` | Name servers answer authoritatively (AA bit set) for the zone. | Info | + +{{% notice style="info" title="Why these matter" %}} +An open `AXFR` lets anyone download the entire zone, exposing your internal naming. Open recursion turns your authoritative server into an amplification relay and cache-poisoning target. Unbounded `ANY` responses are a classic amplification vector that RFC 8482 was written to neutralise. +{{% /notice %}} + +## Options + +This checker has no user-tunable options: it runs a fixed set of probes against each resolved name-server address. + +## In happyDomain + +Enable the Name-server restrictions checker from the **Checks** tab of an Origin service. See {{< relref "/pages/checks" >}} for the full workflow. For the broader health and agreement of those same authoritative servers, see {{< relref "/reference/checkers/authoritative-consistency" >}}. diff --git a/content/reference/checkers/ns-restrictions.fr.md b/content/reference/checkers/ns-restrictions.fr.md new file mode 100644 index 0000000..3200525 --- /dev/null +++ b/content/reference/checkers/ns-restrictions.fr.md @@ -0,0 +1,36 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Restrictions des serveurs de noms +description: "Sonde chaque serveur faisant autorité d'une zone pour confirmer qu'il est correctement verrouillé : transferts de zone refusés, pas de récursion ouverte, gestion d'ANY conforme à la RFC 8482." +weight: 90 +--- + +Le vérificateur **Restrictions des serveurs de noms** vérifie que les serveurs faisant autorité d'une zone sont correctement verrouillés. Pour chaque serveur de noms déclaré, il résout le nom d'hôte puis lance une série de sondes DNS contre chaque adresse IPv4 et IPv6 renvoyée (les cibles IPv6 sont ignorées sans erreur lorsque l'hôte n'a pas de connectivité IPv6). L'objectif est de détecter les erreurs de configuration courantes qui divulguent des données ou transforment un serveur de noms en vecteur d'abus : transferts de zone ouverts, récursion ouverte et réponses `ANY` non bornées. + +Ce vérificateur s'applique au niveau du **service** : il cible un service d'origine ou d'origine NS-seule (`abstract.Origin`, `abstract.NSOnlyOrigin`) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +Chaque règle émet un constat par adresse de serveur de noms sondée, avec un `code` stable. + +| Règle | Vérifie | Sévérité en cas d'échec | +|---|---|---| +| `ns_resolution` | Chaque nom d'hôte NS déclaré dans la délégation se résout en au moins une adresse IP. | Critique | +| `ns_axfr_refused` | Les transferts de zone `AXFR` sont refusés par chaque serveur faisant autorité. | Critique | +| `ns_ixfr_refused` | Les transferts de zone `IXFR` sont refusés par chaque serveur faisant autorité. | Avertissement | +| `ns_no_recursion` | Les serveurs faisant autorité n'annoncent pas la récursion (bit RA non positionné). | Avertissement | +| `ns_any_handled` | Les requêtes `ANY` sont traitées conformément à la RFC 8482 (HINFO ou réponse minimale plutôt que le contenu complet de la zone). | Avertissement | +| `ns_is_authoritative` | Les serveurs de noms répondent de façon autoritaire (bit AA positionné) pour la zone. | Info | + +{{% notice style="info" title="Pourquoi c'est important" %}} +Un `AXFR` ouvert permet à quiconque de télécharger la zone entière, exposant votre nommage interne. La récursion ouverte transforme votre serveur faisant autorité en relais d'amplification et en cible d'empoisonnement de cache. Les réponses `ANY` non bornées constituent un vecteur d'amplification classique que la RFC 8482 a été écrite pour neutraliser. +{{% /notice %}} + +## Options + +Ce vérificateur n'expose aucune option réglable : il exécute un ensemble fixe de sondes contre chaque adresse de serveur de noms résolue. + +## Dans happyDomain + +Activez le vérificateur Restrictions des serveurs de noms depuis l'onglet **Vérifications** d'un service d'origine. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet. Pour la santé et l'accord plus larges de ces mêmes serveurs faisant autorité, voyez {{< relref "/reference/checkers/authoritative-consistency" >}}. diff --git a/content/reference/checkers/ping.en.md b/content/reference/checkers/ping.en.md new file mode 100644 index 0000000..56d642f --- /dev/null +++ b/content/reference/checkers/ping.en.md @@ -0,0 +1,34 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Ping +description: "Sends ICMP probes to every address of a service and reports reachability, average round-trip time, packet loss, and IPv6 coverage." +weight: 190 +--- + +The **Ping (ICMP)** checker measures basic network reachability for the addresses behind a service. It sends a small number of ICMP echo requests to each `A`/`AAAA` address and reports whether the target replied, its average round-trip time (RTT), the observed packet-loss ratio, and whether at least one IPv6 address answered. + +**Scope:** service-level. It attaches to services of type `abstract.Server` (a subdomain that publishes `A`/`AAAA` records) and is configured from that service's **Checks** tab. + +## What it checks + +| Rule | Verifies | Warn / Critical conditions | +|------|----------|----------------------------| +| `ping.reachable` | Every target replied to at least one ICMP probe. | Critical when a target never replies. | +| `ping.rtt` | Average round-trip time stays within thresholds. | Warning above the warning RTT, Critical above the critical RTT. | +| `ping.ipv6_reachable` | At least one IPv6 target replied to an ICMP probe. | Warning when no IPv6 address answers. | +| `ping.packet_loss` | Packet-loss ratio stays within thresholds. | Warning above the warning loss ratio, Critical above the critical loss ratio. | + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Warning RTT threshold (ms) (`warningRTT`) | Average RTT above which the check warns. | 100 | +| Critical RTT threshold (ms) (`criticalRTT`) | Average RTT above which the check is critical. | 500 | +| Warning packet loss threshold (%) (`warningPacketLoss`) | Packet-loss ratio above which the check warns. | 10 | +| Critical packet loss threshold (%) (`criticalPacketLoss`) | Packet-loss ratio above which the check is critical. | 50 | +| Number of pings to send (`count`) | ICMP echo requests sent per target. | 5 | + +## In happyDomain + +This is a service-level checker: configure it from the **Checks** tab of the *Server* service on the relevant subdomain. Its short default interval makes it well suited to lightweight, frequent reachability monitoring. For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/ping.fr.md b/content/reference/checkers/ping.fr.md new file mode 100644 index 0000000..bbcc9ad --- /dev/null +++ b/content/reference/checkers/ping.fr.md @@ -0,0 +1,34 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Ping +description: "Envoie des sondes ICMP à chaque adresse d'un service et rapporte l'accessibilité, le temps d'aller-retour moyen, la perte de paquets et la couverture IPv6." +weight: 190 +--- + +Le vérificateur **Ping (ICMP)** mesure l'accessibilité réseau de base des adresses derrière un service. Il envoie un petit nombre de requêtes echo ICMP à chaque adresse `A`/`AAAA` et rapporte si la cible a répondu, son temps d'aller-retour moyen (RTT), le taux de perte de paquets observé, et si au moins une adresse IPv6 a répondu. + +**Portée** : niveau service. Il s'attache aux services de type `abstract.Server` (un sous-domaine publiant des enregistrements `A`/`AAAA`) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +| Règle | Vérifie | Conditions avertissement / critique | +|-------|---------|-------------------------------------| +| `ping.reachable` | Chaque cible a répondu à au moins une sonde ICMP. | Critique lorsqu'une cible ne répond jamais. | +| `ping.rtt` | Le temps d'aller-retour moyen reste dans les seuils. | Avertissement au-dessus du RTT d'avertissement, critique au-dessus du RTT critique. | +| `ping.ipv6_reachable` | Au moins une cible IPv6 a répondu à une sonde ICMP. | Avertissement quand aucune adresse IPv6 ne répond. | +| `ping.packet_loss` | Le taux de perte de paquets reste dans les seuils. | Avertissement au-dessus du taux d'avertissement, critique au-dessus du taux critique. | + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Seuil d'avertissement RTT (ms) (`warningRTT`) | RTT moyen au-dessus duquel la vérification avertit. | 100 | +| Seuil critique RTT (ms) (`criticalRTT`) | RTT moyen au-dessus duquel la vérification est critique. | 500 | +| Seuil d'avertissement de perte de paquets (%) (`warningPacketLoss`) | Taux de perte au-dessus duquel la vérification avertit. | 10 | +| Seuil critique de perte de paquets (%) (`criticalPacketLoss`) | Taux de perte au-dessus duquel la vérification est critique. | 50 | +| Nombre de pings à envoyer (`count`) | Requêtes echo ICMP envoyées par cible. | 5 | + +## Dans happyDomain + +C'est un vérificateur de niveau service : configurez-le depuis l'onglet **Vérifications** du service « Serveur » sur le sous-domaine concerné. Son intervalle par défaut court le rend adapté à une surveillance d'accessibilité légère et fréquente. Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/ptr.en.md b/content/reference/checkers/ptr.en.md new file mode 100644 index 0000000..9b9a8a6 --- /dev/null +++ b/content/reference/checkers/ptr.en.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: PTR records +description: "Validates reverse DNS for an IP: PTR presence, target syntax, forward resolution and Forward-Confirmed Reverse DNS (FCrDNS)." +weight: 120 +--- + +The **PTR / Reverse DNS** checker verifies that an IP address has a correct, usable reverse-DNS record. A PTR maps an IP back to a hostname; mail servers, SSH daemons and many logging tools rely on it, and a missing or inconsistent PTR is one of the most common reasons outgoing mail is rejected. + +This is a **service-level** checker: it runs on a `PTR` service and is configured from that service's own **Checks** tab. It locates the reverse zone (under `in-addr.arpa` or `ip6.arpa`), queries the authoritative servers, and inspects what they actually serve — both for IPv4 and IPv6 addresses. + +## What it checks + +The checker runs a chain of rules, from structural sanity through query success to target hygiene and Forward-Confirmed Reverse DNS (FCrDNS). + +| Rule | What it verifies | Severity | +|------|------------------|----------| +| `ptr.in_reverse_arpa` | The PTR owner lies under `in-addr.arpa` or `ip6.arpa`. | Critical | +| `ptr.owner_decodable` | The reverse-arpa owner name decodes back to an IP address. | Critical | +| `ptr.reverse_zone_located` | The reverse zone serving the owner can be located (SOA found). | Critical | +| `ptr.query_succeeded` | The PTR query returns NOERROR from the authoritative servers. | Critical | +| `ptr.record_present` | At least one PTR record is served at the owner name. | Critical | +| `ptr.single_record` | Flags more than one PTR on the same IP (RFC 1912 §2.1 recommends exactly one). | Warning | +| `ptr.declared_match` | The PTR target served authoritatively matches the target declared in happyDomain. | Critical | +| `ptr.target_syntax_valid` | The PTR target is a syntactically valid hostname (RFC 952/1123). | Critical | +| `ptr.generic_hostname` | Flags PTR targets that embed the IP or match common ISP auto-generated patterns. | Warning | +| `ptr.target_resolves` | The PTR target resolves to at least one A or AAAA record. | Critical / Warning | +| `ptr.fcrdns_match` | The PTR target's A/AAAA resolves back to the original IP (FCrDNS). | Critical / Warning | +| `ptr.ipv6` | Reports whether the PTR concerns an IPv6 (`ip6.arpa`) address, and that a PTR is present for it. | Critical | +| `ptr.ttl_hygiene` | The PTR TTL is at or above the configured minimum. | Warning | + +The `ptr.target_resolves` and `ptr.fcrdns_match` rules are critical by default but drop to a warning when **Require forward-confirmed reverse DNS** is turned off. + +{{% notice style="info" title="FCrDNS, the round-trip rule" %}} +Forward-Confirmed Reverse DNS means the chain rounds back to itself: the IP's PTR points to a hostname, and that hostname's A/AAAA includes the original IP. Mail servers reject connections from IPs that fail this round-trip, so leave **Require forward-confirmed reverse DNS** enabled for any host that sends mail. +{{% /notice %}} + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Require forward-confirmed reverse DNS (FCrDNS) | When enabled, a PTR whose target does not resolve back to the original IP is critical; otherwise a warning. | `true` | +| Allow multiple PTR records on the same IP | When disabled, more than one PTR at the same owner is flagged as a warning (RFC 1912 §2.1). | `false` | +| Minimum PTR TTL (seconds) | PTR records with a TTL below this threshold are flagged as a warning. | `300` | +| Flag generic-looking PTR hostnames | When enabled, PTR targets embedding the dotted IP or matching common ISP auto-generated patterns warn. | `true` | + +## In happyDomain + +Add the PTR service to the subdomain holding the reverse record, then enable this checker from that service's **Checks** tab. See {{< relref "/pages/checks" >}} for configuring and scheduling checks. The reverse zone, the PTR record and the declared target are filled in automatically from the service. + +For the forward side of alias and hostname resolution, see the related {{< relref "/reference/checkers/alias" >}} checker. diff --git a/content/reference/checkers/ptr.fr.md b/content/reference/checkers/ptr.fr.md new file mode 100644 index 0000000..83c2357 --- /dev/null +++ b/content/reference/checkers/ptr.fr.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Enregistrements PTR +description: "Valide le DNS inverse d'une adresse IP : présence du PTR, syntaxe de la cible, résolution directe et Forward-Confirmed Reverse DNS (FCrDNS)." +weight: 120 +--- + +Le vérificateur **PTR / DNS inverse** vérifie qu'une adresse IP dispose d'un enregistrement de DNS inverse correct et exploitable. Un PTR associe une IP à un nom d'hôte ; les serveurs de messagerie, les démons SSH et de nombreux outils de journalisation s'appuient dessus, et un PTR absent ou incohérent est l'une des causes les plus fréquentes de rejet du courrier sortant. + +Il s'agit d'un vérificateur de **niveau service** : il s'exécute sur un service `PTR` et se configure depuis l'onglet **Vérifications** de ce service. Il localise la zone inverse (sous `in-addr.arpa` ou `ip6.arpa`), interroge les serveurs faisant autorité et inspecte ce qu'ils servent réellement, aussi bien pour les adresses IPv4 qu'IPv6. + +## Ce qui est vérifié + +Le vérificateur enchaîne une série de règles, de la cohérence structurelle au succès de la requête, puis à l'hygiène de la cible et au Forward-Confirmed Reverse DNS (FCrDNS). + +| Règle | Ce qui est vérifié | Sévérité | +|-------|--------------------|----------| +| `ptr.in_reverse_arpa` | Le propriétaire du PTR se trouve sous `in-addr.arpa` ou `ip6.arpa`. | Critique | +| `ptr.owner_decodable` | Le nom du propriétaire en `.arpa` se décode bien en une adresse IP. | Critique | +| `ptr.reverse_zone_located` | La zone inverse servant ce propriétaire peut être localisée (SOA trouvé). | Critique | +| `ptr.query_succeeded` | La requête PTR renvoie NOERROR depuis les serveurs faisant autorité. | Critique | +| `ptr.record_present` | Au moins un enregistrement PTR est servi au nom du propriétaire. | Critique | +| `ptr.single_record` | Signale plusieurs PTR sur la même IP (la RFC 1912 §2.1 en recommande un seul). | Avertissement | +| `ptr.declared_match` | La cible PTR servie fait autorité correspond à celle déclarée dans happyDomain. | Critique | +| `ptr.target_syntax_valid` | La cible PTR est un nom d'hôte syntaxiquement valide (RFC 952/1123). | Critique | +| `ptr.generic_hostname` | Signale les cibles PTR qui contiennent l'IP ou suivent un motif générique de FAI. | Avertissement | +| `ptr.target_resolves` | La cible PTR se résout vers au moins un enregistrement A ou AAAA. | Critique / Avertissement | +| `ptr.fcrdns_match` | Le A/AAAA de la cible PTR se résout de nouveau vers l'IP d'origine (FCrDNS). | Critique / Avertissement | +| `ptr.ipv6` | Indique si le PTR concerne une adresse IPv6 (`ip6.arpa`) et qu'un PTR est présent pour elle. | Critique | +| `ptr.ttl_hygiene` | Le TTL du PTR est supérieur ou égal au minimum configuré. | Avertissement | + +Les règles `ptr.target_resolves` et `ptr.fcrdns_match` sont critiques par défaut, mais passent en avertissement lorsque l'option **Exiger le Forward-Confirmed Reverse DNS** est désactivée. + +{{% notice style="info" title="Le FCrDNS, la règle de l'aller-retour" %}} +Le Forward-Confirmed Reverse DNS signifie que la chaîne boucle sur elle-même : le PTR de l'IP pointe vers un nom d'hôte, et le A/AAAA de ce nom d'hôte inclut l'IP d'origine. Les serveurs de messagerie rejettent les connexions des IP qui échouent à cet aller-retour ; laissez donc **Exiger le Forward-Confirmed Reverse DNS** activé pour tout hôte qui envoie du courrier. +{{% /notice %}} + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Exiger le Forward-Confirmed Reverse DNS (FCrDNS) | Lorsqu'activée, un PTR dont la cible ne se résout pas vers l'IP d'origine est critique ; sinon, c'est un avertissement. | `true` | +| Autoriser plusieurs PTR sur la même IP | Lorsqu'elle est désactivée, plusieurs PTR au même propriétaire sont signalés comme avertissement (RFC 1912 §2.1). | `false` | +| TTL minimal du PTR (secondes) | Les PTR dont le TTL est inférieur à ce seuil sont signalés comme avertissement. | `300` | +| Signaler les noms d'hôte PTR génériques | Lorsqu'activée, les cibles PTR contenant l'IP en notation pointée ou suivant un motif générique de FAI déclenchent un avertissement. | `true` | + +## Dans happyDomain + +Ajoutez le service PTR au sous-domaine portant l'enregistrement inverse, puis activez ce vérificateur depuis l'onglet **Vérifications** de ce service. Consultez {{< relref "/pages/checks" >}} pour configurer et planifier les vérifications. La zone inverse, l'enregistrement PTR et la cible déclarée sont renseignés automatiquement à partir du service. + +Pour le versant direct de la résolution des alias et des noms d'hôte, voyez le vérificateur {{< relref "/reference/checkers/alias" >}}. diff --git a/content/reference/checkers/resolver-propagation.en.md b/content/reference/checkers/resolver-propagation.en.md new file mode 100644 index 0000000..10f0964 --- /dev/null +++ b/content/reference/checkers/resolver-propagation.en.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Resolver propagation +description: "Probes a worldwide catalog of public recursive resolvers across several transports and regions, then compares their answers to the zone's authoritative servers." +weight: 100 +--- + +The **Resolver propagation** checker measures how a zone is seen from the *outside*, across the public internet. It probes a curated catalog of public recursive resolvers (Cloudflare, Google, Quad9, OpenDNS, Yandex, regional ISPs and more) over several transports (UDP, TCP, DoT, DoH) and from multiple regions, then compares their answers both to each other and to the zone's authoritative name servers. This surfaces propagation gaps, regional splits, `SOA` serial drift, stale caches, DNSSEC validation failures, `SERVFAIL`/`NXDOMAIN` inconsistencies and resolver filtering. + +This checker is **service-level**: it targets an *Origin* or *NS-only Origin* service (`abstract.Origin`, `abstract.NSOnlyOrigin`) and is configured from that service's **Checks** tab. + +## What it checks + +| Finding code | What it checks | Severity | +|---|---|---| +| `resolver_propagation.selection` | The current option set selects at least one public resolver. | Critical | +| `resolver_propagation.reachable` | At least one selected resolver answered a query. | Critical | +| `resolver_propagation.latency` | Resolvers that are unreachable or whose average response time exceeds the threshold. | Warning | +| `resolver_propagation.filtered_hit` | Filtered resolvers returning a different answer than the consensus (typical blocklist behaviour). | Info | +| `resolver_propagation.consensus` | Public resolvers agree on a single answer for each probed RRset. | Warning | +| `resolver_propagation.matches_authoritative` | The public consensus matches the answer served by the zone's authoritative servers. | Critical | +| `resolver_propagation.nxdomain` | RRsets for which some resolvers return `NXDOMAIN` while others return `NOERROR`. | Critical | +| `resolver_propagation.servfail` | RRsets for which any resolver returns `SERVFAIL` (usually DNSSEC or reachability failure). | Critical | +| `resolver_propagation.regional_split` | Regions where every resolver agrees on an answer that differs from the global consensus. | Warning | +| `resolver_propagation.serial_drift` | Disagreement on the `SOA` serial across unfiltered resolvers. | Warning | +| `resolver_propagation.stale_cache` | Resolvers still serving an `SOA` serial below the one saved by happyDomain. | Info | +| `resolver_propagation.dnssec` | Validating resolvers successfully validate the zone's DNSSEC chain. | Critical | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| `recordTypes` | Comma-separated RR types to probe at every owner. Empty = derive from the working zone (SOA/NS at the apex plus the RR types actually defined on each owner). | _derived from zone_ | +| `subdomains` | Comma-separated owner names to probe in addition to the apex (e.g. `www,mail,@`). Empty = apex only. | `www` | +| `includeFiltered` | Probe filtering resolvers (malware/family/adblock). Their answers diverge by design; enable only when diagnosing a blocklist hit. | `false` | +| `region` | Restrict to a region: `all`, `global`, `na`, `eu`, `asia`, `ru`, `me`. | `all` | +| `transports` | Comma-separated transports to probe: `udp`, `tcp`, `dot`, `doh`. Encrypted transports are only used where published. | `udp` | +| `resolverAllowlist` | Comma-separated resolver IDs or IPs to probe exclusively (e.g. `cloudflare,google,9.9.9.9`). Empty = catalog selection. | _(empty)_ | +| `latencyThresholdMs` | Resolvers averaging above this value emit an info finding. | `500` | +| `runTimeoutSeconds` | Hard wall-clock budget for one propagation run. Slower resolvers report as unreachable. | `30` | + +## In happyDomain + +Enable the Resolver propagation checker from the **Checks** tab of an Origin service. See {{< relref "/pages/checks" >}} for the full workflow. This checker is the outward-facing counterpart to {{< relref "/reference/checkers/authoritative-consistency" >}}, which examines the authoritative servers directly; running both gives you the picture from the origin and from the resolvers that query it. diff --git a/content/reference/checkers/resolver-propagation.fr.md b/content/reference/checkers/resolver-propagation.fr.md new file mode 100644 index 0000000..03e92d8 --- /dev/null +++ b/content/reference/checkers/resolver-propagation.fr.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Propagation chez les résolveurs +description: "Sonde un catalogue mondial de résolveurs récursifs publics sur plusieurs transports et régions, puis compare leurs réponses aux serveurs faisant autorité de la zone." +weight: 100 +--- + +Le vérificateur **Propagation chez les résolveurs** mesure la façon dont une zone est vue depuis l'*extérieur*, à travers l'internet public. Il sonde un catalogue choisi de résolveurs récursifs publics (Cloudflare, Google, Quad9, OpenDNS, Yandex, FAI régionaux et autres) sur plusieurs transports (UDP, TCP, DoT, DoH) et depuis plusieurs régions, puis compare leurs réponses entre elles et avec celles des serveurs faisant autorité de la zone. Cela révèle les retards de propagation, les divergences régionales, les écarts de numéro de série `SOA`, les caches périmés, les échecs de validation DNSSEC, les incohérences `SERVFAIL`/`NXDOMAIN` et le filtrage par les résolveurs. + +Ce vérificateur s'applique au niveau du **service** : il cible un service d'origine ou d'origine NS-seule (`abstract.Origin`, `abstract.NSOnlyOrigin`) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +| Code de constat | Ce qui est vérifié | Sévérité | +|---|---|---| +| `resolver_propagation.selection` | Le jeu d'options courant sélectionne au moins un résolveur public. | Critique | +| `resolver_propagation.reachable` | Au moins un résolveur sélectionné a répondu à une requête. | Critique | +| `resolver_propagation.latency` | Résolveurs injoignables ou dont le temps de réponse moyen dépasse le seuil. | Avertissement | +| `resolver_propagation.filtered_hit` | Résolveurs filtrants renvoyant une réponse différente du consensus (comportement typique d'une liste de blocage). | Info | +| `resolver_propagation.consensus` | Les résolveurs publics s'accordent sur une réponse unique pour chaque RRset sondé. | Avertissement | +| `resolver_propagation.matches_authoritative` | Le consensus public correspond à la réponse servie par les serveurs faisant autorité de la zone. | Critique | +| `resolver_propagation.nxdomain` | RRset pour lesquels certains résolveurs renvoient `NXDOMAIN` quand d'autres renvoient `NOERROR`. | Critique | +| `resolver_propagation.servfail` | RRset pour lesquels un résolveur renvoie `SERVFAIL` (généralement échec DNSSEC ou de joignabilité). | Critique | +| `resolver_propagation.regional_split` | Régions où tous les résolveurs s'accordent sur une réponse différente du consensus mondial. | Avertissement | +| `resolver_propagation.serial_drift` | Désaccord sur le numéro de série `SOA` parmi les résolveurs non filtrants. | Avertissement | +| `resolver_propagation.stale_cache` | Résolveurs servant encore un numéro de série `SOA` inférieur à celui enregistré par happyDomain. | Info | +| `resolver_propagation.dnssec` | Les résolveurs validants valident avec succès la chaîne DNSSEC de la zone. | Critique | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| `recordTypes` | Types de RR à sonder à chaque propriétaire, séparés par des virgules. Vide : dérivés de la zone de travail (SOA/NS à l'apex plus les types de RR réellement définis sur chaque propriétaire). | _dérivé de la zone_ | +| `subdomains` | Noms de propriétaires à sonder en plus de l'apex, séparés par des virgules (par exemple `www,mail,@`). Vide : apex seul. | `www` | +| `includeFiltered` | Sonde les résolveurs filtrants (malware/famille/anti-pub). Leurs réponses divergent par conception ; n'activer que pour diagnostiquer un blocage. | `false` | +| `region` | Restreint à une région : `all`, `global`, `na`, `eu`, `asia`, `ru`, `me`. | `all` | +| `transports` | Transports à sonder, séparés par des virgules : `udp`, `tcp`, `dot`, `doh`. Les transports chiffrés ne sont utilisés que là où ils sont publiés. | `udp` | +| `resolverAllowlist` | Identifiants ou IP de résolveurs à sonder exclusivement, séparés par des virgules (par exemple `cloudflare,google,9.9.9.9`). Vide : sélection du catalogue. | _(vide)_ | +| `latencyThresholdMs` | Les résolveurs dont la moyenne dépasse cette valeur émettent un constat d'information. | `500` | +| `runTimeoutSeconds` | Budget temps absolu pour une exécution de propagation. Les résolveurs plus lents sont signalés comme injoignables. | `30` | + +## Dans happyDomain + +Activez le vérificateur Propagation chez les résolveurs depuis l'onglet **Vérifications** d'un service d'origine. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet. Ce vérificateur est le pendant tourné vers l'extérieur de {{< relref "/reference/checkers/authoritative-consistency" >}}, qui examine directement les serveurs faisant autorité ; exécuter les deux donne la vue depuis l'origine et depuis les résolveurs qui l'interrogent. diff --git a/content/reference/checkers/reverse-zone.en.md b/content/reference/checkers/reverse-zone.en.md new file mode 100644 index 0000000..61b5deb --- /dev/null +++ b/content/reference/checkers/reverse-zone.en.md @@ -0,0 +1,43 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Reverse zone +description: "Inspects the PTR records of an in-addr.arpa or ip6.arpa reverse zone for FCrDNS, target resolvability, hostname syntax, generic names and TTL hygiene." +weight: 110 +--- + +The **Reverse zone** checker inspects the `PTR` records of a reverse DNS zone (`in-addr.arpa` or `ip6.arpa`) and validates that they are well formed and consistent with forward DNS. It verifies Forward-Confirmed Reverse DNS (FCrDNS), that targets resolve and are syntactically valid host names, flags generic or auto-generated names and short TTLs, and catches multiple-`PTR`-per-IP violations (RFC 1912 §2.1). Correct reverse DNS matters in practice: mail servers and SSH endpoints routinely reject or downgrade connections from IPs without proper FCrDNS. + +This checker is **zone-level**: it operates on the full content of a reverse zone (it applies to the domain and reads the whole zone). + +## What it checks + +| Finding code | What it verifies | Severity | +|---|---|---| +| `reverse_zone.is_reverse_arpa` | The zone is under `in-addr.arpa` or `ip6.arpa`. | Critical | +| `reverse_zone.has_ptrs` | The reverse zone declares at least one `PTR` record. | Warning | +| `reverse_zone.fcrdns` | Every `PTR` target's `A`/`AAAA` round-trips back to the original IP (Forward-Confirmed Reverse DNS). | Critical | +| `reverse_zone.target_resolves` | Every `PTR` target resolves to at least one `A` or `AAAA` record. | Critical | +| `reverse_zone.single_ptr_per_ip` | Flags IPs with multiple `PTR` records (RFC 1912 §2.1 recommends exactly one). | Warning | +| `reverse_zone.target_syntax` | Every `PTR` target is a syntactically valid host name. | Critical | +| `reverse_zone.generic_hostname` | Flags `PTR` targets that embed the IP or match common ISP auto-generated patterns. | Warning | +| `reverse_zone.ttl_hygiene` | Flags `PTR` records whose TTL is below the configured minimum. | Warning | +| `reverse_zone.truncated` | Reports when the zone has more `PTR`s than the configured cap allows to inspect. | Info | + +## Options + +| Option | Meaning | Default | +|---|---|---| +| `requireForwardMatch` | When enabled, a `PTR` whose target does not resolve back to the original IP is critical (otherwise warning). Mail and SSH servers require FCrDNS. | `true` | +| `allowMultiplePTR` | When disabled, more than one `PTR` at the same owner is reported as warning (RFC 1912 §2.1 recommends a single `PTR` per IP). | `false` | +| `minTTL` | `PTR` records with a TTL below this threshold (in seconds) are flagged as warning. | `300` | +| `flagGenericPTR` | When enabled, `PTR` targets that embed the dotted IP or match common ISP auto-generated patterns are flagged as warning. | `true` | +| `maxPTRsToCheck` | Caps the number of `PTR` records inspected per run, protecting the checker against very large reverse zones. | `1024` | + +{{% notice style="info" title="Forward-Confirmed Reverse DNS" %}} +FCrDNS means the `PTR` target, looked up forward, resolves back to the original IP address. A `PTR` that points to a host whose `A`/`AAAA` does not include that IP fails the round-trip and is treated as a misconfiguration by many mail and SSH servers. +{{% /notice %}} + +## In happyDomain + +Enable the Reverse zone checker on a reverse (`in-addr.arpa` / `ip6.arpa`) domain from its **Checks** view. See {{< relref "/pages/checks" >}} for the full workflow. diff --git a/content/reference/checkers/reverse-zone.fr.md b/content/reference/checkers/reverse-zone.fr.md new file mode 100644 index 0000000..751d6fa --- /dev/null +++ b/content/reference/checkers/reverse-zone.fr.md @@ -0,0 +1,43 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Zone inverse +description: "Inspecte les enregistrements PTR d'une zone inverse in-addr.arpa ou ip6.arpa : FCrDNS, résolvabilité des cibles, syntaxe des noms, noms génériques et hygiène des TTL." +weight: 110 +--- + +Le vérificateur **Zone inverse** inspecte les enregistrements `PTR` d'une zone DNS inverse (`in-addr.arpa` ou `ip6.arpa`) et valide qu'ils sont bien formés et cohérents avec le DNS direct. Il vérifie le Forward-Confirmed Reverse DNS (FCrDNS), s'assure que les cibles se résolvent et sont des noms d'hôtes syntaxiquement valides, signale les noms génériques ou auto-générés et les TTL trop courts, et détecte les violations de plusieurs `PTR` par IP (RFC 1912 §2.1). Un DNS inverse correct compte en pratique : les serveurs de courrier et les points d'accès SSH rejettent ou dégradent régulièrement les connexions provenant d'IP sans FCrDNS valide. + +Ce vérificateur s'applique au niveau de la **zone** : il opère sur le contenu complet d'une zone inverse (il s'applique au domaine et lit l'intégralité de la zone). + +## Ce qu'il vérifie + +| Code de constat | Ce qui est vérifié | Sévérité | +|---|---|---| +| `reverse_zone.is_reverse_arpa` | La zone est sous `in-addr.arpa` ou `ip6.arpa`. | Critique | +| `reverse_zone.has_ptrs` | La zone inverse déclare au moins un enregistrement `PTR`. | Avertissement | +| `reverse_zone.fcrdns` | Le `A`/`AAAA` de chaque cible `PTR` revient bien à l'IP d'origine (Forward-Confirmed Reverse DNS). | Critique | +| `reverse_zone.target_resolves` | Chaque cible `PTR` se résout en au moins un enregistrement `A` ou `AAAA`. | Critique | +| `reverse_zone.single_ptr_per_ip` | Signale les IP ayant plusieurs `PTR` (la RFC 1912 §2.1 en recommande exactement un). | Avertissement | +| `reverse_zone.target_syntax` | Chaque cible `PTR` est un nom d'hôte syntaxiquement valide. | Critique | +| `reverse_zone.generic_hostname` | Signale les cibles `PTR` qui intègrent l'IP ou correspondent aux motifs auto-générés courants des FAI. | Avertissement | +| `reverse_zone.ttl_hygiene` | Signale les `PTR` dont le TTL est inférieur au minimum configuré. | Avertissement | +| `reverse_zone.truncated` | Signale lorsque la zone compte plus de `PTR` que le plafond configuré ne permet d'inspecter. | Info | + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| `requireForwardMatch` | Si activé, un `PTR` dont la cible ne revient pas à l'IP d'origine est critique (sinon avertissement). Les serveurs de courrier et SSH exigent le FCrDNS. | `true` | +| `allowMultiplePTR` | Si désactivé, plus d'un `PTR` au même propriétaire est signalé en avertissement (la RFC 1912 §2.1 recommande un seul `PTR` par IP). | `false` | +| `minTTL` | Les `PTR` dont le TTL est inférieur à ce seuil (en secondes) sont signalés en avertissement. | `300` | +| `flagGenericPTR` | Si activé, les cibles `PTR` qui intègrent l'IP pointée ou correspondent aux motifs auto-générés courants des FAI sont signalées en avertissement. | `true` | +| `maxPTRsToCheck` | Plafonne le nombre de `PTR` inspectés par exécution, protégeant le vérificateur contre les très grandes zones inverses. | `1024` | + +{{% notice style="info" title="Forward-Confirmed Reverse DNS" %}} +Le FCrDNS signifie que la cible du `PTR`, résolue en direct, revient bien à l'adresse IP d'origine. Un `PTR` pointant vers un hôte dont le `A`/`AAAA` n'inclut pas cette IP échoue à l'aller-retour et est considéré comme une mauvaise configuration par de nombreux serveurs de courrier et SSH. +{{% /notice %}} + +## Dans happyDomain + +Activez le vérificateur Zone inverse sur un domaine inverse (`in-addr.arpa` / `ip6.arpa`) depuis sa vue **Vérifications**. Consultez {{< relref "/pages/checks" >}} pour le déroulé complet. diff --git a/content/reference/checkers/sip.en.md b/content/reference/checkers/sip.en.md new file mode 100644 index 0000000..747fc7f --- /dev/null +++ b/content/reference/checkers/sip.en.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SIP +description: "Probes a domain's SIP/VoIP deployment end-to-end: RFC 3263 NAPTR/SRV resolution, endpoint reachability over UDP/TCP/TLS, and a SIP OPTIONS ping with capability inspection." +weight: 270 +--- + +The **SIP** checker probes a domain's SIP/VoIP deployment from its DNS records, following RFC 3263 resolution: NAPTR → SRV (`_sip._udp`, `_sip._tcp`, `_sips._tcp`) → A/AAAA. It tests reachability on every resolved `target:port` over UDP, TCP and TLS, then sends a raw SIP `OPTIONS` ping and inspects the reply (status line, `Server`/`User-Agent`, advertised `Allow` methods, round-trip time). + +This checker is **service-level**: it targets a *SIP* service (`abstract.SIP`) published on a subdomain and is configured from that service's own **Checks** tab. When no SRV record is published, the checker falls back to `:5060` / `:5061`, with a visible info marker in the report. + +{{% notice style="info" title="TLS posture is folded in, not duplicated" %}} +For the TLS handshake the checker uses `InsecureSkipVerify`: it confirms only that a TLS session can be established. Every `_sips._tcp` target is published as a `tls.endpoint.v1` discovery entry so the dedicated TLS checker can verify the certificate chain, hostname match, expiry and cipher posture. Those findings are folded back onto the SIP service page through the `sip.tls_quality` rule. See {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | Severity | +|---|---|---| +| `sip.srv_present` | `_sip._udp` / `_sip._tcp` / `_sips._tcp` SRV records are published and resolvable. | Critical | +| `sip.transport_diversity` | Modern SIP transports (TCP, and ideally TLS) are published alongside legacy UDP. | Warning | +| `sip.srv_targets_resolvable` | Every SRV target resolves to at least one A or AAAA address. | Critical | +| `sip.endpoint_reachable` | Every discovered SIP endpoint accepts a connection on its transport. | Critical | +| `sip.options_response` | Every reachable SIP endpoint answers `OPTIONS` with a 2xx response. | Critical | +| `sip.options_capabilities` | Reviews the `Allow` header advertised in `OPTIONS` replies (INVITE support, presence of `Allow`). | Warning | +| `sip.ipv6_coverage` | At least one SIP endpoint is reachable over IPv6. | Info | +| `sip.tls_quality` | Folds the downstream TLS checker findings (chain, hostname match, expiry) onto the SIP service. | Critical | + +The checker performs, in order: the NAPTR lookup (`SIP+D2U`, `SIP+D2T`, `SIPS+D2T`), the SRV lookup for the three transports (with the `5060`/`5061` fallback), A/AAAA resolution of every SRV target, TCP connect / UDP send / TLS handshake, and the SIP `OPTIONS` request with its status, headers and `Allow` parsed. + +## Options + +| Option | Meaning | Default | +|---|---|---| +| SIP domain | The domain to test (auto-filled from the service scope). Required. | *(auto)* | +| Per-endpoint timeout (seconds) | Probe timeout for each endpoint. | `5` | +| Probe `_sip._udp` | Whether to probe the UDP transport. Disable if UDP is firewalled or the checker host cannot send UDP. | `true` | +| Probe `_sip._tcp` | Whether to probe the TCP transport. | `true` | +| Probe `_sips._tcp` (TLS) | Whether to probe the TLS transport. | `true` | + +## In happyDomain + +Enable the SIP checker from the **Checks** tab of a SIP service. The domain is filled in automatically. See {{< relref "/pages/checks" >}} for the full workflow, and {{< relref "/reference/checkers/tls" >}} for the certificate posture of the `_sips._tcp` endpoints. diff --git a/content/reference/checkers/sip.fr.md b/content/reference/checkers/sip.fr.md new file mode 100644 index 0000000..9a57d8f --- /dev/null +++ b/content/reference/checkers/sip.fr.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SIP +description: "Sonde le déploiement SIP/VoIP d'un domaine de bout en bout : résolution NAPTR/SRV (RFC 3263), accessibilité des points d'accès en UDP/TCP/TLS et un ping SIP OPTIONS avec inspection des capacités." +weight: 270 +--- + +Le vérificateur **SIP** sonde le déploiement SIP/VoIP d'un domaine à partir de ses enregistrements DNS, en suivant la résolution de la RFC 3263 : NAPTR → SRV (`_sip._udp`, `_sip._tcp`, `_sips._tcp`) → A/AAAA. Il teste l'accessibilité de chaque `cible:port` résolue en UDP, TCP et TLS, puis envoie un ping SIP `OPTIONS` brut et inspecte la réponse (ligne de statut, `Server`/`User-Agent`, méthodes `Allow` annoncées, temps d'aller-retour). + +Il s'agit d'un vérificateur de **niveau service** : il cible un service *SIP* (`abstract.SIP`) publié sur un sous-domaine et se configure depuis l'onglet **Vérifications** de ce service. Lorsqu'aucun enregistrement SRV n'est publié, le vérificateur se rabat sur `:5060` / `:5061`, avec un marqueur d'information visible dans le rapport. + +{{% notice style="info" title="La posture TLS est intégrée, pas dupliquée" %}} +Pour la poignée de main TLS, le vérificateur utilise `InsecureSkipVerify` : il confirme uniquement qu'une session TLS peut être établie. Chaque cible `_sips._tcp` est publiée comme entrée de découverte `tls.endpoint.v1` afin que le vérificateur TLS dédié puisse vérifier la chaîne de certificats, la correspondance du nom d'hôte, l'expiration et la posture des algorithmes. Ces constats sont réintégrés sur la page du service SIP via la règle `sip.tls_quality`. Consultez {{< relref "/reference/checkers/tls" >}}. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qui est vérifié | Gravité | +|---|---|---| +| `sip.srv_present` | Les enregistrements SRV `_sip._udp` / `_sip._tcp` / `_sips._tcp` sont publiés et résolvables. | Critique | +| `sip.transport_diversity` | Des transports SIP modernes (TCP, et idéalement TLS) sont publiés en plus de l'UDP historique. | Avertissement | +| `sip.srv_targets_resolvable` | Chaque cible SRV se résout en au moins une adresse A ou AAAA. | Critique | +| `sip.endpoint_reachable` | Chaque point d'accès SIP découvert accepte une connexion sur son transport. | Critique | +| `sip.options_response` | Chaque point d'accès SIP accessible répond à `OPTIONS` par une réponse 2xx. | Critique | +| `sip.options_capabilities` | Examine l'en-tête `Allow` annoncé dans les réponses `OPTIONS` (prise en charge d'INVITE, présence d'`Allow`). | Avertissement | +| `sip.ipv6_coverage` | Au moins un point d'accès SIP est accessible en IPv6. | Info | +| `sip.tls_quality` | Réintègre les constats du vérificateur TLS aval (chaîne, correspondance du nom d'hôte, expiration) sur le service SIP. | Critique | + +Le vérificateur effectue, dans l'ordre : la recherche NAPTR (`SIP+D2U`, `SIP+D2T`, `SIPS+D2T`), la recherche SRV pour les trois transports (avec le repli `5060`/`5061`), la résolution A/AAAA de chaque cible SRV, la connexion TCP / l'envoi UDP / la poignée de main TLS, et la requête SIP `OPTIONS` avec son statut, ses en-têtes et son `Allow` analysés. + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Domaine SIP | Le domaine à tester (renseigné automatiquement depuis la portée du service). Obligatoire. | *(auto)* | +| Délai d'attente par point d'accès (secondes) | Délai de sonde pour chaque point d'accès. | `5` | +| Sonder `_sip._udp` | Faut-il sonder le transport UDP. À désactiver si l'UDP est filtré ou si l'hôte du vérificateur ne peut pas émettre d'UDP. | `true` | +| Sonder `_sip._tcp` | Faut-il sonder le transport TCP. | `true` | +| Sonder `_sips._tcp` (TLS) | Faut-il sonder le transport TLS. | `true` | + +## Dans happyDomain + +Activez le vérificateur SIP depuis l'onglet **Vérifications** d'un service SIP. Le domaine est renseigné automatiquement. Consultez {{< relref "/pages/checks" >}} pour le fonctionnement complet, et {{< relref "/reference/checkers/tls" >}} pour la posture des certificats des points d'accès `_sips._tcp`. diff --git a/content/reference/checkers/smtp.en.md b/content/reference/checkers/smtp.en.md new file mode 100644 index 0000000..65f90c2 --- /dev/null +++ b/content/reference/checkers/smtp.en.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SMTP +description: "Probes every MX target of a domain on port 25 the way an operator would with swaks: TCP connect, banner, EHLO, STARTTLS, mail-transaction and open-relay probes, reverse DNS and IPv6 coverage." +weight: 200 +--- + +The **Inbound SMTP (MX posture)** checker exercises the *inbound* side of a domain's mail service. For every MX target of the zone it performs the live probes a human operator would run with `swaks` or `telnet … 25`: TCP connect, ESMTP banner and EHLO, STARTTLS negotiation, mail-transaction probes (null sender, postmaster, open-relay), reverse DNS / FCrDNS, extension inventory, and IPv4/IPv6 coverage. The result is an actionable HTML report. + +**Scope:** service-level. It attaches to services of type `svcs.MXs` (the DNS-level MX record set) and is configured from that service's **Checks** tab. + +The probe answers "can this domain *receive* mail correctly?". It does **not** test outbound deliverability (SPF/DKIM/DMARC alignment, spam scoring, blacklist status), which is the job of the {{< relref "/reference/checkers/happydeliver" >}} checker. Mail-transaction probes always stop at `RCPT` and emit `RSET`: no `DATA` is sent, so no mail is delivered. + +## What it checks + +| Rule | Verifies | Severity | +|------|----------|----------| +| `smtp.null_mx` | Reports whether the domain publishes a null MX (RFC 7505). | Info | +| `smtp.mx_present` | The domain publishes at least one MX record (or a null MX). | Critical | +| `smtp.mx_sanity` | Flags MX targets violating RFC 5321 § 5.1 (IP literals, CNAME chains, unresolved names). | Critical | +| `smtp.endpoint_reachable` | Every MX endpoint accepts a TCP connection on port 25. | Critical | +| `smtp.banner_sanity` | Every reachable endpoint emits a 220 SMTP greeting. | Critical | +| `smtp.ehlo_supported` | Every endpoint accepts EHLO. | Critical | +| `smtp.starttls_offered` | Every endpoint advertises the STARTTLS extension. | Critical | +| `smtp.starttls_handshake` | The STARTTLS handshake succeeds wherever advertised. | Critical | +| `smtp.auth_posture` | Flags endpoints advertising SMTP AUTH before STARTTLS (cleartext credentials). | Critical | +| `smtp.reverse_dns` | Every endpoint has a matching PTR record (FCrDNS). | Warning | +| `smtp.null_sender` | Endpoints accept the null sender `MAIL FROM:<>` (required for DSNs). | Critical | +| `smtp.postmaster` | Endpoints accept `RCPT TO:` (RFC 5321 § 4.5.1). | Critical | +| `smtp.open_relay` | Flags endpoints that relay mail for recipients outside the tested domain. | Critical | +| `smtp.extension_posture` | Reports ESMTP extension posture (PIPELINING, 8BITMIME). | Info | +| `smtp.ipv6_reachable` | At least one MX endpoint is reachable over IPv6. | Info | +| `smtp.tls_quality` | Folds downstream TLS findings (chain, hostname, expiry) onto SMTP. | Critical | + +Certificate posture itself is out of scope here: each MX target is published as a `tls.endpoint.v1` discovery entry (opportunistic STARTTLS), and the {{< relref "/reference/checkers/tls" >}} checker runs certificate analysis on the same connection. Its findings are folded back into the `smtp.tls_quality` rule and the HTML report. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Domain (`domain`) | Domain to test. Auto-filled from the service. | (from service) | +| Per-endpoint timeout (seconds) (`timeout`) | Per-endpoint connection timeout. | 12 | +| EHLO hostname (`helo_name`) | Hostname announced in EHLO/HELO. Use a name that resolves and has a valid PTR. | `mx-checker.happydomain.org` | +| Probe null sender (`test_null_sender`) | Probe `MAIL FROM:<>` (RFC 5321 DSN acceptance). | true | +| Probe postmaster (`test_postmaster`) | Probe `RCPT TO:` (RFC 5321 § 4.5.1). | true | +| Probe open-relay posture (`test_open_relay`) | Probe a recipient outside the tested domain to detect open relays. | true | +| Open-relay probe recipient (`test_probe_address`) | Mailbox (outside the tested domain) used for the open-relay probe. | `postmaster@example.com` | + +## In happyDomain + +This is a service-level checker: configure it from the **Checks** tab of the *E-Mail servers* (MX) service. To confirm that mail your domain *sends* lands in the inbox, pair it with the {{< relref "/reference/checkers/happydeliver" >}} checker. For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/smtp.fr.md b/content/reference/checkers/smtp.fr.md new file mode 100644 index 0000000..cfca968 --- /dev/null +++ b/content/reference/checkers/smtp.fr.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SMTP +description: "Sonde chaque cible MX d'un domaine sur le port 25 comme le ferait un opérateur avec swaks : connexion TCP, bannière, EHLO, STARTTLS, transactions de messagerie et sonde de relais ouvert, DNS inverse et couverture IPv6." +weight: 200 +--- + +Le vérificateur **SMTP entrant (posture MX)** examine le côté *entrant* du service de messagerie d'un domaine. Pour chaque cible MX de la zone, il effectue les sondes en direct qu'un opérateur exécuterait avec `swaks` ou `telnet … 25` : connexion TCP, bannière ESMTP et EHLO, négociation STARTTLS, sondes de transaction (expéditeur nul, postmaster, relais ouvert), DNS inverse / FCrDNS, inventaire des extensions et couverture IPv4/IPv6. Le résultat est un rapport HTML exploitable. + +**Portée** : niveau service. Il s'attache aux services de type `svcs.MXs` (l'ensemble des enregistrements MX) et se configure depuis l'onglet **Vérifications** de ce service. + +La sonde répond à la question « ce domaine peut-il *recevoir* le courrier correctement ? ». Elle ne teste **pas** la délivrabilité sortante (alignement SPF/DKIM/DMARC, score anti-spam, statut de liste noire), ce qui est le rôle du vérificateur {{< relref "/reference/checkers/happydeliver" >}}. Les sondes de transaction s'arrêtent toujours à `RCPT` et émettent `RSET` : aucun `DATA` n'est envoyé, donc aucun message n'est délivré. + +## Ce qu'il vérifie + +| Règle | Vérifie | Sévérité | +|-------|---------|----------| +| `smtp.null_mx` | Indique si le domaine publie un MX nul (RFC 7505). | Info | +| `smtp.mx_present` | Le domaine publie au moins un enregistrement MX (ou un MX nul). | Critique | +| `smtp.mx_sanity` | Signale les cibles MX violant la RFC 5321 § 5.1 (littéraux IP, chaînes CNAME, noms non résolus). | Critique | +| `smtp.endpoint_reachable` | Chaque point de terminaison MX accepte une connexion TCP sur le port 25. | Critique | +| `smtp.banner_sanity` | Chaque point de terminaison joignable émet une salutation SMTP 220. | Critique | +| `smtp.ehlo_supported` | Chaque point de terminaison accepte EHLO. | Critique | +| `smtp.starttls_offered` | Chaque point de terminaison annonce l'extension STARTTLS. | Critique | +| `smtp.starttls_handshake` | La poignée de main STARTTLS aboutit là où elle est annoncée. | Critique | +| `smtp.auth_posture` | Signale les points de terminaison annonçant SMTP AUTH avant STARTTLS (identifiants en clair). | Critique | +| `smtp.reverse_dns` | Chaque point de terminaison a un enregistrement PTR concordant (FCrDNS). | Avertissement | +| `smtp.null_sender` | Les points de terminaison acceptent l'expéditeur nul `MAIL FROM:<>` (requis pour les DSN). | Critique | +| `smtp.postmaster` | Les points de terminaison acceptent `RCPT TO:` (RFC 5321 § 4.5.1). | Critique | +| `smtp.open_relay` | Signale les points de terminaison relayant le courrier pour des destinataires hors du domaine testé. | Critique | +| `smtp.extension_posture` | Rapporte la posture des extensions ESMTP (PIPELINING, 8BITMIME). | Info | +| `smtp.ipv6_reachable` | Au moins un point de terminaison MX est joignable en IPv6. | Info | +| `smtp.tls_quality` | Intègre les constats TLS en aval (chaîne, nom, expiration) au rapport SMTP. | Critique | + +La posture des certificats elle-même est hors de portée ici : chaque cible MX est publiée comme entrée de découverte `tls.endpoint.v1` (STARTTLS opportuniste), et le vérificateur {{< relref "/reference/checkers/tls" >}} effectue l'analyse des certificats sur la même connexion. Ses constats sont réintégrés dans la règle `smtp.tls_quality` et dans le rapport HTML. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Domaine (`domain`) | Domaine à tester. Rempli automatiquement depuis le service. | (depuis le service) | +| Délai par point de terminaison (secondes) (`timeout`) | Délai de connexion par point de terminaison. | 12 | +| Nom EHLO (`helo_name`) | Nom annoncé dans EHLO/HELO. Utilisez un nom qui résout et possède un PTR valide. | `mx-checker.happydomain.org` | +| Sonder l'expéditeur nul (`test_null_sender`) | Sonde `MAIL FROM:<>` (acceptation des DSN, RFC 5321). | true | +| Sonder le postmaster (`test_postmaster`) | Sonde `RCPT TO:` (RFC 5321 § 4.5.1). | true | +| Sonder la posture de relais ouvert (`test_open_relay`) | Sonde un destinataire hors du domaine testé pour détecter les relais ouverts. | true | +| Destinataire de la sonde de relais ouvert (`test_probe_address`) | Boîte (hors du domaine testé) utilisée pour la sonde de relais ouvert. | `postmaster@example.com` | + +## Dans happyDomain + +C'est un vérificateur de niveau service : configurez-le depuis l'onglet **Vérifications** du service « Serveurs e-mail » (MX). Pour confirmer que le courrier que votre domaine *envoie* arrive en boîte de réception, associez-le au vérificateur {{< relref "/reference/checkers/happydeliver" >}}. Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/ssh.en.md b/content/reference/checkers/ssh.en.md new file mode 100644 index 0000000..f642586 --- /dev/null +++ b/content/reference/checkers/ssh.en.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SSH +description: "Connects to the advertised SSH ports of a server and audits reachability, banner-to-CVE matches, the full algorithm posture, observed host keys, SSHFP alignment and authentication methods." +weight: 280 +--- + +The **SSH** checker produces a comprehensive security audit of the SSH service exposed by a *Server*. It connects to the advertised SSH port(s) on every `A`/`AAAA` address and reports reachability, banner-to-CVE matches, the full algorithm posture (key exchange, host-key, cipher, MAC, compression), the observed host keys, SSHFP fingerprint alignment, and the authentication methods the server exposes. Results are presented as a "fix me fast" HTML report. + +**Scope:** service-level. It attaches to services of type `abstract.Server` (a subdomain that publishes `A`/`AAAA` and optionally `SSHFP` records) and is configured from that service's **Checks** tab. + +## What it checks + +| Rule | Verifies | Severity | +|------|----------|----------| +| `ssh.tcp_reachable` | Every probed (address, port) pair accepts a TCP connection. | Critical | +| `ssh.handshake` | The SSH banner exchange and KEXINIT parse succeed on every reachable endpoint. | Critical | +| `ssh.protocol_version` | Every endpoint advertises SSH-2 and rejects legacy SSH-1. | Critical | +| `ssh.banner_software` | Flags servers whose banner is not a recognised OpenSSH build. | Info | +| `ssh.known_vulnerabilities` | Matches the advertised OpenSSH version against a curated CVE catalog (regreSSHion, Terrapin, etc.). | Critical | +| `ssh.host_key_strength` | Flags host keys below the accepted minimum size (e.g. RSA < 2048 bits). | Critical | +| `ssh.kex_algorithms` | Flags weak or broken key-exchange algorithms. | Critical | +| `ssh.host_key_algorithms` | Flags weak or deprecated host-key algorithms (ssh-rsa/SHA-1, ssh-dss…). | Critical | +| `ssh.cipher_algorithms` | Flags weak or broken symmetric ciphers (CBC, 3DES, RC4…). | Critical | +| `ssh.mac_algorithms` | Flags weak MAC algorithms (SHA-1, non-ETM…). | Critical | +| `ssh.strict_kex` | The server advertises the strict-KEX marker (CVE-2023-48795 Terrapin mitigation). | Warning | +| `ssh.preauth_compression` | Flags servers offering pre-authentication zlib compression. | Info | +| `ssh.auth_methods` | Reviews advertised authentication methods (password exposure, public-key availability). | Warning | +| `ssh.sshfp_alignment` | Compares published SSHFP records against observed host keys (match, missing, mismatch). | Critical | +| `ssh.sshfp_hash` | Flags SSHFP record sets that only publish SHA-1 (type 1) fingerprints. | Warning | + +CVE matching covers, among others, regreSSHion (CVE-2024-6387), the ssh-agent PKCS#11 RCE (CVE-2023-38408), Terrapin (CVE-2023-48795), and several older username-enumeration and command-injection issues. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Ports (`ports`) | Comma-separated extra TCP ports to probe. Port 22 is always probed. | (empty) | +| Per-endpoint probe timeout (ms) (`probeTimeoutMs`) | Maximum time for dial + banner + KEXINIT + handshake on a single endpoint. | 10000 | +| Enumerate authentication methods (`includeAuthProbe`) | Open a second connection with a dummy user to discover advertised auth methods. | true | + +## In happyDomain + +This is a service-level checker: configure it from the **Checks** tab of the *Server* service on the relevant subdomain. Its SSHFP rules cross-reference the `SSHFP` records published in your zone, so keeping those records in sync with the server's host keys improves the result. For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/ssh.fr.md b/content/reference/checkers/ssh.fr.md new file mode 100644 index 0000000..f7972e4 --- /dev/null +++ b/content/reference/checkers/ssh.fr.md @@ -0,0 +1,45 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: SSH +description: "Se connecte aux ports SSH annoncés d'un serveur et audite l'accessibilité, les correspondances bannière/CVE, la posture complète des algorithmes, les clés d'hôte observées, l'alignement SSHFP et les méthodes d'authentification." +weight: 280 +--- + +Le vérificateur **SSH** produit un audit de sécurité complet du service SSH exposé par un service « Serveur ». Il se connecte aux ports SSH annoncés sur chaque adresse `A`/`AAAA` et rapporte l'accessibilité, les correspondances bannière/CVE, la posture complète des algorithmes (échange de clés, clé d'hôte, chiffrement, MAC, compression), les clés d'hôte observées, l'alignement des empreintes SSHFP et les méthodes d'authentification exposées par le serveur. Les résultats sont présentés dans un rapport HTML orienté correction rapide. + +**Portée** : niveau service. Il s'attache aux services de type `abstract.Server` (un sous-domaine publiant des enregistrements `A`/`AAAA` et éventuellement `SSHFP`) et se configure depuis l'onglet **Vérifications** de ce service. + +## Ce qu'il vérifie + +| Règle | Vérifie | Sévérité | +|-------|---------|----------| +| `ssh.tcp_reachable` | Chaque paire (adresse, port) sondée accepte une connexion TCP. | Critique | +| `ssh.handshake` | L'échange de bannière SSH et l'analyse KEXINIT aboutissent sur chaque point de terminaison joignable. | Critique | +| `ssh.protocol_version` | Chaque point de terminaison annonce SSH-2 et rejette l'ancien SSH-1. | Critique | +| `ssh.banner_software` | Signale les serveurs dont la bannière n'est pas une version OpenSSH reconnue. | Info | +| `ssh.known_vulnerabilities` | Confronte la version OpenSSH annoncée à un catalogue de CVE (regreSSHion, Terrapin, etc.). | Critique | +| `ssh.host_key_strength` | Signale les clés d'hôte sous la taille minimale acceptée (par exemple RSA < 2048 bits). | Critique | +| `ssh.kex_algorithms` | Signale les algorithmes d'échange de clés faibles ou cassés. | Critique | +| `ssh.host_key_algorithms` | Signale les algorithmes de clé d'hôte faibles ou obsolètes (ssh-rsa/SHA-1, ssh-dss, etc.). | Critique | +| `ssh.cipher_algorithms` | Signale les chiffrements symétriques faibles ou cassés (CBC, 3DES, RC4, etc.). | Critique | +| `ssh.mac_algorithms` | Signale les algorithmes MAC faibles (SHA-1, non-ETM, etc.). | Critique | +| `ssh.strict_kex` | Le serveur annonce le marqueur strict-KEX (mitigation Terrapin, CVE-2023-48795). | Avertissement | +| `ssh.preauth_compression` | Signale les serveurs offrant la compression zlib avant authentification. | Info | +| `ssh.auth_methods` | Examine les méthodes d'authentification annoncées (exposition par mot de passe, disponibilité de la clé publique). | Avertissement | +| `ssh.sshfp_alignment` | Compare les enregistrements SSHFP publiés aux clés d'hôte observées (concordance, manquant, divergence). | Critique | +| `ssh.sshfp_hash` | Signale les jeux SSHFP ne publiant que des empreintes SHA-1 (type 1). | Avertissement | + +La correspondance CVE couvre notamment regreSSHion (CVE-2024-6387), la RCE PKCS#11 de ssh-agent (CVE-2023-38408), Terrapin (CVE-2023-48795) et plusieurs anciennes failles d'énumération d'utilisateurs et d'injection de commandes. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Ports (`ports`) | Ports TCP supplémentaires à sonder, séparés par des virgules. Le port 22 est toujours sondé. | (vide) | +| Délai de sonde par point de terminaison (ms) (`probeTimeoutMs`) | Temps maximal pour la connexion, la bannière, le KEXINIT et la poignée de main sur un point de terminaison. | 10000 | +| Énumérer les méthodes d'authentification (`includeAuthProbe`) | Ouvre une seconde connexion avec un utilisateur factice pour découvrir les méthodes d'authentification annoncées. | true | + +## Dans happyDomain + +C'est un vérificateur de niveau service : configurez-le depuis l'onglet **Vérifications** du service « Serveur » sur le sous-domaine concerné. Ses règles SSHFP recoupent les enregistrements `SSHFP` publiés dans votre zone ; garder ces enregistrements synchronisés avec les clés d'hôte du serveur améliore le résultat. Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/stun-turn.en.md b/content/reference/checkers/stun-turn.en.md new file mode 100644 index 0000000..eb816a0 --- /dev/null +++ b/content/reference/checkers/stun-turn.en.md @@ -0,0 +1,55 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: STUN / TURN +description: "Probes STUN and TURN servers end-to-end: discovery, reachability, TLS/DTLS, STUN binding and authenticated TURN relay." +weight: 310 +--- + +The **STUN / TURN** checker probes STUN and TURN servers end-to-end. STUN and TURN are the NAT-traversal servers that real-time applications (WebRTC, voice and video) rely on to establish peer-to-peer media: STUN lets a host discover its public reflexive address, while TURN relays media when a direct path cannot be opened. + +This is a **service-level** checker. It runs SRV discovery (or uses an explicit URI), checks TCP/UDP reachability and the TLS/DTLS handshake, issues a STUN binding request, verifies that the TURN server requires authentication, performs an authenticated TURN `Allocate`, and finally exercises the relay path with a `CreatePermission + Send` round-trip. + +## What it checks + +| Rule | What it verifies | Severity | +|------|------------------|----------| +| `stun_turn.discovery` | At least one STUN/TURN endpoint could be discovered (explicit URI or SRV lookup). | Critical | +| `stun_turn.srv_stun` | At least one STUN endpoint is available via SRV (`_stun` / `_stuns`) or explicit URI. | Warning | +| `stun_turn.srv_turn` | At least one TURN endpoint is available via SRV (`_turn` / `_turns`) or explicit URI. | Critical | +| `stun_turn.dial` | Every discovered endpoint accepts a connection (TCP/TLS handshake or UDP socket). | Critical | +| `stun_turn.tls_transport` | At least one TLS/DTLS transport (`stuns` / `turns`) succeeds when present. | Critical | +| `stun_turn.ipv6_coverage` | At least one STUN/TURN hostname resolves to an IPv6 address. | Warning | +| `stun_turn.stun_binding` | The STUN Binding request receives a XOR-MAPPED-ADDRESS reply. | Critical | +| `stun_turn.reflexive_public` | Flags endpoints returning a private/loopback reflexive address (server unaware of its public IP). | Critical | +| `stun_turn.stun_latency` | Compares the STUN Binding RTT against the warning/critical thresholds. | Critical | +| `stun_turn.turn_open_relay` | The TURN server requires authentication (challenges an unauthenticated `Allocate` with 401). | Critical | +| `stun_turn.turn_auth` | The supplied TURN credentials (or REST shared secret) yield a successful `Allocate`. | Critical | +| `stun_turn.relay_public` | Flags TURN servers whose allocated relay address is private/loopback (missing public relay IP). | Critical | +| `stun_turn.relay_echo` | The TURN relay path can carry traffic to the configured probe peer (`CreatePermission + Send`). | Warning | + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Zone | Zone used for SRV-based discovery (`_stun._udp` / `_turn._udp` / `_turns._tcp`) when no explicit URI is given. Filled in automatically. | (auto-filled) | +| Server URI | Explicit STUN/TURN URI (RFC 7064/7065). Overrides SRV-based discovery. | — | +| Mode | `auto` probes both STUN and TURN; `stun` skips TURN allocation tests; `turn` requires TURN allocation. | `auto` | +| TURN username | Username for long-term TURN credentials. | — | +| TURN password | Password for long-term TURN credentials (secret). | — | +| REST API shared secret | Shared secret to derive ephemeral credentials (draft-uberti-rtcweb-turn-rest); takes precedence over username/password (secret). | — | +| Realm | Optional explicit TURN realm. | — | +| Transports | Comma-separated transports to test among `udp`, `tcp`, `tls`, `dtls`. | `udp,tcp,tls` | +| Relay echo target | `host:port` used to validate the relay path; a `CreatePermission + Send` is issued, no payload data is exchanged. | `1.1.1.1:53` | +| Also test ChannelBind | Additionally exercise ChannelBind through the relay connection. | `false` | +| RTT warning threshold (ms) | STUN Binding round-trip time above which a warning is raised. | 200 | +| RTT critical threshold (ms) | STUN Binding round-trip time above which a critical alert is raised. | 1000 | +| Per-probe timeout (s) | Time budget for each individual probe. | 5 | + +{{% notice style="info" title="Credentials are needed for the TURN tests" %}} +The authentication, relay-public and relay-echo rules only run when valid TURN credentials are provided — either a username/password pair or a REST API shared secret. Without them, the checker still validates discovery, reachability, TLS and STUN binding, but cannot exercise the TURN relay path. +{{% /notice %}} + +## In happyDomain + +Enable this checker from the **Checks** tab of the relevant service; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The zone is filled in automatically; supply a server URI and TURN credentials as needed for your deployment. diff --git a/content/reference/checkers/stun-turn.fr.md b/content/reference/checkers/stun-turn.fr.md new file mode 100644 index 0000000..5b13ce5 --- /dev/null +++ b/content/reference/checkers/stun-turn.fr.md @@ -0,0 +1,55 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: STUN / TURN +description: "Sonde de bout en bout les serveurs STUN et TURN : découverte, accessibilité, TLS/DTLS, binding STUN et relais TURN authentifié." +weight: 310 +--- + +Le vérificateur **STUN / TURN** sonde de bout en bout les serveurs STUN et TURN. STUN et TURN sont les serveurs de traversée de NAT sur lesquels reposent les applications temps réel (WebRTC, voix et vidéo) pour établir un flux média pair à pair : STUN permet à un hôte de découvrir son adresse réflexive publique, tandis que TURN relaie le média lorsqu'aucun chemin direct ne peut être ouvert. + +Il s'agit d'un vérificateur de **niveau service**. Il effectue la découverte SRV (ou utilise une URI explicite), contrôle l'accessibilité TCP/UDP et la poignée de main TLS/DTLS, émet une requête de binding STUN, vérifie que le serveur TURN exige une authentification, réalise un `Allocate` TURN authentifié, puis éprouve le chemin de relais par un aller-retour `CreatePermission + Send`. + +## Ce qui est vérifié + +| Règle | Ce qu'elle vérifie | Sévérité | +|-------|--------------------|----------| +| `stun_turn.discovery` | Au moins un point d'accès STUN/TURN a pu être découvert (URI explicite ou résolution SRV). | Critique | +| `stun_turn.srv_stun` | Au moins un point d'accès STUN est disponible via SRV (`_stun` / `_stuns`) ou URI explicite. | Avertissement | +| `stun_turn.srv_turn` | Au moins un point d'accès TURN est disponible via SRV (`_turn` / `_turns`) ou URI explicite. | Critique | +| `stun_turn.dial` | Chaque point d'accès découvert accepte une connexion (poignée de main TCP/TLS ou socket UDP). | Critique | +| `stun_turn.tls_transport` | Au moins un transport TLS/DTLS (`stuns` / `turns`) aboutit lorsqu'il est présent. | Critique | +| `stun_turn.ipv6_coverage` | Au moins un nom d'hôte STUN/TURN se résout vers une adresse IPv6. | Avertissement | +| `stun_turn.stun_binding` | La requête de binding STUN reçoit une réponse XOR-MAPPED-ADDRESS. | Critique | +| `stun_turn.reflexive_public` | Signale les points d'accès renvoyant une adresse réflexive privée ou de bouclage (serveur ignorant son IP publique). | Critique | +| `stun_turn.stun_latency` | Compare le temps d'aller-retour du binding STUN aux seuils d'avertissement et critique. | Critique | +| `stun_turn.turn_open_relay` | Le serveur TURN exige une authentification (répond à un `Allocate` non authentifié par un 401). | Critique | +| `stun_turn.turn_auth` | Les identifiants TURN fournis (ou le secret partagé REST) permettent un `Allocate` réussi. | Critique | +| `stun_turn.relay_public` | Signale les serveurs TURN dont l'adresse de relais allouée est privée ou de bouclage (IP de relais publique manquante). | Critique | +| `stun_turn.relay_echo` | Le chemin de relais TURN peut acheminer du trafic vers le pair de test configuré (`CreatePermission + Send`). | Avertissement | + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Zone | Zone utilisée pour la découverte SRV (`_stun._udp` / `_turn._udp` / `_turns._tcp`) en l'absence d'URI explicite. Renseignée automatiquement. | (renseignée automatiquement) | +| URI du serveur | URI STUN/TURN explicite (RFC 7064/7065). Prend le pas sur la découverte SRV. | (aucun) | +| Mode | `auto` sonde à la fois STUN et TURN ; `stun` ignore les tests d'allocation TURN ; `turn` exige l'allocation TURN. | `auto` | +| Nom d'utilisateur TURN | Nom d'utilisateur pour les identifiants TURN à long terme. | (aucun) | +| Mot de passe TURN | Mot de passe pour les identifiants TURN à long terme (secret). | (aucun) | +| Secret partagé API REST | Secret partagé pour dériver des identifiants éphémères (draft-uberti-rtcweb-turn-rest) ; prend le pas sur le nom d'utilisateur et le mot de passe (secret). | (aucun) | +| Realm | Realm TURN explicite facultatif. | (aucun) | +| Transports | Liste de transports à tester, séparés par des virgules, parmi `udp`, `tcp`, `tls`, `dtls`. | `udp,tcp,tls` | +| Cible de l'écho de relais | `hôte:port` utilisé pour valider le chemin de relais ; un `CreatePermission + Send` est émis, aucune donnée utile n'est échangée. | `1.1.1.1:53` | +| Tester aussi ChannelBind | Éprouve en plus ChannelBind sur la connexion de relais. | `false` | +| Seuil d'avertissement de RTT (ms) | Temps d'aller-retour du binding STUN au-delà duquel un avertissement est déclenché. | 200 | +| Seuil critique de RTT (ms) | Temps d'aller-retour du binding STUN au-delà duquel une alerte critique est déclenchée. | 1000 | +| Délai par sonde (s) | Budget de temps alloué à chaque sonde individuelle. | 5 | + +{{% notice style="info" title="Des identifiants sont nécessaires pour les tests TURN" %}} +Les règles d'authentification, de relais public et d'écho de relais ne s'exécutent que lorsque des identifiants TURN valides sont fournis : soit un couple nom d'utilisateur/mot de passe, soit un secret partagé d'API REST. Sans eux, le vérificateur valide tout de même la découverte, l'accessibilité, le TLS et le binding STUN, mais ne peut pas éprouver le chemin de relais TURN. +{{% /notice %}} + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** du service concerné ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. La zone est renseignée automatiquement ; fournissez une URI de serveur et des identifiants TURN selon les besoins de votre déploiement. diff --git a/content/reference/checkers/tls.en.md b/content/reference/checkers/tls.en.md new file mode 100644 index 0000000..5d52738 --- /dev/null +++ b/content/reference/checkers/tls.en.md @@ -0,0 +1,50 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: TLS posture +description: "Dials every TLS endpoint discovered for a domain, completes the handshake (with STARTTLS upgrade where needed) and audits certificate chain, hostname coverage, expiry and protocol strength." +weight: 170 +--- + +The **TLS** checker (internal name `TLS`) evaluates the transport-security posture of every TLS endpoint exposed by a domain. It does not scan ports on its own: it consumes **discovery entries** of type `tls.endpoint.v1` published by other service checkers (XMPP, SRV, CalDAV, CardDAV, SMTP…). For each discovered endpoint it performs a real TCP dial, an optional protocol-specific STARTTLS upgrade, and a full TLS handshake, then reports a per-endpoint posture. + +**Scope:** domain-level. The checker runs against the whole domain and folds in the endpoints that every other service checker has advertised. A given endpoint is therefore only probed if some service checker (for example {{< relref "/reference/checkers/smtp" >}}) published it. + +## What it checks + +| Rule | Verifies | Severity | +|------|----------|----------| +| `tls.endpoints_discovered` | At least one TLS endpoint has been discovered for this target. | Info | +| `tls.reachability` | Every discovered endpoint accepts a TCP connection. | Critical | +| `tls.handshake` | The TLS handshake completes on every reachable endpoint. | Critical | +| `tls.starttls_advertised` | STARTTLS endpoints advertise the upgrade capability. | Critical | +| `tls.starttls_dialect_supported` | The discovered STARTTLS dialect is implemented by the checker. | Critical | +| `tls.peer_certificate_present` | The server presented a certificate during the handshake. | Critical | +| `tls.chain_validity` | The presented chain validates against the system trust store. | Critical | +| `tls.hostname_match` | The leaf certificate covers the probed hostname (SNI). | Critical | +| `tls.expiry` | Flags expired or soon-to-expire leaf certificates. | Critical | +| `tls.version` | Flags endpoints negotiating a TLS version below TLS 1.2. | Warning | +| `tls.cipher_suite` | Reports the cipher suite negotiated on each endpoint. | Info | +| `tls.enum.versions` | Flags endpoints that still accept TLS versions below TLS 1.2 (enumeration option). | Warning | +| `tls.enum.ciphers` | Flags endpoints accepting broken cipher suites (NULL, anonymous, EXPORT, RC4, 3DES) (enumeration option). | Warning | + +STARTTLS upgrades are supported for SMTP/submission, IMAP, POP3, and XMPP (c2s and s2s). When a service checker marks an endpoint as requiring STARTTLS, the absence of the upgrade is reported as Critical; otherwise it is treated as opportunistic and reported as Warning. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Per-endpoint probe timeout (ms) (`probeTimeoutMs`) | Maximum time allowed for dial + STARTTLS + TLS handshake on a single endpoint. | 10000 | +| Enumerate accepted TLS versions and cipher suites (`enumerateCiphers`) | When enabled, each direct-TLS endpoint is swept with one ClientHello per (version, cipher) pair to discover the exact set the server accepts. Adds roughly 50 handshakes per endpoint. | false | + +The list of discovery entries is filled automatically from what other checkers publish and is not user-editable. + +## In happyDomain + +The TLS checker is a domain-level check: enable it from the domain's checks view. Because it works on endpoints discovered by other checkers, it pairs naturally with service-level checkers that publish TLS endpoints, such as {{< relref "/reference/checkers/smtp" >}}. + +{{% notice style="info" title="TLS posture vs DANE" %}} +This checker validates the live certificate against the system trust store. Pinning the certificate in DNS through TLSA records is a separate concern, handled by the {{< relref "/reference/checkers/dane" >}} checker. +{{% /notice %}} + +For the general workflow of configuring and reading checks, see {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/tls.fr.md b/content/reference/checkers/tls.fr.md new file mode 100644 index 0000000..0fe009d --- /dev/null +++ b/content/reference/checkers/tls.fr.md @@ -0,0 +1,50 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Posture TLS +description: "Se connecte à chaque point de terminaison TLS découvert pour un domaine, termine la poignée de main (avec bascule STARTTLS si nécessaire) et audite la chaîne de certificats, la couverture du nom, l'expiration et la robustesse du protocole." +weight: 170 +--- + +Le vérificateur **TLS** (nom interne « TLS ») évalue la posture de sécurité du transport de chaque point de terminaison TLS exposé par un domaine. Il ne scanne pas de ports lui-même : il consomme des **entrées de découverte** de type `tls.endpoint.v1` publiées par d'autres vérificateurs de service (XMPP, SRV, CalDAV, CardDAV, SMTP, etc.). Pour chaque point de terminaison découvert, il effectue une véritable connexion TCP, une bascule STARTTLS spécifique au protocole le cas échéant, puis une poignée de main TLS complète, et il rapporte une posture par point de terminaison. + +**Portée** : niveau domaine. Le vérificateur s'exécute sur l'ensemble du domaine et intègre les points de terminaison annoncés par les autres vérificateurs de service. Un point de terminaison n'est donc sondé que si un vérificateur de service (par exemple {{< relref "/reference/checkers/smtp" >}}) l'a publié. + +## Ce qu'il vérifie + +| Règle | Vérifie | Sévérité | +|-------|---------|----------| +| `tls.endpoints_discovered` | Au moins un point de terminaison TLS a été découvert pour cette cible. | Info | +| `tls.reachability` | Chaque point de terminaison découvert accepte une connexion TCP. | Critique | +| `tls.handshake` | La poignée de main TLS aboutit sur chaque point de terminaison joignable. | Critique | +| `tls.starttls_advertised` | Les points de terminaison STARTTLS annoncent la capacité de bascule. | Critique | +| `tls.starttls_dialect_supported` | Le dialecte STARTTLS découvert est implémenté par le vérificateur. | Critique | +| `tls.peer_certificate_present` | Le serveur a présenté un certificat pendant la poignée de main. | Critique | +| `tls.chain_validity` | La chaîne présentée se valide avec le magasin de confiance du système. | Critique | +| `tls.hostname_match` | Le certificat feuille couvre le nom sondé (SNI). | Critique | +| `tls.expiry` | Signale les certificats feuilles expirés ou proches de l'expiration. | Critique | +| `tls.version` | Signale les points de terminaison négociant une version TLS inférieure à TLS 1.2. | Avertissement | +| `tls.cipher_suite` | Rapporte la suite cryptographique négociée sur chaque point de terminaison. | Info | +| `tls.enum.versions` | Signale les points de terminaison acceptant encore des versions TLS inférieures à TLS 1.2 (option d'énumération). | Avertissement | +| `tls.enum.ciphers` | Signale les points de terminaison acceptant des suites cryptographiques cassées (NULL, anonyme, EXPORT, RC4, 3DES) (option d'énumération). | Avertissement | + +Les bascules STARTTLS sont prises en charge pour SMTP/submission, IMAP, POP3 et XMPP (c2s et s2s). Lorsqu'un vérificateur de service marque un point de terminaison comme exigeant STARTTLS, l'absence de bascule est rapportée comme critique ; sinon, elle est considérée comme opportuniste et rapportée comme avertissement. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Délai de sonde par point de terminaison (ms) (`probeTimeoutMs`) | Temps maximal alloué pour la connexion, la bascule STARTTLS et la poignée de main TLS sur un point de terminaison. | 10000 | +| Énumérer les versions et suites TLS acceptées (`enumerateCiphers`) | Lorsqu'activée, chaque point de terminaison en TLS direct est balayé avec un ClientHello par paire (version, suite) afin de découvrir l'ensemble exact accepté par le serveur. Ajoute environ 50 poignées de main par point de terminaison. | false | + +La liste des entrées de découverte est remplie automatiquement à partir de ce que les autres vérificateurs publient et n'est pas modifiable par l'utilisateur. + +## Dans happyDomain + +Le vérificateur TLS est une vérification de niveau domaine : activez-le depuis la vue des vérifications du domaine. Comme il travaille sur des points de terminaison découverts par d'autres vérificateurs, il s'associe naturellement aux vérificateurs de service qui publient des points de terminaison TLS, comme {{< relref "/reference/checkers/smtp" >}}. + +{{% notice style="info" title="Posture TLS et DANE" %}} +Ce vérificateur valide le certificat en direct avec le magasin de confiance du système. L'épinglage du certificat dans le DNS via des enregistrements TLSA est un sujet distinct, traité par le vérificateur {{< relref "/reference/checkers/dane" >}}. +{{% /notice %}} + +Pour le fonctionnement général de la configuration et de la lecture des vérifications, voir {{< relref "/pages/checks" >}}. diff --git a/content/reference/checkers/xmpp.en.md b/content/reference/checkers/xmpp.en.md new file mode 100644 index 0000000..f5ee617 --- /dev/null +++ b/content/reference/checkers/xmpp.en.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: XMPP +description: "Probes a domain's XMPP deployment: SRV discovery, reachability, STARTTLS, SASL mechanisms and federation authentication." +weight: 290 +--- + +The **XMPP** checker probes a domain's XMPP (Jabber) deployment end-to-end, much like [xmpp.net](https://xmpp.net/) does: it discovers the relevant SRV records, opens a stream to each endpoint, negotiates STARTTLS, inspects the offered SASL mechanisms and confirms that server-to-server federation can authenticate. + +This is a **service-level** checker. It applies to services of type **XMPP** and is configured from that service's own **Checks** tab. It probes the four standard service names (`_xmpp-client._tcp`, `_xmpp-server._tcp`, `_xmpps-client._tcp`, `_xmpps-server._tcp`), the legacy `_jabber._tcp`, and falls back to `:5222` / `:5269` when no SRV record is published. + +{{% notice style="info" title="TLS posture is checked separately" %}} +Certificate chain, hostname (SAN) match, expiry and cipher posture are **out of scope** here: a dedicated {{< relref "/reference/checkers/tls" >}} checker handles them. The XMPP checker only confirms that STARTTLS completes, records the negotiated TLS version and cipher for context, and folds the downstream TLS findings back onto the XMPP service report through the `xmpp.tls_quality` rule. +{{% /notice %}} + +## What it checks + +| Rule | What it verifies | Severity | +|------|------------------|----------| +| `xmpp.srv_c2s` | Client-to-server SRV records (`_xmpp-client` / `_xmpps-client` / `_jabber`) are published and resolvable. | Critical | +| `xmpp.srv_s2s` | Server-to-server SRV records (`_xmpp-server` / `_xmpps-server`) are published and resolvable. | Critical | +| `xmpp.c2s_reachable` | At least one client-to-server endpoint accepts TCP and completes TLS. | Critical | +| `xmpp.s2s_reachable` | At least one server-to-server endpoint accepts TCP and completes TLS. | Critical | +| `xmpp.starttls_required` | STARTTLS is advertised and required on every reachable c2s/s2s endpoint. | Critical | +| `xmpp.sasl_mechanisms` | The c2s SASL offer is sound (SCRAM present, no password-equivalent PLAIN-only). | Critical | +| `xmpp.s2s_dialback` | Server-to-server endpoints advertise dialback or SASL EXTERNAL after TLS (federation auth). | Critical | +| `xmpp.ipv6_reachable` | Flags deployments reachable only over IPv4. | Info | +| `xmpp.direct_tls` | Flags c2s deployments that do not publish XEP-0368 direct-TLS (`_xmpps-*`) SRV records. | Info | +| `xmpp.tls_quality` | Folds the downstream TLS checker findings (certificate chain, hostname match, expiry) onto the XMPP service. | Critical | + +The probe also covers TCP reachability of A/AAAA targets, stream feature parsing and IPv4/IPv6 coverage, surfaced through the rules above and the HTML report. + +## Options + +| Option | Meaning | Default | +|--------|---------|---------| +| Domain | XMPP domain (JID domain) to test. Filled in automatically from the service. | (auto-filled) | +| Mode | Which side to probe: `c2s` (client-to-server), `s2s` (server-to-server), or `both`. | `both` | +| Per-endpoint timeout (seconds) | Time budget for each probed endpoint. | 10 | + +## In happyDomain + +Enable this checker from the **Checks** tab of an XMPP service; see {{< relref "/pages/checks" >}} for how to configure and schedule checks. The domain is filled in automatically from the service. For the certificate side of the same endpoints, pair it with the {{< relref "/reference/checkers/tls" >}} checker. diff --git a/content/reference/checkers/xmpp.fr.md b/content/reference/checkers/xmpp.fr.md new file mode 100644 index 0000000..11cc9c6 --- /dev/null +++ b/content/reference/checkers/xmpp.fr.md @@ -0,0 +1,44 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: XMPP +description: "Sonde le déploiement XMPP d'un domaine : découverte SRV, accessibilité, STARTTLS, mécanismes SASL et authentification de fédération." +weight: 290 +--- + +Le vérificateur **XMPP** sonde de bout en bout le déploiement XMPP (Jabber) d'un domaine, à la manière de [xmpp.net](https://xmpp.net/) : il découvre les enregistrements SRV pertinents, ouvre un flux vers chaque point d'accès, négocie STARTTLS, inspecte les mécanismes SASL proposés et confirme que la fédération de serveur à serveur peut s'authentifier. + +Il s'agit d'un vérificateur de **niveau service**. Il s'applique aux services de type **XMPP** et se configure depuis l'onglet **Vérifications** de ce service. Il sonde les quatre noms de service standard (`_xmpp-client._tcp`, `_xmpp-server._tcp`, `_xmpps-client._tcp`, `_xmpps-server._tcp`), l'ancien `_jabber._tcp`, et se rabat sur `:5222` / `:5269` lorsqu'aucun enregistrement SRV n'est publié. + +{{% notice style="info" title="La posture TLS est vérifiée séparément" %}} +La chaîne de certificats, la correspondance du nom d'hôte (SAN), l'expiration et la posture des chiffrements sont **hors périmètre** ici : un vérificateur {{< relref "/reference/checkers/tls" >}} dédié s'en charge. Le vérificateur XMPP confirme seulement que STARTTLS aboutit, enregistre la version et le chiffrement TLS négociés à titre de contexte, et reverse les conclusions TLS dans le rapport du service XMPP via la règle `xmpp.tls_quality`. +{{% /notice %}} + +## Ce qui est vérifié + +| Règle | Ce qu'elle vérifie | Sévérité | +|-------|--------------------|----------| +| `xmpp.srv_c2s` | Les enregistrements SRV client vers serveur (`_xmpp-client` / `_xmpps-client` / `_jabber`) sont publiés et résolvables. | Critique | +| `xmpp.srv_s2s` | Les enregistrements SRV serveur vers serveur (`_xmpp-server` / `_xmpps-server`) sont publiés et résolvables. | Critique | +| `xmpp.c2s_reachable` | Au moins un point d'accès client vers serveur accepte le TCP et achève le TLS. | Critique | +| `xmpp.s2s_reachable` | Au moins un point d'accès serveur vers serveur accepte le TCP et achève le TLS. | Critique | +| `xmpp.starttls_required` | STARTTLS est annoncé et requis sur chaque point d'accès c2s/s2s joignable. | Critique | +| `xmpp.sasl_mechanisms` | L'offre SASL c2s est saine (présence de SCRAM, absence d'un PLAIN seul équivalent à un mot de passe en clair). | Critique | +| `xmpp.s2s_dialback` | Les points d'accès serveur vers serveur annoncent le dialback ou SASL EXTERNAL après le TLS (authentification de fédération). | Critique | +| `xmpp.ipv6_reachable` | Signale les déploiements joignables uniquement en IPv4. | Info | +| `xmpp.direct_tls` | Signale les déploiements c2s qui ne publient pas d'enregistrements SRV direct-TLS XEP-0368 (`_xmpps-*`). | Info | +| `xmpp.tls_quality` | Reverse sur le service XMPP les conclusions du vérificateur TLS sous-jacent (chaîne de certificats, correspondance du nom d'hôte, expiration). | Critique | + +La sonde couvre aussi l'accessibilité TCP des cibles A/AAAA, l'analyse des fonctionnalités de flux et la couverture IPv4/IPv6, exposées au travers des règles ci-dessus et du rapport HTML. + +## Options + +| Option | Signification | Défaut | +|--------|---------------|--------| +| Domaine | Domaine XMPP (domaine du JID) à tester. Renseigné automatiquement depuis le service. | (renseigné automatiquement) | +| Mode | Côté à sonder : `c2s` (client vers serveur), `s2s` (serveur vers serveur) ou `both` (les deux). | `both` | +| Délai par point d'accès (secondes) | Budget de temps alloué à chaque point d'accès sondé. | 10 | + +## Dans happyDomain + +Activez ce vérificateur depuis l'onglet **Vérifications** d'un service XMPP ; consultez {{< relref "/pages/checks" >}} pour savoir comment configurer et planifier les vérifications. Le domaine est renseigné automatiquement depuis le service. Pour le volet certificat de ces mêmes points d'accès, associez-le au vérificateur {{< relref "/reference/checkers/tls" >}}. diff --git a/content/reference/checkers/zonemaster.en.md b/content/reference/checkers/zonemaster.en.md new file mode 100644 index 0000000..de34501 --- /dev/null +++ b/content/reference/checkers/zonemaster.en.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Zonemaster +description: "Run the Zonemaster test suite against a domain through its JSON-RPC API and group the results by test category (delegation, consistency, DNSSEC…)." +weight: 350 +--- + +The **Zonemaster** checker runs the [Zonemaster](https://zonemaster.net/) test suite against a domain and reports its findings grouped by test category. Zonemaster is a well-established DNS health and delegation validator; this checker drives it through its JSON-RPC API, stores the full results as an observation, and renders an HTML report grouped by module and severity. + +This checker is **domain-level**: it evaluates the domain's delegation and zone content rather than a single service. + +## How it works + +For each run the checker submits the domain to a Zonemaster JSON-RPC endpoint (the official public API by default), waits for the test batch to complete, and stores every message Zonemaster returns. Each message carries a module, a test case and a Zonemaster severity (INFO / NOTICE / WARNING / ERROR / CRITICAL). + +{{% notice style="info" title="Point only at a trusted Zonemaster instance" %}} +The Zonemaster API URL is an administrator option. Because the checker issues requests to whatever URL is configured and surfaces the responses, point it only at a Zonemaster instance you trust. +{{% /notice %}} + +## What it checks + +The checker maps each Zonemaster test module onto a category rule. Every rule emits a `.summary` state, plus one state per WARNING-or-worse message (so downstream consumers can match on stable codes); INFO and NOTICE messages are folded into the summary counts. + +| Rule | What it covers | +|---|---| +| `zonemaster.dnssec` | DNSSEC tests (signatures, NSEC/NSEC3, DS/DNSKEY coherence). | +| `zonemaster.delegation` | Delegation tests (parent/child NS agreement, glue, referrals). | +| `zonemaster.consistency` | Consistency tests (SOA serial, NS set, zone content across servers). | +| `zonemaster.connectivity` | Connectivity tests (UDP/TCP reachability of authoritative servers, AS diversity). | +| `zonemaster.nameserver` | Nameserver tests (server behaviour, EDNS, unknown RR handling). | +| `zonemaster.syntax` | Syntax tests (domain name syntax, hostname legality). | +| `zonemaster.zone` | Zone tests (SOA values, MX presence, mandatory records). | +| `zonemaster.address` | Address tests (nameserver IP addresses, private/reserved ranges). | +| `zonemaster.basic` | Basic/system tests (initial reachability and fundamental requirements). | + +Zonemaster severities are mapped onto happyDomain statuses: CRITICAL and ERROR → Critical; WARNING → Warning; NOTICE, INFO and DEBUG → Info. Each summary takes the worst status among its category's messages. When Zonemaster returns no message for a category, that rule reports Unknown (not tested). + +## Options + +| Option | Meaning | Default | +|---|---|---| +| Domain name to check (`domainName`) | Domain submitted to Zonemaster. **Required.** | auto-filled | +| Profile (`profile`) | Zonemaster profile name to run the tests under. | `default` | +| Result language (`language`, per user) | Language of the returned messages (`en`, `fr`, `de`, `es`, `sv`, `da`, `fi`, `nb`, `nl`, `pt`). | `en` | +| Zonemaster API URL (`zonemasterAPIURL`, admin) | JSON-RPC endpoint to query. | `https://zonemaster.net/api` | + +## In happyDomain + +Enable this checker for the domain from the **Checks** view. See {{< relref "/pages/checks" >}} for scheduling and reading checks. + +Zonemaster overlaps in part with {{< relref "/reference/checkers/dnsviz" >}} on DNSSEC, but covers a broader range of delegation, connectivity and zone-content tests. For NSEC/NSEC3 hardening specifically, see {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/checkers/zonemaster.fr.md b/content/reference/checkers/zonemaster.fr.md new file mode 100644 index 0000000..0e5d360 --- /dev/null +++ b/content/reference/checkers/zonemaster.fr.md @@ -0,0 +1,52 @@ +--- +date: 2026-06-11T09:00:00+02:00 +author: nemunaire +title: Zonemaster +description: "Lance la suite de tests Zonemaster sur un domaine via son API JSON-RPC et regroupe les résultats par catégorie de test (délégation, cohérence, DNSSEC…)." +weight: 350 +--- + +Le vérificateur **Zonemaster** lance la suite de tests [Zonemaster](https://zonemaster.net/) sur un domaine et rapporte ses constats regroupés par catégorie de test. Zonemaster est un validateur reconnu de la santé DNS et de la délégation ; ce vérificateur le pilote via son API JSON-RPC, conserve l'ensemble des résultats sous forme d'observation et produit un rapport HTML regroupé par module et par sévérité. + +Ce vérificateur s'applique au **niveau domaine** : il évalue la délégation et le contenu de zone du domaine plutôt qu'un service isolé. + +## Fonctionnement + +À chaque exécution, le vérificateur soumet le domaine à un point d'accès JSON-RPC Zonemaster (l'API publique officielle par défaut), attend la fin du lot de tests et conserve chaque message renvoyé par Zonemaster. Chaque message porte un module, un cas de test et une sévérité Zonemaster (INFO / NOTICE / WARNING / ERROR / CRITICAL). + +{{% notice style="info" title="Ne pointez que vers une instance Zonemaster de confiance" %}} +L'URL de l'API Zonemaster est une option d'administrateur. Comme le vérificateur émet des requêtes vers l'URL configurée et en restitue les réponses, ne le pointez que vers une instance Zonemaster en laquelle vous avez confiance. +{{% /notice %}} + +## Ce qui est vérifié + +Le vérificateur projette chaque module de test Zonemaster sur une règle de catégorie. Chaque règle émet un état `.summary`, plus un état par message de niveau WARNING ou pire (afin que les consommateurs en aval puissent s'appuyer sur des codes stables) ; les messages INFO et NOTICE sont agrégés dans les compteurs du résumé. + +| Règle | Ce qu'elle couvre | +|---|---| +| `zonemaster.dnssec` | Tests DNSSEC (signatures, NSEC/NSEC3, cohérence DS/DNSKEY). | +| `zonemaster.delegation` | Tests de délégation (accord NS parent/enfant, glue, renvois). | +| `zonemaster.consistency` | Tests de cohérence (numéro de série SOA, ensemble NS, contenu de zone entre serveurs). | +| `zonemaster.connectivity` | Tests de connectivité (joignabilité UDP/TCP des serveurs autoritaires, diversité d'AS). | +| `zonemaster.nameserver` | Tests des serveurs de noms (comportement du serveur, EDNS, traitement des RR inconnus). | +| `zonemaster.syntax` | Tests de syntaxe (syntaxe des noms de domaine, légalité des noms d'hôtes). | +| `zonemaster.zone` | Tests de zone (valeurs SOA, présence de MX, enregistrements obligatoires). | +| `zonemaster.address` | Tests d'adresses (adresses IP des serveurs de noms, plages privées/réservées). | +| `zonemaster.basic` | Tests de base/système (joignabilité initiale et prérequis fondamentaux). | + +Les sévérités Zonemaster sont projetées sur les statuts de happyDomain : CRITICAL et ERROR vers Critique ; WARNING vers Avertissement ; NOTICE, INFO et DEBUG vers Info. Chaque résumé retient le pire statut parmi les messages de sa catégorie. Lorsque Zonemaster ne renvoie aucun message pour une catégorie, la règle correspondante rapporte Inconnu (non testée). + +## Options + +| Option | Signification | Défaut | +|---|---|---| +| Nom de domaine à vérifier (`domainName`) | Domaine soumis à Zonemaster. **Obligatoire.** | prérempli | +| Profil (`profile`) | Nom du profil Zonemaster sous lequel exécuter les tests. | `default` | +| Langue des résultats (`language`, par utilisateur) | Langue des messages renvoyés (`en`, `fr`, `de`, `es`, `sv`, `da`, `fi`, `nb`, `nl`, `pt`). | `en` | +| URL de l'API Zonemaster (`zonemasterAPIURL`, admin) | Point d'accès JSON-RPC à interroger. | `https://zonemaster.net/api` | + +## Dans happyDomain + +Activez ce vérificateur pour le domaine depuis la vue **Vérifications**. Voir {{< relref "/pages/checks" >}} pour la planification et la lecture des vérifications. + +Zonemaster recoupe en partie {{< relref "/reference/checkers/dnsviz" >}} sur le DNSSEC, mais couvre un éventail plus large de tests de délégation, de connectivité et de contenu de zone. Pour le durcissement NSEC/NSEC3 en particulier, voir {{< relref "/reference/checkers/dnssec" >}}. diff --git a/content/reference/plugins/tests.en.md b/content/reference/plugins/tests.en.md index 76bb719..306d398 100644 --- a/content/reference/plugins/tests.en.md +++ b/content/reference/plugins/tests.en.md @@ -1,311 +1,235 @@ --- -title: "Writing a happyDomain Plugin" -description: "Technical guide for developing test plugins for happyDomain" +title: "Writing a happyDomain Checker Plugin" +description: "Technical guide for developing checker plugins for happyDomain" --- -happyDomain supports external **test plugins** — shared libraries (`.so` files) that add domain or service health checks to a running instance. Plugins are loaded at startup without recompiling the server; the operator simply drops a `.so` file into a configured directory. +happyDomain can be extended with external **checker plugins** — shared libraries (`.so` files) that add automated diagnostics on zones, domains, services or users. A checker plugin is loaded into the running happyDomain process at startup; the operator simply drops a `.so` file into a configured directory, no recompilation of the server required. -## How it works - -A plugin receives a set of options assembled from several configuration scopes, runs a check (HTTP call, DNS query, …), and returns a result with a status level and an optional detailed report. Results are stored and displayed in the happyDomain UI alongside the domain or service they concern. - -When happyDomain starts it scans every directory listed in the `plugins-directories` configuration option. For each file it finds, it: - -1. Opens the shared library. -2. Looks up the exported symbol `NewTestPlugin`. -3. Calls `NewTestPlugin()` to obtain a plugin value. -4. Registers the plugin under each name returned by `PluginEnvName()`. - -If the file is not a valid Go plugin, if `NewTestPlugin` is missing, or if it returns an error, a warning is logged and the file is skipped. The server always starts regardless of individual plugin load failures. - ---- - -## The `TestPlugin` interface - -Every plugin must implement four methods: - -```go -type TestPlugin interface { - PluginEnvName() []string - Version() PluginVersionInfo - AvailableOptions() PluginOptionsDocumentation - RunTest(PluginOptions, map[string]string) (*PluginResult, error) -} -``` - ---- - -## Project structure - -A plugin is a standalone Go module compiled with `-buildmode=plugin`. It must be in `package main` and export exactly one symbol: - -```go -func NewTestPlugin() (happydns.TestPlugin, error) -``` - -Recommended layout: - -``` -myplugin/ -├── go.mod -├── Makefile -└── plugin.go # (or split across multiple .go files) -``` - -### go.mod - -``` -module git.happydns.org/happyDomain/plugins/myplugin - -go 1.25 - -require git.happydns.org/happyDomain v0.0.0 -replace git.happydns.org/happyDomain => ../../ -``` - -The `replace` directive points to your local happyDomain checkout, ensuring the plugin is compiled against the exact same types as the server. +A checker has two halves: it **collects** raw data about a target (an observation), then **evaluates** that data against a set of rules to produce a status. Results are stored and displayed in the happyDomain UI alongside the domain or service they concern. {{< notice style="warning" >}} -A Go plugin and the host process share the same runtime. They **must** be compiled with the same Go toolchain version and the same versions of every shared dependency. Any mismatch produces a hard error at load time. +A `.so` plugin is loaded into the happyDomain process and runs with the same privileges as the server. Treat the plugin directory as a trusted location: happyDomain refuses to load plugins from a directory it cannot trust (see [Security and deployment](#security-and-deployment)). {{< /notice >}} --- -## Entry point +## What a checker plugin must export + +Plugins are built against the **`checker-sdk-go`** module, published separately from the happyDomain core. Throughout this page, `checker` refers to the package `git.happydns.org/checker-sdk-go/checker`. + +happyDomain's loader looks for a single exported symbol named `NewCheckerPlugin` with this exact signature: ```go +func NewCheckerPlugin() (*checker.CheckerDefinition, checker.ObservationProvider, error) +``` + +The two return values describe the two halves of a checker: + +- **`*CheckerDefinition`** describes the checker: its identifier, name, version, the observation keys it relies on, the options it accepts, its rules, an optional aggregator, a scheduling interval, and whether it exposes HTML reports or metrics. See the [field table](#checkerdefinition-fields) below. +- **`ObservationProvider`** is the data-collection half. It exposes a `Key()` (the observation key the rules look up) and a `Collect(ctx, opts)` method that returns the raw observation payload. happyDomain serialises that result to JSON and caches it per observation context. +- Return a non-nil `error` if the plugin cannot initialise (a missing environment variable, a broken cgo dependency, …). The host logs the error and skips the file rather than aborting startup. + +A single `.so` may export several plugin kinds. The loader runs every known plugin loader against every file, then skips any symbol it does not recognise, so one binary can ship more than one plugin. + +--- + +## Minimal example + +This is the smallest plugin that loads. It collects a fixed observation and declares no rules. Adapt it from [`checker-dummy`](https://git.happydns.org/checker-dummy), the reference implementation. + +```go +// Command plugin is the happyDomain plugin entrypoint for the dummy checker. +// +// Build with: +// go build -buildmode=plugin -o checker-dummy.so ./plugin package main -import "git.happydns.org/happyDomain/model" +import ( + "context" -func NewTestPlugin() (happydns.TestPlugin, error) { - return &MyPlugin{}, nil + "git.happydns.org/checker-sdk-go/checker" +) + +type dummyProvider struct{} + +func (dummyProvider) Key() checker.ObservationKey { return "dummy.observation" } + +func (dummyProvider) Collect(ctx context.Context, opts checker.CheckerOptions) (any, error) { + return map[string]string{"hello": "world"}, nil +} + +// NewCheckerPlugin is the symbol resolved by happyDomain at startup. +func NewCheckerPlugin() (*checker.CheckerDefinition, checker.ObservationProvider, error) { + def := &checker.CheckerDefinition{ + ID: "com.example.dummy", + Name: "Dummy checker", + Version: "0.1.0", + ObservationKeys: []checker.ObservationKey{"dummy.observation"}, + // Add Rules / Aggregator / Options here in a real plugin. + } + return def, dummyProvider{}, nil } ``` -The constructor is a good place to perform one-time initialisation (open config files, create an HTTP client, …). Return an error if the plugin cannot function. +{{< notice style="warning" >}} +A Go plugin and the host process share the same runtime. They **must** be compiled with the same Go toolchain version and the same versions of every shared dependency. Any mismatch produces a hard error at load time. See [Build constraints](#build-constraints). +{{< /notice >}} --- -## Naming — `PluginEnvName()` +## `CheckerDefinition` fields -Returns one or more short, lowercase identifiers. These names are used to look up the plugin via the API and to key its stored configuration. - -```go -func (p *MyPlugin) PluginEnvName() []string { - return []string{"myplugin"} -} -``` - -Choose names that are unlikely to collide (e.g. `"zonemaster"`, `"matrixim"`) and keep them **stable across versions** because they are persisted alongside user configuration. If two loaded plugins claim the same name, the second one is skipped and a conflict is logged. - ---- - -## Version and availability — `Version()` - -Describes the plugin and controls where it appears in the UI: - -```go -func (p *MyPlugin) Version() happydns.PluginVersionInfo { - return happydns.PluginVersionInfo{ - Name: "My Plugin", - Version: "1.0", - AvailableOn: happydns.PluginAvailability{ - ApplyToDomain: true, - ApplyToService: false, - LimitToProviders: nil, // nil or empty = all providers - LimitToServices: []string{"abstract.MatrixIM"}, - }, - } -} -``` +The `*CheckerDefinition` returned by `NewCheckerPlugin` is the description of your checker: | Field | Type | Description | |---|---|---| -| `ApplyToDomain` | `bool` | Plugin can be run against a whole domain | -| `ApplyToService` | `bool` | Plugin can be run against a specific DNS service | -| `LimitToProviders` | `[]string` | Restrict to certain DNS provider identifiers (empty = no restriction) | -| `LimitToServices` | `[]string` | Restrict to certain service type identifiers, e.g. `"abstract.MatrixIM"` (empty = no restriction) | +| `ID` | `string` | **Required.** Stable, persistent identifier. Pick a namespaced value (`com.example.dnssec-freshness`, not `dnssec`) and never change it: it keys stored results and user configuration. | +| `Name` | `string` | Human-readable name shown in the UI. | +| `Version` | `string` | Plugin version (e.g. `"1.0.0"`). | +| `Availability` | `CheckerAvailability` | Declares which scopes the checker applies to and any provider/service restrictions (see below). | +| `Options` | `CheckerOptionsDocumentation` | Documents the options the checker accepts, grouped by scope (see below). | +| `Rules` | `[]CheckRule` | The rules evaluated against the collected observation. | +| `Aggregator` | `CheckAggregator` | Optional. Combines the per-rule `CheckState`s into a single summary state. | +| `Interval` | `*CheckIntervalSpec` | Optional scheduling bounds (`Min`, `Max`, `Default` durations). | +| `HasHTMLReport` | `bool` | Set when the provider implements `CheckerHTMLReporter`. | +| `HasMetrics` | `bool` | Set when the provider implements `CheckerMetricsReporter`. | +| `ObservationKeys` | `[]ObservationKey` | The observation keys this checker reads. | -Both `ApplyToDomain` and `ApplyToService` may be `true` simultaneously. +### Availability ---- - -## Options — `AvailableOptions()` - -Options are key/value pairs (`map[string]any`) that configure each test run. They are declared grouped by **scope**, i.e. who sets them and how long they persist: - -```go -func (p *MyPlugin) AvailableOptions() happydns.PluginOptionsDocumentation { - return happydns.PluginOptionsDocumentation{ - RunOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - ServiceOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - DomainOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - UserOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - AdminOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - } -} -``` - -### Option scopes - -| Scope | Who sets it | Storage key | Typical use | -|---|---|---|---| -| `RunOpts` | User, at test time | _(transient)_ | Per-invocation parameters | -| `ServiceOpts` | User | plugin + user + domain + service | Service-level configuration | -| `DomainOpts` | User | plugin + user + domain | Domain-level configuration | -| `UserOpts` | User | plugin + user | Personal preferences (e.g. language) | -| `AdminOpts` | Administrator | plugin | Instance-wide settings, shared credentials | - -Before `RunTest` is called, happyDomain merges all scoped values from least specific (admin) to most specific (run-time). More-specific values silently override less-specific ones. `RunTest` always receives a single flat map and does not need to know which scope each value came from. - -### Option fields - -Each option is a `PluginOptionDocumentation` (an alias for `Field`): +`CheckerAvailability` controls where the checker is offered in the UI: | Field | Type | Description | |---|---|---| -| `Id` | `string` | **Required.** Key used in the `PluginOptions` map inside `RunTest` | -| `Type` | `string` | Input type: `"string"`, `"select"` | -| `Label` | `string` | Human-readable label shown in the UI | -| `Placeholder` | `string` | Placeholder text for the input field | -| `Default` | `any` | Default value pre-filled in the form | -| `Choices` | `[]string` | Options for `"select"` inputs | -| `Required` | `bool` | Whether the field must be filled before running | -| `Secret` | `bool` | Marks the field as sensitive (e.g. an API key) | -| `Hide` | `bool` | Hides the field from the user entirely | -| `Textarea` | `bool` | Renders a multiline text area | -| `Description` | `string` | Help text displayed below the field | -| `AutoFill` | `string` | Populate the field automatically from context (see below) | +| `ApplyToDomain` | `bool` | Checker can run against a whole domain. | +| `ApplyToZone` | `bool` | Checker can run against a zone. | +| `ApplyToService` | `bool` | Checker can run against a specific service. | +| `LimitToProviders` | `[]string` | Restrict to certain DNS provider identifiers (empty = no restriction). | +| `LimitToServices` | `[]string` | Restrict to certain service type identifiers, e.g. `"abstract.MatrixIM"` (empty = no restriction). | -### Auto-fill +### Options -When `AutoFill` is set, happyDomain populates the field from the test context; the user is not prompted: +Options are declared grouped by **scope**, i.e. who sets them and how long they persist. Each scope is a slice of `CheckerOptionDocumentation`: -| Constant | String value | Populated with | +| Scope | Who sets it | Typical use | |---|---|---| -| `happydns.AutoFillDomainName` | `"domain_name"` | FQDN of the domain under test, e.g. `"example.com."` | -| `happydns.AutoFillSubdomain` | `"subdomain"` | Subdomain relative to the zone, e.g. `"www"` — service-scoped tests only | -| `happydns.AutoFillServiceType` | `"service_type"` | Service type identifier, e.g. `"abstract.MatrixIM"` — service-scoped tests only | +| `AdminOpts` | Administrator | Instance-wide settings, shared credentials. | +| `UserOpts` | User | Personal preferences (e.g. language). | +| `DomainOpts` | User | Domain-level configuration. | +| `ServiceOpts` | User | Service-level configuration. | +| `RunOpts` | User, at run time | Per-invocation parameters. | -```go -{ - Id: "domainName", - Type: "string", - Label: "Domain name", - AutoFill: happydns.AutoFillDomainName, - Required: true, -} -``` +happyDomain merges the scoped values from least specific (admin) to most specific (run-time) before calling `Collect`, so the provider receives a single flat `CheckerOptions` map. Each option is a `CheckerOptionField` with fields such as `Id`, `Type`, `Label`, `Default`, `Choices`, `Required`, `Secret`, `Description` and `AutoFill`. Read typed values out of the map with the SDK helpers `checker.GetOption`, `checker.GetIntOption`, `checker.GetBoolOption`, … + +{{< notice style="info" >}} +When happyDomain registers an externalisable checker, it automatically appends an `endpoint` admin option, so the administrator can delegate collection to a remote HTTP endpoint instead of running the checker in-process. Leave it empty to run locally. +{{< /notice >}} --- -## Running the check — `RunTest()` +## The `ObservationProvider` -`RunTest` receives the merged option map and a metadata map (reserved for future use), performs the check, and returns a `PluginResult`. - -Always assert option values to a concrete type before use — the map holds `any`: +The provider is the data-collection half of the checker: ```go -func (p *MyPlugin) RunTest(opts happydns.PluginOptions, _ map[string]string) (*happydns.PluginResult, error) { - domain, ok := opts["domainName"].(string) - if !ok || domain == "" { - return nil, fmt.Errorf("domainName option is required") - } - - // … perform the check … - - return &happydns.PluginResult{ - Status: happydns.PluginResultStatusOK, - StatusLine: "All good", - Report: myStructuredReport, - }, nil +type ObservationProvider interface { + Key() ObservationKey + Collect(ctx context.Context, opts CheckerOptions) (any, error) } ``` -Return a **non-nil error** only for unexpected failures (network errors, invalid configuration). For expected check failures — the monitored service is down, DNS records are wrong — return a `PluginResult` with an appropriate status and a human-readable `StatusLine`. +- `Key()` returns the observation key this provider fills. It must match one of the `ObservationKeys` declared in the definition. +- `Collect` performs the actual work (a DNS query, an HTTP call, …) and returns any JSON-serialisable value. happyDomain marshals it to JSON and caches it; the rules then read it back. -### Result fields +A provider can optionally implement additional SDK interfaces to extend its behaviour: -| Field | Type | Description | -|---|---|---| -| `Status` | `PluginResultStatus` | Overall result level (see below) | -| `StatusLine` | `string` | Short summary displayed in the UI | -| `Report` | `any` | Any JSON-serialisable value stored as structured diagnostic data | - -### Status levels (worst → best) - -| Constant | Meaning | +| Interface | Purpose | |---|---| -| `PluginResultStatusKO` | Check failed | -| `PluginResultStatusWarn` | Check passed with warnings | -| `PluginResultStatusInfo` | Informational, no action required | -| `PluginResultStatusOK` | Check fully passed | +| `CheckerHTMLReporter` | `GetHTMLReport(ctx ReportContext)` renders the stored observation as an HTML document. | +| `CheckerMetricsReporter` | `ExtractMetrics(ctx ReportContext, collectedAt)` produces time-series metrics. | +| `CheckEnabler` | `IsEligible(ctx, opts)` decides, from the target's actual data, whether running the checker is meaningful at all. | +| `DiscoveryPublisher` | `DiscoverEntries(data)` publishes `DiscoveryEntry` records other checkers can consume. | + +Rules return `CheckState` values whose `Status` is one of `StatusOK`, `StatusInfo`, `StatusWarn`, `StatusCrit`, `StatusError` or `StatusUnknown`. + +### Optional: standalone server + +The SDK also provides `checker.Server`, HTTP scaffolding for running a checker as a remote endpoint instead of (or alongside) an in-process plugin. It exposes the routes `/health` and `/collect`, plus `/definition`, `/evaluate` and `/report` when the provider implements the matching optional interfaces. A provider that implements `CheckerInteractive` (`RenderForm` / `ParseForm`) additionally gets a human-facing form on `/check`, usable outside of happyDomain. See the [SDK README](https://git.happydns.org/checker-sdk-go) for details; the in-process plugin path described above does not require any of this. --- -## Building +## Build constraints -```bash -go build -buildmode=plugin -o happydomain-plugin-test-myplugin.so \ - git.happydns.org/happyDomain/plugins/myplugin -``` +Go's `plugin` package is unforgiving. To load successfully, your plugin must be built with: -Minimal `Makefile`: +- the **same Go toolchain version** as happyDomain itself, including the same patch level; +- the **same versions of every shared dependency** (pin them in your `go.mod`, vendoring the exact versions happyDomain ships); +- `CGO_ENABLED=1`; +- the same `GOOS`/`GOARCH` as the host binary. -```makefile -PLUGIN_NAME=myplugin -TARGET=../happydomain-plugin-test-$(PLUGIN_NAME).so +If any of these do not match, `plugin.Open` fails with a (sometimes cryptic) error like *"plugin was built with a different version of package …"*. The host logs it and skips the file. -all: $(TARGET) - -$(TARGET): *.go - go build -buildmode=plugin -o $@ git.happydns.org/happyDomain/plugins/$(PLUGIN_NAME) -``` - -The prefix `happydomain-plugin-test-` is a convention; happyDomain loads every file in the plugin directories regardless of its name. +Go's `plugin` package only works on **linux**, **darwin** and **freebsd**. On other platforms happyDomain is built without plugin support and the configured plugin directories are ignored, with a warning logged at startup. --- -## Deployment +## Security and deployment -### 1. Copy the `.so` file +### Directory and file permissions + +Loading a `.so` file is arbitrary code execution as the happyDomain process, so the loader enforces strict ownership before it touches any file: + +- The plugin directory **must not be a symbolic link** — happyDomain refuses to follow one, to prevent it being redirected to an attacker-controlled path. +- The plugin directory **must not be group- or world-writable**. A directory writable by anyone but the owner is treated as a fatal misconfiguration and aborts loading. +- Any individual `.so` file that is **group- or world-writable is skipped** (logged and ignored), even inside a properly locked-down directory. + +In practice: keep the directory owned by the happyDomain user, mode `0755`, and the plugin files mode `0644`. ```bash -cp happydomain-plugin-test-myplugin.so /usr/lib/happydomain/plugins/ +sudo install -d -m 0755 -o happydomain /var/lib/happydomain/plugins +sudo install -m 0644 -o happydomain checker-dummy.so /var/lib/happydomain/plugins/ ``` -### 2. Point happyDomain at the directory - -`happydomain.conf`: - -``` -plugins-directories=/usr/lib/happydomain/plugins -``` - -Environment variable: +### Building the plugin ```bash -HAPPYDOMAIN_PLUGINS_DIRECTORIES=/usr/lib/happydomain/plugins +CGO_ENABLED=1 go build -buildmode=plugin -o checker-dummy.so ./plugin ``` -Multiple directories may be listed as a comma-separated value. +### Pointing happyDomain at the directory -### 3. Check the logs +The directory is configured with the **`--plugins-directory`** flag, which **may be repeated** to scan several directories: -On a successful load: - -``` -Plugin My Plugin loaded (version 1.0) +```bash +happydomain --plugins-directory /var/lib/happydomain/plugins ``` -On a name conflict or load error a warning is logged with the filename and reason. +The equivalent environment variable is `HAPPYDOMAIN_PLUGINS_DIRECTORY`. + +The loader scans each configured directory and attempts to load every `.so` file it finds. An individual plugin that fails to load — wrong build, missing symbols, a panic in its factory — is logged and skipped without aborting startup; one bad `.so` never prevents the others from loading. + +### Restart and check the logs + +```bash +sudo systemctl restart happydomain +``` + +On a successful load, happyDomain logs: + +``` +Plugin com.example.dummy (/var/lib/happydomain/plugins/checker-dummy.so) loaded +``` --- -## Reference implementations +## Licensing -Two plugins are bundled in this directory: +Checker plugins import only `git.happydns.org/checker-sdk-go/checker`, which is licensed under **Apache-2.0**. The SDK is deliberately split out of the AGPL-3.0 happyDomain core as a small, stable public API for third-party checkers. -- **`matrix/`** — queries the Matrix federation tester API. Demonstrates `ApplyToService` with `LimitToServices` and `AdminOpts` for the backend URL. -- **`zonemaster/`** — drives the Zonemaster JSON-RPC API, polls for completion, and maps results to severity levels. Demonstrates `AutoFillDomainName`, `UserOpts` for language selection, and multi-level status mapping. +A plugin built against this SDK is therefore **not** a derivative work of happyDomain, and you may distribute your checker `.so` under any license you choose (MIT, Apache, proprietary, AGPL — whatever fits your needs). + +--- + +## Reference implementation + +[`checker-dummy`](https://git.happydns.org/checker-dummy) is the fully working, documented template that this page mirrors. Start from it when writing your own checker. diff --git a/content/reference/plugins/tests.fr.md b/content/reference/plugins/tests.fr.md index 535d704..b5494fd 100644 --- a/content/reference/plugins/tests.fr.md +++ b/content/reference/plugins/tests.fr.md @@ -1,311 +1,235 @@ --- -title: "Écrire un plugin happyDomain" -description: "Guide technique pour développer des plugins de test pour happyDomain" +title: "Écrire un plugin de vérification happyDomain" +description: "Guide technique pour développer des plugins checker pour happyDomain" --- -happyDomain prend en charge des **plugins de test** externes — des bibliothèques partagées (fichiers `.so`) qui ajoutent des vérifications de santé sur les domaines ou les services d'une instance en cours d'exécution. Les plugins sont chargés au démarrage sans recompiler le serveur ; l'opérateur dépose simplement un fichier `.so` dans un répertoire configuré. +happyDomain peut être étendu par des **plugins de vérification** (*checkers*) externes : des bibliothèques partagées (fichiers `.so`) qui ajoutent des diagnostics automatisés sur les zones, les domaines, les services ou les utilisateurs. Un plugin checker est chargé dans le processus happyDomain au démarrage. L'opérateur dépose simplement un fichier `.so` dans un répertoire configuré, sans recompiler le serveur. -## Fonctionnement - -Un plugin reçoit un ensemble d'options assemblées depuis plusieurs portées de configuration, exécute une vérification (appel HTTP, requête DNS, …) et renvoie un résultat avec un niveau de statut et un rapport détaillé optionnel. Les résultats sont stockés et affichés dans l'interface happyDomain aux côtés du domaine ou du service concerné. - -Au démarrage, happyDomain parcourt chaque répertoire listé dans l'option de configuration `plugins-directories`. Pour chaque fichier trouvé, il : - -1. Ouvre la bibliothèque partagée. -2. Recherche le symbole exporté `NewTestPlugin`. -3. Appelle `NewTestPlugin()` pour obtenir une valeur de plugin. -4. Enregistre le plugin sous chaque nom renvoyé par `PluginEnvName()`. - -Si le fichier n'est pas un plugin Go valide, si `NewTestPlugin` est absent ou s'il retourne une erreur, un avertissement est journalisé et le fichier est ignoré. Le serveur démarre toujours, quels que soient les échecs de chargement individuels. - ---- - -## L'interface `TestPlugin` - -Tout plugin doit implémenter quatre méthodes : - -```go -type TestPlugin interface { - PluginEnvName() []string - Version() PluginVersionInfo - AvailableOptions() PluginOptionsDocumentation - RunTest(PluginOptions, map[string]string) (*PluginResult, error) -} -``` - ---- - -## Structure du projet - -Un plugin est un module Go autonome compilé avec `-buildmode=plugin`. Il doit être dans `package main` et exporter exactement un symbole : - -```go -func NewTestPlugin() (happydns.TestPlugin, error) -``` - -Organisation recommandée : - -``` -myplugin/ -├── go.mod -├── Makefile -└── plugin.go # (ou réparti sur plusieurs fichiers .go) -``` - -### go.mod - -``` -module git.happydns.org/happyDomain/plugins/myplugin - -go 1.25 - -require git.happydns.org/happyDomain v0.0.0 -replace git.happydns.org/happyDomain => ../../ -``` - -La directive `replace` pointe vers votre dépôt local happyDomain, garantissant que le plugin est compilé avec exactement les mêmes types que le serveur. +Un checker comporte deux moitiés. Il **collecte** d'abord des données brutes sur une cible (une observation). Il **évalue** ensuite ces données au regard d'un ensemble de règles afin de produire un statut. Les résultats sont stockés puis affichés dans l'interface de happyDomain, à côté du domaine ou du service concerné. {{< notice style="warning" >}} -Un plugin Go et le processus hôte partagent le même environnement d'exécution. Ils **doivent** être compilés avec la même version de la chaîne d'outils Go et les mêmes versions de toutes les dépendances partagées. Tout écart provoque une erreur fatale au chargement. +Un plugin `.so` est chargé dans le processus happyDomain et s'exécute avec les mêmes privilèges que le serveur. Le répertoire des plugins doit être considéré comme un emplacement de confiance : happyDomain refuse de charger des plugins depuis un répertoire qui ne l'est pas (voir [Sécurité et déploiement](#sécurité-et-déploiement)). {{< /notice >}} --- -## Point d'entrée +## Ce qu'un plugin checker doit exporter + +Les plugins sont construits avec le module **`checker-sdk-go`**, publié séparément du cœur de happyDomain. Dans cette page, `checker` désigne le paquet `git.happydns.org/checker-sdk-go/checker`. + +Le chargeur de happyDomain recherche un unique symbole exporté nommé `NewCheckerPlugin`, avec cette signature exacte : ```go +func NewCheckerPlugin() (*checker.CheckerDefinition, checker.ObservationProvider, error) +``` + +Les deux valeurs de retour décrivent les deux moitiés d'un checker : + +- **`*CheckerDefinition`** décrit le checker : son identifiant, son nom, sa version, les clés d'observation dont il dépend, les options qu'il accepte, ses règles, un agrégateur optionnel, un intervalle de planification, et s'il expose des rapports HTML ou des métriques. Voir le [tableau des champs](#champs-de-checkerdefinition) ci-dessous. +- **`ObservationProvider`** est la moitié chargée de la collecte. Elle expose une méthode `Key()` (la clé d'observation que les règles consultent) et une méthode `Collect(ctx, opts)` qui renvoie la charge utile brute de l'observation. happyDomain sérialise ce résultat en JSON et le met en cache pour chaque contexte d'observation. +- Renvoyez une `error` non nulle si le plugin ne peut pas s'initialiser (variable d'environnement manquante, dépendance cgo cassée, …). L'hôte journalise l'erreur et ignore le fichier, sans interrompre le démarrage. + +Un même fichier `.so` peut exporter plusieurs types de plugins. Le chargeur applique chaque chargeur connu à chaque fichier, puis ignore tout symbole qu'il ne reconnaît pas. Un binaire peut donc fournir plusieurs plugins. + +--- + +## Exemple minimal + +Voici le plus petit plugin qui se charge. Il collecte une observation fixe et ne déclare aucune règle. On peut l'adapter à partir de [`checker-dummy`](https://git.happydns.org/checker-dummy), l'implémentation de référence. + +```go +// Command plugin is the happyDomain plugin entrypoint for the dummy checker. +// +// Build with: +// go build -buildmode=plugin -o checker-dummy.so ./plugin package main -import "git.happydns.org/happyDomain/model" +import ( + "context" -func NewTestPlugin() (happydns.TestPlugin, error) { - return &MyPlugin{}, nil + "git.happydns.org/checker-sdk-go/checker" +) + +type dummyProvider struct{} + +func (dummyProvider) Key() checker.ObservationKey { return "dummy.observation" } + +func (dummyProvider) Collect(ctx context.Context, opts checker.CheckerOptions) (any, error) { + return map[string]string{"hello": "world"}, nil +} + +// NewCheckerPlugin is the symbol resolved by happyDomain at startup. +func NewCheckerPlugin() (*checker.CheckerDefinition, checker.ObservationProvider, error) { + def := &checker.CheckerDefinition{ + ID: "com.example.dummy", + Name: "Dummy checker", + Version: "0.1.0", + ObservationKeys: []checker.ObservationKey{"dummy.observation"}, + // Add Rules / Aggregator / Options here in a real plugin. + } + return def, dummyProvider{}, nil } ``` -Le constructeur est l'endroit idéal pour effectuer une initialisation unique (ouvrir des fichiers de configuration, créer un client HTTP, …). Retournez une erreur si le plugin ne peut pas fonctionner. +{{< notice style="warning" >}} +Un plugin Go et le processus hôte partagent le même *runtime*. Ils **doivent** être compilés avec la même version de la chaîne d'outils Go et les mêmes versions de chaque dépendance partagée. Toute divergence produit une erreur bloquante au chargement. Voir [Contraintes de build](#contraintes-de-build). +{{< /notice >}} --- -## Nommage — `PluginEnvName()` +## Champs de `CheckerDefinition` -Renvoie un ou plusieurs identifiants courts en minuscules. Ces noms sont utilisés pour retrouver le plugin via l'API et pour indexer sa configuration stockée. - -```go -func (p *MyPlugin) PluginEnvName() []string { - return []string{"myplugin"} -} -``` - -Choisissez des noms peu susceptibles d'entrer en conflit (ex. `"zonemaster"`, `"matrixim"`) et gardez-les **stables entre les versions**, car ils sont persistés avec la configuration utilisateur. Si deux plugins chargés revendiquent le même nom, le second est ignoré et un conflit est journalisé. - ---- - -## Version et disponibilité — `Version()` - -Décrit le plugin et contrôle l'endroit où il apparaît dans l'interface : - -```go -func (p *MyPlugin) Version() happydns.PluginVersionInfo { - return happydns.PluginVersionInfo{ - Name: "My Plugin", - Version: "1.0", - AvailableOn: happydns.PluginAvailability{ - ApplyToDomain: true, - ApplyToService: false, - LimitToProviders: nil, // nil ou vide = tous les fournisseurs - LimitToServices: []string{"abstract.MatrixIM"}, - }, - } -} -``` +Le `*CheckerDefinition` renvoyé par `NewCheckerPlugin` est la description de votre checker : | Champ | Type | Description | |---|---|---| -| `ApplyToDomain` | `bool` | Le plugin peut être exécuté sur un domaine entier | -| `ApplyToService` | `bool` | Le plugin peut être exécuté sur un service DNS spécifique | -| `LimitToProviders` | `[]string` | Restreint à certains identifiants de fournisseurs DNS (vide = aucune restriction) | -| `LimitToServices` | `[]string` | Restreint à certains types de services, ex. `"abstract.MatrixIM"` (vide = aucune restriction) | +| `ID` | `string` | **Requis.** Identifiant stable et persistant. Choisissez une valeur préfixée par un espace de noms (`com.example.dnssec-freshness`, et non `dnssec`) et ne la changez jamais : elle indexe les résultats stockés et la configuration utilisateur. | +| `Name` | `string` | Nom lisible affiché dans l'interface. | +| `Version` | `string` | Version du plugin (par exemple `"1.0.0"`). | +| `Availability` | `CheckerAvailability` | Déclare les portées auxquelles le checker s'applique et d'éventuelles restrictions de fournisseur ou de service (voir ci-dessous). | +| `Options` | `CheckerOptionsDocumentation` | Documente les options acceptées par le checker, regroupées par portée (voir ci-dessous). | +| `Rules` | `[]CheckRule` | Les règles évaluées sur l'observation collectée. | +| `Aggregator` | `CheckAggregator` | Optionnel. Combine les `CheckState` produits par chaque règle en un état de synthèse unique. | +| `Interval` | `*CheckIntervalSpec` | Bornes de planification optionnelles (durées `Min`, `Max`, `Default`). | +| `HasHTMLReport` | `bool` | À activer lorsque le provider implémente `CheckerHTMLReporter`. | +| `HasMetrics` | `bool` | À activer lorsque le provider implémente `CheckerMetricsReporter`. | +| `ObservationKeys` | `[]ObservationKey` | Les clés d'observation que ce checker lit. | -`ApplyToDomain` et `ApplyToService` peuvent être tous les deux `true` simultanément. +### Disponibilité ---- - -## Options — `AvailableOptions()` - -Les options sont des paires clé/valeur (`map[string]any`) qui configurent chaque exécution de test. Elles sont déclarées regroupées par **portée**, c'est-à-dire qui les définit et combien de temps elles persistent : - -```go -func (p *MyPlugin) AvailableOptions() happydns.PluginOptionsDocumentation { - return happydns.PluginOptionsDocumentation{ - RunOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - ServiceOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - DomainOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - UserOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - AdminOpts: []happydns.PluginOptionDocumentation{ /* … */ }, - } -} -``` - -### Portées des options - -| Portée | Qui la définit | Clé de stockage | Usage typique | -|---|---|---|---| -| `RunOpts` | L'utilisateur, au moment du test | _(transitoire)_ | Paramètres propres à l'exécution | -| `ServiceOpts` | L'utilisateur | plugin + utilisateur + domaine + service | Configuration au niveau du service | -| `DomainOpts` | L'utilisateur | plugin + utilisateur + domaine | Configuration au niveau du domaine | -| `UserOpts` | L'utilisateur | plugin + utilisateur | Préférences personnelles (ex. langue) | -| `AdminOpts` | L'administrateur | plugin | Paramètres d'instance, identifiants partagés | - -Avant l'appel à `RunTest`, happyDomain fusionne toutes les valeurs par portée, de la moins spécifique (admin) à la plus spécifique (exécution). Les valeurs plus spécifiques écrasent silencieusement les moins spécifiques. `RunTest` reçoit toujours une map plate unique et n'a pas besoin de savoir de quelle portée provient chaque valeur. - -### Champs d'une option - -Chaque option est un `PluginOptionDocumentation` (un alias pour `Field`) : +`CheckerAvailability` contrôle l'endroit où le checker est proposé dans l'interface : | Champ | Type | Description | |---|---|---| -| `Id` | `string` | **Obligatoire.** Clé utilisée dans la map `PluginOptions` dans `RunTest` | -| `Type` | `string` | Type de saisie : `"string"`, `"select"` | -| `Label` | `string` | Libellé lisible affiché dans l'interface | -| `Placeholder` | `string` | Texte indicatif du champ de saisie | -| `Default` | `any` | Valeur par défaut pré-remplie dans le formulaire | -| `Choices` | `[]string` | Options pour les saisies de type `"select"` | -| `Required` | `bool` | Indique si le champ doit être rempli avant l'exécution | -| `Secret` | `bool` | Marque le champ comme sensible (ex. une clé API) | -| `Hide` | `bool` | Masque entièrement le champ à l'utilisateur | -| `Textarea` | `bool` | Affiche une zone de texte multiligne | -| `Description` | `string` | Texte d'aide affiché sous le champ | -| `AutoFill` | `string` | Remplit le champ automatiquement depuis le contexte (voir ci-dessous) | +| `ApplyToDomain` | `bool` | Le checker peut s'exécuter sur un domaine entier. | +| `ApplyToZone` | `bool` | Le checker peut s'exécuter sur une zone. | +| `ApplyToService` | `bool` | Le checker peut s'exécuter sur un service précis. | +| `LimitToProviders` | `[]string` | Restreint à certains identifiants de fournisseurs DNS (vide = aucune restriction). | +| `LimitToServices` | `[]string` | Restreint à certains identifiants de types de services, par exemple `"abstract.MatrixIM"` (vide = aucune restriction). | -### Remplissage automatique +### Options -Lorsque `AutoFill` est défini, happyDomain remplit le champ à partir du contexte du test ; l'utilisateur n'est pas sollicité : +Les options sont déclarées par **portée**, c'est-à-dire selon qui les définit et combien de temps elles persistent. Chaque portée est une tranche de `CheckerOptionDocumentation` : -| Constante | Valeur chaîne | Rempli avec | +| Portée | Qui la définit | Usage habituel | |---|---|---| -| `happydns.AutoFillDomainName` | `"domain_name"` | FQDN du domaine testé, ex. `"example.com."` | -| `happydns.AutoFillSubdomain` | `"subdomain"` | Sous-domaine relatif à la zone, ex. `"www"` — tests à portée service uniquement | -| `happydns.AutoFillServiceType` | `"service_type"` | Identifiant du type de service, ex. `"abstract.MatrixIM"` — tests à portée service uniquement | +| `AdminOpts` | Administrateur | Réglages valables pour toute l'instance, identifiants partagés. | +| `UserOpts` | Utilisateur | Préférences personnelles (par exemple la langue). | +| `DomainOpts` | Utilisateur | Configuration au niveau du domaine. | +| `ServiceOpts` | Utilisateur | Configuration au niveau du service. | +| `RunOpts` | Utilisateur, au moment de l'exécution | Paramètres propres à une invocation. | -```go -{ - Id: "domainName", - Type: "string", - Label: "Nom de domaine", - AutoFill: happydns.AutoFillDomainName, - Required: true, -} -``` +happyDomain fusionne les valeurs des différentes portées, de la moins spécifique (administrateur) à la plus spécifique (exécution), avant d'appeler `Collect`. Le provider reçoit donc une unique table `CheckerOptions` à plat. Chaque option est un `CheckerOptionField` avec des champs comme `Id`, `Type`, `Label`, `Default`, `Choices`, `Required`, `Secret`, `Description` et `AutoFill`. On lit les valeurs typées de la table à l'aide des fonctions du SDK `checker.GetOption`, `checker.GetIntOption`, `checker.GetBoolOption`, … + +{{< notice style="info" >}} +Lorsque happyDomain enregistre un checker externalisable, il ajoute automatiquement une option d'administration `endpoint`. L'administrateur peut ainsi déléguer la collecte à un point d'accès HTTP distant plutôt que de l'exécuter dans le processus. Laissée vide, elle fait fonctionner le checker localement. +{{< /notice >}} --- -## Exécuter la vérification — `RunTest()` +## L'`ObservationProvider` -`RunTest` reçoit la map d'options fusionnée et une map de métadonnées (réservée à un usage futur), effectue la vérification et renvoie un `PluginResult`. - -Convertissez toujours les valeurs d'options vers un type concret avant de les utiliser — la map contient des valeurs de type `any` : +Le provider est la moitié du checker chargée de la collecte : ```go -func (p *MyPlugin) RunTest(opts happydns.PluginOptions, _ map[string]string) (*happydns.PluginResult, error) { - domain, ok := opts["domainName"].(string) - if !ok || domain == "" { - return nil, fmt.Errorf("l'option domainName est obligatoire") - } - - // … effectuer la vérification … - - return &happydns.PluginResult{ - Status: happydns.PluginResultStatusOK, - StatusLine: "Tout est bon", - Report: myStructuredReport, - }, nil +type ObservationProvider interface { + Key() ObservationKey + Collect(ctx context.Context, opts CheckerOptions) (any, error) } ``` -Retournez une **erreur non nulle** uniquement pour les échecs inattendus (erreurs réseau, configuration invalide). Pour les échecs de vérification attendus — le service surveillé est indisponible, les enregistrements DNS sont incorrects — retournez un `PluginResult` avec un statut approprié et un `StatusLine` lisible par un humain. +- `Key()` renvoie la clé d'observation que ce provider remplit. Elle doit correspondre à l'une des `ObservationKeys` déclarées dans la définition. +- `Collect` effectue le travail réel (une requête DNS, un appel HTTP, …) et renvoie n'importe quelle valeur sérialisable en JSON. happyDomain la convertit en JSON et la met en cache ; les règles la relisent ensuite. -### Champs du résultat +Un provider peut implémenter des interfaces supplémentaires du SDK pour étendre son comportement : -| Champ | Type | Description | -|---|---|---| -| `Status` | `PluginResultStatus` | Niveau de résultat global (voir ci-dessous) | -| `StatusLine` | `string` | Résumé court affiché dans l'interface | -| `Report` | `any` | Toute valeur sérialisable en JSON, stockée comme données de diagnostic structurées | - -### Niveaux de statut (du pire au meilleur) - -| Constante | Signification | +| Interface | Rôle | |---|---| -| `PluginResultStatusKO` | La vérification a échoué | -| `PluginResultStatusWarn` | La vérification a réussi avec des avertissements | -| `PluginResultStatusInfo` | Informatif, aucune action requise | -| `PluginResultStatusOK` | La vérification a entièrement réussi | +| `CheckerHTMLReporter` | `GetHTMLReport(ctx ReportContext)` rend l'observation stockée sous forme de document HTML. | +| `CheckerMetricsReporter` | `ExtractMetrics(ctx ReportContext, collectedAt)` produit des métriques temporelles. | +| `CheckEnabler` | `IsEligible(ctx, opts)` décide, à partir des données réelles de la cible, s'il est pertinent d'exécuter le checker. | +| `DiscoveryPublisher` | `DiscoverEntries(data)` publie des enregistrements `DiscoveryEntry` que d'autres checkers peuvent consommer. | + +Les règles renvoient des valeurs `CheckState` dont le `Status` vaut `StatusOK`, `StatusInfo`, `StatusWarn`, `StatusCrit`, `StatusError` ou `StatusUnknown`. + +### Optionnel : serveur autonome + +Le SDK fournit aussi `checker.Server`, une ossature HTTP pour exécuter un checker comme un point d'accès distant plutôt que (ou en plus) d'un plugin chargé dans le processus. Elle expose les routes `/health` et `/collect`, ainsi que `/definition`, `/evaluate` et `/report` lorsque le provider implémente les interfaces optionnelles correspondantes. Un provider qui implémente `CheckerInteractive` (`RenderForm` / `ParseForm`) dispose en outre d'un formulaire `/check` destiné aux humains, utilisable en dehors de happyDomain. Voir le [README du SDK](https://git.happydns.org/checker-sdk-go) pour les détails ; le mode plugin décrit plus haut n'en a pas besoin. --- -## Compilation +## Contraintes de build -```bash -go build -buildmode=plugin -o happydomain-plugin-test-myplugin.so \ - git.happydns.org/happyDomain/plugins/myplugin -``` +Le paquet `plugin` de Go est intransigeant. Pour se charger correctement, votre plugin doit être compilé avec : -`Makefile` minimal : +- la **même version de la chaîne d'outils Go** que happyDomain, jusqu'au même niveau de correctif ; +- les **mêmes versions de chaque dépendance partagée** (à figer dans votre `go.mod`, en vendorisant les versions exactes que happyDomain embarque) ; +- `CGO_ENABLED=1` ; +- les mêmes `GOOS` et `GOARCH` que le binaire hôte. -```makefile -PLUGIN_NAME=myplugin -TARGET=../happydomain-plugin-test-$(PLUGIN_NAME).so +Si l'un de ces points ne correspond pas, `plugin.Open` échoue avec une erreur parfois obscure, du type *« plugin was built with a different version of package … »*. L'hôte la journalise et ignore le fichier. -all: $(TARGET) - -$(TARGET): *.go - go build -buildmode=plugin -o $@ git.happydns.org/happyDomain/plugins/$(PLUGIN_NAME) -``` - -Le préfixe `happydomain-plugin-test-` est une convention ; happyDomain charge tous les fichiers présents dans les répertoires de plugins, quel que soit leur nom. +Le paquet `plugin` de Go ne fonctionne que sur **linux**, **darwin** et **freebsd**. Sur les autres plateformes, happyDomain est construit sans prise en charge des plugins et les répertoires configurés sont ignorés, avec un avertissement journalisé au démarrage. --- -## Déploiement +## Sécurité et déploiement -### 1. Copier le fichier `.so` +### Permissions du répertoire et des fichiers + +Charger un fichier `.so` revient à exécuter du code arbitraire avec les droits du processus happyDomain. Le chargeur impose donc des règles strictes de propriété avant de toucher au moindre fichier : + +- Le répertoire des plugins **ne doit pas être un lien symbolique** : happyDomain refuse de le suivre, pour éviter qu'il soit redirigé vers un chemin contrôlé par un attaquant. +- Le répertoire des plugins **ne doit pas être accessible en écriture au groupe ni à tous**. Un répertoire modifiable par quelqu'un d'autre que son propriétaire est traité comme une erreur de configuration bloquante et interrompt le chargement. +- Tout fichier `.so` **accessible en écriture au groupe ou à tous est ignoré** (journalisé puis écarté), même dans un répertoire par ailleurs verrouillé. + +En pratique : conservez le répertoire détenu par l'utilisateur happydomain, en mode `0755`, et les fichiers de plugins en mode `0644`. ```bash -cp happydomain-plugin-test-myplugin.so /usr/lib/happydomain/plugins/ +sudo install -d -m 0755 -o happydomain /var/lib/happydomain/plugins +sudo install -m 0644 -o happydomain checker-dummy.so /var/lib/happydomain/plugins/ ``` -### 2. Indiquer le répertoire à happyDomain - -`happydomain.conf` : - -``` -plugins-directories=/usr/lib/happydomain/plugins -``` - -Variable d'environnement : +### Construire le plugin ```bash -HAPPYDOMAIN_PLUGINS_DIRECTORIES=/usr/lib/happydomain/plugins +CGO_ENABLED=1 go build -buildmode=plugin -o checker-dummy.so ./plugin ``` -Plusieurs répertoires peuvent être listés en les séparant par des virgules. +### Indiquer le répertoire à happyDomain -### 3. Vérifier les journaux +Le répertoire se configure avec l'option **`--plugins-directory`**, qui **peut être répétée** pour analyser plusieurs répertoires : -En cas de chargement réussi : - -``` -Plugin My Plugin loaded (version 1.0) +```bash +happydomain --plugins-directory /var/lib/happydomain/plugins ``` -En cas de conflit de nom ou d'erreur de chargement, un avertissement est journalisé avec le nom du fichier et la raison. +La variable d'environnement équivalente est `HAPPYDOMAIN_PLUGINS_DIRECTORY`. + +Le chargeur analyse chaque répertoire configuré et tente de charger tous les fichiers `.so` qu'il y trouve. Un plugin qui échoue au chargement (mauvaise compilation, symboles absents, panique dans sa fabrique) est journalisé puis ignoré, sans interrompre le démarrage : un seul `.so` défectueux n'empêche jamais le chargement des autres. + +### Redémarrer et vérifier les journaux + +```bash +sudo systemctl restart happydomain +``` + +En cas de chargement réussi, happyDomain journalise : + +``` +Plugin com.example.dummy (/var/lib/happydomain/plugins/checker-dummy.so) loaded +``` --- -## Implémentations de référence +## Licence -Deux plugins sont fournis dans ce répertoire : +Les plugins checker n'importent que `git.happydns.org/checker-sdk-go/checker`, sous licence **Apache-2.0**. Le SDK a été délibérément détaché du cœur de happyDomain (sous AGPL-3.0) pour offrir une API publique réduite et stable aux checkers tiers. -- **`matrix/`** — interroge l'API de test de fédération Matrix. Illustre `ApplyToService` avec `LimitToServices` et `AdminOpts` pour l'URL du serveur tiers. -- **`zonemaster/`** — pilote l'API JSON-RPC de Zonemaster, attend la fin du test et agrège les résultats par niveau de sévérité. Illustre `AutoFillDomainName`, `UserOpts` pour la sélection de la langue et la gestion de statuts multi-niveaux. +Un plugin construit avec ce SDK n'est donc **pas** une œuvre dérivée de happyDomain. Vous pouvez distribuer votre `.so` sous la licence de votre choix (MIT, Apache, propriétaire ou AGPL, selon vos besoins). + +--- + +## Implémentation de référence + +[`checker-dummy`](https://git.happydns.org/checker-dummy) est le modèle complet et documenté dont s'inspire cette page. Partez-en pour écrire votre propre checker. diff --git a/content/reference/records/SOA.en.md b/content/reference/records/SOA.en.md index 45f1665..f3e5352 100644 --- a/content/reference/records/SOA.en.md +++ b/content/reference/records/SOA.en.md @@ -2,9 +2,36 @@ date: 2021-01-12T21:38:49+02:00 author: Frederic title: SOA (Start Of Authority) +description: "Understand the Start Of Authority record, the mandatory record at the apex of every DNS zone, and how happyDomain manages it for you." weight: 10 aliases: records/SOA --- -The Start of Authority-SOA is the first record of a zone. +The **Start Of Authority** (SOA) record is defined by [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035). It is mandatory and unique: exactly one SOA must sit at the apex (the root) of every DNS zone. Its presence declares that the name server is authoritative for the zone and carries the parameters that govern how the zone is replicated between servers and cached by resolvers. + +## Fields of the SOA record + +The SOA record gathers seven values: + +| Field | Description | +|---|---| +| **MNAME** (primary name server) | The hostname of the primary (master) name server for the zone. | +| **RNAME** (responsible party) | The email address of the person responsible for the zone, encoded in DNS form: the `@` is replaced by a dot (for example `hostmaster.example.com.` means `hostmaster@example.com`). | +| **Serial** | A version number for the zone. It must increase every time the zone changes, so that secondary servers know they need to transfer the new content. | +| **Refresh** | How often (in seconds) a secondary server checks the primary for an updated serial. | +| **Retry** | How long (in seconds) a secondary waits before retrying a failed refresh. | +| **Expire** | How long (in seconds) a secondary keeps serving the zone when it cannot reach the primary, before considering the data stale. | +| **Minimum** (negative-cache TTL) | The duration for which resolvers cache negative answers (NXDOMAIN), per [RFC 2308](https://www.rfc-editor.org/rfc/rfc2308). | + +## The SOA in happyDomain + +happyDomain does not present the SOA as a standalone record to edit field by field. Instead, the apex of your zone is modelled as an **Origin** service, which groups the SOA together with the zone's name servers (NS records). You will therefore find the SOA at the root of your domain, alongside the list of authoritative name servers, rather than in a separate form. + +The **serial** is, in most cases, handled automatically. When you publish your changes, many DNS providers manage the serial themselves: happyDomain detects this capability and re-reads the zone after publication to reflect the serial the provider actually assigned. You normally do not need (nor are you expected) to set it by hand. + +{{% notice style="info" title="What you can and cannot change" %}} +The exact behaviour depends on your DNS provider. Some providers expose the full SOA and let happyDomain submit its values; others manage the SOA serial — and sometimes the other timers — on their side. When the provider takes care of the serial, any value happyDomain shows for it simply reflects the published state and is refreshed automatically. +{{% /notice %}} + +For more on how the apex and other groupings are represented, see the {{< relref "../services" >}} chapter. diff --git a/content/reference/records/SOA.fr.md b/content/reference/records/SOA.fr.md index 3f573d8..090d534 100644 --- a/content/reference/records/SOA.fr.md +++ b/content/reference/records/SOA.fr.md @@ -1,9 +1,36 @@ --- date: 2020-12-15T01:01:08+01:00 title: SOA (Start Of Authority) +description: "Comprendre l'enregistrement Start Of Authority, présent obligatoirement à la racine de chaque zone DNS, et la façon dont happyDomain le gère pour vous." weight: 10 aliases: records/SOA --- -Le SOA est le premier enregistrement d'une zone. +L'enregistrement **Start Of Authority** (SOA) est défini par la [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035). Il est obligatoire et unique : un seul SOA figure à l'apex (la racine) de chaque zone DNS. Sa présence indique que le serveur de noms fait autorité sur la zone. Il porte également les paramètres qui régissent la réplication de la zone entre serveurs et sa mise en cache par les résolveurs. + +## Les champs de l'enregistrement SOA + +Le SOA réunit sept valeurs : + +| Champ | Description | +|---|---| +| **MNAME** (serveur primaire) | Le nom du serveur de noms primaire (maître) de la zone. | +| **RNAME** (responsable) | L'adresse de courriel du responsable de la zone, encodée à la manière du DNS : le `@` est remplacé par un point. Ainsi, `hostmaster.example.com.` désigne `hostmaster@example.com`. | +| **Serial** | Un numéro de version de la zone. Il augmente à chaque modification, afin que les serveurs secondaires sachent qu'ils doivent transférer le nouveau contenu. | +| **Refresh** | L'intervalle (en secondes) au bout duquel un serveur secondaire vérifie le numéro de série auprès du primaire. | +| **Retry** | Le délai (en secondes) que respecte un secondaire avant de retenter une vérification ayant échoué. | +| **Expire** | La durée (en secondes) pendant laquelle un secondaire continue de servir la zone lorsqu'il ne parvient pas à joindre le primaire, avant de considérer les données comme périmées. | +| **Minimum** (cache négatif) | La durée pendant laquelle les résolveurs conservent en cache les réponses négatives (NXDOMAIN), selon la [RFC 2308](https://www.rfc-editor.org/rfc/rfc2308). | + +## Le SOA dans happyDomain + +happyDomain ne présente pas le SOA comme un enregistrement à éditer champ par champ. La racine de votre zone est plutôt modélisée par un service **Origin**, qui regroupe le SOA et les serveurs de noms de la zone (les enregistrements NS). On retrouve donc le SOA à la racine du domaine, aux côtés de la liste des serveurs faisant autorité, et non dans un formulaire distinct. + +Le **numéro de série** est, dans la plupart des cas, géré automatiquement. Lors de la publication de vos modifications, de nombreux hébergeurs DNS gèrent eux-mêmes ce numéro. happyDomain détecte cette capacité, puis relit la zone après publication afin de refléter le numéro de série réellement attribué par l'hébergeur. Vous n'avez normalement pas à le renseigner à la main. + +{{% notice style="info" title="Ce que l'on peut modifier, et ce que l'on ne peut pas" %}} +Le comportement exact dépend de votre hébergeur DNS. Certains exposent l'ensemble du SOA et laissent happyDomain en transmettre les valeurs ; d'autres gèrent eux-mêmes le numéro de série (et parfois les autres minuteries). Lorsque l'hébergeur prend en charge le numéro de série, la valeur affichée par happyDomain reflète simplement l'état publié et se met à jour automatiquement. +{{% /notice %}} + +Pour en savoir plus sur la représentation de l'apex et des autres regroupements, consultez le chapitre {{< relref "../services" >}}. diff --git a/content/reference/records/TXT.en.md b/content/reference/records/TXT.en.md index cefc6b6..03c040f 100644 --- a/content/reference/records/TXT.en.md +++ b/content/reference/records/TXT.en.md @@ -5,6 +5,40 @@ title: TXT weight: 20 aliases: records/TXT +description: "The TXT record attaches free-form text to a DNS name. Learn what it is used for and how happyDomain edits it through the Text Record service." --- -Please, help us to write this Documentation screen +A **TXT record** (defined in [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035)) attaches one or more free-form text strings to a name in your zone. It carries no predefined meaning of its own, which makes it one of the most versatile record types: any application is free to define its own convention for the text it stores there. + +## Common uses + +Because a TXT record can hold arbitrary text, it has become the carrier for many widespread conventions: + +- **Domain ownership and site verification** — a provider asks you to publish a token so it can confirm you control the domain. +- **SPF** — declares which servers are allowed to send e-mail for your domain. +- **DKIM** — publishes the public key used to sign your outgoing e-mail. +- **DMARC** — sets the policy applied when SPF or DKIM checks fail. +- Various other key or policy publications defined by different tools. + +For most of these purposes, happyDomain offers dedicated, higher-level **services** (SPF, DKIM, DMARC, site verification, and more) that are easier and safer to use than a raw TXT record: they guide you with the right fields and validate the syntax for you. Browse them in the {{< relref "/reference/services" >}} chapter, in particular the e-mail-related services. Prefer those services whenever one matches your need. + +{{% notice style="info" title="When a TXT record becomes a service" %}} +When happyDomain reads your zone, it recognises TXT records that follow a known convention (SPF, DKIM, DMARC, …) and presents them as their dedicated service rather than as a plain Text Record. Only TXT records without a recognised prefix or syntax are shown as a raw **Text Record**. +{{% /notice %}} + +## Editing a TXT record in happyDomain + +In the zone editor, a plain TXT record appears as a **Text Record** service. It is intentionally minimal: a single field holds the text content of the record. + +To work with one: + +1. Open the subdomain where the record should live (the apex of the zone, or any subdomain such as `www`). +2. Add or open the **Text Record** service. +3. Type the full text string in its only field. +4. Adjust the **TTL** if needed, then publish your changes to apply them. + +The value you enter is stored verbatim. Editing it and publishing updates the corresponding TXT record on that subdomain. + +{{% notice style="note" title="Long strings" %}} +A single text string inside a TXT record cannot exceed 255 bytes at the DNS protocol level. Longer values are automatically split into 255-byte chunks for you. You simply enter the complete string in happyDomain — no manual splitting is required. +{{% /notice %}} diff --git a/content/reference/records/TXT.fr.md b/content/reference/records/TXT.fr.md index 2dbb67e..9094e9d 100644 --- a/content/reference/records/TXT.fr.md +++ b/content/reference/records/TXT.fr.md @@ -4,6 +4,40 @@ title: TXT weight: 20 aliases: records/TXT +description: "L'enregistrement TXT associe du texte libre à un nom DNS. Découvrez à quoi il sert et comment happyDomain l'édite grâce au service Enregistrement texte." --- -Documentation à faire +Un **enregistrement TXT** (défini par la [RFC 1035](https://www.rfc-editor.org/rfc/rfc1035)) associe une ou plusieurs chaînes de texte libre à un nom de votre zone. Il ne porte aucune signification propre. C'est ce qui en fait l'un des types d'enregistrement les plus polyvalents : chaque application est libre de définir sa propre convention pour le texte qu'elle y dépose. + +## Usages courants + +Comme un enregistrement TXT peut contenir n'importe quel texte, il est devenu le support de nombreuses conventions répandues : + +- **Vérification de propriété ou de site** : un fournisseur demande de publier un jeton afin de confirmer que l'on contrôle bien le domaine. +- **SPF** : déclare quels serveurs sont autorisés à envoyer du courrier pour le domaine. +- **DKIM** : publie la clé publique servant à signer le courrier sortant. +- **DMARC** : définit la politique à appliquer lorsqu'une vérification SPF ou DKIM échoue. +- Diverses autres publications de clés ou de politiques propres à différents outils. + +Pour la plupart de ces usages, happyDomain propose des **services** dédiés, de plus haut niveau (SPF, DKIM, DMARC, vérification de site, etc.). Ils sont plus simples et plus sûrs à utiliser qu'un enregistrement TXT brut : ils guident la saisie avec les bons champs et en valident la syntaxe. On les retrouve dans le chapitre {{< relref "/reference/services" >}}, notamment parmi les services liés au courrier électronique. Mieux vaut recourir à ces services dès que l'un d'eux correspond au besoin. + +{{% notice style="info" title="Quand un enregistrement TXT devient un service" %}} +Lorsque happyDomain lit votre zone, il reconnaît les enregistrements TXT qui suivent une convention connue (SPF, DKIM, DMARC, etc.) et les présente sous leur service dédié plutôt que comme un simple enregistrement texte. Seuls les enregistrements TXT sans préfixe ni syntaxe reconnus apparaissent comme un **Enregistrement texte** brut. +{{% /notice %}} + +## Éditer un enregistrement TXT dans happyDomain + +Dans l'éditeur de zone, un enregistrement TXT ordinaire apparaît sous la forme d'un service **Enregistrement texte**. Il est volontairement minimal : un unique champ contient le contenu textuel de l'enregistrement. + +Pour le manipuler : + +1. Ouvrez le sous-domaine où l'enregistrement doit se trouver (la racine de la zone, ou un sous-domaine comme `www`). +2. Ajoutez ou ouvrez le service **Enregistrement texte**. +3. Saisissez la chaîne de texte complète dans son unique champ. +4. Ajustez la **durée de vie** (TTL) si besoin, puis publiez vos modifications pour les appliquer. + +La valeur saisie est conservée telle quelle. La modifier puis publier met à jour l'enregistrement TXT correspondant sur ce sous-domaine. + +{{% notice style="note" title="Chaînes longues" %}} +Au niveau du protocole DNS, une chaîne de texte ne peut excéder 255 octets dans un enregistrement TXT. Les valeurs plus longues sont automatiquement découpées en fragments de 255 octets. Il suffit de saisir la chaîne complète dans happyDomain : aucun découpage manuel n'est nécessaire. +{{% /notice %}} diff --git a/content/reference/services/email.en.md b/content/reference/services/email.en.md index 67ab4d8..32be324 100644 --- a/content/reference/services/email.en.md +++ b/content/reference/services/email.en.md @@ -2,8 +2,57 @@ date: 2021-01-12T21:38:49+02:00 author: Frederic title: E-Mail +description: "Declare the mail servers of a zone (MX records) and the related anti-spoofing services (SPF, DKIM, DMARC) that govern how mail is sent and received." aliases: services/email --- -The E-Mail service allows you to define an e-mail server on the zone, as well as the zone settings for sending/receiving e-mails. +The **E-Mail** service lets you declare the mail servers responsible for a zone, and points you to the companion services that control how mail is sent and authenticated for that domain. + +In happyDomain, this service is named **E-Mail servers**: its single job is to publish the `MX` records that tell the rest of the Internet *where* to deliver mail addressed to your domain. Everything that protects *outgoing* mail (proving that a message really comes from you) is handled by separate, dedicated services described further down. + +## Receiving mail: MX records + +An `MX` (Mail eXchanger) record names a host that accepts mail for the domain. A zone usually publishes several of them so that delivery keeps working if one server is unavailable. + +Each entry has two parts: + +- **Priority** — a number that orders the servers. Sending servers try the **lowest** number first; higher numbers are used only as fallbacks. Two records sharing the same priority are treated as equivalent and load-balanced. +- **Mail server** — the hostname of the machine that receives the mail (for example `mx1.example.com.`). This host must itself resolve to an address; it should not be a bare IP. + +A common setup looks like this: + +| Priority | Mail server | +|---|---| +| 10 | `mx1.example.com.` | +| 20 | `mx2.example.com.` | + +Here `mx1` is tried first, and `mx2` is the backup. + +{{% notice style="info" title="One E-Mail service per subdomain" %}} +The E-Mail servers service is *single*: a given subdomain can hold only one such service, which gathers all of its `MX` records together. To declare mail servers for both the apex (`example.com`) and a subdomain (`mail.example.com`), add the service to each of them separately. +{{% /notice %}} + +## Sending mail: authentication and anti-spoofing + +Publishing `MX` records is enough to *receive* mail, but it says nothing about which servers are allowed to *send* mail on your behalf. Without that, anyone can forge messages using your domain. happyDomain offers several dedicated services, each managing its own DNS records, to establish that posture: + +- **SPF** (*Sender Policy Framework*) — a `TXT` record, usually at the zone apex, that lists the servers authorized to send mail for the domain. Receivers compare the sending server against this list. +- **DKIM** (*DomainKeys Identified Mail*) — publishes the public half of a signing key as a `TXT` record under a `._domainkey` selector. Your mail servers sign outgoing messages, and receivers verify the signature against this published key. +- **DMARC** (*Domain-based Message Authentication, Reporting and Conformance*) — a `TXT` record at `_dmarc` that tells receivers what to do with messages failing SPF or DKIM checks (let them through, quarantine, or reject), and where to send aggregate reports. + +Two further services cover transport security and reporting: + +- **MTA-STS** — declares that mail to your domain must be delivered over a secured (TLS) connection. +- **TLS-RPT** — collects reports about TLS delivery problems encountered by sending servers. + +These services are independent of the E-Mail servers service. You can add only the ones you need, but a complete and well-protected mail configuration typically combines `MX`, SPF, DKIM and DMARC. + +## In the zone editor + +To configure mail for a subdomain in the happyDomain zone editor: + +1. Add the **E-Mail servers** service to the subdomain and fill in one line per mail server, with its priority and hostname. +2. Add **SPF**, **DKIM** and **DMARC** as their own services on the relevant subdomain (SPF and DMARC usually at the apex). Each one presents a dedicated form rather than raw record text. + +Because each of these is a distinct abstract service, you manage them separately even though they all work together to make mail for your domain both deliverable and trustworthy. See the {{< relref "/reference/services" >}} chapter for the full list of available services. diff --git a/content/reference/services/email.fr.md b/content/reference/services/email.fr.md index 6cd3b18..d133e80 100644 --- a/content/reference/services/email.fr.md +++ b/content/reference/services/email.fr.md @@ -1,8 +1,57 @@ --- date: 2020-12-15T01:01:08+01:00 title: E-Mail +description: "Déclarez les serveurs de courrier d'une zone (enregistrements MX) ainsi que les services complémentaires (SPF, DKIM, DMARC) qui encadrent l'envoi et la réception des courriels." aliases: services/email --- -Le service E-Mail permet de définir un serveur de courrier électronique sur la zone, ainsi que le paramétrage de la zone en vue d'envoyer/recevoir des courriels. +Le service **E-Mail** permet de déclarer les serveurs de courrier responsables d'une zone. Il oriente également vers les services associés, qui régissent la manière dont le courrier est envoyé et authentifié pour le domaine. + +Dans happyDomain, ce service porte le nom de **E-Mail servers**. Son unique rôle consiste à publier les enregistrements `MX`, ceux qui indiquent au reste d'Internet *où* livrer les courriels adressés à votre domaine. Tout ce qui protège le courrier *sortant*, c'est-à-dire prouver qu'un message provient réellement de vous, relève de services dédiés et distincts, décrits plus bas. + +## Recevoir du courrier : les enregistrements MX + +Un enregistrement `MX` (*Mail eXchanger*) désigne une machine qui accepte le courrier du domaine. Une zone en publie généralement plusieurs, afin que la livraison continue de fonctionner si l'un des serveurs devient indisponible. + +Chaque entrée comporte deux parties : + +- **La priorité** : un nombre qui ordonne les serveurs. Les serveurs émetteurs essaient d'abord le nombre le **plus bas** ; les valeurs plus élevées ne servent que de secours. Deux enregistrements partageant la même priorité sont considérés comme équivalents et se répartissent la charge. +- **Le serveur de courrier** : le nom d'hôte de la machine qui reçoit le courrier (par exemple `mx1.example.com.`). Cet hôte doit lui-même se résoudre vers une adresse ; il ne s'agit pas d'indiquer directement une adresse IP. + +Une configuration courante ressemble à ceci : + +| Priorité | Serveur de courrier | +|---|---| +| 10 | `mx1.example.com.` | +| 20 | `mx2.example.com.` | + +Ici, `mx1` est contacté en premier et `mx2` sert de secours. + +{{% notice style="info" title="Un seul service E-Mail par sous-domaine" %}} +Le service E-Mail servers est *unique* : un sous-domaine donné ne peut héberger qu'un seul service de ce type, qui rassemble l'ensemble de ses enregistrements `MX`. Pour déclarer des serveurs de courrier à la fois sur l'apex (`example.com`) et sur un sous-domaine (`mail.example.com`), on ajoute le service à chacun d'eux séparément. +{{% /notice %}} + +## Envoyer du courrier : authentification et lutte contre l'usurpation + +Publier des enregistrements `MX` suffit pour *recevoir* du courrier, mais ne dit rien sur les serveurs autorisés à en *envoyer* en votre nom. Sans cette indication, n'importe qui peut forger des messages au nom de votre domaine. happyDomain propose plusieurs services dédiés, chacun gérant ses propres enregistrements DNS, pour établir cette protection : + +- **SPF** (*Sender Policy Framework*) : un enregistrement `TXT`, placé en général à l'apex de la zone, qui énumère les serveurs autorisés à envoyer du courrier pour le domaine. Les destinataires comparent le serveur émetteur à cette liste. +- **DKIM** (*DomainKeys Identified Mail*) : publie la partie publique d'une clé de signature dans un enregistrement `TXT`, sous un sélecteur `._domainkey`. Vos serveurs signent les messages sortants, et les destinataires vérifient la signature à l'aide de cette clé publiée. +- **DMARC** (*Domain-based Message Authentication, Reporting and Conformance*) : un enregistrement `TXT` placé sur `_dmarc`, qui indique aux destinataires comment traiter les messages échouant aux contrôles SPF ou DKIM (les laisser passer, les mettre en quarantaine ou les rejeter), et où envoyer les rapports agrégés. + +Deux autres services couvrent la sécurité du transport et la remontée d'informations : + +- **MTA-STS** : déclare que le courrier destiné à votre domaine doit être livré au travers d'une connexion sécurisée (TLS). +- **TLS-RPT** : recueille les rapports relatifs aux problèmes de livraison TLS rencontrés par les serveurs émetteurs. + +Ces services sont indépendants du service E-Mail servers. On peut n'ajouter que ceux dont on a besoin, mais une configuration de courrier complète et bien protégée associe le plus souvent `MX`, SPF, DKIM et DMARC. + +## Dans l'éditeur de zone + +Pour configurer le courrier d'un sous-domaine dans l'éditeur de zone de happyDomain : + +1. On ajoute le service **E-Mail servers** au sous-domaine, puis on renseigne une ligne par serveur de courrier, avec sa priorité et son nom d'hôte. +2. On ajoute **SPF**, **DKIM** et **DMARC** en tant que services à part entière sur le sous-domaine concerné (SPF et DMARC se placent généralement à l'apex). Chacun présente un formulaire dédié plutôt que le contenu brut de l'enregistrement. + +Comme chacune de ces abstractions constitue un service distinct, on les gère séparément, même si elles concourent toutes à rendre le courrier de votre domaine à la fois livrable et digne de confiance. Le chapitre {{< relref "/reference/services" >}} présente la liste complète des services disponibles.