diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e10d28d --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +*.retry +.vault-pass +facts_cache/ +*.vault +*.secret +*.pem +*.key +*.p12 +*.pfx +.env +.env.* +id_rsa +id_ed25519 +__pycache__/ +*.pyc +*.swp +*.swo +*~ +.vscode/ +.idea/ +tmp/ +dist/ +*.tar +*.tar.gz +*.zip diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c313ac..c5f6e6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ ## 2026-06-19 ### Ajouté -- Ajout d’une structure globale pour `Set-OPS`. -- Ajout d’un espace dédié aux templates VM sans rendre le dépôt exclusif à Proxmox. -- Ajout des playbooks `vm_templates/debian13_proxmox_*`. -- Ajout de rôles classés par domaine : `base`, `security`, `vm_template`. +- Structure initiale globale du dépôt Set-OPS. +- Playbooks de création du template Debian 13 Proxmox. +- Rôles de base Debian. +- Rôles de hardening template-safe. +- Playbook de vérification. +- Playbook de nettoyage final avant conversion en template. diff --git a/CLAUDE.md b/CLAUDE.md index 4b0776d..164f9f2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,221 +1,19 @@ # CLAUDE.md — Set-OPS -## Instruction principale +Claude Code doit lire et respecter `AGENTS.md`. -Claude Code doit lire et respecter `AGENTS.md` avant toute modification dans ce dépôt. +`AGENTS.md` est la source d'autorité principale. -`AGENTS.md` est la source d’autorité principale pour : - -- les principes Ansible ; -- la structure du dépôt ; -- les règles de sécurité ; -- les conventions de nommage ; -- la gestion du `CHANGELOG.md` ; -- les limites sur les actions destructives ; -- la règle : Codex ou Claude Code, jamais les deux en même temps. - -En cas de contradiction entre `CLAUDE.md` et `AGENTS.md`, suivre `AGENTS.md`. - ---- - -## Règle d’or IA - -Un seul agent IA travaille dans ce dépôt à la fois. - -- Soit Codex. -- Soit Claude Code. -- Jamais les deux simultanément. - -Avant de modifier quoi que ce soit, vérifier l’état du dépôt : - -```bash -git status --short -``` - -Ne pas continuer si des changements non compris sont présents. - ---- - -## Comportement attendu de Claude Code - -Avant de modifier : +Avant modification : 1. Lire `AGENTS.md`. -2. Lire `README.md`, `CHANGELOG.md` et `ansible.cfg` s’ils existent. -3. Inspecter l’arborescence existante. -4. Identifier la portée exacte de la demande. -5. Proposer le plus petit changement utile. -6. Préserver les conventions existantes. -7. Ne pas réorganiser massivement le dépôt sans demande explicite. +2. Lire `README.md`, `CHANGELOG.md` et `ansible.cfg`. +3. Vérifier `git status --short`. +4. Proposer le plus petit changement utile. Après modification : 1. Résumer les fichiers modifiés. 2. Indiquer les commandes de validation. -3. Signaler clairement ce qui n’a pas été testé. +3. Signaler ce qui n'a pas été testé. 4. Mettre à jour `CHANGELOG.md` si pertinent. - ---- - -## Limites de sécurité - -Ne jamais commiter ou générer : - -- mots de passe ; -- clés privées SSH ; -- tokens API ; -- secrets non chiffrés ; -- fichiers `.env` sensibles ; -- certificats privés ; -- backups réels ; -- exports de production non anonymisés ; -- fichiers contenant des informations confidentielles de Chezlepro Inc. - -Toute variable sensible doit être gérée hors dépôt ou avec un mécanisme explicitement prévu, par exemple : - -- Ansible Vault ; -- fichier local non versionné ; -- secret injecté hors dépôt. - ---- - -## Actions destructives - -Toute action pouvant causer une perte d’accès, de données ou de disponibilité doit être protégée. - -Exemples : - -- suppression de paquets critiques ; -- modification SSH bloquante ; -- modification firewall ; -- redémarrage massif ; -- formatage disque ; -- modification de partitions ; -- suppression d’utilisateurs ; -- purge de données ; -- changement réseau pouvant couper l’accès. - -Pour ces actions, exiger une confirmation explicite ou une variable du type : - -```yaml -confirm_destructive_action: true -``` - -Sans cette confirmation, refuser l’exécution. - ---- - -## SSH - -État transitoire accepté pendant la construction : - -```text -PasswordAuthentication yes -``` - -État cible recommandé : - -```text -PermitRootLogin no -PubkeyAuthentication yes -PasswordAuthentication no -``` - -Ne jamais désactiver l’authentification par mot de passe avant d’avoir confirmé que l’accès SSH par clé fonctionne. - ---- - -## Sudo - -Le compte technique `ansible` peut être configuré avec sudo sans mot de passe lorsque c’est requis pour l’automatisation : - -```text -ansible ALL=(ALL) NOPASSWD:ALL -``` - -Cette règle doit être placée dans : - -```text -/etc/sudoers.d/90-ansible -``` - -Toujours valider avec : - -```bash -visudo -cf /etc/sudoers.d/90-ansible -``` - ---- - -## Ansible - -Les playbooks doivent rester : - -- idempotents ; -- lisibles ; -- sobres ; -- compatibles Debian 13 sauf exception documentée ; -- testables avec `--check` autant que possible ; -- exempts de dépendances SaaS ou cloud inutiles. - -Préférer les modules `ansible.builtin.*`. - -Éviter `shell` et `command` sauf nécessité réelle. Si une commande shell est utilisée, elle doit être encadrée avec les paramètres appropriés : - -- `changed_when` -- `failed_when` -- `creates` -- `removes` - ---- - -## Validation minimale - -Avant de considérer une modification comme terminée, tenter les validations pertinentes : - -```bash -ansible-playbook --syntax-check playbooks/nom.yml -ansible-playbook -i inventories/lab/hosts.yml playbooks/nom.yml --check -ansible-lint -``` - -Si une commande de validation n’a pas été exécutée ou si un outil est absent, le signaler clairement. - ---- - -## CHANGELOG - -Chaque modification significative doit être inscrite dans `CHANGELOG.md`. - -Format recommandé : - -```markdown -## YYYY-MM-DD - -### Ajouté -- ... - -### Modifié -- ... - -### Corrigé -- ... -``` - ---- - -## Résumé opérationnel - -Set-OPS est un dépôt d’exploitation réelle pour les serveurs de Chezlepro Inc. - -Priorités : - -- reproductibilité ; -- sobriété ; -- clarté ; -- sécurité ; -- maintenance ; -- autonomie ; -- résilience. - -La complexité doit toujours être justifiée par un bénéfice opérationnel clair. diff --git a/README.md b/README.md index 2eddcaf..27165c3 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,23 @@ -# Set-OPS — exploitation Ansible Chezlepro +# Set-OPS -`Set-OPS` est le dépôt Ansible central pour construire, configurer, maintenir et documenter les systèmes de Chezlepro Inc. +Dépôt Ansible central pour construire, configurer, maintenir et documenter les systèmes de Chezlepro Inc. -Ce dépôt n’est pas exclusif à la création du template Proxmox. -Le template Debian 13 n’est qu’un premier chantier dans une structure plus large. +## Domaines prévus -## Portée du dépôt +- templates de VM Proxmox ; +- socle Debian ; +- hardening ; +- maintenance ; +- web ; +- bases de données ; +- monitoring ; +- sauvegardes ; +- identité ; +- applications. -Le dépôt doit pouvoir accueillir progressivement : +## Premier chantier -- les templates de VM Proxmox ; -- les socles Debian ; -- le durcissement SSH ; -- les utilisateurs et sudo ; -- le reverse proxy ; -- les serveurs web statiques ; -- les bases de données ; -- la supervision ; -- les sauvegardes ; -- les services applicatifs ; -- les tâches de maintenance ; -- les validations et audits ; -- la documentation d’exploitation. - -## Principe d’organisation - -Les playbooks sont classés par domaine fonctionnel : - -```text -playbooks/ -├── bootstrap/ -├── baseline/ -├── hardening/ -├── maintenance/ -├── monitoring/ -├── networking/ -├── storage/ -├── proxmox/ -├── vm_templates/ -├── web/ -├── database/ -├── identity/ -├── backup/ -└── applications/ -``` - -Les rôles sont également classés par domaine : - -```text -roles/ -├── base/ -├── security/ -├── proxmox/ -├── vm_template/ -├── web/ -├── database/ -├── monitoring/ -├── backup/ -├── identity/ -├── storage/ -└── applications/ -``` - -## Template Debian 13 Proxmox - -La préparation du modèle Debian 13 se trouve dans : +Template Debian 13 Proxmox : ```text playbooks/vm_templates/debian13_proxmox_prepare.yml @@ -72,16 +25,15 @@ playbooks/vm_templates/debian13_proxmox_verify.yml playbooks/vm_templates/debian13_proxmox_cleanup.yml ``` -Les rôles associés se trouvent principalement dans : +## Principe -```text -roles/base/ -roles/security/ -roles/vm_template/ -``` +Le template contient seulement le socle commun. -## Règle importante +Les services spécialisés seront installés ensuite sur les clones : -Le template de VM doit contenir seulement le socle commun. - -Les logiciels applicatifs lourds — NGINX, PostgreSQL, MariaDB, Docker/Podman, Redis, Nextcloud, GitLab, monitoring complet — doivent être installés par des playbooks dédiés sur les clones, pas directement dans le template. +- NGINX ; +- PostgreSQL ; +- MariaDB ; +- Docker/Podman ; +- monitoring complet ; +- applications métier. diff --git a/SOLUTION.md b/SOLUTION.md new file mode 100644 index 0000000..5731100 --- /dev/null +++ b/SOLUTION.md @@ -0,0 +1,62 @@ +# La solution Set-OPS + +## Décision + +`Set-OPS` est le dépôt Ansible global de Chezlepro Inc. + +Le template Debian 13 Proxmox est seulement un chantier dans ce dépôt. + +## Ce qu'on fait maintenant + +On garde une seule structure simple : + +```text +inventories/ +playbooks/ +roles/ +docs/ +``` + +Les rôles sont nommés clairement, sans sous-arborescence complexe. + +## Commande principale pour construire le template + +```bash +ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml --ask-pass --ask-become-pass +``` + +Après que sudo sans mot de passe fonctionne : + +```bash +ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml +``` + +## Vérification + +```bash +ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_verify.yml +``` + +## Nettoyage final avant conversion + +```bash +ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_cleanup.yml -e confirm_template_cleanup=true +``` + +Ensuite : + +```bash +sudo shutdown -h now +``` + +Puis côté Proxmox : + +```bash +qm template VMID +``` + +## Important + +Le pare-feu `nftables` est installé et préparé, mais il n'est pas activé par défaut dans le template. + +C'est volontaire pour éviter de couper SSH pendant la construction. diff --git a/docs/architecture-set-ops.md b/docs/architecture-set-ops.md index f1f620b..8644468 100644 --- a/docs/architecture-set-ops.md +++ b/docs/architecture-set-ops.md @@ -1,26 +1,18 @@ # Architecture Set-OPS -`Set-OPS` est un dépôt global d’exploitation. +Set-OPS est un dépôt global d'exploitation. ## Domaines ```text -bootstrap : premier accès, comptes, prérequis baseline : socle commun Debian -hardening : sécurité et durcissement -maintenance : mises à jour, nettoyage, redémarrages contrôlés +hardening : sécurité +maintenance : mises à jour monitoring : supervision -networking : DNS, pare-feu, réseau -storage : stockage, montages, clients -proxmox : opérations hyperviseur +proxmox : hyperviseurs vm_templates : modèles de VM -web : NGINX, sites, reverse proxy -database : PostgreSQL, MariaDB -identity : IAM, Keycloak, annuaires +web : services web +database : bases de données backup : sauvegardes applications : services applicatifs ``` - -## Règle - -Le template Debian 13 Proxmox est un composant de `Set-OPS`, pas le dépôt au complet. diff --git a/docs/vm_templates/debian13-proxmox.md b/docs/vm_templates/debian13-proxmox.md index 54e8231..cdcd414 100644 --- a/docs/vm_templates/debian13-proxmox.md +++ b/docs/vm_templates/debian13-proxmox.md @@ -1,29 +1,19 @@ # Template Debian 13 Proxmox -## Playbooks - -Préparation : +## Préparation ```bash ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml --ask-pass --ask-become-pass ``` -Vérification : +## Vérification ```bash ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_verify.yml ``` -Nettoyage final : +## Nettoyage ```bash ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_cleanup.yml -e confirm_template_cleanup=true ``` - -## Conversion Proxmox - -Après extinction : - -```bash -qm template VMID -``` diff --git a/inventories/lab/group_vars/all.yml b/inventories/lab/group_vars/all.yml index 4014ef3..068b6ff 100644 --- a/inventories/lab/group_vars/all.yml +++ b/inventories/lab/group_vars/all.yml @@ -2,17 +2,59 @@ chezlepro_timezone: "America/Toronto" chezlepro_admin_user: "ansible" +# SSH pendant la construction du template. +# Passer à "no" seulement après validation des clés SSH. +chezlepro_ssh_port: 22 chezlepro_ssh_password_authentication: "yes" chezlepro_ssh_permit_root_login: "no" chezlepro_ssh_pubkey_authentication: "yes" +chezlepro_ssh_client_alive_interval: 300 +chezlepro_ssh_client_alive_count_max: 2 +chezlepro_ssh_max_auth_tries: 4 +chezlepro_ssh_login_grace_time: "30s" +# systemd-ssh-generator / VSOCK chezlepro_disable_systemd_ssh_auto: true +# Cloud-init cloud_init_ssh_pwauth: true cloud_init_manage_etc_hosts: true cloud_init_disable_root: true cloud_init_ssh_deletekeys: true +# Pare-feu : préparé mais non activé dans le template. +chezlepro_nftables_enabled: false +chezlepro_firewall_allow_ssh: true +chezlepro_firewall_allow_icmp: true +chezlepro_firewall_input_policy: "drop" +chezlepro_firewall_forward_policy: "drop" +chezlepro_firewall_output_policy: "accept" +chezlepro_firewall_extra_tcp_ports: [] +chezlepro_firewall_extra_udp_ports: [] + +# Fail2ban +chezlepro_fail2ban_enabled: true +chezlepro_fail2ban_bantime: "1h" +chezlepro_fail2ban_findtime: "10m" +chezlepro_fail2ban_maxretry: 5 + +# Sécurité +chezlepro_auditd_enabled: true +chezlepro_apparmor_enabled: true +chezlepro_sysctl_apply: true +chezlepro_disable_core_dumps: true + +# Unattended upgrades +chezlepro_unattended_upgrades_enabled: true +chezlepro_unattended_remove_unused_dependencies: true +chezlepro_unattended_automatic_reboot: false + +# Journald +chezlepro_journald_system_max_use: "200M" +chezlepro_journald_runtime_max_use: "100M" +chezlepro_journald_max_retention_sec: "1month" + +# Nettoyage final confirm_template_cleanup: false chezlepro_common_packages: @@ -62,3 +104,16 @@ chezlepro_common_packages: - unattended-upgrades - apt-listchanges - needrestart + +chezlepro_hardening_packages: + - apparmor + - apparmor-utils + - auditd + - audispd-plugins + - fail2ban + - nftables + - unattended-upgrades + - apt-listchanges + - debsums + - needrestart + - libpam-pwquality diff --git a/inventories/lab/hosts.yml b/inventories/lab/hosts.yml index 2e80014..1cebd2e 100644 --- a/inventories/lab/hosts.yml +++ b/inventories/lab/hosts.yml @@ -3,7 +3,7 @@ all: vm_templates: hosts: basiqueChezlepro: - ansible_host: 192.168.11.150 + ansible_host: 192.168.12.99 ansible_user: ansible ansible_become: true diff --git a/inventories/production/hosts.yml b/inventories/production/hosts.yml index c4d6e7d..3546931 100644 --- a/inventories/production/hosts.yml +++ b/inventories/production/hosts.yml @@ -2,15 +2,11 @@ all: children: vm_templates: hosts: {} - web_servers: hosts: {} - database_servers: hosts: {} - monitoring_servers: hosts: {} - proxmox_hosts: hosts: {} diff --git a/playbooks/applications/README.md b/playbooks/applications/README.md new file mode 100644 index 0000000..53334b4 --- /dev/null +++ b/playbooks/applications/README.md @@ -0,0 +1,3 @@ +# Playbooks applications + +Espace réservé aux futurs playbooks. diff --git a/playbooks/backup/README.md b/playbooks/backup/README.md new file mode 100644 index 0000000..bed2996 --- /dev/null +++ b/playbooks/backup/README.md @@ -0,0 +1,3 @@ +# Playbooks backup + +Espace réservé aux futurs playbooks. diff --git a/playbooks/baseline/debian_common.yml b/playbooks/baseline/debian_common.yml index dc7390a..86c333c 100644 --- a/playbooks/baseline/debian_common.yml +++ b/playbooks/baseline/debian_common.yml @@ -5,6 +5,6 @@ gather_facts: true roles: - - role: base/common_packages - - role: base/chrony - - role: security/ssh_baseline + - common_packages + - chrony + - ssh_baseline diff --git a/playbooks/database/README.md b/playbooks/database/README.md index f87f83b..e402aed 100644 --- a/playbooks/database/README.md +++ b/playbooks/database/README.md @@ -1,9 +1,3 @@ # Playbooks database -Espace réservé aux futurs playbooks de bases de données : - -- PostgreSQL ; -- MariaDB ; -- sauvegardes ; -- réplication ; -- durcissement. +Espace réservé aux futurs playbooks. diff --git a/playbooks/hardening/debian_server_hardening.yml b/playbooks/hardening/debian_server_hardening.yml new file mode 100644 index 0000000..8691fbc --- /dev/null +++ b/playbooks/hardening/debian_server_hardening.yml @@ -0,0 +1,24 @@ +--- +- name: Appliquer le hardening Debian serveur Chezlepro + hosts: all + 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: + - hardening_packages + - sysctl_hardening + - core_dumps + - unattended_upgrades + - apparmor + - auditd + - fail2ban_ssh + - journald + - ssh_hardening + - nftables_baseline diff --git a/playbooks/monitoring/README.md b/playbooks/monitoring/README.md index 3ef5d61..4a6644b 100644 --- a/playbooks/monitoring/README.md +++ b/playbooks/monitoring/README.md @@ -1,9 +1,3 @@ # Playbooks monitoring -Espace réservé aux futurs playbooks de supervision : - -- agents ; -- sondes ; -- Icinga/Nagios ; -- exporters ; -- règles d’alerte. +Espace réservé aux futurs playbooks. diff --git a/playbooks/proxmox/README.md b/playbooks/proxmox/README.md index c15cbfc..121e423 100644 --- a/playbooks/proxmox/README.md +++ b/playbooks/proxmox/README.md @@ -1,5 +1,3 @@ # Playbooks Proxmox -Espace réservé aux opérations Proxmox. - -Attention : les actions sur les hyperviseurs et le stockage doivent être protégées par confirmation explicite. +Espace réservé aux futurs playbooks. diff --git a/playbooks/site.yml b/playbooks/site.yml index b527c62..a179247 100644 --- a/playbooks/site.yml +++ b/playbooks/site.yml @@ -1,12 +1,12 @@ --- -- name: Point d’entrée général Set-OPS +- name: Point d'entrée général Set-OPS hosts: all gather_facts: true become: true tasks: - - name: Afficher un message volontairement non destructif + - name: Message ansible.builtin.debug: msg: - "Set-OPS est un dépôt global." - - "Utiliser un playbook spécialisé : baseline, vm_templates, web, database, monitoring, etc." + - "Utiliser un playbook spécialisé." diff --git a/playbooks/vm_templates/debian13_proxmox_cleanup.yml b/playbooks/vm_templates/debian13_proxmox_cleanup.yml index f0d6871..1f5c420 100644 --- a/playbooks/vm_templates/debian13_proxmox_cleanup.yml +++ b/playbooks/vm_templates/debian13_proxmox_cleanup.yml @@ -5,4 +5,4 @@ gather_facts: true roles: - - role: vm_template/template_cleanup + - template_cleanup diff --git a/playbooks/vm_templates/debian13_proxmox_prepare.yml b/playbooks/vm_templates/debian13_proxmox_prepare.yml index 55a8b7e..f59fbfc 100644 --- a/playbooks/vm_templates/debian13_proxmox_prepare.yml +++ b/playbooks/vm_templates/debian13_proxmox_prepare.yml @@ -9,7 +9,7 @@ ansible.builtin.assert: that: - ansible_facts.distribution == "Debian" - fail_msg: "Ce playbook est prévu pour Debian seulement." + fail_msg: "Ce playbook est prévu pour Debian." - name: Avertir si la version Debian n'est pas 13 ansible.builtin.debug: @@ -17,14 +17,24 @@ when: ansible_facts.distribution_major_version != "13" roles: - - role: base/common_packages - - role: base/qemu_guest_agent - - role: base/cloud_init - - role: security/sudo_ansible - - role: base/chrony - - role: security/ssh_baseline - - role: vm_template/systemd_ssh_auto - - role: base/motd + - common_packages + - qemu_guest_agent + - cloud_init + - sudo_ansible + - chrony + - ssh_baseline + - systemd_ssh_auto + - motd + - hardening_packages + - sysctl_hardening + - core_dumps + - unattended_upgrades + - apparmor + - auditd + - fail2ban_ssh + - journald + - ssh_hardening + - nftables_baseline post_tasks: - name: Afficher le statut cloud-init @@ -37,9 +47,10 @@ ansible.builtin.debug: var: cloud_init_status.stdout_lines - - name: Rappel + - name: Message final ansible.builtin.debug: msg: - "Préparation terminée." - - "Si GRUB a été modifié, redémarrer la VM avant validation finale." - - "Ne pas convertir en template avant le playbook de nettoyage." + - "Redémarrer si GRUB a changé." + - "Ne pas convertir avant le playbook de nettoyage final." + - "nftables est installé mais désactivé par défaut." diff --git a/playbooks/vm_templates/debian13_proxmox_verify.yml b/playbooks/vm_templates/debian13_proxmox_verify.yml index 80694b1..f918b4b 100644 --- a/playbooks/vm_templates/debian13_proxmox_verify.yml +++ b/playbooks/vm_templates/debian13_proxmox_verify.yml @@ -39,3 +39,13 @@ - name: Afficher cloud-init ansible.builtin.debug: var: cloud_init_version.stdout + + - name: Vérifier les erreurs critiques du boot courant + ansible.builtin.command: journalctl -b -p err..alert --no-pager + register: boot_errors + changed_when: false + failed_when: false + + - name: Afficher les erreurs du boot courant + ansible.builtin.debug: + var: boot_errors.stdout_lines diff --git a/playbooks/web/README.md b/playbooks/web/README.md index e7863bc..aea692f 100644 --- a/playbooks/web/README.md +++ b/playbooks/web/README.md @@ -1,9 +1,3 @@ # Playbooks web -Espace réservé aux futurs playbooks web : - -- reverse proxy ; -- NGINX ; -- sites statiques ; -- certificats ; -- publication locale. +Espace réservé aux futurs playbooks. diff --git a/roles/apparmor/README.md b/roles/apparmor/README.md new file mode 100644 index 0000000..2f6ff03 --- /dev/null +++ b/roles/apparmor/README.md @@ -0,0 +1,3 @@ +# Rôle apparmor + +Installe et active AppArmor. diff --git a/roles/apparmor/defaults/main.yml b/roles/apparmor/defaults/main.yml new file mode 100644 index 0000000..28435ea --- /dev/null +++ b/roles/apparmor/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_apparmor_enabled: true diff --git a/roles/apparmor/tasks/main.yml b/roles/apparmor/tasks/main.yml new file mode 100644 index 0000000..3e0972b --- /dev/null +++ b/roles/apparmor/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Installer AppArmor + ansible.builtin.apt: + name: + - apparmor + - apparmor-utils + state: present + +- name: Activer AppArmor + ansible.builtin.systemd: + name: apparmor + enabled: true + state: started + when: chezlepro_apparmor_enabled | bool + failed_when: false diff --git a/roles/auditd/README.md b/roles/auditd/README.md new file mode 100644 index 0000000..a892e78 --- /dev/null +++ b/roles/auditd/README.md @@ -0,0 +1,3 @@ +# Rôle auditd + +Installe auditd et ajoute des règles sobres. diff --git a/roles/auditd/defaults/main.yml b/roles/auditd/defaults/main.yml new file mode 100644 index 0000000..ba35681 --- /dev/null +++ b/roles/auditd/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_auditd_enabled: true diff --git a/roles/auditd/handlers/main.yml b/roles/auditd/handlers/main.yml new file mode 100644 index 0000000..4848348 --- /dev/null +++ b/roles/auditd/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Restart auditd + ansible.builtin.systemd: + name: auditd + state: restarted + failed_when: false diff --git a/roles/auditd/tasks/main.yml b/roles/auditd/tasks/main.yml new file mode 100644 index 0000000..bc3150f --- /dev/null +++ b/roles/auditd/tasks/main.yml @@ -0,0 +1,25 @@ +--- +- name: Installer auditd + ansible.builtin.apt: + name: + - auditd + - audispd-plugins + state: present + +- name: Déployer les règles auditd Chezlepro + ansible.builtin.template: + src: 99-chezlepro.rules.j2 + dest: /etc/audit/rules.d/99-chezlepro.rules + owner: root + group: root + mode: "0640" + notify: Restart auditd + when: chezlepro_auditd_enabled | bool + +- name: Activer auditd + ansible.builtin.systemd: + name: auditd + enabled: true + state: started + when: chezlepro_auditd_enabled | bool + failed_when: false diff --git a/roles/auditd/templates/99-chezlepro.rules.j2 b/roles/auditd/templates/99-chezlepro.rules.j2 new file mode 100644 index 0000000..5cf5a2d --- /dev/null +++ b/roles/auditd/templates/99-chezlepro.rules.j2 @@ -0,0 +1,19 @@ +# Managed by Ansible — Set-OPS +-D +-b 8192 +-f 1 + +-w /etc/passwd -p wa -k identity +-w /etc/group -p wa -k identity +-w /etc/shadow -p wa -k identity +-w /etc/gshadow -p wa -k identity +-w /etc/sudoers -p wa -k sudoers +-w /etc/sudoers.d/ -p wa -k sudoers +-w /etc/ssh/sshd_config -p wa -k sshd +-w /etc/ssh/sshd_config.d/ -p wa -k sshd +-w /etc/apt/ -p wa -k apt-config + +-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change +-a always,exit -F arch=b64 -S sethostname,setdomainname -k system-locale + +-e 1 diff --git a/roles/chrony/README.md b/roles/chrony/README.md new file mode 100644 index 0000000..36dbc45 --- /dev/null +++ b/roles/chrony/README.md @@ -0,0 +1,3 @@ +# Rôle chrony + +Installe et active chrony. diff --git a/roles/chrony/tasks/main.yml b/roles/chrony/tasks/main.yml new file mode 100644 index 0000000..b4ec91b --- /dev/null +++ b/roles/chrony/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: Installer chrony + ansible.builtin.apt: + name: chrony + state: present + +- name: Activer et démarrer chrony + ansible.builtin.systemd: + name: chrony + enabled: true + state: started diff --git a/roles/cloud_init/README.md b/roles/cloud_init/README.md new file mode 100644 index 0000000..b3e52ce --- /dev/null +++ b/roles/cloud_init/README.md @@ -0,0 +1,3 @@ +# Rôle cloud_init + +Installe et configure cloud-init pour Proxmox. diff --git a/roles/cloud_init/defaults/main.yml b/roles/cloud_init/defaults/main.yml new file mode 100644 index 0000000..ca32b5c --- /dev/null +++ b/roles/cloud_init/defaults/main.yml @@ -0,0 +1,5 @@ +--- +cloud_init_ssh_pwauth: true +cloud_init_manage_etc_hosts: true +cloud_init_disable_root: true +cloud_init_ssh_deletekeys: true diff --git a/roles/cloud_init/tasks/main.yml b/roles/cloud_init/tasks/main.yml new file mode 100644 index 0000000..2704d87 --- /dev/null +++ b/roles/cloud_init/tasks/main.yml @@ -0,0 +1,32 @@ +--- +- name: Installer cloud-init et cloud-guest-utils + ansible.builtin.apt: + name: + - cloud-init + - cloud-guest-utils + state: present + +- name: Déployer la configuration cloud-init Chezlepro + ansible.builtin.template: + src: 99_chezlepro.cfg.j2 + dest: /etc/cloud/cloud.cfg.d/99_chezlepro.cfg + owner: root + group: root + mode: "0644" + +- name: Activer les services cloud-init Debian 13 + ansible.builtin.systemd: + name: "{{ item }}" + enabled: true + loop: + - cloud-init-local.service + - cloud-init-main.service + - cloud-init-network.service + - cloud-config.service + - cloud-final.service + failed_when: false + +- name: Vérifier cloud-init + ansible.builtin.command: cloud-init --version + register: cloud_init_version + changed_when: false diff --git a/roles/cloud_init/templates/99_chezlepro.cfg.j2 b/roles/cloud_init/templates/99_chezlepro.cfg.j2 new file mode 100644 index 0000000..cf9f192 --- /dev/null +++ b/roles/cloud_init/templates/99_chezlepro.cfg.j2 @@ -0,0 +1,22 @@ +# Managed by Ansible — Set-OPS + +datasource_list: [ NoCloud, ConfigDrive, None ] + +preserve_hostname: false +manage_etc_hosts: {{ cloud_init_manage_etc_hosts | bool | lower }} +disable_root: {{ cloud_init_disable_root | bool | lower }} +ssh_pwauth: {{ cloud_init_ssh_pwauth | bool | lower }} + +ssh_deletekeys: {{ cloud_init_ssh_deletekeys | bool | lower }} +ssh_genkeytypes: + - rsa + - ecdsa + - ed25519 + +growpart: + mode: auto + devices: + - / + ignore_growroot_disabled: false + +resize_rootfs: true diff --git a/roles/common_packages/README.md b/roles/common_packages/README.md new file mode 100644 index 0000000..df081f9 --- /dev/null +++ b/roles/common_packages/README.md @@ -0,0 +1,3 @@ +# Rôle common_packages + +Installe le socle logiciel commun. diff --git a/roles/common_packages/defaults/main.yml b/roles/common_packages/defaults/main.yml new file mode 100644 index 0000000..60789a8 --- /dev/null +++ b/roles/common_packages/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_common_packages: [] diff --git a/roles/common_packages/tasks/main.yml b/roles/common_packages/tasks/main.yml new file mode 100644 index 0000000..3251f73 --- /dev/null +++ b/roles/common_packages/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Mettre à jour le cache APT + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: Appliquer les mises à jour disponibles + ansible.builtin.apt: + upgrade: full + +- name: Installer les paquets communs + ansible.builtin.apt: + name: "{{ chezlepro_common_packages }}" + state: present + +- name: Supprimer les dépendances devenues inutiles + ansible.builtin.apt: + autoremove: true diff --git a/roles/core_dumps/README.md b/roles/core_dumps/README.md new file mode 100644 index 0000000..d126007 --- /dev/null +++ b/roles/core_dumps/README.md @@ -0,0 +1,3 @@ +# Rôle core_dumps + +Désactive les core dumps. diff --git a/roles/core_dumps/defaults/main.yml b/roles/core_dumps/defaults/main.yml new file mode 100644 index 0000000..55c1b5e --- /dev/null +++ b/roles/core_dumps/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_disable_core_dumps: true diff --git a/roles/core_dumps/tasks/main.yml b/roles/core_dumps/tasks/main.yml new file mode 100644 index 0000000..c26a10d --- /dev/null +++ b/roles/core_dumps/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Désactiver les core dumps via limits.d + ansible.builtin.template: + src: 99-chezlepro-core-dumps.conf.j2 + dest: /etc/security/limits.d/99-chezlepro-core-dumps.conf + owner: root + group: root + mode: "0644" + when: chezlepro_disable_core_dumps | bool + +- name: Configurer systemd-coredump si présent + ansible.builtin.template: + src: coredump.conf.j2 + dest: /etc/systemd/coredump.conf + owner: root + group: root + mode: "0644" + when: chezlepro_disable_core_dumps | bool + failed_when: false diff --git a/roles/core_dumps/templates/99-chezlepro-core-dumps.conf.j2 b/roles/core_dumps/templates/99-chezlepro-core-dumps.conf.j2 new file mode 100644 index 0000000..b9efa30 --- /dev/null +++ b/roles/core_dumps/templates/99-chezlepro-core-dumps.conf.j2 @@ -0,0 +1,3 @@ +# Managed by Ansible — Set-OPS +* hard core 0 +* soft core 0 diff --git a/roles/core_dumps/templates/coredump.conf.j2 b/roles/core_dumps/templates/coredump.conf.j2 new file mode 100644 index 0000000..ef6974a --- /dev/null +++ b/roles/core_dumps/templates/coredump.conf.j2 @@ -0,0 +1,4 @@ +# Managed by Ansible — Set-OPS +[Coredump] +Storage=none +ProcessSizeMax=0 diff --git a/roles/fail2ban_ssh/README.md b/roles/fail2ban_ssh/README.md new file mode 100644 index 0000000..70137d5 --- /dev/null +++ b/roles/fail2ban_ssh/README.md @@ -0,0 +1,3 @@ +# Rôle fail2ban_ssh + +Configure fail2ban pour SSH. diff --git a/roles/fail2ban_ssh/defaults/main.yml b/roles/fail2ban_ssh/defaults/main.yml new file mode 100644 index 0000000..f68e7c1 --- /dev/null +++ b/roles/fail2ban_ssh/defaults/main.yml @@ -0,0 +1,6 @@ +--- +chezlepro_fail2ban_enabled: true +chezlepro_fail2ban_bantime: "1h" +chezlepro_fail2ban_findtime: "10m" +chezlepro_fail2ban_maxretry: 5 +chezlepro_ssh_port: 22 diff --git a/roles/fail2ban_ssh/handlers/main.yml b/roles/fail2ban_ssh/handlers/main.yml new file mode 100644 index 0000000..83fad83 --- /dev/null +++ b/roles/fail2ban_ssh/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart fail2ban + ansible.builtin.systemd: + name: fail2ban + state: restarted diff --git a/roles/fail2ban_ssh/tasks/main.yml b/roles/fail2ban_ssh/tasks/main.yml new file mode 100644 index 0000000..f163cd3 --- /dev/null +++ b/roles/fail2ban_ssh/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Installer fail2ban + ansible.builtin.apt: + name: fail2ban + state: present + +- name: Créer le répertoire jail.d + ansible.builtin.file: + path: /etc/fail2ban/jail.d + state: directory + owner: root + group: root + mode: "0755" + +- name: Déployer la jail SSH Chezlepro + ansible.builtin.template: + src: sshd-chezlepro.local.j2 + dest: /etc/fail2ban/jail.d/sshd-chezlepro.local + owner: root + group: root + mode: "0644" + notify: Restart fail2ban + +- name: Activer fail2ban + ansible.builtin.systemd: + name: fail2ban + enabled: true + state: started + when: chezlepro_fail2ban_enabled | bool diff --git a/roles/fail2ban_ssh/templates/sshd-chezlepro.local.j2 b/roles/fail2ban_ssh/templates/sshd-chezlepro.local.j2 new file mode 100644 index 0000000..9d6db05 --- /dev/null +++ b/roles/fail2ban_ssh/templates/sshd-chezlepro.local.j2 @@ -0,0 +1,9 @@ +# Managed by Ansible — Set-OPS + +[sshd] +enabled = {{ 'true' if chezlepro_fail2ban_enabled | bool else 'false' }} +port = {{ chezlepro_ssh_port }} +backend = systemd +maxretry = {{ chezlepro_fail2ban_maxretry }} +findtime = {{ chezlepro_fail2ban_findtime }} +bantime = {{ chezlepro_fail2ban_bantime }} diff --git a/roles/hardening_packages/README.md b/roles/hardening_packages/README.md new file mode 100644 index 0000000..94bb78c --- /dev/null +++ b/roles/hardening_packages/README.md @@ -0,0 +1,3 @@ +# Rôle hardening_packages + +Installe les paquets de hardening Debian. diff --git a/roles/hardening_packages/defaults/main.yml b/roles/hardening_packages/defaults/main.yml new file mode 100644 index 0000000..a4ed7f3 --- /dev/null +++ b/roles/hardening_packages/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_hardening_packages: [] diff --git a/roles/hardening_packages/tasks/main.yml b/roles/hardening_packages/tasks/main.yml new file mode 100644 index 0000000..d85bf95 --- /dev/null +++ b/roles/hardening_packages/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: Installer les paquets de hardening + ansible.builtin.apt: + name: "{{ chezlepro_hardening_packages }}" + state: present + update_cache: true + cache_valid_time: 3600 diff --git a/roles/journald/README.md b/roles/journald/README.md new file mode 100644 index 0000000..560beda --- /dev/null +++ b/roles/journald/README.md @@ -0,0 +1,3 @@ +# Rôle journald + +Limite et configure journald. diff --git a/roles/journald/defaults/main.yml b/roles/journald/defaults/main.yml new file mode 100644 index 0000000..6c0f443 --- /dev/null +++ b/roles/journald/defaults/main.yml @@ -0,0 +1,4 @@ +--- +chezlepro_journald_system_max_use: "200M" +chezlepro_journald_runtime_max_use: "100M" +chezlepro_journald_max_retention_sec: "1month" diff --git a/roles/journald/handlers/main.yml b/roles/journald/handlers/main.yml new file mode 100644 index 0000000..f9a7600 --- /dev/null +++ b/roles/journald/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart journald + ansible.builtin.systemd: + name: systemd-journald + state: restarted diff --git a/roles/journald/tasks/main.yml b/roles/journald/tasks/main.yml new file mode 100644 index 0000000..7fc604c --- /dev/null +++ b/roles/journald/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Créer le répertoire journald.conf.d + ansible.builtin.file: + path: /etc/systemd/journald.conf.d + state: directory + owner: root + group: root + mode: "0755" + +- name: Déployer la configuration journald Chezlepro + ansible.builtin.template: + src: 99-chezlepro.conf.j2 + dest: /etc/systemd/journald.conf.d/99-chezlepro.conf + owner: root + group: root + mode: "0644" + notify: Restart journald diff --git a/roles/journald/templates/99-chezlepro.conf.j2 b/roles/journald/templates/99-chezlepro.conf.j2 new file mode 100644 index 0000000..96cfac5 --- /dev/null +++ b/roles/journald/templates/99-chezlepro.conf.j2 @@ -0,0 +1,7 @@ +# Managed by Ansible — Set-OPS +[Journal] +SystemMaxUse={{ chezlepro_journald_system_max_use }} +RuntimeMaxUse={{ chezlepro_journald_runtime_max_use }} +MaxRetentionSec={{ chezlepro_journald_max_retention_sec }} +Compress=yes +Seal=yes diff --git a/roles/motd/README.md b/roles/motd/README.md new file mode 100644 index 0000000..8940469 --- /dev/null +++ b/roles/motd/README.md @@ -0,0 +1,3 @@ +# Rôle motd + +Déploie un MOTD simple. diff --git a/roles/motd/tasks/main.yml b/roles/motd/tasks/main.yml new file mode 100644 index 0000000..3814c1d --- /dev/null +++ b/roles/motd/tasks/main.yml @@ -0,0 +1,8 @@ +--- +- name: Déployer le MOTD Chezlepro + ansible.builtin.template: + src: motd.j2 + dest: /etc/motd + owner: root + group: root + mode: "0644" diff --git a/roles/motd/templates/motd.j2 b/roles/motd/templates/motd.j2 new file mode 100644 index 0000000..140d1ad --- /dev/null +++ b/roles/motd/templates/motd.j2 @@ -0,0 +1,2 @@ +Système Chezlepro +Gestion : Set-OPS / Ansible diff --git a/roles/nftables_baseline/README.md b/roles/nftables_baseline/README.md new file mode 100644 index 0000000..a084f2c --- /dev/null +++ b/roles/nftables_baseline/README.md @@ -0,0 +1,3 @@ +# Rôle nftables_baseline + +Prépare nftables. Désactivé par défaut dans le template. diff --git a/roles/nftables_baseline/defaults/main.yml b/roles/nftables_baseline/defaults/main.yml new file mode 100644 index 0000000..288f360 --- /dev/null +++ b/roles/nftables_baseline/defaults/main.yml @@ -0,0 +1,10 @@ +--- +chezlepro_nftables_enabled: false +chezlepro_firewall_allow_ssh: true +chezlepro_firewall_allow_icmp: true +chezlepro_firewall_input_policy: "drop" +chezlepro_firewall_forward_policy: "drop" +chezlepro_firewall_output_policy: "accept" +chezlepro_ssh_port: 22 +chezlepro_firewall_extra_tcp_ports: [] +chezlepro_firewall_extra_udp_ports: [] diff --git a/roles/nftables_baseline/handlers/main.yml b/roles/nftables_baseline/handlers/main.yml new file mode 100644 index 0000000..7abbffa --- /dev/null +++ b/roles/nftables_baseline/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Reload nftables + ansible.builtin.command: nft -f /etc/nftables.conf + changed_when: true diff --git a/roles/nftables_baseline/tasks/main.yml b/roles/nftables_baseline/tasks/main.yml new file mode 100644 index 0000000..440e419 --- /dev/null +++ b/roles/nftables_baseline/tasks/main.yml @@ -0,0 +1,30 @@ +--- +- name: Installer nftables + ansible.builtin.apt: + name: nftables + state: present + +- name: Déployer la configuration nftables Chezlepro + ansible.builtin.template: + src: nftables.conf.j2 + dest: /etc/nftables.conf + owner: root + group: root + mode: "0644" + notify: Reload nftables + when: chezlepro_nftables_enabled | bool + +- name: Activer nftables si demandé + ansible.builtin.systemd: + name: nftables + enabled: true + state: started + when: chezlepro_nftables_enabled | bool + +- name: Désactiver nftables si demandé + ansible.builtin.systemd: + name: nftables + enabled: false + state: stopped + when: not (chezlepro_nftables_enabled | bool) + failed_when: false diff --git a/roles/nftables_baseline/templates/nftables.conf.j2 b/roles/nftables_baseline/templates/nftables.conf.j2 new file mode 100644 index 0000000..602b684 --- /dev/null +++ b/roles/nftables_baseline/templates/nftables.conf.j2 @@ -0,0 +1,39 @@ +#!/usr/sbin/nft -f +# Managed by Ansible — Set-OPS + +flush ruleset + +table inet chezlepro_filter { + chain input { + type filter hook input priority 0; policy {{ chezlepro_firewall_input_policy }}; + + iif "lo" accept + ct state established,related accept + ct state invalid drop + +{% if chezlepro_firewall_allow_icmp | bool %} + ip protocol icmp accept + ip6 nexthdr icmpv6 accept +{% endif %} + +{% if chezlepro_firewall_allow_ssh | bool %} + tcp dport {{ chezlepro_ssh_port }} accept +{% endif %} + +{% for port in chezlepro_firewall_extra_tcp_ports %} + tcp dport {{ port }} accept +{% endfor %} + +{% for port in chezlepro_firewall_extra_udp_ports %} + udp dport {{ port }} accept +{% endfor %} + } + + chain forward { + type filter hook forward priority 0; policy {{ chezlepro_firewall_forward_policy }}; + } + + chain output { + type filter hook output priority 0; policy {{ chezlepro_firewall_output_policy }}; + } +} diff --git a/roles/qemu_guest_agent/README.md b/roles/qemu_guest_agent/README.md new file mode 100644 index 0000000..3131d0b --- /dev/null +++ b/roles/qemu_guest_agent/README.md @@ -0,0 +1,3 @@ +# Rôle qemu_guest_agent + +Installe et active qemu-guest-agent. diff --git a/roles/qemu_guest_agent/tasks/main.yml b/roles/qemu_guest_agent/tasks/main.yml new file mode 100644 index 0000000..6125609 --- /dev/null +++ b/roles/qemu_guest_agent/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: Installer qemu-guest-agent + ansible.builtin.apt: + name: qemu-guest-agent + state: present + +- name: Activer et démarrer qemu-guest-agent + ansible.builtin.systemd: + name: qemu-guest-agent + enabled: true + state: started diff --git a/roles/ssh_baseline/README.md b/roles/ssh_baseline/README.md new file mode 100644 index 0000000..9f72675 --- /dev/null +++ b/roles/ssh_baseline/README.md @@ -0,0 +1,3 @@ +# Rôle ssh_baseline + +Déploie la configuration SSH de base. diff --git a/roles/ssh_baseline/defaults/main.yml b/roles/ssh_baseline/defaults/main.yml new file mode 100644 index 0000000..13c7a1f --- /dev/null +++ b/roles/ssh_baseline/defaults/main.yml @@ -0,0 +1,4 @@ +--- +chezlepro_ssh_password_authentication: "yes" +chezlepro_ssh_permit_root_login: "no" +chezlepro_ssh_pubkey_authentication: "yes" diff --git a/roles/ssh_baseline/handlers/main.yml b/roles/ssh_baseline/handlers/main.yml new file mode 100644 index 0000000..d165557 --- /dev/null +++ b/roles/ssh_baseline/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Validate and reload ssh + block: + - name: Valider la configuration SSH + ansible.builtin.command: sshd -t + changed_when: false + + - name: Recharger SSH + ansible.builtin.systemd: + name: ssh + state: reloaded diff --git a/roles/ssh_baseline/tasks/main.yml b/roles/ssh_baseline/tasks/main.yml new file mode 100644 index 0000000..daddc37 --- /dev/null +++ b/roles/ssh_baseline/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Installer openssh-server + ansible.builtin.apt: + name: openssh-server + state: present + +- name: Créer le répertoire sshd_config.d + ansible.builtin.file: + path: /etc/ssh/sshd_config.d + state: directory + owner: root + group: root + mode: "0755" + +- name: Déployer la configuration SSH Chezlepro + ansible.builtin.template: + src: 10-chezlepro.conf.j2 + dest: /etc/ssh/sshd_config.d/10-chezlepro.conf + owner: root + group: root + mode: "0644" + notify: Validate and reload ssh + +- name: Activer et démarrer SSH + ansible.builtin.systemd: + name: ssh + enabled: true + state: started diff --git a/roles/ssh_baseline/templates/10-chezlepro.conf.j2 b/roles/ssh_baseline/templates/10-chezlepro.conf.j2 new file mode 100644 index 0000000..058168a --- /dev/null +++ b/roles/ssh_baseline/templates/10-chezlepro.conf.j2 @@ -0,0 +1,8 @@ +# Managed by Ansible — Set-OPS + +PermitRootLogin {{ chezlepro_ssh_permit_root_login }} +PubkeyAuthentication {{ chezlepro_ssh_pubkey_authentication }} +PasswordAuthentication {{ chezlepro_ssh_password_authentication }} +KbdInteractiveAuthentication no +X11Forwarding no +UsePAM yes diff --git a/roles/ssh_hardening/README.md b/roles/ssh_hardening/README.md new file mode 100644 index 0000000..969ecc3 --- /dev/null +++ b/roles/ssh_hardening/README.md @@ -0,0 +1,3 @@ +# Rôle ssh_hardening + +Ajoute des réglages SSH plus stricts. diff --git a/roles/ssh_hardening/defaults/main.yml b/roles/ssh_hardening/defaults/main.yml new file mode 100644 index 0000000..e0d55c0 --- /dev/null +++ b/roles/ssh_hardening/defaults/main.yml @@ -0,0 +1,9 @@ +--- +chezlepro_ssh_port: 22 +chezlepro_ssh_password_authentication: "yes" +chezlepro_ssh_permit_root_login: "no" +chezlepro_ssh_pubkey_authentication: "yes" +chezlepro_ssh_client_alive_interval: 300 +chezlepro_ssh_client_alive_count_max: 2 +chezlepro_ssh_max_auth_tries: 4 +chezlepro_ssh_login_grace_time: "30s" diff --git a/roles/ssh_hardening/handlers/main.yml b/roles/ssh_hardening/handlers/main.yml new file mode 100644 index 0000000..d165557 --- /dev/null +++ b/roles/ssh_hardening/handlers/main.yml @@ -0,0 +1,11 @@ +--- +- name: Validate and reload ssh + block: + - name: Valider la configuration SSH + ansible.builtin.command: sshd -t + changed_when: false + + - name: Recharger SSH + ansible.builtin.systemd: + name: ssh + state: reloaded diff --git a/roles/ssh_hardening/tasks/main.yml b/roles/ssh_hardening/tasks/main.yml new file mode 100644 index 0000000..4c635c9 --- /dev/null +++ b/roles/ssh_hardening/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: Déployer le hardening SSH additionnel + ansible.builtin.template: + src: 20-chezlepro-hardening.conf.j2 + dest: /etc/ssh/sshd_config.d/20-chezlepro-hardening.conf + owner: root + group: root + mode: "0644" + notify: Validate and reload ssh diff --git a/roles/ssh_hardening/templates/20-chezlepro-hardening.conf.j2 b/roles/ssh_hardening/templates/20-chezlepro-hardening.conf.j2 new file mode 100644 index 0000000..c10be9f --- /dev/null +++ b/roles/ssh_hardening/templates/20-chezlepro-hardening.conf.j2 @@ -0,0 +1,15 @@ +# Managed by Ansible — Set-OPS + +Port {{ chezlepro_ssh_port }} +PermitRootLogin {{ chezlepro_ssh_permit_root_login }} +PubkeyAuthentication {{ chezlepro_ssh_pubkey_authentication }} +PasswordAuthentication {{ chezlepro_ssh_password_authentication }} +KbdInteractiveAuthentication no +PermitEmptyPasswords no +X11Forwarding no +AllowTcpForwarding no +AllowAgentForwarding no +ClientAliveInterval {{ chezlepro_ssh_client_alive_interval }} +ClientAliveCountMax {{ chezlepro_ssh_client_alive_count_max }} +MaxAuthTries {{ chezlepro_ssh_max_auth_tries }} +LoginGraceTime {{ chezlepro_ssh_login_grace_time }} diff --git a/roles/sudo_ansible/README.md b/roles/sudo_ansible/README.md new file mode 100644 index 0000000..04040d4 --- /dev/null +++ b/roles/sudo_ansible/README.md @@ -0,0 +1,3 @@ +# Rôle sudo_ansible + +Configure sudo NOPASSWD pour le compte technique. diff --git a/roles/sudo_ansible/defaults/main.yml b/roles/sudo_ansible/defaults/main.yml new file mode 100644 index 0000000..d1911fe --- /dev/null +++ b/roles/sudo_ansible/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_admin_user: ansible diff --git a/roles/sudo_ansible/tasks/main.yml b/roles/sudo_ansible/tasks/main.yml new file mode 100644 index 0000000..04638b6 --- /dev/null +++ b/roles/sudo_ansible/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: S'assurer que le groupe sudo existe + ansible.builtin.group: + name: sudo + state: present + +- name: S'assurer que le compte technique existe + ansible.builtin.user: + name: "{{ chezlepro_admin_user }}" + shell: /bin/bash + groups: sudo + append: true + create_home: true + state: present + +- name: Déployer sudo NOPASSWD pour le compte technique + ansible.builtin.template: + src: 90-ansible.j2 + dest: "/etc/sudoers.d/90-{{ chezlepro_admin_user }}" + owner: root + group: root + mode: "0440" + validate: "visudo -cf %s" diff --git a/roles/sudo_ansible/templates/90-ansible.j2 b/roles/sudo_ansible/templates/90-ansible.j2 new file mode 100644 index 0000000..af33be0 --- /dev/null +++ b/roles/sudo_ansible/templates/90-ansible.j2 @@ -0,0 +1,2 @@ +# Managed by Ansible — Set-OPS +{{ chezlepro_admin_user }} ALL=(ALL) NOPASSWD:ALL diff --git a/roles/sysctl_hardening/README.md b/roles/sysctl_hardening/README.md new file mode 100644 index 0000000..6d071da --- /dev/null +++ b/roles/sysctl_hardening/README.md @@ -0,0 +1,3 @@ +# Rôle sysctl_hardening + +Déploie des paramètres sysctl raisonnables. diff --git a/roles/sysctl_hardening/defaults/main.yml b/roles/sysctl_hardening/defaults/main.yml new file mode 100644 index 0000000..8275411 --- /dev/null +++ b/roles/sysctl_hardening/defaults/main.yml @@ -0,0 +1,29 @@ +--- +chezlepro_sysctl_apply: true +chezlepro_sysctl_hardening_values: + fs.protected_hardlinks: 1 + fs.protected_symlinks: 1 + fs.protected_fifos: 2 + fs.protected_regular: 2 + fs.suid_dumpable: 0 + kernel.core_uses_pid: 1 + kernel.ctrl-alt-del: 0 + kernel.dmesg_restrict: 1 + kernel.kptr_restrict: 2 + kernel.perf_event_paranoid: 2 + kernel.randomize_va_space: 2 + net.ipv4.conf.all.accept_redirects: 0 + net.ipv4.conf.default.accept_redirects: 0 + net.ipv6.conf.all.accept_redirects: 0 + net.ipv6.conf.default.accept_redirects: 0 + net.ipv4.conf.all.send_redirects: 0 + net.ipv4.conf.default.send_redirects: 0 + net.ipv4.conf.all.accept_source_route: 0 + net.ipv4.conf.default.accept_source_route: 0 + net.ipv6.conf.all.accept_source_route: 0 + net.ipv6.conf.default.accept_source_route: 0 + net.ipv4.icmp_echo_ignore_broadcasts: 1 + net.ipv4.icmp_ignore_bogus_error_responses: 1 + net.ipv4.tcp_syncookies: 1 + net.ipv4.conf.all.log_martians: 1 + net.ipv4.conf.default.log_martians: 1 diff --git a/roles/sysctl_hardening/handlers/main.yml b/roles/sysctl_hardening/handlers/main.yml new file mode 100644 index 0000000..15d80f0 --- /dev/null +++ b/roles/sysctl_hardening/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Reload sysctl + ansible.builtin.command: sysctl --system + changed_when: true diff --git a/roles/sysctl_hardening/tasks/main.yml b/roles/sysctl_hardening/tasks/main.yml new file mode 100644 index 0000000..9db7c46 --- /dev/null +++ b/roles/sysctl_hardening/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- name: Déployer les paramètres sysctl de hardening + ansible.builtin.template: + src: 99-chezlepro-hardening.conf.j2 + dest: /etc/sysctl.d/99-chezlepro-hardening.conf + owner: root + group: root + mode: "0644" + notify: Reload sysctl + when: chezlepro_sysctl_apply | bool diff --git a/roles/sysctl_hardening/templates/99-chezlepro-hardening.conf.j2 b/roles/sysctl_hardening/templates/99-chezlepro-hardening.conf.j2 new file mode 100644 index 0000000..2dc837e --- /dev/null +++ b/roles/sysctl_hardening/templates/99-chezlepro-hardening.conf.j2 @@ -0,0 +1,5 @@ +# Managed by Ansible — Set-OPS + +{% for key, value in chezlepro_sysctl_hardening_values | dictsort %} +{{ key }} = {{ value }} +{% endfor %} diff --git a/roles/systemd_ssh_auto/README.md b/roles/systemd_ssh_auto/README.md new file mode 100644 index 0000000..1321b33 --- /dev/null +++ b/roles/systemd_ssh_auto/README.md @@ -0,0 +1,3 @@ +# Rôle systemd_ssh_auto + +Désactive systemd.ssh_auto pour éviter le bruit SSH/VSOCK. diff --git a/roles/systemd_ssh_auto/defaults/main.yml b/roles/systemd_ssh_auto/defaults/main.yml new file mode 100644 index 0000000..91ed923 --- /dev/null +++ b/roles/systemd_ssh_auto/defaults/main.yml @@ -0,0 +1,2 @@ +--- +chezlepro_disable_systemd_ssh_auto: true diff --git a/roles/systemd_ssh_auto/handlers/main.yml b/roles/systemd_ssh_auto/handlers/main.yml new file mode 100644 index 0000000..1567104 --- /dev/null +++ b/roles/systemd_ssh_auto/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Update grub + ansible.builtin.command: update-grub + changed_when: true diff --git a/roles/systemd_ssh_auto/tasks/main.yml b/roles/systemd_ssh_auto/tasks/main.yml new file mode 100644 index 0000000..180de1b --- /dev/null +++ b/roles/systemd_ssh_auto/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: Déployer le paramètre GRUB pour désactiver systemd.ssh_auto + ansible.builtin.template: + src: 99-chezlepro-systemd-ssh-auto.cfg.j2 + dest: /etc/default/grub.d/99-chezlepro-systemd-ssh-auto.cfg + owner: root + group: root + mode: "0644" + when: chezlepro_disable_systemd_ssh_auto | bool + notify: Update grub + +- name: Supprimer le paramètre si désactivé + ansible.builtin.file: + path: /etc/default/grub.d/99-chezlepro-systemd-ssh-auto.cfg + state: absent + when: not (chezlepro_disable_systemd_ssh_auto | bool) + notify: Update grub diff --git a/roles/systemd_ssh_auto/templates/99-chezlepro-systemd-ssh-auto.cfg.j2 b/roles/systemd_ssh_auto/templates/99-chezlepro-systemd-ssh-auto.cfg.j2 new file mode 100644 index 0000000..afbac27 --- /dev/null +++ b/roles/systemd_ssh_auto/templates/99-chezlepro-systemd-ssh-auto.cfg.j2 @@ -0,0 +1,2 @@ +# Managed by Ansible — Set-OPS +GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} systemd.ssh_auto=no" diff --git a/roles/template_cleanup/README.md b/roles/template_cleanup/README.md new file mode 100644 index 0000000..f0e2fcb --- /dev/null +++ b/roles/template_cleanup/README.md @@ -0,0 +1,3 @@ +# Rôle template_cleanup + +Nettoyage final avant conversion Proxmox. diff --git a/roles/template_cleanup/defaults/main.yml b/roles/template_cleanup/defaults/main.yml new file mode 100644 index 0000000..f98f4b9 --- /dev/null +++ b/roles/template_cleanup/defaults/main.yml @@ -0,0 +1,3 @@ +--- +confirm_template_cleanup: false +chezlepro_admin_user: ansible diff --git a/roles/template_cleanup/tasks/main.yml b/roles/template_cleanup/tasks/main.yml new file mode 100644 index 0000000..935709b --- /dev/null +++ b/roles/template_cleanup/tasks/main.yml @@ -0,0 +1,63 @@ +--- +- name: Refuser le nettoyage sans confirmation explicite + ansible.builtin.assert: + that: + - confirm_template_cleanup | bool + fail_msg: "Nettoyage refusé. Relancer avec -e confirm_template_cleanup=true" + +- name: Nettoyer cloud-init + ansible.builtin.command: cloud-init clean --logs + changed_when: true + +- name: Nettoyer le cache APT + ansible.builtin.apt: + clean: true + +- name: Supprimer les paquets devenus inutiles + ansible.builtin.apt: + autoremove: true + +- name: Rotation des journaux systemd + ansible.builtin.command: journalctl --rotate + changed_when: true + failed_when: false + +- name: Vider les anciens journaux systemd + ansible.builtin.command: journalctl --vacuum-time=1s + changed_when: true + failed_when: false + +- name: Vider /etc/machine-id + ansible.builtin.copy: + dest: /etc/machine-id + content: "" + owner: root + group: root + mode: "0444" + +- name: Supprimer l'ancien machine-id D-Bus + ansible.builtin.file: + path: /var/lib/dbus/machine-id + state: absent + +- name: Recréer le lien D-Bus vers /etc/machine-id + ansible.builtin.file: + src: /etc/machine-id + dest: /var/lib/dbus/machine-id + state: link + force: true + +- name: Supprimer les historiques shell + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - /root/.bash_history + - "/home/{{ chezlepro_admin_user }}/.bash_history" + failed_when: false + +- name: Message final + ansible.builtin.debug: + msg: + - "Nettoyage final terminé." + - "Éteindre la VM puis convertir en template Proxmox." diff --git a/roles/unattended_upgrades/README.md b/roles/unattended_upgrades/README.md new file mode 100644 index 0000000..b6a8e26 --- /dev/null +++ b/roles/unattended_upgrades/README.md @@ -0,0 +1,3 @@ +# Rôle unattended_upgrades + +Configure les mises à jour automatiques de sécurité. diff --git a/roles/unattended_upgrades/defaults/main.yml b/roles/unattended_upgrades/defaults/main.yml new file mode 100644 index 0000000..c03d4c0 --- /dev/null +++ b/roles/unattended_upgrades/defaults/main.yml @@ -0,0 +1,4 @@ +--- +chezlepro_unattended_upgrades_enabled: true +chezlepro_unattended_remove_unused_dependencies: true +chezlepro_unattended_automatic_reboot: false diff --git a/roles/unattended_upgrades/tasks/main.yml b/roles/unattended_upgrades/tasks/main.yml new file mode 100644 index 0000000..8ec10bf --- /dev/null +++ b/roles/unattended_upgrades/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Installer unattended-upgrades + ansible.builtin.apt: + name: + - unattended-upgrades + - apt-listchanges + state: present + +- name: Configurer les mises à jour automatiques + ansible.builtin.template: + src: 20auto-upgrades.j2 + dest: /etc/apt/apt.conf.d/20auto-upgrades + owner: root + group: root + mode: "0644" + +- name: Configurer unattended-upgrades + ansible.builtin.template: + src: 50unattended-upgrades.j2 + dest: /etc/apt/apt.conf.d/50unattended-upgrades + owner: root + group: root + mode: "0644" diff --git a/roles/unattended_upgrades/templates/20auto-upgrades.j2 b/roles/unattended_upgrades/templates/20auto-upgrades.j2 new file mode 100644 index 0000000..4688423 --- /dev/null +++ b/roles/unattended_upgrades/templates/20auto-upgrades.j2 @@ -0,0 +1,4 @@ +// Managed by Ansible — Set-OPS +APT::Periodic::Update-Package-Lists "{{ 1 if chezlepro_unattended_upgrades_enabled | bool else 0 }}"; +APT::Periodic::Unattended-Upgrade "{{ 1 if chezlepro_unattended_upgrades_enabled | bool else 0 }}"; +APT::Periodic::AutocleanInterval "7"; diff --git a/roles/unattended_upgrades/templates/50unattended-upgrades.j2 b/roles/unattended_upgrades/templates/50unattended-upgrades.j2 new file mode 100644 index 0000000..9f8f9bb --- /dev/null +++ b/roles/unattended_upgrades/templates/50unattended-upgrades.j2 @@ -0,0 +1,11 @@ +// Managed by Ansible — Set-OPS + +Unattended-Upgrade::Origins-Pattern { + "origin=Debian,codename=${distro_codename}-security,label=Debian-Security"; +}; + +Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; +Unattended-Upgrade::Remove-New-Unused-Dependencies "{{ 'true' if chezlepro_unattended_remove_unused_dependencies | bool else 'false' }}"; +Unattended-Upgrade::Remove-Unused-Dependencies "{{ 'true' if chezlepro_unattended_remove_unused_dependencies | bool else 'false' }}"; +Unattended-Upgrade::Automatic-Reboot "{{ 'true' if chezlepro_unattended_automatic_reboot | bool else 'false' }}"; +Unattended-Upgrade::SyslogEnable "true";