serveur_openldap : TLS via step_ca + organisation en intrant (code prod)
- TLS LDAPS/STARTTLS : pont du cert step_ca (client_pki, root:root 600) vers /etc/ldap/tls lisible par openldap ; script + unité path systemd qui re-synchronise et recharge slapd au renouvellement ; olcTLS* dans cn=config ; SLAPD_SERVICES expose ldaps://. Dégrade proprement sans cert. - Organisation : intrant chezlepro_organisation (remplace « Exemple Inc »). Validé statiquement (ansible-lint, syntax) ; déploiement réel à suivre. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
1e2c323156
commit
1edd205d13
8 changed files with 164 additions and 1 deletions
|
|
@ -3,6 +3,14 @@
|
||||||
## 2026-07-02
|
## 2026-07-02
|
||||||
|
|
||||||
### Ajouté
|
### Ajouté
|
||||||
|
- **`serveur_openldap` durci pour la prod : TLS via step_ca + organisation en intrant.**
|
||||||
|
- **TLS (LDAPS + STARTTLS)** : le certificat d'hôte step_ca (déposé par `client_pki`,
|
||||||
|
`root:root 600`) est synchronisé vers un emplacement lisible par `openldap` (`/etc/ldap/tls`)
|
||||||
|
par un script + une unité `path` systemd qui **re-synchronise et recharge slapd à chaque
|
||||||
|
renouvellement** ; `olcTLS*` configuré dans `cn=config`, `SLAPD_SERVICES` expose `ldaps://`.
|
||||||
|
Dégrade proprement (slapd en clair local) si `client_pki` n'a pas encore posé le cert.
|
||||||
|
- **Organisation** : nouvel intrant `chezlepro_organisation` (remplace le « Exemple Inc » codé).
|
||||||
|
- *Écrit en code de prod, éprouvé statiquement ; validation par déploiement réel à suivre.*
|
||||||
- **`docs/courriel-conception.md`** — cadrage du futur service de courriel souverain :
|
- **`docs/courriel-conception.md`** — cadrage du futur service de courriel souverain :
|
||||||
full self-host, suite **Stalwart** (adoptée, enveloppée par un rôle mince), topologie
|
full self-host, suite **Stalwart** (adoptée, enveloppée par un rôle mince), topologie
|
||||||
MX primaire + MX secours, intégration identité (LDAP) / DNS / PKI (Let's Encrypt public
|
MX primaire + MX secours, intégration identité (LDAP) / DNS / PKI (Let's Encrypt public
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ serveur_openldap_service: "slapd"
|
||||||
|
|
||||||
# Identite de l'annuaire.
|
# Identite de l'annuaire.
|
||||||
serveur_openldap_domaine: "{{ domaine_interne }}"
|
serveur_openldap_domaine: "{{ domaine_interne }}"
|
||||||
serveur_openldap_organisation: "Exemple Inc"
|
serveur_openldap_organisation: "{{ chezlepro_organisation | default('Organisation') }}"
|
||||||
# Base DN derivee du domaine interne (ex. acme.local -> dc=acme,dc=local).
|
# Base DN derivee du domaine interne (ex. acme.local -> dc=acme,dc=local).
|
||||||
serveur_openldap_base_dn: "dc={{ serveur_openldap_domaine.split('.') | join(',dc=') }}"
|
serveur_openldap_base_dn: "dc={{ serveur_openldap_domaine.split('.') | join(',dc=') }}"
|
||||||
serveur_openldap_admin_dn: "cn=admin,{{ serveur_openldap_base_dn }}"
|
serveur_openldap_admin_dn: "cn=admin,{{ serveur_openldap_base_dn }}"
|
||||||
|
|
@ -20,3 +20,15 @@ serveur_openldap_admin_password: "{{ vault_openldap_admin | default('') }}" # r
|
||||||
serveur_openldap_ou:
|
serveur_openldap_ou:
|
||||||
- people
|
- people
|
||||||
- groups
|
- groups
|
||||||
|
|
||||||
|
# --- TLS (LDAPS + STARTTLS) via le certificat d'hote step_ca ---
|
||||||
|
# Requiert l'integration client_pki sur le noeud (fournit le cert + le renouvellement).
|
||||||
|
serveur_openldap_tls_actif: true
|
||||||
|
# Certificat SOURCE depose par client_pki (root:root 600, illisible par openldap).
|
||||||
|
serveur_openldap_tls_source_cert: "/etc/step/certs/{{ ansible_fqdn | default(ansible_hostname) }}.crt"
|
||||||
|
serveur_openldap_tls_source_cle: "/etc/step/certs/{{ ansible_fqdn | default(ansible_hostname) }}.key"
|
||||||
|
serveur_openldap_tls_source_ca: "/etc/step/certs/root_ca.crt"
|
||||||
|
# Emplacement PONT, lisible par openldap ; resynchronise a chaque renouvellement.
|
||||||
|
serveur_openldap_tls_dir: "/etc/ldap/tls"
|
||||||
|
# Services slapd exposes (ldaps ajoute pour le TLS ; ldapi pour l'admin local).
|
||||||
|
serveur_openldap_services: "ldap:/// ldaps:/// ldapi:///"
|
||||||
|
|
|
||||||
7
roles/serveur_openldap/handlers/main.yml
Normal file
7
roles/serveur_openldap/handlers/main.yml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
- name: Redemarrer slapd
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ serveur_openldap_service }}"
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: not ansible_check_mode
|
||||||
|
|
@ -58,3 +58,95 @@
|
||||||
loop_control:
|
loop_control:
|
||||||
label: "ou={{ item }}"
|
label: "ou={{ item }}"
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
# --- TLS (LDAPS + STARTTLS) via le certificat step_ca depose par client_pki ---
|
||||||
|
- name: TLS — creer le repertoire pont lisible par openldap
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ serveur_openldap_tls_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: openldap
|
||||||
|
group: openldap
|
||||||
|
mode: "0750"
|
||||||
|
when: serveur_openldap_tls_actif | bool
|
||||||
|
|
||||||
|
- name: TLS — deployer le script de synchronisation du certificat
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: setops-slapd-cert-sync.sh.j2
|
||||||
|
dest: /usr/local/sbin/setops-slapd-cert-sync
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: serveur_openldap_tls_actif | bool
|
||||||
|
|
||||||
|
- name: TLS — deployer les unites de synchronisation (service + path)
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.s }}"
|
||||||
|
dest: "{{ item.d }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
loop:
|
||||||
|
- { s: "setops-slapd-cert-sync.service.j2", d: "/etc/systemd/system/setops-slapd-cert-sync.service" }
|
||||||
|
- { s: "setops-slapd-cert-sync.path.j2", d: "/etc/systemd/system/setops-slapd-cert-sync.path" }
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.d | basename }}"
|
||||||
|
when: serveur_openldap_tls_actif | bool
|
||||||
|
|
||||||
|
- name: TLS — synchroniser le certificat maintenant (si client_pki l'a depose)
|
||||||
|
ansible.builtin.command: /usr/local/sbin/setops-slapd-cert-sync
|
||||||
|
changed_when: false
|
||||||
|
when:
|
||||||
|
- serveur_openldap_tls_actif | bool
|
||||||
|
- not ansible_check_mode
|
||||||
|
|
||||||
|
- name: TLS — activer la surveillance du certificat (renouvellement)
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: setops-slapd-cert-sync.path
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
daemon_reload: true
|
||||||
|
when:
|
||||||
|
- serveur_openldap_tls_actif | bool
|
||||||
|
- not ansible_check_mode
|
||||||
|
|
||||||
|
- name: TLS — verifier que le certificat pont est en place
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ serveur_openldap_tls_dir }}/cert.pem"
|
||||||
|
register: serveur_openldap_cert_pont
|
||||||
|
when: serveur_openldap_tls_actif | bool
|
||||||
|
|
||||||
|
- name: TLS — avertir si le certificat n'est pas encore disponible
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: >-
|
||||||
|
client_pki n'a pas encore depose de certificat sur ce noeud
|
||||||
|
({{ serveur_openldap_tls_source_cert }}). TLS slapd NON configure : deploie
|
||||||
|
l'integration client_pki sur ce noeud, puis relance le deploiement.
|
||||||
|
when:
|
||||||
|
- serveur_openldap_tls_actif | bool
|
||||||
|
- not ansible_check_mode
|
||||||
|
- not (serveur_openldap_cert_pont.stat.exists | default(false))
|
||||||
|
|
||||||
|
- name: TLS — configurer slapd (olcTLS* dans cn=config)
|
||||||
|
community.general.ldap_attrs:
|
||||||
|
dn: cn=config
|
||||||
|
server_uri: ldapi:///
|
||||||
|
attributes:
|
||||||
|
olcTLSCACertificateFile: "{{ serveur_openldap_tls_dir }}/ca.pem"
|
||||||
|
olcTLSCertificateFile: "{{ serveur_openldap_tls_dir }}/cert.pem"
|
||||||
|
olcTLSCertificateKeyFile: "{{ serveur_openldap_tls_dir }}/key.pem"
|
||||||
|
state: exact
|
||||||
|
when:
|
||||||
|
- serveur_openldap_tls_actif | bool
|
||||||
|
- not ansible_check_mode
|
||||||
|
- serveur_openldap_cert_pont.stat.exists | default(false)
|
||||||
|
notify: Redemarrer slapd
|
||||||
|
|
||||||
|
- name: TLS — exposer LDAPS (SLAPD_SERVICES)
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/default/slapd
|
||||||
|
regexp: '^SLAPD_SERVICES='
|
||||||
|
line: 'SLAPD_SERVICES="{{ serveur_openldap_services }}"'
|
||||||
|
when:
|
||||||
|
- serveur_openldap_tls_actif | bool
|
||||||
|
- serveur_openldap_cert_pont.stat.exists | default(false)
|
||||||
|
notify: Redemarrer slapd
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
# Gere par Set-OPS (role serveur_openldap). Ne pas editer a la main.
|
||||||
|
# Surveille le certificat step_ca : au renouvellement (client_pki), resynchronise
|
||||||
|
# vers slapd et le recharge.
|
||||||
|
[Unit]
|
||||||
|
Description=Set-OPS — surveille le certificat step_ca de slapd
|
||||||
|
|
||||||
|
[Path]
|
||||||
|
PathChanged={{ serveur_openldap_tls_source_cert }}
|
||||||
|
Unit=setops-slapd-cert-sync.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Gere par Set-OPS (role serveur_openldap). Ne pas editer a la main.
|
||||||
|
[Unit]
|
||||||
|
Description=Set-OPS — synchronise le certificat step_ca vers slapd
|
||||||
|
After=slapd.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/sbin/setops-slapd-cert-sync
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Gere par Set-OPS (role serveur_openldap). Ne pas editer a la main.
|
||||||
|
# Synchronise le certificat step_ca (depose par client_pki, root:root 600) vers un
|
||||||
|
# emplacement lisible par openldap, puis recharge slapd. Idempotent ; appele au
|
||||||
|
# deploiement ET a chaque renouvellement (unite path).
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SRC_CERT="{{ serveur_openldap_tls_source_cert }}"
|
||||||
|
SRC_KEY="{{ serveur_openldap_tls_source_cle }}"
|
||||||
|
SRC_CA="{{ serveur_openldap_tls_source_ca }}"
|
||||||
|
DST="{{ serveur_openldap_tls_dir }}"
|
||||||
|
|
||||||
|
# Rien a faire tant que client_pki n'a pas depose le certificat d'hote.
|
||||||
|
[ -f "$SRC_CERT" ] && [ -f "$SRC_KEY" ] || exit 0
|
||||||
|
|
||||||
|
install -o openldap -g openldap -m 0644 "$SRC_CERT" "$DST/cert.pem"
|
||||||
|
install -o openldap -g openldap -m 0640 "$SRC_KEY" "$DST/key.pem"
|
||||||
|
[ -f "$SRC_CA" ] && install -o openldap -g openldap -m 0644 "$SRC_CA" "$DST/ca.pem"
|
||||||
|
|
||||||
|
# Recharge slapd s'il tourne (sans echouer s'il est absent/arrete).
|
||||||
|
if systemctl --quiet is-active slapd 2>/dev/null; then
|
||||||
|
systemctl reload slapd 2>/dev/null || systemctl restart slapd
|
||||||
|
fi
|
||||||
|
|
@ -79,6 +79,7 @@ FICHIERS_INTRANTS = {"identite": INTRANTS_IDENTITE, "proxmox": INTRANTS_PROXMOX}
|
||||||
INTRANTS_SCHEMA = [
|
INTRANTS_SCHEMA = [
|
||||||
("domaine_interne", "identite", "constante", "Identité", "Domaine DNS interne", "str"),
|
("domaine_interne", "identite", "constante", "Identité", "Domaine DNS interne", "str"),
|
||||||
("chezlepro_timezone", "identite", "defaut", "Identité", "Fuseau horaire", "str"),
|
("chezlepro_timezone", "identite", "defaut", "Identité", "Fuseau horaire", "str"),
|
||||||
|
("chezlepro_organisation", "identite", "defaut", "Identité", "Organisation (annuaire LDAP, certificats)", "str"),
|
||||||
("proxmox_api_host", "proxmox", "constante", "Proxmox", "Hôte API Proxmox", "str"),
|
("proxmox_api_host", "proxmox", "constante", "Proxmox", "Hôte API Proxmox", "str"),
|
||||||
("proxmox_api_user", "proxmox", "constante", "Proxmox", "Utilisateur API", "str"),
|
("proxmox_api_user", "proxmox", "constante", "Proxmox", "Utilisateur API", "str"),
|
||||||
("proxmox_api_port", "proxmox", "constante", "Proxmox", "Port API", "str"),
|
("proxmox_api_port", "proxmox", "constante", "Proxmox", "Port API", "str"),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue