2026-06-24 20:17:46 -04:00
|
|
|
---
|
|
|
|
|
- name: Installer nftables
|
|
|
|
|
ansible.builtin.apt:
|
|
|
|
|
name: nftables
|
|
|
|
|
state: present
|
|
|
|
|
|
2026-07-07 03:08:09 -04:00
|
|
|
- name: Vérifier la présence du ruleset résolu (généré par make flux)
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "{{ nftables_baseline_ruleset_genere }}"
|
|
|
|
|
delegate_to: localhost
|
|
|
|
|
become: false
|
|
|
|
|
changed_when: false
|
|
|
|
|
register: nftables_baseline_ruleset_stat
|
|
|
|
|
|
|
|
|
|
- name: Déployer le ruleset nftables résolu (moindre privilège, généré)
|
|
|
|
|
ansible.builtin.copy:
|
|
|
|
|
src: "{{ nftables_baseline_ruleset_genere }}"
|
|
|
|
|
dest: /etc/nftables.conf
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Reload nftables
|
|
|
|
|
when:
|
|
|
|
|
- nftables_baseline_enabled | bool
|
|
|
|
|
- nftables_baseline_ruleset_stat.stat.exists
|
|
|
|
|
|
|
|
|
|
- name: Déployer la configuration nftables Set-OPS (gabarit plat — repli)
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.template:
|
|
|
|
|
src: nftables.conf.j2
|
|
|
|
|
dest: /etc/nftables.conf
|
|
|
|
|
owner: root
|
|
|
|
|
group: root
|
|
|
|
|
mode: "0644"
|
|
|
|
|
notify: Reload nftables
|
2026-07-07 03:08:09 -04:00
|
|
|
when:
|
|
|
|
|
- nftables_baseline_enabled | bool
|
|
|
|
|
- not nftables_baseline_ruleset_stat.stat.exists
|
2026-06-24 20:17:46 -04:00
|
|
|
|
2026-08-30 10:00:18 -04:00
|
|
|
# ARMER LE PARE-FEU COUPE LA MAIN QUI L'ARME (mesure du 2026-08-30).
|
|
|
|
|
#
|
|
|
|
|
# Une session SSH ouverte AVANT le demarrage de nftables n'a aucune entree conntrack.
|
|
|
|
|
# Des que le ruleset s'installe, ses paquets arrivent en `invalid` et tombent sur
|
|
|
|
|
# `ct state invalid drop` — la session meurt. Les connexions NEUVES passent sans
|
|
|
|
|
# probleme (SYN -> NEW -> suivi) : le pare-feu est correct, c'est la continuite qui
|
|
|
|
|
# ne l'est pas.
|
|
|
|
|
#
|
|
|
|
|
# CE N'EST PAS UN VERROUILLAGE, ET C'EST CE QUI LE REND DANGEREUX. Rien n'echoue :
|
|
|
|
|
# Ansible attend une reponse qui ne viendra jamais, sans delai. Le 2026-08-30, un
|
|
|
|
|
# deploiement est reste suspendu CINQUANTE-HUIT MINUTES sur six machines, pendant que
|
|
|
|
|
# les quinze repondaient parfaitement a qui se connectait a neuf.
|
|
|
|
|
#
|
|
|
|
|
# `async` + `poll: 0` : on lance et on ne guette pas la reponse — elle ne peut pas
|
|
|
|
|
# revenir. `reset_connection` jette la session morte, `wait_for_connection` en ouvre
|
|
|
|
|
# une neuve, qui elle sera suivie par conntrack des sa poignee.
|
|
|
|
|
- name: Activer nftables si demandé (sans attendre la reponse)
|
2026-06-24 20:17:46 -04:00
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: nftables
|
|
|
|
|
enabled: true
|
|
|
|
|
state: started
|
2026-08-30 10:00:18 -04:00
|
|
|
async: 60
|
|
|
|
|
poll: 0
|
|
|
|
|
when: nftables_baseline_enabled | bool
|
|
|
|
|
|
|
|
|
|
- name: Jeter la session que le pare-feu vient de couper
|
|
|
|
|
ansible.builtin.meta: reset_connection
|
|
|
|
|
|
|
|
|
|
# LE DELAI EST UNE ATTENTE, PAS UN VERDICT : si l'hote ne revient pas, c'est un vrai
|
|
|
|
|
# verrouillage — la garde `nftables_admin_ssh` a manque sa cible — et il faut le dire
|
|
|
|
|
# fort plutot que de laisser un playbook pendre.
|
|
|
|
|
- name: Reprendre la main sur l'hote qu'on vient d'armer
|
|
|
|
|
ansible.builtin.wait_for_connection:
|
|
|
|
|
delay: 3
|
|
|
|
|
timeout: 90
|
2026-06-24 20:17:46 -04:00
|
|
|
when: nftables_baseline_enabled | bool
|
|
|
|
|
|
|
|
|
|
- name: Désactiver nftables si demandé
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: nftables
|
|
|
|
|
enabled: false
|
|
|
|
|
state: stopped
|
|
|
|
|
when: not (nftables_baseline_enabled | bool)
|
|
|
|
|
failed_when: false
|