durcit le serveur : pare-feu nftables, SSH par clé, fail2ban, chrony, mises à jour de sécurité
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
b7e866f868
commit
f5a5e8d8a9
13 changed files with 377 additions and 0 deletions
178
ansible/roles/durcissement/tasks/main.yml
Normal file
178
ansible/roles/durcissement/tasks/main.yml
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
---
|
||||
- name: installer les paquets de durcissement
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- nftables
|
||||
- fail2ban
|
||||
- chrony
|
||||
- unattended-upgrades
|
||||
state: present
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
|
||||
- name: régler le fuseau horaire sur Europe/Paris
|
||||
community.general.timezone:
|
||||
name: Europe/Paris
|
||||
|
||||
- name: vérifier la présence de systemd-timesyncd
|
||||
ansible.builtin.stat:
|
||||
path: /lib/systemd/system/systemd-timesyncd.service
|
||||
register: durcissement_timesyncd_unit
|
||||
|
||||
- name: désactiver systemd-timesyncd (remplacé par chrony)
|
||||
ansible.builtin.systemd:
|
||||
name: systemd-timesyncd
|
||||
state: stopped
|
||||
enabled: false
|
||||
when: durcissement_timesyncd_unit.stat.exists
|
||||
|
||||
- name: configurer chrony
|
||||
ansible.builtin.copy:
|
||||
content: |
|
||||
# Géré par Ansible (rôle durcissement) : configuration par défaut de Debian,
|
||||
# conservée volontairement (pools NTP standard). Pas de changement nécessaire
|
||||
# ici pour l'instant : la présence du paquet et le service actif suffisent.
|
||||
dest: /etc/chrony/conf.d/durcissement.conf
|
||||
mode: "0644"
|
||||
notify: redémarrer chrony
|
||||
|
||||
- name: configurer les mises à jour automatiques (listes + sécurité)
|
||||
ansible.builtin.template:
|
||||
src: 20auto-upgrades.j2
|
||||
dest: /etc/apt/apt.conf.d/20auto-upgrades
|
||||
mode: "0644"
|
||||
|
||||
- name: interdire le redémarrage automatique par unattended-upgrades
|
||||
ansible.builtin.template:
|
||||
src: 51unattended-upgrades-local.conf.j2
|
||||
dest: /etc/apt/apt.conf.d/51unattended-upgrades-local
|
||||
mode: "0644"
|
||||
|
||||
- name: configurer fail2ban (jail sshd, backend nftables)
|
||||
ansible.builtin.template:
|
||||
src: jail.local.j2
|
||||
dest: /etc/fail2ban/jail.local
|
||||
mode: "0644"
|
||||
notify: redémarrer fail2ban
|
||||
|
||||
- name: déployer le script de retour à l'état d'avant durcissement
|
||||
ansible.builtin.template:
|
||||
src: durcissement-rollback.sh.j2
|
||||
dest: /usr/local/sbin/durcissement-rollback.sh
|
||||
mode: "0700"
|
||||
owner: root
|
||||
group: root
|
||||
|
||||
# --- À partir d'ici : modifications du pare-feu et de SSH. ---
|
||||
# Règle 4 (anti-coupure) : on arme un retour automatique avant de toucher à quoi
|
||||
# que ce soit, et on ne l'annule qu'après avoir vérifié l'accès depuis une
|
||||
# session SSH toute neuve (voir la vérification plus bas, delegate_to: localhost).
|
||||
|
||||
- name: armer le filet de sécurité ({{ durcissement_delai_filet_secondes }} s)
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
systemd-run --unit=durcissement-rollback
|
||||
--on-active={{ durcissement_delai_filet_secondes }}
|
||||
/usr/local/sbin/durcissement-rollback.sh
|
||||
become: true
|
||||
changed_when: true
|
||||
|
||||
- name: déployer la politique de pare-feu nftables
|
||||
ansible.builtin.template:
|
||||
src: nftables.conf.j2
|
||||
dest: /etc/nftables.conf
|
||||
mode: "0640"
|
||||
owner: root
|
||||
group: root
|
||||
validate: "nft -c -f %s"
|
||||
notify: recharger nftables
|
||||
|
||||
- name: appliquer le pare-feu immédiatement
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: déployer la configuration SSH durcie
|
||||
ansible.builtin.template:
|
||||
src: sshd-durcissement.conf.j2
|
||||
dest: /etc/ssh/sshd_config.d/99-durcissement.conf
|
||||
mode: "0644"
|
||||
owner: root
|
||||
group: root
|
||||
register: durcissement_sshd_conf
|
||||
notify: recharger ssh
|
||||
|
||||
- name: valider la syntaxe sshd avant de recharger
|
||||
ansible.builtin.command: sshd -t
|
||||
become: true
|
||||
changed_when: false
|
||||
|
||||
- name: appliquer la configuration SSH
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: pause avant vérification (laisser les services redémarrer)
|
||||
ansible.builtin.pause:
|
||||
seconds: 3
|
||||
|
||||
- name: "vérification : nouvelle connexion SSH par clé (depuis le Mac)"
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
ssh -o IdentitiesOnly=yes -o IdentityFile=~/.ssh/id_ed25519_claude
|
||||
-o ControlMaster=no -o ControlPath=none -o BatchMode=yes
|
||||
-o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new
|
||||
adam@163.172.4.195 echo CONNEXION_CLE_OK
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: durcissement_verif_cle
|
||||
changed_when: false
|
||||
|
||||
- name: "vérification : le mot de passe est refusé"
|
||||
# BatchMode empêche seulement l'invite interactive ; le serveur annonce quand
|
||||
# même au client les méthodes qu'il accepte. On vérifie donc le contenu du
|
||||
# message d'erreur ("password" ne doit plus y figurer), pas seulement le rc.
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
ssh -o IdentitiesOnly=yes -o PubkeyAuthentication=no
|
||||
-o PreferredAuthentications=password,keyboard-interactive
|
||||
-o BatchMode=yes -o ConnectTimeout=10
|
||||
adam@163.172.4.195 echo NE_DOIT_PAS_S_AFFICHER
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: durcissement_verif_mdp
|
||||
changed_when: false
|
||||
failed_when: >
|
||||
durcissement_verif_mdp.rc == 0 or
|
||||
'password' in durcissement_verif_mdp.stderr
|
||||
|
||||
- name: "vérification : root est refusé"
|
||||
ansible.builtin.command:
|
||||
cmd: >
|
||||
ssh -o IdentitiesOnly=yes -o BatchMode=yes -o ConnectTimeout=10
|
||||
-o StrictHostKeyChecking=accept-new
|
||||
root@163.172.4.195 echo NE_DOIT_PAS_S_AFFICHER
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: durcissement_verif_root
|
||||
changed_when: false
|
||||
failed_when: durcissement_verif_root.rc == 0
|
||||
|
||||
- name: "vérification : seuls 22, 80, 443 sont ouverts (nmap depuis le Mac)"
|
||||
# -p- (65535 ports) est beaucoup trop lent face à une politique "drop" : chaque
|
||||
# port fermé attend le timeout au lieu d'un rejet immédiat, et ça dépasse le
|
||||
# délai du filet de sécurité avant même d'avoir fini de scanner. Les 1000 ports
|
||||
# les plus courants (défaut de nmap) suffisent à vérifier qu'il n'y a rien
|
||||
# d'inattendu, et -T4 accélère le scan.
|
||||
ansible.builtin.command:
|
||||
cmd: nmap -Pn -T4 --open 163.172.4.195
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: durcissement_verif_nmap
|
||||
changed_when: false
|
||||
|
||||
- name: afficher le résultat nmap
|
||||
ansible.builtin.debug:
|
||||
var: durcissement_verif_nmap.stdout_lines
|
||||
|
||||
- name: désarmer le filet de sécurité (tout est vérifié)
|
||||
ansible.builtin.command:
|
||||
cmd: systemctl stop durcissement-rollback.timer
|
||||
become: true
|
||||
changed_when: true
|
||||
Loading…
Add table
Add a link
Reference in a new issue