chore: update and add playbook haproxy

This commit is contained in:
Nuxgrid
2026-07-30 19:04:12 +02:00
parent 76592a5c12
commit ec59d5933b
4 changed files with 182 additions and 1 deletions
+48
View File
@@ -0,0 +1,48 @@
---
# Les ports 80/443 sont publiés par Docker (docker-compose du conteneur waf), donc
# UFW seul ne suffit pas : Docker insère ses propres règles NAT/FORWARD directement
# dans iptables et les contourne. On filtre donc dans la chaîne DOCKER-USER, seul
# point garanti d'être évalué avant les règles de Docker.
#
# Résultat : seul le load-balancer (IP VPN) peut atteindre 80/443 sur ces hôtes,
# tout le reste d'internet est bloqué. SSH et le reste du trafic ne sont pas touchés.
- name: Restreindre l'accès HTTP/HTTPS des serveurs applicatifs au load-balancer
hosts: prod:replica-prod
become: true
gather_facts: false
vars:
lb_vpn_ip: "{{ hostvars['load-balancer']['vpn_ip'] }}"
tasks:
- name: Installer iptables-persistent
ansible.builtin.apt:
name: iptables-persistent
state: present
update_cache: yes
- name: Bloquer les connexions 80/443 non issues du load-balancer
ansible.builtin.iptables:
chain: DOCKER-USER
protocol: tcp
match: multiport
destination_ports: "80,443"
jump: DROP
action: insert
comment: "app-firewall: bloque 80/443 hors load-balancer"
- name: Autoriser les connexions 80/443 depuis le load-balancer (VPN)
ansible.builtin.iptables:
chain: DOCKER-USER
protocol: tcp
source: "{{ lb_vpn_ip }}/32"
match: multiport
destination_ports: "80,443"
jump: RETURN
action: insert
comment: "app-firewall: autorise 80/443 depuis le load-balancer"
- name: Sauvegarder les règles iptables (persistance au reboot)
ansible.builtin.command: netfilter-persistent save
changed_when: false
+127
View File
@@ -0,0 +1,127 @@
---
# Le certificat mln-uber.club n'est pas généré ici : il existe déjà sur prod-uber
# (utilisé par le conteneur waf du docker-compose). On le récupère et on le copie
# vers le load-balancer. Relancer ce playbook après chaque renouvellement du cert
# sur prod-uber pour resynchroniser HAProxy.
- name: Récupérer le certificat mln-uber.club depuis prod-uber
hosts: prod-uber
become: true
gather_facts: false
vars:
# À CONFIRMER : chemin réel du cert sur prod-uber (aucun playbook ne le dépose
# actuellement à cet endroit — à ajuster si différent).
app_cert_dir: "{{ docker_dir }}/certs"
local_cert_sync_dir: /tmp/mln-uber-cert-sync
tasks:
- name: Créer le dossier temporaire local de synchronisation
ansible.builtin.file:
path: "{{ local_cert_sync_dir }}"
state: directory
mode: "0700"
delegate_to: localhost
become: false
- name: Rapatrier fullchain.pem et privkey.pem
ansible.builtin.fetch:
src: "{{ app_cert_dir }}/{{ item }}"
dest: "{{ local_cert_sync_dir }}/{{ item }}"
flat: true
loop:
- fullchain.pem
- privkey.pem
- name: Restreindre les permissions locales de la clé privée
ansible.builtin.file:
path: "{{ local_cert_sync_dir }}/privkey.pem"
mode: "0600"
delegate_to: localhost
become: false
- name: Déploiement HAProxy (load-balancer)
hosts: load-balancer
become: true
gather_facts: true
vars:
haproxy_cert_dir: /etc/haproxy/certs
haproxy_cert_path: "{{ haproxy_cert_dir }}/{{ domain_name }}.pem"
local_cert_sync_dir: /tmp/mln-uber-cert-sync
tasks:
- name: Installer HAProxy
ansible.builtin.apt:
name: haproxy
state: present
update_cache: yes
- name: Créer le dossier des certificats HAProxy
ansible.builtin.file:
path: "{{ haproxy_cert_dir }}"
state: directory
owner: root
group: root
mode: "0750"
- name: Copier fullchain.pem et privkey.pem sur le load-balancer
ansible.builtin.copy:
src: "{{ local_cert_sync_dir }}/{{ item }}"
dest: "{{ haproxy_cert_dir }}/{{ item }}"
owner: root
group: root
mode: "0640"
loop:
- fullchain.pem
- privkey.pem
notify: reload haproxy
- name: Construire le certificat combiné pour HAProxy (fullchain + privkey)
ansible.builtin.shell: >
cat {{ haproxy_cert_dir }}/fullchain.pem
{{ haproxy_cert_dir }}/privkey.pem
> {{ haproxy_cert_path }}
notify: reload haproxy
- name: Restreindre les permissions du certificat combiné
ansible.builtin.file:
path: "{{ haproxy_cert_path }}"
owner: root
group: root
mode: "0640"
- name: Ouvrir le port HTTPS dans UFW
ansible.builtin.ufw:
rule: allow
port: "443"
proto: tcp
- name: Déployer la configuration HAProxy
ansible.builtin.template:
src: ../templates/haproxy.cfg.j2
dest: /etc/haproxy/haproxy.cfg
owner: root
group: root
mode: "0644"
validate: haproxy -c -f %s
notify: reload haproxy
- name: Démarrer et activer HAProxy
ansible.builtin.systemd:
name: haproxy
state: started
enabled: yes
- name: Nettoyer les fichiers temporaires locaux
ansible.builtin.file:
path: "{{ local_cert_sync_dir }}"
state: absent
delegate_to: localhost
become: false
handlers:
- name: reload haproxy
ansible.builtin.systemd:
name: haproxy
state: reloaded
+1 -1
View File
@@ -23,7 +23,7 @@ s3-uber ansible_host=80.96.58.164 ansible_user=omnex ansible_ssh_private_key_fil
vpn-uber ansible_host=131.123.42.158 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.1 vpn-uber ansible_host=131.123.42.158 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.1
[load-balancer] [load-balancer]
load-balancer ansible_host=93.185.166.221 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex load-balancer ansible_host=93.185.166.221 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.12
[infra] [infra]
monitoring-uber ansible_host=185.103.167.138 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.2 monitoring-uber ansible_host=185.103.167.138 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.2
+6
View File
@@ -0,0 +1,6 @@
# Domaine servi par le load-balancer HAProxy — utilisé par infra/playbook-haproxy.yml
# pour nommer le certificat combiné. Doit correspondre au nom codé en dur dans
# templates/haproxy.cfg.j2 (bind *:443 ssl crt /etc/haproxy/certs/mln-uber.club.pem).
# Le certificat lui-même n'est pas généré ici : il est copié depuis prod-uber
# (voir infra/playbook-haproxy.yml, play "Récupérer le certificat...").
domain_name: "mln-uber.club"