diff --git a/AGENTS.md b/AGENTS.md index 869c913..9ca8ed5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -333,7 +333,6 @@ Les concepts comme socle Debian ou durcissement commun doivent être représent ```text serveur_debian -> socle commun Debian serveur_durci -> durcissement commun -client_dns -> intégration cliente DNS client_pki -> intégration cliente PKI / ACME ``` @@ -377,14 +376,11 @@ serveur_debian Les groupes spécialisés doivent s'ajouter selon les besoins réels, par exemple : ```text -client_dns client_pki -client_ldap -client_supervision client_metrique -serveur_web_frontal serveur_postgresql serveur_prometheus +serveur_keycloak ``` Ne pas cibler `all` par défaut pour un playbook qui ne s'applique pas réellement à tous les hôtes. diff --git a/README.md b/README.md index e8b6b49..d258ff7 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Chaque groupe opérationnel doit avoir son playbook homonyme dans `playbooks/gro La conformité normale des VM passe par ces playbooks de groupes. Les rôles de socle et de durcissement sont appliqués par `serveur_debian` et `serveur_durci`, pas par des playbooks de couches séparés. -Les groupes opérationnels avec des hôtes, comme `serveur_web_frontal` ou `client_dns`, sont validés contre `playbooks/groupes/` par les commandes d'inventaire. +Les groupes opérationnels avec des hôtes, comme `serveur_keycloak` ou `client_pki`, sont validés contre `playbooks/groupes/` par les commandes d'inventaire. Le catalogue des services et intégrations prévus est dans `docs/catalogue-services.md`. diff --git a/docs/catalogue-services.md b/docs/catalogue-services.md index 0acc7c6..285be55 100644 --- a/docs/catalogue-services.md +++ b/docs/catalogue-services.md @@ -24,9 +24,9 @@ Un service central peut partager un hôte avec d'autres services de la même fon > de la colonne « Rôle » des tables. **Implémentés** (`tasks` + `templates` + `handlers`, validés) : `serveur_step_ca`, -`client_pki`, `serveur_powerdns`, `client_dns`, `serveur_openldap`, `client_ldap`, +`client_pki`, `serveur_powerdns`, `serveur_openldap`, `serveur_keycloak`, `serveur_postgresql`, `serveur_redis`, `serveur_nginx`, -`serveur_sendmail`, `client_smtp`, `serveur_prometheus`, `client_metrique`, `serveur_loki`, +`client_smtp`, `serveur_prometheus`, `client_metrique`, `serveur_loki`, `client_journal`, `serveur_grafana`, `serveur_icinga`, `serveur_forgejo`. Plus le socle et le durcissement, appliqués par `serveur_debian` / `serveur_durci`. @@ -48,7 +48,11 @@ icinga2 + icingadb + redis dédié, base PostgreSQL via registre — supervise, via `serveur_oauth2_proxy` — `testmail` se connecte par le SSO, voit la supervision, et un processus métier BPM rend un état). **Pile Icinga complète : moteur + Web 2 + BPM, au SSO.** Plus la passerelle **`serveur_oauth2_proxy`** (oauth2-proxy) : SSO OIDC générique réutilisable pour toute app sans OIDC -natif. Restent « code non éprouvé » : `serveur_sendmail`. +natif. Plus les **agents de flotte** `client_metrique` / `client_journal` / `client_smtp` (éprouvés +sur 4 nœuds : Prometheus scrape la flotte, Loki collecte les logs, relais courrier système). **Tous +les rôles vivants sont éprouvés.** *Rôles retirés (2026-07-04, supersédés/hors-conception)* : +`serveur_sendmail` (→ Postfix), `client_dns` (→ plancher + `client_unbound`), `client_ldap` (login +LDAP OS, hors design). > **Lacunes connues sur Keycloak** (déployé mais pas complet) : la **fédération LDAP** (Keycloak > → OpenLDAP, modèle d'identité A) n'est **pas encore automatisée** dans le rôle ; l'**edge nginx** @@ -77,7 +81,6 @@ en rôles `serveur_*` normaux avec leur playbook de groupe. | Prometheus | `serveur_prometheus` | `playbooks/groupes/serveur_prometheus.yml` | `prometheus` | | Grafana | `serveur_grafana` | `playbooks/groupes/serveur_grafana.yml` | `grafana` | | Forgejo | `serveur_forgejo` | `playbooks/groupes/serveur_forgejo.yml` | `forgejo` | -| Sendmail MTA | `serveur_sendmail` | `playbooks/groupes/serveur_sendmail.yml` | `sendmail` | | step-ca | `serveur_step_ca` | `playbooks/groupes/serveur_step_ca.yml` | `step_ca` | | PowerDNS | `serveur_powerdns` | `playbooks/groupes/serveur_powerdns.yml` | `serveur_powerdns` | | Redis | `serveur_redis` | `playbooks/groupes/serveur_redis.yml` | `redis` | @@ -123,9 +126,7 @@ Dépendance d'intégration prévue : `serveur_web_frontal` devra publier via `se | Intégration | Groupe | Playbook | Rôle | | --- | --- | --- | --- | -| Résolution DNS interne | `client_dns` | `playbooks/groupes/client_dns.yml` | `client_dns` | | Confiance PKI / ACME | `client_pki` | `playbooks/groupes/client_pki.yml` | `client_pki` | -| Authentification LDAP | `client_ldap` | `playbooks/groupes/client_ldap.yml` | `client_ldap` | | Supervision Icinga | `client_supervision` | `playbooks/groupes/client_supervision.yml` | `client_supervision` | | Métriques Prometheus | `client_metrique` | `playbooks/groupes/client_metrique.yml` | `client_metriques` | | Journaux vers Loki | `client_journal` | `playbooks/groupes/client_journal.yml` | `client_journaux` | @@ -139,7 +140,6 @@ L'ordre ci-dessous privilégie les dépendances structurantes avant les applicat 1. `serveur_powerdns` - Service central : DNS interne autoritaire et/ou résolution interne selon le design retenu. - - Intégration à prévoir : `client_dns`. - Raison : les autres intégrations auront besoin de noms stables plutôt que d'adresses IP. 2. `serveur_step_ca` @@ -152,8 +152,8 @@ L'ordre ci-dessous privilégie les dépendances structurantes avant les applicat - Intégration à prévoir : publication des services HTTP derrière le proxy. - Raison : plusieurs services seront consommés par navigateur ou API et doivent passer par un point d'entrée cohérent. -4. `serveur_sendmail` - - Service central : relais SMTP sortant. +4. `serveur_postfix` + - Service central : MTA (courriel entrant + sortant interne) + relais SMTP. - Intégration à prévoir : `client_smtp`. - Raison : les notifications, réinitialisations de mot de passe et alertes doivent fonctionner tôt. @@ -165,9 +165,9 @@ L'ordre ci-dessous privilégie les dépendances structurantes avant les applicat - Raison : Keycloak, Grafana, Icinga Web 2, Forgejo et Nextcloud peuvent dépendre de PostgreSQL. 6. `serveur_openldap` - - Service central : annuaire interne. - - Intégration à prévoir : `client_ldap`. - - Raison : l'identité Unix et l'annuaire doivent exister avant les intégrations d'authentification avancées. + - Service central : annuaire interne (source de vérité des identités). + - Consommateurs : Keycloak (fédération/SSO), courriel (Postfix/Dovecot), apps. + - Raison : l'annuaire doit exister avant l'identité fédérée et le courriel. 7. `serveur_keycloak` - Service central : SSO/OIDC/SAML. diff --git a/docs/courriel-conception.md b/docs/courriel-conception.md index 16d8b05..fb87d85 100644 --- a/docs/courriel-conception.md +++ b/docs/courriel-conception.md @@ -15,9 +15,10 @@ | PKI | **Deux CA distinctes** (voir §6) : Let's Encrypt pour les faces publiques, **step_ca** pour l'interne. | | Démarche | **Deux étapes** (voir §11) : **(A) fonctionnement INTERNE** d'abord (step_ca, LDAP, SMTP/IMAP internes, zéro dépendance publique) ; **(B) fonctionnement EXTERNE** ensuite (Namespro, Let's Encrypt, reprise du MX `.53`). | -Le rôle existant `serveur_sendmail` (relais sortant Postfix, sans boîtes) **reste** pour le -courrier de notification système (via `client_smtp`/msmtp). Il ne fait pas partie de ce -service et ne le remplace pas. +Le courrier de **notification système** des nœuds (cron, alertes) est relayé vers le MTA +`serveur_postfix` (edge-mta) via `client_smtp`/msmtp. C'est distinct de ce service de boîtes +et ne le remplace pas. *(Note : l'ancien rôle `serveur_sendmail` a été retiré — supersédé par +Postfix.)* > **Historique — pivot depuis Stalwart (2026-07-02).** On avait d'abord choisi Stalwart > (binaire unique, moderne). Le prototypage a révélé un projet **jeune et volatil** : @@ -170,8 +171,9 @@ _dmarc TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@chezlepro. la soumission Postfix), backend **LDAP**, TLS step_ca. - `serveur_rspamd` — anti-spam, **signature DKIM**, greylisting ; branché à Postfix par milter. - `serveur_postfix` en **mode relais** (paramètre) pour le MX de secours. -- **Intégrations** des nœuds mail : `client_ldap` (auth/annuaire), `client_pki` (certs - internes), `client_dns`. +- **Intégrations** des nœuds mail : `client_pki` (certs internes), `client_backup`, + `client_metrique` / `client_journal` (observabilité). L'annuaire est résolu par + `resoudre_annuaire` (côté rôle), pas une intégration OS. - **Secrets (voûte)** : bind LDAP, **clé privée DKIM**, éventuel secret ACME (Étape B) — via `vault_*`, câblés aux rôles. diff --git a/docs/dependances-groupes.yml b/docs/dependances-groupes.yml index 957f8ba..753ea9f 100644 --- a/docs/dependances-groupes.yml +++ b/docs/dependances-groupes.yml @@ -1,30 +1,11 @@ --- groupes: - client_dns: - requiert_groupes_actifs: [] - raison: "Dependance molle : la resolution interne repose d'abord sur le plancher - /etc/hosts (role hosts_statiques du socle). client_dns ne configure un resolver - que si un DNS interne existe ; sinon il est inerte. Aucun prerequis bloquant." - surveillance: "Verifier /etc/hosts a jour ; DNS interne optionnel (externe/dynamique)." - client_pki: requiert_groupes_actifs: - serveur_step_ca raison: "La confiance CA et ACME client dependent de l'autorite interne." surveillance: "Verifier validite CA, emission ACME et expiration des certificats." - client_ldap: - requiert_groupes_actifs: - - serveur_openldap - raison: "La configuration NSS/PAM/SSSD depend de l'annuaire LDAP." - surveillance: "Verifier bind LDAP, latence et expiration des certificats LDAP." - - client_supervision: - requiert_groupes_actifs: - - serveur_icinga - raison: "Les agents ou checks clients doivent se rattacher a une plateforme Icinga active." - surveillance: "Verifier enregistrement des hotes, fraicheur des checks et notifications." - client_metrique: requiert_groupes_actifs: - serveur_prometheus @@ -39,8 +20,8 @@ groupes: client_smtp: requiert_groupes_actifs: - - serveur_sendmail - raison: "Les notifications locales doivent relayer vers un MTA actif." + - serveur_postfix + raison: "Les notifications locales doivent relayer vers un MTA actif (Postfix)." surveillance: "Verifier file d'attente, relais SMTP et echecs de livraison." serveur_keycloak: @@ -70,18 +51,3 @@ groupes: raison: "Forgejo depend d'une base, d'une publication HTTP(S) et d'un relais courriel (MTA Postfix)." surveillance: "Verifier HTTP(S), base, files Git et envoi courriel." - serveur_nextcloud: - requiert_groupes_actifs: - - serveur_postgresql - - serveur_redis - - serveur_nginx - - serveur_sendmail - raison: "Nextcloud depend d'une base, d'un cache, d'un frontal web et du courriel." - surveillance: "Verifier jobs, base, Redis, HTTP(S), stockage et courriel." - - serveur_collabora: - requiert_groupes_actifs: - - serveur_nextcloud - - serveur_nginx - raison: "Collabora est expose via le frontal web et integre a Nextcloud." - surveillance: "Verifier connectivite Nextcloud, websocket et disponibilite HTTP(S)." diff --git a/docs/dimensionnement-ressources.md b/docs/dimensionnement-ressources.md index a3c7e42..8485b58 100644 --- a/docs/dimensionnement-ressources.md +++ b/docs/dimensionnement-ressources.md @@ -69,7 +69,6 @@ la somme. Le socle (`serveur_debian`/`serveur_durci`) et les groupes d'état son | --- | --- | --- | --- | | serveur_step_ca | 1 | 256 | 2 | | serveur_powerdns | 1 | 512 | 2 | -| serveur_sendmail | 1 | 512 | 5 | | serveur_nginx | 1 | 512 | 3 | | serveur_openldap | 1 | 512 | 3 | | serveur_keycloak | 2 | 1536 | 5 | diff --git a/docs/dns-interne.md b/docs/dns-interne.md index 845bd36..4a8902e 100644 --- a/docs/dns-interne.md +++ b/docs/dns-interne.md @@ -6,17 +6,17 @@ Le service DNS interne est la premiere capacite de plateforme. > `serveur_debian`) genere `/etc/hosts` sur **chaque** VM depuis l'inventaire : tout > l'ecosysteme se resout par nom **meme serveur DNS eteint** (et au bootstrap, avant > que PowerDNS ne soit la). PowerDNS devient une **commodite** (zone, externe, -> dynamique), plus un point de defaillance : la dependance `client_dns -> powerdns` -> est **molle** (client_dns est inerte si aucun DNS interne n'existe). +> dynamique), plus un point de defaillance. Le resolveur local `client_unbound` est +> **optionnel** (opt-in, avec bascule validee) : sans lui, le plancher `/etc/hosts` suffit. ## Groupes ```text serveur_powerdns -> service DNS central PowerDNS Authoritative -client_dns -> integration cliente DNS +client_unbound -> resolveur local optionnel (opt-in, bascule validee) ``` -`client_dns` depend de `serveur_powerdns` dans `docs/dependances-groupes.yml`. +`client_unbound` (résolveur local optionnel) peut viser PowerDNS en stub-zone + récursion. ## Zone initiale @@ -65,22 +65,20 @@ Raison : Quand `serveur_postgresql` sera stable, il sera possible de migrer vers un backend SQL si le besoin operationnel le justifie. -## Clients DNS +## Résolveur local (optionnel) -Le role `client_dns` valide : +Le role `client_unbound` (opt-in) installe un résolveur récursif local qui, en stub-zone, +délègue les noms internes à PowerDNS et récurse le reste. -- qu'un serveur `serveur_powerdns` actif existe ; -- que la zone repond a une requete SOA ; -- que le nom de l'hote existe dans la zone. - -La modification du resolver local est protegee : +La bascule du resolver local est **protegee** (le role valide qu'Unbound répond AVANT de +basculer `/etc/resolv.conf`) : ```yaml -client_dns_apply: true -client_dns_confirm: true +client_unbound_apply: true +client_unbound_confirm: true ``` -Sans ces deux variables, le role valide les prerequis mais ne modifie pas `/etc/resolv.conf`. +Sans ces deux variables, le role prépare Unbound mais ne modifie pas `/etc/resolv.conf`. Cette protection est volontaire : une mauvaise configuration DNS peut couper la resolution de noms. diff --git a/docs/intrants-communs.md b/docs/intrants-communs.md index daa4fe5..1fcacf9 100644 --- a/docs/intrants-communs.md +++ b/docs/intrants-communs.md @@ -36,10 +36,10 @@ nftables baseline · fail2ban SSH · auditd · AppArmor · sysctl · unattended- journald (rétention) · core_dumps · systemd_ssh_auto. ### F. Endpoints des services centraux (les rôles `client_*` en dérivent) -- DNS interne (`client_dns_nameservers`, zone = `domaine_interne`). +- DNS interne : plancher `/etc/hosts` (`hosts_statiques`) + PowerDNS + `client_unbound` (opt-in). - AC/PKI (`client_pki_ca_url` → infra-pki, provisioner). -- IdM/LDAP (`client_ldap_uri` → idm, base DN dérivé). -- Relais courriel (`client_smtp_relais` → infra-mail, port 25). +- IdM/LDAP : annuaire résolu par `resoudre_annuaire` (hôte + base DN dérivés du domaine). +- Relais courriel (`client_smtp_relais` → edge-mta, MTA Postfix, port 25). - Métriques (node_exporter `:9100`). - Journaux (`client_journal_loki_url` → obs). - Temps (NTP) : **implicite** (pool Debian par défaut — aucun intrant configuré). @@ -78,7 +78,7 @@ domaines publics, `edge`, autorité DNS, FQDN exposés. | Secrets Vault | **Constante** 🔒 | — (gérés à part, jamais en clair) | | `chezlepro_timezone` | Défaut | par hôte (rare) | | `proxmox_clone_noeud` / `stockage` / `pont` | Défaut | par hôte (`serveurs.yml`) | -| DNS internes (`client_dns_nameservers`) | Défaut | par hôte / groupe | +| DNS internes (plancher `/etc/hosts` + PowerDNS + `client_unbound`) | Défaut | par hôte / groupe | | Politiques durcissement (SSH, nftables, fail2ban, journald…) | Défaut | par hôte / groupe | | Relais SMTP, TLS internes | Défaut | par hôte / groupe | | `ciuser`, compte `ansible` | Défaut | rarement surchargé | diff --git a/docs/nomenclature-vm.md b/docs/nomenclature-vm.md index 267989a..8e71946 100644 --- a/docs/nomenclature-vm.md +++ b/docs/nomenclature-vm.md @@ -45,7 +45,7 @@ Les anciens noms de test `web-01` et `web-02` sont retirés. Ils ne doivent pas | --- | --- | | `infra-pki-01` | `serveur_step_ca` | | `infra-edge-01` | `serveur_nginx` | -| `infra-mail-01` | `serveur_sendmail` | +| `infra-mail-01` | `serveur_dovecot` (mail-store) | | `infra-dns-01` | `serveur_powerdns` | | `idm-01` | `serveur_openldap`, `serveur_keycloak` | | `data-01` | `serveur_postgresql`, `serveur_redis` | diff --git a/docs/pouvoirs-set-ops.md b/docs/pouvoirs-set-ops.md index 6ab881d..b6ca031 100644 --- a/docs/pouvoirs-set-ops.md +++ b/docs/pouvoirs-set-ops.md @@ -92,7 +92,7 @@ prouvés. - **Forge logicielle** : `serveur_forgejo`. - **Observabilité** : `serveur_prometheus`, `serveur_grafana`, `serveur_loki`, `serveur_icinga`, avec les clients `client_metrique`, `client_journal`, `client_supervision`. -- **Intégrations transverses** : `client_ldap`, `client_dns`, `client_smtp`. +- **Intégrations transverses** : `client_pki`, `client_backup`, `client_smtp`, `client_metrique`, `client_journal`, `client_unbound`. - **Méta-rôles d'agrégation** : `identity`, `applications`, `database`, `web`, `monitoring`, `backup`, `storage`. diff --git a/exemples/modeles/forge/plan/applications.yml b/exemples/modeles/forge/plan/applications.yml index 9484e0b..db16b35 100644 --- a/exemples/modeles/forge/plan/applications.yml +++ b/exemples/modeles/forge/plan/applications.yml @@ -7,7 +7,7 @@ applications: groupe: serveur_nginx hote: infra-edge-01 sendmail: - groupe: serveur_sendmail + groupe: serveur_postfix hote: infra-mail-01 powerdns: groupe: serveur_powerdns diff --git a/exemples/modeles/identite/plan/applications.yml b/exemples/modeles/identite/plan/applications.yml index ac404e3..804cbf9 100644 --- a/exemples/modeles/identite/plan/applications.yml +++ b/exemples/modeles/identite/plan/applications.yml @@ -7,7 +7,7 @@ applications: groupe: serveur_nginx hote: infra-edge-01 sendmail: - groupe: serveur_sendmail + groupe: serveur_postfix hote: infra-mail-01 powerdns: groupe: serveur_powerdns diff --git a/exemples/modeles/integral/plan/applications.yml b/exemples/modeles/integral/plan/applications.yml index ce6256e..66105a9 100644 --- a/exemples/modeles/integral/plan/applications.yml +++ b/exemples/modeles/integral/plan/applications.yml @@ -7,7 +7,7 @@ applications: groupe: serveur_nginx hote: infra-edge-01 sendmail: - groupe: serveur_sendmail + groupe: serveur_postfix hote: infra-mail-01 powerdns: groupe: serveur_powerdns diff --git a/exemples/modeles/observabilite/plan/applications.yml b/exemples/modeles/observabilite/plan/applications.yml index 398a4f7..dfe3625 100644 --- a/exemples/modeles/observabilite/plan/applications.yml +++ b/exemples/modeles/observabilite/plan/applications.yml @@ -7,7 +7,7 @@ applications: groupe: serveur_nginx hote: infra-edge-01 sendmail: - groupe: serveur_sendmail + groupe: serveur_postfix hote: infra-mail-01 powerdns: groupe: serveur_powerdns diff --git a/exemples/modeles/presence-web/plan/applications.yml b/exemples/modeles/presence-web/plan/applications.yml index 1bd333a..5486354 100644 --- a/exemples/modeles/presence-web/plan/applications.yml +++ b/exemples/modeles/presence-web/plan/applications.yml @@ -2,7 +2,7 @@ applications: pki: { groupe: serveur_step_ca, hote: infra-pki-01 } edge: { groupe: serveur_nginx, hote: infra-edge-01 } - mail: { groupe: serveur_sendmail, hote: infra-mail-01 } + mail: { groupe: serveur_postfix, hote: infra-mail-01 } dns: { groupe: serveur_powerdns, hote: infra-dns-01 } bdd: { groupe: serveur_postgresql, hote: data-01, port: 5432 } cache: { groupe: serveur_redis, hote: data-01 } diff --git a/exemples/modeles/socle/plan/applications.yml b/exemples/modeles/socle/plan/applications.yml index c78c0b2..e5a86e2 100644 --- a/exemples/modeles/socle/plan/applications.yml +++ b/exemples/modeles/socle/plan/applications.yml @@ -7,7 +7,7 @@ applications: groupe: serveur_nginx hote: infra-edge-01 sendmail: - groupe: serveur_sendmail + groupe: serveur_postfix hote: infra-mail-01 powerdns: groupe: serveur_powerdns diff --git a/playbooks/groupes/client_dns.yml b/playbooks/groupes/client_dns.yml deleted file mode 100644 index af888f0..0000000 --- a/playbooks/groupes/client_dns.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Appliquer le groupe client_dns - hosts: client_dns - become: true - gather_facts: true - - pre_tasks: - - name: Vérifier que la cible est Debian - ansible.builtin.assert: - that: - - ansible_facts.distribution == "Debian" - fail_msg: "Ce playbook est prévu pour Debian." - - roles: - - client_dns diff --git a/playbooks/groupes/client_ldap.yml b/playbooks/groupes/client_ldap.yml deleted file mode 100644 index db053a0..0000000 --- a/playbooks/groupes/client_ldap.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Appliquer le groupe client_ldap - hosts: client_ldap - become: true - gather_facts: true - - pre_tasks: - - name: Vérifier que la cible est Debian - ansible.builtin.assert: - that: - - ansible_facts.distribution == "Debian" - fail_msg: "Ce playbook est prévu pour Debian." - - roles: - - client_ldap diff --git a/playbooks/groupes/serveur_sendmail.yml b/playbooks/groupes/serveur_sendmail.yml deleted file mode 100644 index 4b2248c..0000000 --- a/playbooks/groupes/serveur_sendmail.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- -- name: Appliquer le groupe serveur_sendmail - hosts: serveur_sendmail - become: true - gather_facts: true - - pre_tasks: - - name: Vérifier que la cible est Debian - ansible.builtin.assert: - that: - - ansible_facts.distribution == "Debian" - fail_msg: "Ce playbook est prévu pour Debian." - - roles: - - serveur_sendmail diff --git a/roles/client_dns/README.md b/roles/client_dns/README.md deleted file mode 100644 index a471120..0000000 --- a/roles/client_dns/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Role `client_dns` - -Valide et configure l'integration DNS cliente vers le service PowerDNS interne. - -Par defaut, le role valide les prerequis mais ne modifie pas le resolver local. -La modification DNS est volontairement protegee, car une mauvaise configuration -peut couper la resolution de noms. - -Pour appliquer la configuration resolver : - -```yaml -client_dns_apply: true -client_dns_confirm: true -``` - -Le serveur DNS requis vient du groupe `serveur_powerdns`. diff --git a/roles/client_dns/defaults/main.yml b/roles/client_dns/defaults/main.yml deleted file mode 100644 index eca4f10..0000000 --- a/roles/client_dns/defaults/main.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -client_dns_apply: false -client_dns_confirm: false -client_dns_zone: "{{ domaine_interne }}" -client_dns_search_domains: - - "{{ client_dns_zone }}" -client_dns_nameservers: [] -client_dns_resolv_conf_path: "/etc/resolv.conf" -client_dns_resolv_conf_header: "Gere par Ansible Set-OPS - client_dns" diff --git a/roles/client_dns/tasks/main.yml b/roles/client_dns/tasks/main.yml deleted file mode 100644 index dbf9547..0000000 --- a/roles/client_dns/tasks/main.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -- name: Déterminer les serveurs DNS internes depuis l'inventaire - ansible.builtin.set_fact: - client_dns_effective_nameservers: >- - {{ - client_dns_nameservers - if (client_dns_nameservers | length > 0) - else ( - groups.get('serveur_powerdns', []) - | map('extract', hostvars, 'ansible_host') - | select('defined') - | list - ) - }} - -- name: Sans DNS interne, s'appuyer sur le plancher /etc/hosts (résolution garantie) - ansible.builtin.debug: - msg: >- - Aucun serveur DNS interne déclaré : la résolution interne repose sur le - plancher /etc/hosts (rôle hosts_statiques). Configuration du resolver ignorée. - when: client_dns_effective_nameservers | length == 0 - -- name: Installer les outils de diagnostic DNS - ansible.builtin.apt: - name: dnsutils - state: present - update_cache: true - cache_valid_time: 3600 - -# Les tâches ci-dessous ne s'exécutent que si un DNS interne existe. -# Sinon /etc/hosts (socle) assure déjà la résolution interne : dépendance molle. -- name: Valider la zone DNS interne sur le serveur primaire - ansible.builtin.command: - cmd: "dig @{{ client_dns_effective_nameservers[0] }} {{ client_dns_zone }} SOA +short" - register: client_dns_soa_check - changed_when: false - failed_when: client_dns_soa_check.stdout | trim == "" - when: client_dns_effective_nameservers | length > 0 - -- name: Refuser la modification DNS sans confirmation explicite - ansible.builtin.assert: - that: - - client_dns_confirm | bool - fail_msg: "Modification DNS refusee: definir client_dns_confirm=true pour modifier le resolver." - when: - - client_dns_apply | bool - - client_dns_effective_nameservers | length > 0 - -- name: Configurer le resolver client - ansible.builtin.template: - src: resolv.conf.j2 - dest: "{{ client_dns_resolv_conf_path }}" - owner: root - group: root - mode: "0644" - backup: true - when: - - client_dns_apply | bool - - client_dns_confirm | bool - - client_dns_effective_nameservers | length > 0 - -- name: Valider la résolution du nom local dans la zone interne - ansible.builtin.command: - cmd: "dig @{{ client_dns_effective_nameservers[0] }} {{ inventory_hostname }}.{{ client_dns_zone }} A +short" - register: client_dns_host_check - changed_when: false - failed_when: client_dns_host_check.stdout | trim == "" - when: - - ansible_host is defined - - client_dns_effective_nameservers | length > 0 diff --git a/roles/client_dns/templates/resolv.conf.j2 b/roles/client_dns/templates/resolv.conf.j2 deleted file mode 100644 index e46ffa0..0000000 --- a/roles/client_dns/templates/resolv.conf.j2 +++ /dev/null @@ -1,8 +0,0 @@ -# {{ client_dns_resolv_conf_header }} -{% for nameserver in client_dns_effective_nameservers %} -nameserver {{ nameserver }} -{% endfor %} -{% if client_dns_search_domains | length > 0 %} -search {{ client_dns_search_domains | join(' ') }} -{% endif %} -options timeout:2 attempts:2 rotate diff --git a/roles/client_ldap/README.md b/roles/client_ldap/README.md deleted file mode 100644 index fa80509..0000000 --- a/roles/client_ldap/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# client_ldap - -Intégration cliente **identité utilisateur** : l'hôte authentifie les utilisateurs -via l'annuaire central `serveur_openldap`, grâce à **SSSD** (NSS + PAM). - -## Rôle -- Installe `sssd`, `sssd-ldap`, `libnss-sss`, `libpam-sss`. -- Déploie `/etc/sssd/sssd.conf` (`0600`) pointant vers OpenLDAP (`id_provider`/`auth_provider = ldap`). -- Active `sss` dans `/etc/nsswitch.conf` (passwd, group, shadow). -- Active la **création automatique du répertoire personnel** (`pam-auth-update --enable mkhomedir`). -- `libpam-sss` active automatiquement le module PAM `sss`. - -## Effet -Après ce rôle, les comptes de l'annuaire interne peuvent se connecter à l'hôte -(SSH, console) et leur home est créé à la première connexion. Couplé à `client_pki` -(identité machine), l'écosystème a une authentification **machines + utilisateurs** centralisée. - -## Variables principales -| Variable | Défaut | Rôle | -| --- | --- | --- | -| `client_ldap_uri` | `ldap://idm-01.exemple.internal` | URI de l'annuaire | -| `client_ldap_base_dn` | `dc=exemple,dc=internal` | Base de recherche | -| `client_ldap_bind_dn` | `""` (anonyme) | Compte de lecture (optionnel, mdp via Vault) | -| `client_ldap_tls_reqcert` | `never` | Validation TLS (→ `demand` avec LDAPS) | - -## Notes / limites -- **Bind anonyme** par défaut : suppose une lecture publique de l'annuaire. Pour un - bind dédié, définir `client_ldap_bind_dn` + `client_ldap_bind_password` (Vault) et - créer le compte de service dans l'annuaire. -- **LDAP en clair** sur le réseau interne pour l'instant ; basculer en **LDAPS** quand - OpenLDAP exposera un certificat (step_ca), avec `client_ldap_tls_reqcert: demand`. -- Les entrées utilisateurs/groupes (POSIX) doivent exister dans l'annuaire (gestion d'identité). - -## Prérequis -- Dépendance `client_ldap requiert serveur_openldap actif` (déjà dans `docs/dependances-groupes.yml`). diff --git a/roles/client_ldap/defaults/main.yml b/roles/client_ldap/defaults/main.yml deleted file mode 100644 index 9d06eb9..0000000 --- a/roles/client_ldap/defaults/main.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -client_ldap_paquets: - - sssd - - sssd-ldap - - libnss-sss - - libpam-sss - - ldap-utils - -client_ldap_service: "sssd" - -client_ldap_domaine: "{{ domaine_interne.split('.') | first }}" -# uri + base_dn : fournis par le rôle partagé resoudre_annuaire (tasks « Adopter »). -# Rôle DORMANT (login LDAP niveau OS via SSSD, non câblé). L'activer requiert client_pki -# (confiance step_ca pour LDAPS) et client_ldap_tls_reqcert: "demand". - -# Bind de lecture. Vide => bind anonyme (lecture publique de l'annuaire). -client_ldap_bind_dn: "" -client_ldap_bind_password: "{{ vault_ldap_sssd | default('') }}" # rempli depuis la voute (vault_ldap_sssd) - -# TLS : "never" tant que OpenLDAP n'expose pas LDAPS ; passer a "demand" -# avec LDAPS + confiance step_ca (client_pki). -client_ldap_tls_reqcert: "never" - -# Creation automatique du repertoire personnel a la premiere connexion. -client_ldap_mkhomedir: true diff --git a/roles/client_ldap/handlers/main.yml b/roles/client_ldap/handlers/main.yml deleted file mode 100644 index 426e21d..0000000 --- a/roles/client_ldap/handlers/main.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -- name: Redemarrer sssd - ansible.builtin.systemd: - name: "{{ client_ldap_service }}" - state: restarted - listen: Redemarrer sssd diff --git a/roles/client_ldap/tasks/main.yml b/roles/client_ldap/tasks/main.yml deleted file mode 100644 index 5bf0eef..0000000 --- a/roles/client_ldap/tasks/main.yml +++ /dev/null @@ -1,49 +0,0 @@ ---- -- name: Résoudre l'annuaire (rôle partagé) - ansible.builtin.include_role: - name: resoudre_annuaire - -- name: Adopter la connexion annuaire pour SSSD - ansible.builtin.set_fact: - client_ldap_uri: "{{ resoudre_annuaire_uri }}" - client_ldap_base_dn: "{{ resoudre_annuaire_base_dn }}" - -- name: Installer SSSD et les modules LDAP - ansible.builtin.apt: - name: "{{ client_ldap_paquets }}" - state: present - update_cache: true - cache_valid_time: 3600 - -- name: Deployer la configuration SSSD - ansible.builtin.template: - src: sssd.conf.j2 - dest: /etc/sssd/sssd.conf - owner: root - group: root - mode: "0600" - no_log: true - notify: Redemarrer sssd - -- name: Activer SSS dans nsswitch - ansible.builtin.lineinfile: - path: /etc/nsswitch.conf - regexp: '^({{ item }}:\s+)(?!.*\bsss\b)(.*)$' - line: '\1\2 sss' - backrefs: true - loop: - - passwd - - group - - shadow - -- name: Activer la creation automatique des repertoires personnels - ansible.builtin.command: - cmd: pam-auth-update --enable mkhomedir - changed_when: false - when: client_ldap_mkhomedir | bool - -- name: Activer et demarrer SSSD - ansible.builtin.systemd: - name: "{{ client_ldap_service }}" - enabled: true - state: started diff --git a/roles/client_ldap/templates/sssd.conf.j2 b/roles/client_ldap/templates/sssd.conf.j2 deleted file mode 100644 index 87cf8d0..0000000 --- a/roles/client_ldap/templates/sssd.conf.j2 +++ /dev/null @@ -1,18 +0,0 @@ -# Gere par Set-OPS (role client_ldap). Ne pas editer a la main. -[sssd] -config_file_version = 2 -services = nss, pam -domains = {{ client_ldap_domaine }} - -[domain/{{ client_ldap_domaine }}] -id_provider = ldap -auth_provider = ldap -ldap_uri = {{ client_ldap_uri }} -ldap_search_base = {{ client_ldap_base_dn }} -{% if client_ldap_bind_dn | length > 0 %} -ldap_default_bind_dn = {{ client_ldap_bind_dn }} -ldap_default_authtok = {{ client_ldap_bind_password }} -{% endif %} -ldap_tls_reqcert = {{ client_ldap_tls_reqcert }} -cache_credentials = true -enumerate = false diff --git a/roles/client_smtp/README.md b/roles/client_smtp/README.md index 0a197a9..3dc0645 100644 --- a/roles/client_smtp/README.md +++ b/roles/client_smtp/README.md @@ -1,7 +1,7 @@ # client_smtp Intégration cliente **relais mail** : l'hôte relaie son courrier sortant (notifications, -cron, alertes) vers `serveur_sendmail`, via **msmtp**. +cron, alertes) vers `serveur_postfix`, via **msmtp**. ## Rôle - Installe `msmtp` et `msmtp-mta` (`msmtp-mta` fournit `/usr/sbin/sendmail`, donc le @@ -10,7 +10,7 @@ cron, alertes) vers `serveur_sendmail`, via **msmtp**. fait confiance au réseau interne). ## Effet -Tout courrier émis localement (`mail`, cron, scripts) est relayé vers `serveur_sendmail` +Tout courrier émis localement (`mail`, cron, scripts) est relayé vers `serveur_postfix` (infra-mail-01), qui assure la remise. Léger, sans daemon. ## Variables @@ -26,4 +26,4 @@ Tout courrier émis localement (`mail`, cron, scripts) est relayé vers `serveur - TLS interne désactivé pour l'instant ; activable avec la confiance step_ca (`client_pki`). ## Prérequis -- Dépendance `client_smtp requiert serveur_sendmail actif` (déjà dans `docs/dependances-groupes.yml`). +- Dépendance `client_smtp requiert serveur_postfix actif` (déjà dans `docs/dependances-groupes.yml`). diff --git a/roles/client_smtp/defaults/main.yml b/roles/client_smtp/defaults/main.yml index b8de736..f435c4d 100644 --- a/roles/client_smtp/defaults/main.yml +++ b/roles/client_smtp/defaults/main.yml @@ -1,5 +1,5 @@ --- -# Relais mail local leger (msmtp) vers serveur_sendmail. +# Relais mail local leger (msmtp) vers le MTA (serveur_postfix). client_smtp_paquets: - msmtp - msmtp-mta # fournit /usr/sbin/sendmail diff --git a/roles/client_unbound/defaults/main.yml b/roles/client_unbound/defaults/main.yml index 308ab35..46bb71a 100644 --- a/roles/client_unbound/defaults/main.yml +++ b/roles/client_unbound/defaults/main.yml @@ -2,7 +2,7 @@ # Résolveur local Unbound par nœud : cache + récursion (ou forward), avec une # stub-zone vers l'autoritatif interne (PowerDNS). Rend la résolution dynamique # (au lieu du plancher /etc/hosts statique) sans casser Internet. La bascule de -# /etc/resolv.conf est PROTÉGÉE (apply + confirm), comme client_dns. +# /etc/resolv.conf est PROTÉGÉE (apply + confirm) — bascule du résolveur validée avant application. client_unbound_paquets: - unbound - bind9-dnsutils # dig, pour valider avant de basculer le resolver diff --git a/roles/serveur_forgejo/README.md b/roles/serveur_forgejo/README.md index 676c2d5..4b54fa9 100644 --- a/roles/serveur_forgejo/README.md +++ b/roles/serveur_forgejo/README.md @@ -6,7 +6,7 @@ Forge Git **Forgejo** (binaire officiel) — dépôts Git, CI, revue de code. - Installe le binaire Forgejo (version épinglée, lien symbolique courant), utilisateur `git`. - Crée l'arborescence (`/var/lib/forgejo`, `/etc/forgejo`). - **Base PostgreSQL via le registre** (`instance/plan/bases-donnees.yml`, entrée `forgejo`). -- `app.ini` : serveur derrière nginx (`HTTP_ADDR=127.0.0.1`, `ROOT_URL` https), DB, secrets, mailer vers `serveur_sendmail`, inscription désactivée, `INSTALL_LOCK` (pas d'assistant web). +- `app.ini` : serveur derrière nginx (`HTTP_ADDR=127.0.0.1`, `ROOT_URL` https), DB, secrets, mailer vers `serveur_postfix`, inscription désactivée, `INSTALL_LOCK` (pas d'assistant web). - Service systemd + création du **compte administrateur** initial (une fois). ## Secrets requis (Vault) @@ -31,4 +31,4 @@ vault_bd_forgejo: "..." # mot de passe BD (partage avec serveur_postgresql) - Non testé live (forge-01 planifié). ## Prérequis -- Dépendances `serveur_postgresql`, `serveur_nginx`, `serveur_sendmail` (cf. `docs/dependances-groupes.yml`). +- Dépendances `serveur_postgresql`, `serveur_nginx`, `serveur_postfix` (cf. `docs/dependances-groupes.yml`). diff --git a/roles/serveur_openldap/README.md b/roles/serveur_openldap/README.md index b7f84a4..18b5ce8 100644 --- a/roles/serveur_openldap/README.md +++ b/roles/serveur_openldap/README.md @@ -1,6 +1,6 @@ # serveur_openldap -Annuaire interne OpenLDAP (slapd Debian), socle d'identité pour `client_ldap` +Annuaire interne OpenLDAP (slapd Debian), socle d'identité pour le SSO (Keycloak), le courriel et fédération applicative (Keycloak). ## Rôle @@ -32,7 +32,7 @@ refuse de s'exécuter (assertion explicite). slapd déjà installé (changer domaine/mot de passe) nécessite `dpkg-reconfigure slapd` manuel (non automatisé ici pour éviter une purge accidentelle de la base). - TLS (LDAPS) : hors périmètre du socle — viendra avec les certificats de `serveur_step_ca`. -- Entrées utilisateurs/groupes : gérées ailleurs (identité / `client_ldap`). +- Entrées utilisateurs/groupes : gérées ailleurs (provisioning de l'annuaire). ## Prérequis - Collection `community.general` (`ldap_entry`) + `python3-ldap` sur la cible. diff --git a/roles/serveur_sendmail/README.md b/roles/serveur_sendmail/README.md deleted file mode 100644 index 0a93993..0000000 --- a/roles/serveur_sendmail/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# serveur_sendmail - -Relais SMTP sortant interne. **Implémenté avec Postfix** (fournit l'interface -`sendmail`-compatible `/usr/sbin/sendmail` qu'utilisent les clients). - -## Rôle -- Préconfigure Postfix via debconf (installation non interactive, « Internet Site »). -- Installe `postfix` et `ssl-cert`. -- Déploie `/etc/postfix/main.cf` : relais sortant uniquement, **n'accepte de relayer que pour `mynetworks`** (réseaux internes). -- **Valide la configuration (`postfix check`) avant de recharger** (handler `Valider et recharger postfix`). - -## Sécurité -- `smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination` → pas de relais ouvert. -- `mynetworks` par défaut : boucle locale + `10.0.0.0/16`. -- N'héberge pas de boîtes (`mydestination` ne contient pas le domaine) : remise relayée. -- TLS opportuniste (`may`), certificat snakeoil par défaut. - -## Variables principales -| Variable | Défaut | Rôle | -| --- | --- | --- | -| `serveur_sendmail_domaine` | `exemple.internal` | `mydomain` / mailname | -| `serveur_sendmail_reseaux_autorises` | boucle + `10.0.0.0/16` | `mynetworks` (qui peut relayer) | -| `serveur_sendmail_smarthost` | `""` | Relais amont (vide = remise directe MX) | -| `serveur_sendmail_inet_interfaces` | `all` | Interfaces d'écoute | -| `serveur_sendmail_tls_cert` / `_cle` | snakeoil | Certificat TLS | - -## Smarthost amont -```yaml -serveur_sendmail_smarthost: "[smtp.exemple.com]:587" -``` -(L'authentification SASL vers un smarthost externe, si requise, viendra avec ses -identifiants depuis Ansible Vault — hors périmètre du socle actuel.) - -## Hors périmètre -- Réception/hébergement de courrier (boîtes, IMAP). -- Authentification SASL sortante vers smarthost (à ajouter avec Vault si besoin). -- DKIM/SPF/DMARC signature (phase dédiée). diff --git a/roles/serveur_sendmail/defaults/main.yml b/roles/serveur_sendmail/defaults/main.yml deleted file mode 100644 index f0141fb..0000000 --- a/roles/serveur_sendmail/defaults/main.yml +++ /dev/null @@ -1,31 +0,0 @@ ---- -# Relais SMTP sortant base sur Postfix (fournit l'interface sendmail-compatible). -serveur_sendmail_packages: - - postfix - - ssl-cert - -serveur_sendmail_service_name: "postfix" - -# Identite. -serveur_sendmail_domaine: "{{ domaine_interne }}" -serveur_sendmail_origine: "$mydomain" -serveur_sendmail_nom_hote: "{{ ansible_fqdn | default(ansible_hostname) }}" - -# Reseaux internes autorises a relayer (client_smtp). -serveur_sendmail_reseaux_autorises: - - "127.0.0.0/8" - - "[::1]/128" - - "10.0.0.0/16" - -# Smarthost amont optionnel. Vide => remise directe (MX). -serveur_sendmail_smarthost: "" # ex. "[smtp.exemple.com]:587" - -# Relais uniquement : ne pas heberger de boites pour le domaine. -serveur_sendmail_destinations_locales: "$myhostname, localhost.$mydomain, localhost" - -# Interfaces d'ecoute. -serveur_sendmail_inet_interfaces: "all" - -# TLS (snakeoil par defaut ; bascule vers l'AC interne plus tard). -serveur_sendmail_tls_cert: "/etc/ssl/certs/ssl-cert-snakeoil.pem" -serveur_sendmail_tls_cle: "/etc/ssl/private/ssl-cert-snakeoil.key" diff --git a/roles/serveur_sendmail/handlers/main.yml b/roles/serveur_sendmail/handlers/main.yml deleted file mode 100644 index 170864b..0000000 --- a/roles/serveur_sendmail/handlers/main.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -- name: Verifier la configuration Postfix - when: not ansible_check_mode - ansible.builtin.command: - cmd: postfix check - changed_when: false - listen: Valider et recharger postfix - -- name: Recharger postfix - when: not ansible_check_mode - ansible.builtin.systemd: - name: "{{ serveur_sendmail_service_name }}" - state: reloaded - listen: Valider et recharger postfix diff --git a/roles/serveur_sendmail/meta/empreinte.yml b/roles/serveur_sendmail/meta/empreinte.yml deleted file mode 100644 index d749186..0000000 --- a/roles/serveur_sendmail/meta/empreinte.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -# Empreinte ressources du logiciel — dimensionnement VM derive (scripts/instancier.py). -# Sommee au socle SE + marge pour estimer coeurs/RAM/disque de la VM hote. -# Override possible par hote dans le plan (serveurs.yml: coeurs/memoire/disque). -setops_empreinte: - coeurs: 1 - memoire_mo: 512 - disque_go: 5 diff --git a/roles/serveur_sendmail/tasks/main.yml b/roles/serveur_sendmail/tasks/main.yml deleted file mode 100644 index 0f21331..0000000 --- a/roles/serveur_sendmail/tasks/main.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -- name: Preconfigurer Postfix (debconf, installation non interactive) - ansible.builtin.debconf: - name: postfix - question: "{{ item.question }}" - vtype: "{{ item.vtype }}" - value: "{{ item.value }}" - loop: - - { question: "postfix/main_mailer_type", vtype: "select", value: "Internet Site" } - - { question: "postfix/mailname", vtype: "string", value: "{{ serveur_sendmail_domaine }}" } - loop_control: - label: "{{ item.question }}" - -- name: Installer Postfix - ansible.builtin.apt: - name: "{{ serveur_sendmail_packages }}" - state: present - update_cache: true - cache_valid_time: 3600 - -- name: Deployer la configuration Postfix - ansible.builtin.template: - src: main.cf.j2 - dest: /etc/postfix/main.cf - owner: root - group: root - mode: "0644" - notify: Valider et recharger postfix - -- name: Activer et demarrer Postfix - when: not ansible_check_mode - ansible.builtin.systemd: - name: "{{ serveur_sendmail_service_name }}" - enabled: true - state: started diff --git a/roles/serveur_sendmail/templates/main.cf.j2 b/roles/serveur_sendmail/templates/main.cf.j2 deleted file mode 100644 index 7c4e26b..0000000 --- a/roles/serveur_sendmail/templates/main.cf.j2 +++ /dev/null @@ -1,31 +0,0 @@ -# Gere par Set-OPS (role serveur_sendmail, base Postfix). Ne pas editer a la main. -smtpd_banner = $myhostname ESMTP -biff = no -append_dot_mydomain = no -readme_directory = no -compatibility_level = 3.6 - -myhostname = {{ serveur_sendmail_nom_hote }} -mydomain = {{ serveur_sendmail_domaine }} -myorigin = {{ serveur_sendmail_origine }} -mydestination = {{ serveur_sendmail_destinations_locales }} -mynetworks = {{ serveur_sendmail_reseaux_autorises | join(', ') }} -relayhost = {{ serveur_sendmail_smarthost }} -inet_interfaces = {{ serveur_sendmail_inet_interfaces }} -inet_protocols = all - -alias_maps = hash:/etc/aliases -alias_database = hash:/etc/aliases -mailbox_size_limit = 0 -recipient_delimiter = + - -# Relais limite aux reseaux internes. -smtpd_relay_restrictions = permit_mynetworks, reject_unauth_destination - -# TLS opportuniste. -smtpd_tls_cert_file = {{ serveur_sendmail_tls_cert }} -smtpd_tls_key_file = {{ serveur_sendmail_tls_cle }} -smtpd_tls_security_level = may -smtp_tls_security_level = may -smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache -smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache