Retirer 3 rôles legacy (serveur_sendmail, client_dns, client_ldap) + nettoyage
Supprimés (supersédés / hors-conception) : serveur_sendmail (→ Postfix), client_dns (→ plancher + client_unbound), client_ldap (login LDAP OS, hors design). Rôles + playbooks de groupe retirés. Nettoyage des références : - dependances-groupes.yml : entrées client_dns/client_ldap retirées + entrées mortes des scaffoldings (nextcloud/collabora/client_supervision) ; deps périmées corrigées (client_smtp → serveur_postfix ; serveur_keycloak → serveur_postgresql, la raison parlait à tort de Nextcloud). - 6 modèles d'exemple : app mail serveur_sendmail → serveur_postfix. - README, AGENTS : listes/glossaire nettoyés. - catalogue-services : listes, tables, roadmap ; note « rôles retirés ». - nomenclature-vm : infra-mail-01 → serveur_dovecot (était faux). - courriel-conception, dns-interne (re-ciblé client_unbound), pouvoirs, intrants, READMEs (client_smtp/forgejo/openldap/unbound). ansible-lint : 0 échec (366 fichiers). instancier OK. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
bcab586845
commit
e006dee693
39 changed files with 56 additions and 532 deletions
|
|
@ -333,7 +333,6 @@ Les concepts comme socle Debian ou durcissement commun doivent être représent
|
||||||
```text
|
```text
|
||||||
serveur_debian -> socle commun Debian
|
serveur_debian -> socle commun Debian
|
||||||
serveur_durci -> durcissement commun
|
serveur_durci -> durcissement commun
|
||||||
client_dns -> intégration cliente DNS
|
|
||||||
client_pki -> intégration cliente PKI / ACME
|
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 :
|
Les groupes spécialisés doivent s'ajouter selon les besoins réels, par exemple :
|
||||||
|
|
||||||
```text
|
```text
|
||||||
client_dns
|
|
||||||
client_pki
|
client_pki
|
||||||
client_ldap
|
|
||||||
client_supervision
|
|
||||||
client_metrique
|
client_metrique
|
||||||
serveur_web_frontal
|
|
||||||
serveur_postgresql
|
serveur_postgresql
|
||||||
serveur_prometheus
|
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.
|
Ne pas cibler `all` par défaut pour un playbook qui ne s'applique pas réellement à tous les hôtes.
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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`.
|
Le catalogue des services et intégrations prévus est dans `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.
|
> de la colonne « Rôle » des tables.
|
||||||
|
|
||||||
**Implémentés** (`tasks` + `templates` + `handlers`, validés) : `serveur_step_ca`,
|
**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_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
|
`client_journal`, `serveur_grafana`, `serveur_icinga`, `serveur_forgejo`. Plus le socle et
|
||||||
le durcissement, appliqués par `serveur_debian` / `serveur_durci`.
|
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
|
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
|
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
|
**`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
|
> **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**
|
> → 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` |
|
| Prometheus | `serveur_prometheus` | `playbooks/groupes/serveur_prometheus.yml` | `prometheus` |
|
||||||
| Grafana | `serveur_grafana` | `playbooks/groupes/serveur_grafana.yml` | `grafana` |
|
| Grafana | `serveur_grafana` | `playbooks/groupes/serveur_grafana.yml` | `grafana` |
|
||||||
| Forgejo | `serveur_forgejo` | `playbooks/groupes/serveur_forgejo.yml` | `forgejo` |
|
| 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` |
|
| step-ca | `serveur_step_ca` | `playbooks/groupes/serveur_step_ca.yml` | `step_ca` |
|
||||||
| PowerDNS | `serveur_powerdns` | `playbooks/groupes/serveur_powerdns.yml` | `serveur_powerdns` |
|
| PowerDNS | `serveur_powerdns` | `playbooks/groupes/serveur_powerdns.yml` | `serveur_powerdns` |
|
||||||
| Redis | `serveur_redis` | `playbooks/groupes/serveur_redis.yml` | `redis` |
|
| 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 |
|
| 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` |
|
| 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` |
|
| Supervision Icinga | `client_supervision` | `playbooks/groupes/client_supervision.yml` | `client_supervision` |
|
||||||
| Métriques Prometheus | `client_metrique` | `playbooks/groupes/client_metrique.yml` | `client_metriques` |
|
| Métriques Prometheus | `client_metrique` | `playbooks/groupes/client_metrique.yml` | `client_metriques` |
|
||||||
| Journaux vers Loki | `client_journal` | `playbooks/groupes/client_journal.yml` | `client_journaux` |
|
| 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`
|
1. `serveur_powerdns`
|
||||||
- Service central : DNS interne autoritaire et/ou résolution interne selon le design retenu.
|
- 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.
|
- Raison : les autres intégrations auront besoin de noms stables plutôt que d'adresses IP.
|
||||||
|
|
||||||
2. `serveur_step_ca`
|
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.
|
- 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.
|
- Raison : plusieurs services seront consommés par navigateur ou API et doivent passer par un point d'entrée cohérent.
|
||||||
|
|
||||||
4. `serveur_sendmail`
|
4. `serveur_postfix`
|
||||||
- Service central : relais SMTP sortant.
|
- Service central : MTA (courriel entrant + sortant interne) + relais SMTP.
|
||||||
- Intégration à prévoir : `client_smtp`.
|
- Intégration à prévoir : `client_smtp`.
|
||||||
- Raison : les notifications, réinitialisations de mot de passe et alertes doivent fonctionner tôt.
|
- 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.
|
- Raison : Keycloak, Grafana, Icinga Web 2, Forgejo et Nextcloud peuvent dépendre de PostgreSQL.
|
||||||
|
|
||||||
6. `serveur_openldap`
|
6. `serveur_openldap`
|
||||||
- Service central : annuaire interne.
|
- Service central : annuaire interne (source de vérité des identités).
|
||||||
- Intégration à prévoir : `client_ldap`.
|
- Consommateurs : Keycloak (fédération/SSO), courriel (Postfix/Dovecot), apps.
|
||||||
- Raison : l'identité Unix et l'annuaire doivent exister avant les intégrations d'authentification avancées.
|
- Raison : l'annuaire doit exister avant l'identité fédérée et le courriel.
|
||||||
|
|
||||||
7. `serveur_keycloak`
|
7. `serveur_keycloak`
|
||||||
- Service central : SSO/OIDC/SAML.
|
- Service central : SSO/OIDC/SAML.
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,10 @@
|
||||||
| PKI | **Deux CA distinctes** (voir §6) : Let's Encrypt pour les faces publiques, **step_ca** pour l'interne. |
|
| 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`). |
|
| 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
|
Le courrier de **notification système** des nœuds (cron, alertes) est relayé vers le MTA
|
||||||
courrier de notification système (via `client_smtp`/msmtp). Il ne fait pas partie de ce
|
`serveur_postfix` (edge-mta) via `client_smtp`/msmtp. C'est distinct de ce service de boîtes
|
||||||
service et ne le remplace pas.
|
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
|
> **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** :
|
> (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.
|
la soumission Postfix), backend **LDAP**, TLS step_ca.
|
||||||
- `serveur_rspamd` — anti-spam, **signature DKIM**, greylisting ; branché à Postfix par milter.
|
- `serveur_rspamd` — anti-spam, **signature DKIM**, greylisting ; branché à Postfix par milter.
|
||||||
- `serveur_postfix` en **mode relais** (paramètre) pour le MX de secours.
|
- `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
|
- **Intégrations** des nœuds mail : `client_pki` (certs internes), `client_backup`,
|
||||||
internes), `client_dns`.
|
`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) —
|
- **Secrets (voûte)** : bind LDAP, **clé privée DKIM**, éventuel secret ACME (Étape B) —
|
||||||
via `vault_*`, câblés aux rôles.
|
via `vault_*`, câblés aux rôles.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,11 @@
|
||||||
---
|
---
|
||||||
groupes:
|
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:
|
client_pki:
|
||||||
requiert_groupes_actifs:
|
requiert_groupes_actifs:
|
||||||
- serveur_step_ca
|
- serveur_step_ca
|
||||||
raison: "La confiance CA et ACME client dependent de l'autorite interne."
|
raison: "La confiance CA et ACME client dependent de l'autorite interne."
|
||||||
surveillance: "Verifier validite CA, emission ACME et expiration des certificats."
|
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:
|
client_metrique:
|
||||||
requiert_groupes_actifs:
|
requiert_groupes_actifs:
|
||||||
- serveur_prometheus
|
- serveur_prometheus
|
||||||
|
|
@ -39,8 +20,8 @@ groupes:
|
||||||
|
|
||||||
client_smtp:
|
client_smtp:
|
||||||
requiert_groupes_actifs:
|
requiert_groupes_actifs:
|
||||||
- serveur_sendmail
|
- serveur_postfix
|
||||||
raison: "Les notifications locales doivent relayer vers un MTA actif."
|
raison: "Les notifications locales doivent relayer vers un MTA actif (Postfix)."
|
||||||
surveillance: "Verifier file d'attente, relais SMTP et echecs de livraison."
|
surveillance: "Verifier file d'attente, relais SMTP et echecs de livraison."
|
||||||
|
|
||||||
serveur_keycloak:
|
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)."
|
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."
|
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)."
|
|
||||||
|
|
|
||||||
|
|
@ -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_step_ca | 1 | 256 | 2 |
|
||||||
| serveur_powerdns | 1 | 512 | 2 |
|
| serveur_powerdns | 1 | 512 | 2 |
|
||||||
| serveur_sendmail | 1 | 512 | 5 |
|
|
||||||
| serveur_nginx | 1 | 512 | 3 |
|
| serveur_nginx | 1 | 512 | 3 |
|
||||||
| serveur_openldap | 1 | 512 | 3 |
|
| serveur_openldap | 1 | 512 | 3 |
|
||||||
| serveur_keycloak | 2 | 1536 | 5 |
|
| serveur_keycloak | 2 | 1536 | 5 |
|
||||||
|
|
|
||||||
|
|
@ -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
|
> `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
|
> 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,
|
> que PowerDNS ne soit la). PowerDNS devient une **commodite** (zone, externe,
|
||||||
> dynamique), plus un point de defaillance : la dependance `client_dns -> powerdns`
|
> dynamique), plus un point de defaillance. Le resolveur local `client_unbound` est
|
||||||
> est **molle** (client_dns est inerte si aucun DNS interne n'existe).
|
> **optionnel** (opt-in, avec bascule validee) : sans lui, le plancher `/etc/hosts` suffit.
|
||||||
|
|
||||||
## Groupes
|
## Groupes
|
||||||
|
|
||||||
```text
|
```text
|
||||||
serveur_powerdns -> service DNS central PowerDNS Authoritative
|
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
|
## 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.
|
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 ;
|
La bascule du resolver local est **protegee** (le role valide qu'Unbound répond AVANT de
|
||||||
- que la zone repond a une requete SOA ;
|
basculer `/etc/resolv.conf`) :
|
||||||
- que le nom de l'hote existe dans la zone.
|
|
||||||
|
|
||||||
La modification du resolver local est protegee :
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
client_dns_apply: true
|
client_unbound_apply: true
|
||||||
client_dns_confirm: 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.
|
Cette protection est volontaire : une mauvaise configuration DNS peut couper la resolution de noms.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ nftables baseline · fail2ban SSH · auditd · AppArmor · sysctl · unattended-
|
||||||
journald (rétention) · core_dumps · systemd_ssh_auto.
|
journald (rétention) · core_dumps · systemd_ssh_auto.
|
||||||
|
|
||||||
### F. Endpoints des services centraux (les rôles `client_*` en dérivent)
|
### 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).
|
- AC/PKI (`client_pki_ca_url` → infra-pki, provisioner).
|
||||||
- IdM/LDAP (`client_ldap_uri` → idm, base DN dérivé).
|
- IdM/LDAP : annuaire résolu par `resoudre_annuaire` (hôte + base DN dérivés du domaine).
|
||||||
- Relais courriel (`client_smtp_relais` → infra-mail, port 25).
|
- Relais courriel (`client_smtp_relais` → edge-mta, MTA Postfix, port 25).
|
||||||
- Métriques (node_exporter `:9100`).
|
- Métriques (node_exporter `:9100`).
|
||||||
- Journaux (`client_journal_loki_url` → obs).
|
- Journaux (`client_journal_loki_url` → obs).
|
||||||
- Temps (NTP) : **implicite** (pool Debian par défaut — aucun intrant configuré).
|
- 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) |
|
| Secrets Vault | **Constante** 🔒 | — (gérés à part, jamais en clair) |
|
||||||
| `chezlepro_timezone` | Défaut | par hôte (rare) |
|
| `chezlepro_timezone` | Défaut | par hôte (rare) |
|
||||||
| `proxmox_clone_noeud` / `stockage` / `pont` | Défaut | par hôte (`serveurs.yml`) |
|
| `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 |
|
| Politiques durcissement (SSH, nftables, fail2ban, journald…) | Défaut | par hôte / groupe |
|
||||||
| Relais SMTP, TLS internes | Défaut | par hôte / groupe |
|
| Relais SMTP, TLS internes | Défaut | par hôte / groupe |
|
||||||
| `ciuser`, compte `ansible` | Défaut | rarement surchargé |
|
| `ciuser`, compte `ansible` | Défaut | rarement surchargé |
|
||||||
|
|
|
||||||
|
|
@ -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-pki-01` | `serveur_step_ca` |
|
||||||
| `infra-edge-01` | `serveur_nginx` |
|
| `infra-edge-01` | `serveur_nginx` |
|
||||||
| `infra-mail-01` | `serveur_sendmail` |
|
| `infra-mail-01` | `serveur_dovecot` (mail-store) |
|
||||||
| `infra-dns-01` | `serveur_powerdns` |
|
| `infra-dns-01` | `serveur_powerdns` |
|
||||||
| `idm-01` | `serveur_openldap`, `serveur_keycloak` |
|
| `idm-01` | `serveur_openldap`, `serveur_keycloak` |
|
||||||
| `data-01` | `serveur_postgresql`, `serveur_redis` |
|
| `data-01` | `serveur_postgresql`, `serveur_redis` |
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ prouvés.
|
||||||
- **Forge logicielle** : `serveur_forgejo`.
|
- **Forge logicielle** : `serveur_forgejo`.
|
||||||
- **Observabilité** : `serveur_prometheus`, `serveur_grafana`, `serveur_loki`, `serveur_icinga`,
|
- **Observabilité** : `serveur_prometheus`, `serveur_grafana`, `serveur_loki`, `serveur_icinga`,
|
||||||
avec les clients `client_metrique`, `client_journal`, `client_supervision`.
|
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`,
|
- **Méta-rôles d'agrégation** : `identity`, `applications`, `database`, `web`, `monitoring`,
|
||||||
`backup`, `storage`.
|
`backup`, `storage`.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ applications:
|
||||||
groupe: serveur_nginx
|
groupe: serveur_nginx
|
||||||
hote: infra-edge-01
|
hote: infra-edge-01
|
||||||
sendmail:
|
sendmail:
|
||||||
groupe: serveur_sendmail
|
groupe: serveur_postfix
|
||||||
hote: infra-mail-01
|
hote: infra-mail-01
|
||||||
powerdns:
|
powerdns:
|
||||||
groupe: serveur_powerdns
|
groupe: serveur_powerdns
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ applications:
|
||||||
groupe: serveur_nginx
|
groupe: serveur_nginx
|
||||||
hote: infra-edge-01
|
hote: infra-edge-01
|
||||||
sendmail:
|
sendmail:
|
||||||
groupe: serveur_sendmail
|
groupe: serveur_postfix
|
||||||
hote: infra-mail-01
|
hote: infra-mail-01
|
||||||
powerdns:
|
powerdns:
|
||||||
groupe: serveur_powerdns
|
groupe: serveur_powerdns
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ applications:
|
||||||
groupe: serveur_nginx
|
groupe: serveur_nginx
|
||||||
hote: infra-edge-01
|
hote: infra-edge-01
|
||||||
sendmail:
|
sendmail:
|
||||||
groupe: serveur_sendmail
|
groupe: serveur_postfix
|
||||||
hote: infra-mail-01
|
hote: infra-mail-01
|
||||||
powerdns:
|
powerdns:
|
||||||
groupe: serveur_powerdns
|
groupe: serveur_powerdns
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ applications:
|
||||||
groupe: serveur_nginx
|
groupe: serveur_nginx
|
||||||
hote: infra-edge-01
|
hote: infra-edge-01
|
||||||
sendmail:
|
sendmail:
|
||||||
groupe: serveur_sendmail
|
groupe: serveur_postfix
|
||||||
hote: infra-mail-01
|
hote: infra-mail-01
|
||||||
powerdns:
|
powerdns:
|
||||||
groupe: serveur_powerdns
|
groupe: serveur_powerdns
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
applications:
|
applications:
|
||||||
pki: { groupe: serveur_step_ca, hote: infra-pki-01 }
|
pki: { groupe: serveur_step_ca, hote: infra-pki-01 }
|
||||||
edge: { groupe: serveur_nginx, hote: infra-edge-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 }
|
dns: { groupe: serveur_powerdns, hote: infra-dns-01 }
|
||||||
bdd: { groupe: serveur_postgresql, hote: data-01, port: 5432 }
|
bdd: { groupe: serveur_postgresql, hote: data-01, port: 5432 }
|
||||||
cache: { groupe: serveur_redis, hote: data-01 }
|
cache: { groupe: serveur_redis, hote: data-01 }
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ applications:
|
||||||
groupe: serveur_nginx
|
groupe: serveur_nginx
|
||||||
hote: infra-edge-01
|
hote: infra-edge-01
|
||||||
sendmail:
|
sendmail:
|
||||||
groupe: serveur_sendmail
|
groupe: serveur_postfix
|
||||||
hote: infra-mail-01
|
hote: infra-mail-01
|
||||||
powerdns:
|
powerdns:
|
||||||
groupe: serveur_powerdns
|
groupe: serveur_powerdns
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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`.
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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`).
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
- name: Redemarrer sssd
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: "{{ client_ldap_service }}"
|
|
||||||
state: restarted
|
|
||||||
listen: Redemarrer sssd
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# client_smtp
|
# client_smtp
|
||||||
|
|
||||||
Intégration cliente **relais mail** : l'hôte relaie son courrier sortant (notifications,
|
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
|
## Rôle
|
||||||
- Installe `msmtp` et `msmtp-mta` (`msmtp-mta` fournit `/usr/sbin/sendmail`, donc 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).
|
fait confiance au réseau interne).
|
||||||
|
|
||||||
## Effet
|
## 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.
|
(infra-mail-01), qui assure la remise. Léger, sans daemon.
|
||||||
|
|
||||||
## Variables
|
## 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`).
|
- TLS interne désactivé pour l'instant ; activable avec la confiance step_ca (`client_pki`).
|
||||||
|
|
||||||
## Prérequis
|
## 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`).
|
||||||
|
|
|
||||||
|
|
@ -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:
|
client_smtp_paquets:
|
||||||
- msmtp
|
- msmtp
|
||||||
- msmtp-mta # fournit /usr/sbin/sendmail
|
- msmtp-mta # fournit /usr/sbin/sendmail
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
# Résolveur local Unbound par nœud : cache + récursion (ou forward), avec une
|
# 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
|
# 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
|
# (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:
|
client_unbound_paquets:
|
||||||
- unbound
|
- unbound
|
||||||
- bind9-dnsutils # dig, pour valider avant de basculer le resolver
|
- bind9-dnsutils # dig, pour valider avant de basculer le resolver
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
- Installe le binaire Forgejo (version épinglée, lien symbolique courant), utilisateur `git`.
|
||||||
- Crée l'arborescence (`/var/lib/forgejo`, `/etc/forgejo`).
|
- Crée l'arborescence (`/var/lib/forgejo`, `/etc/forgejo`).
|
||||||
- **Base PostgreSQL via le registre** (`instance/plan/bases-donnees.yml`, entrée `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).
|
- Service systemd + création du **compte administrateur** initial (une fois).
|
||||||
|
|
||||||
## Secrets requis (Vault)
|
## Secrets requis (Vault)
|
||||||
|
|
@ -31,4 +31,4 @@ vault_bd_forgejo: "..." # mot de passe BD (partage avec serveur_postgresql)
|
||||||
- Non testé live (forge-01 planifié).
|
- Non testé live (forge-01 planifié).
|
||||||
|
|
||||||
## Prérequis
|
## 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`).
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# serveur_openldap
|
# 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).
|
et fédération applicative (Keycloak).
|
||||||
|
|
||||||
## Rôle
|
## 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`
|
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).
|
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`.
|
- 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
|
## Prérequis
|
||||||
- Collection `community.general` (`ldap_entry`) + `python3-ldap` sur la cible.
|
- Collection `community.general` (`ldap_entry`) + `python3-ldap` sur la cible.
|
||||||
|
|
|
||||||
|
|
@ -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).
|
|
||||||
|
|
@ -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"
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -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
|
|
||||||
Loading…
Reference in a new issue