chore:: update
This commit is contained in:
@@ -1 +1,3 @@
|
|||||||
.claude/settings.local.json
|
.claude/settings.local.json
|
||||||
|
ota/.env
|
||||||
|
ota/certs/
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIDiDCCAw6gAwIBAgISBbDpQ8oHY7guAk3faJrZKlPmMAoGCCqGSM49BAMDMDMx
|
||||||
|
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQDEwNZ
|
||||||
|
RTEwHhcNMjYwNjA4MTg0MzQ5WhcNMjYwOTA2MTg0MzQ4WjAYMRYwFAYDVQQDEw1t
|
||||||
|
bG4tdWJlci5jbHViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEpOe5wxYPT8ZX
|
||||||
|
OQNIT0nheWK4M+hdmj9pgsi6GEQjOJxqqlkqA6/V8M6ETWea6cjksn0B6MiQydNE
|
||||||
|
PmAaQJgpE6OCAhswggIXMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEF
|
||||||
|
BQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSJlN02wPPN4VXT+t6Ns84LHz2D
|
||||||
|
DzAfBgNVHSMEGDAWgBS7IMpHC/7X5Zz5jwkqo4w3RbG82DAzBggrBgEFBQcBAQQn
|
||||||
|
MCUwIwYIKwYBBQUHMAKGF2h0dHA6Ly95ZTEuaS5sZW5jci5vcmcvMBgGA1UdEQQR
|
||||||
|
MA+CDW1sbi11YmVyLmNsdWIwEwYDVR0gBAwwCjAIBgZngQwBAgEwLwYDVR0fBCgw
|
||||||
|
JjAkoCKgIIYeaHR0cDovL3llMS5jLmxlbmNyLm9yZy8xMDMuY3JsMIIBCwYKKwYB
|
||||||
|
BAHWeQIEAgSB/ASB+QD3AHUAyKPEf8ezrbk1awE/anoSbeM6TkOlxkb5l605dZkd
|
||||||
|
z5oAAAGeqMHjqAAABAMARjBEAiB8S2oE3E/xGA3RdVQehtCjoEXOASBbDbe+Vw0I
|
||||||
|
nHrCqgIgFy24r57bl0bEt/4idmm/MtzbKX1AJZxYv6JqSRoOrfoAfgAai51rD/6/
|
||||||
|
gbR5OcbSMQqG1tEC1PBG4hgsneNfXiYl7wAAAZ6oweQ5AAgAAAUAHD6tDQQDAEcw
|
||||||
|
RQIhAOICIAOd8ccaikz7PAzREsczeq14zSfevdatdzM1TRS3AiAxviAJx4WZtz3O
|
||||||
|
xbhbzWXdVa9Ru/F5lF3groeN9vUUzDAKBggqhkjOPQQDAwNoADBlAjEAiwI/D0h7
|
||||||
|
nlA3o2Ni1Zp2KdTGYrSURx6aUrQHiNga+l8czXlkVqF5RiQLz0mGjA82AjBqn2Hs
|
||||||
|
gRsc/T8Lx32HhtLFca1GPLSs5utEQfP92d+bLhOrZm/iOYurhNp7Z/dN3wE=
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICizCCAhGgAwIBAgIQXd1w3TH4AchcGGp6BLgK/jAKBggqhkjOPQQDAzAuMQsw
|
||||||
|
CQYDVQQGEwJVUzENMAsGA1UEChMESVNSRzEQMA4GA1UEAxMHUm9vdCBZRTAeFw0y
|
||||||
|
NTA5MDMwMDAwMDBaFw0yODA5MDIyMzU5NTlaMDMxCzAJBgNVBAYTAlVTMRYwFAYD
|
||||||
|
VQQKEw1MZXQncyBFbmNyeXB0MQwwCgYDVQQDEwNZRTEwdjAQBgcqhkjOPQIBBgUr
|
||||||
|
gQQAIgNiAAQHZVB1/mimla2hfSurylScjPMZaOJXLz/NnAc2sylm8WDyhU9Ccp+z
|
||||||
|
ASQi5vSwGGJjSGklkD9fdPR8GpyDIOIjCEfrnbt/v+ZSEPLLEGbaM6EccDbN7p9x
|
||||||
|
teIm2Avf+ryjge4wgeswDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF
|
||||||
|
BwMBMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLsgykcL/tflnPmPCSqj
|
||||||
|
jDdFsbzYMB8GA1UdIwQYMBaAFKPIJlqOoUzQNWP8myPIOq5W809WMDIGCCsGAQUF
|
||||||
|
BwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL3llLmkubGVuY3Iub3JnLzATBgNV
|
||||||
|
HSAEDDAKMAgGBmeBDAECATAnBgNVHR8EIDAeMBygGqAYhhZodHRwOi8veWUuYy5s
|
||||||
|
ZW5jci5vcmcvMAoGCCqGSM49BAMDA2gAMGUCMQDgjUEahFT/h3DRakqiPZpLvPgf
|
||||||
|
Zwkt6K2EOMmh1nvEzl83eMLYcod4GCl3b0J1Nn0CMBNYmEQJb4CEG5WoOe7aRn/L
|
||||||
|
VKu6saHmHEynI7ysIPd8zQsK1HdmhlHKlw9Z5GpGvA==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICpjCCAiugAwIBAgIRAIchZfw0tuX7qK3Vs3BftTowCgYIKoZIzj0EAwMwTzEL
|
||||||
|
MAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNo
|
||||||
|
IEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDIwHhcNMjYwNTEzMDAwMDAwWhcN
|
||||||
|
MzIwOTAyMjM1OTU5WjAuMQswCQYDVQQGEwJVUzENMAsGA1UEChMESVNSRzEQMA4G
|
||||||
|
A1UEAxMHUm9vdCBZRTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDwS/6vhrcVqcbBo
|
||||||
|
+wgdI3fwn9x7DNJJOY/lTOti0vkwuRN87RhEhTH17E7XyFjWsPYhIPt/wzOqxTd2
|
||||||
|
b+4ZJNy9ID04YywF9U5zasDVyGSNErVNtz8uSGh5izW87j77GaOB6zCB6DAOBgNV
|
||||||
|
HQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB
|
||||||
|
/zAdBgNVHQ4EFgQUo8gmWo6hTNA1Y/ybI8g6rlbzT1YwHwYDVR0jBBgwFoAUfEKW
|
||||||
|
rt5LSDv6kviejM9ti6lyN5UwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAChhZo
|
||||||
|
dHRwOi8veDIuaS5sZW5jci5vcmcvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMCcGA1Ud
|
||||||
|
HwQgMB4wHKAaoBiGFmh0dHA6Ly94Mi5jLmxlbmNyLm9yZy8wCgYIKoZIzj0EAwMD
|
||||||
|
aQAwZgIxAMU19WCtmxVND8UHBZRoma49Z7jPs64Dma0eTu1OChVbB/2J7GV3nvYK
|
||||||
|
Ax54uk1G9QIxAO0miLVJu8PLNiXXXkiE/gsK3CTRTF/aeo4bMX42Zw40csRU6AC2
|
||||||
|
6hSW1/IWaas6dg==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEcDCCAligAwIBAgIQbI8dxyfHEX97r4U6yYD5zTANBgkqhkiG9w0BAQsFADBP
|
||||||
|
MQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFy
|
||||||
|
Y2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBYMTAeFw0yNjA1MTMwMDAwMDBa
|
||||||
|
Fw0zMjA5MDIyMzU5NTlaME8xCzAJBgNVBAYTAlVTMSkwJwYDVQQKEyBJbnRlcm5l
|
||||||
|
dCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNSRyBSb290IFgy
|
||||||
|
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H
|
||||||
|
ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7
|
||||||
|
AlF9ItgKbppbd9/w+kHsOdx1ymgHDB/qo4H1MIHyMA4GA1UdDwEB/wQEAwIBBjAd
|
||||||
|
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUwAwEB/zAd
|
||||||
|
BgNVHQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwHwYDVR0jBBgwFoAUebRZ5nu2
|
||||||
|
5eQBc4AIiMgaWPbpm24wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAChhZodHRw
|
||||||
|
Oi8veDEuaS5sZW5jci5vcmcvMBMGA1UdIAQMMAowCAYGZ4EMAQIBMCcGA1UdHwQg
|
||||||
|
MB4wHKAaoBiGFmh0dHA6Ly94MS5jLmxlbmNyLm9yZy8wDQYJKoZIhvcNAQELBQAD
|
||||||
|
ggIBAD2/e9frmMxNpCV03qUHegg+MV2wz9644YoXdqtH8RyWYcBO7xfjjGEXdU1e
|
||||||
|
/o0OkEFiynUCOSIk/vLLo7ttz6CPAeNlWfC0XNkoGeWgK6jjXvozBaGuGH5n0Ufo
|
||||||
|
shMeWTuURqNN5G00sSXDTBrpp2+mgvdZQjb8K11TYMA25QA+YHNfbIEL0BniAhKS
|
||||||
|
2gsnJjSzrdZLI+EZ7SEyqdR2rkjd1KutLDU+n3TFyxjniZVGur4YlhMP3mY/dV95
|
||||||
|
IruAkkjOZier6hGBdEgZXXvaCz9u9iVEadsIE75pAGL8oHV5vxdARDiotRpul1IN
|
||||||
|
/UZwzAbrfUFcw1HkAcYD/mlZfnQ2ieCF2MS7j3Vhv7JPDKp45fmykmzYNSrumRW0
|
||||||
|
upFFKDBOoF7hsOb7oLyHS+Uft6jOUfOrogj8YUx38hKb2K20r42OgsSdDdxdeYWc
|
||||||
|
MS3Sb6mwJeSZEYxJ2gaXnDSPaKhhrNkYwljyVQyr4Nq+MEJytXNTnHqaAcrNwZlV
|
||||||
|
pcJL1KBnMrMjP7eanvUwL3FYj3cF17jtboLt7gLoi4+2rWZFvn+w54jmd/FIuhhZ
|
||||||
|
cEaU/wvU6BUNMtcVquVGHp7itQeDth5j+XL3j4WJ2SABwzUl6OeYdgpIt/ITZa+p
|
||||||
|
TT0mQ/r5XyA4MEAiabn7XJjvCERlF2dcn2wqJw+CreTkkQ2R
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-----BEGIN PRIVATE KEY-----
|
||||||
|
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg674do8xZennE30s5
|
||||||
|
41lM0sOSCCF4vszIl+1vnis/jqqhRANCAASk57nDFg9Pxlc5A0hPSeF5Yrgz6F2a
|
||||||
|
P2mCyLoYRCM4nGqqWSoDr9XwzoRNZ5rpyOSyfQHoyJDJ00Q+YBpAmCkT
|
||||||
|
-----END PRIVATE KEY-----
|
||||||
@@ -61,6 +61,14 @@
|
|||||||
- { regexp: '^#?MaxFileSec=', line: 'MaxFileSec=1month' }
|
- { regexp: '^#?MaxFileSec=', line: 'MaxFileSec=1month' }
|
||||||
register: journald_base
|
register: journald_base
|
||||||
|
|
||||||
|
- name: journald - creer le dossier conf.d si absent
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/systemd/journald.conf.d
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
- name: journald - deployer aussi en conf.d
|
- name: journald - deployer aussi en conf.d
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: ../templates/60-journald.conf.j2
|
src: ../templates/60-journald.conf.j2
|
||||||
@@ -96,6 +104,15 @@
|
|||||||
when: chrony_active.stdout != "active"
|
when: chrony_active.stdout != "active"
|
||||||
register: timesyncd_base
|
register: timesyncd_base
|
||||||
|
|
||||||
|
- name: timesyncd - creer le dossier conf.d si absent
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/systemd/timesyncd.conf.d
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: chrony_active.stdout != "active"
|
||||||
|
|
||||||
- name: timesyncd - deployer aussi en conf.d
|
- name: timesyncd - deployer aussi en conf.d
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: ../templates/60-timesyncd.conf.j2
|
src: ../templates/60-timesyncd.conf.j2
|
||||||
|
|||||||
@@ -26,22 +26,106 @@
|
|||||||
ansible.builtin.iptables:
|
ansible.builtin.iptables:
|
||||||
chain: DOCKER-USER
|
chain: DOCKER-USER
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
match: multiport
|
destination_port: "{{ item }}"
|
||||||
destination_ports: "80,443"
|
|
||||||
jump: DROP
|
jump: DROP
|
||||||
action: insert
|
action: insert
|
||||||
comment: "app-firewall: bloque 80/443 hors load-balancer"
|
comment: "app-firewall: bloque {{ item }} hors load-balancer"
|
||||||
|
loop:
|
||||||
|
- "80"
|
||||||
|
- "443"
|
||||||
|
|
||||||
- name: Autoriser les connexions 80/443 depuis le load-balancer (VPN)
|
- name: Autoriser les connexions 80/443 depuis le load-balancer (VPN)
|
||||||
ansible.builtin.iptables:
|
ansible.builtin.iptables:
|
||||||
chain: DOCKER-USER
|
chain: DOCKER-USER
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
source: "{{ lb_vpn_ip }}/32"
|
source: "{{ lb_vpn_ip }}/32"
|
||||||
match: multiport
|
destination_port: "{{ item }}"
|
||||||
destination_ports: "80,443"
|
|
||||||
jump: RETURN
|
jump: RETURN
|
||||||
action: insert
|
action: insert
|
||||||
comment: "app-firewall: autorise 80/443 depuis le load-balancer"
|
comment: "app-firewall: autorise {{ item }} depuis le load-balancer"
|
||||||
|
loop:
|
||||||
|
- "80"
|
||||||
|
- "443"
|
||||||
|
|
||||||
|
- name: Sauvegarder les règles iptables (persistance au reboot)
|
||||||
|
ansible.builtin.command: netfilter-persistent save
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
# Le load-balancer n'a besoin que de faire du reverse-proxy HTTP/HTTPS vers
|
||||||
|
# prod/replica-prod : il n'a aucune raison de se connecter en SSH à quoi que
|
||||||
|
# ce soit. On bloque donc son SSH sortant vers toutes les autres machines du
|
||||||
|
# réseau (chaîne INPUT, en tête de chaîne pour passer avant les ACCEPT VPN
|
||||||
|
# existants), afin de limiter le rayon d'action en cas de compromission du
|
||||||
|
# load-balancer (seul hôte exposé publiquement sur 80/443).
|
||||||
|
|
||||||
|
- name: Empêcher le load-balancer de se connecter en SSH aux autres machines
|
||||||
|
hosts: all:!load-balancer
|
||||||
|
become: true
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
lb_vpn_ip: "{{ hostvars['load-balancer']['vpn_ip'] }}"
|
||||||
|
lb_public_ip: "{{ hostvars['load-balancer']['ansible_host'] }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Installer iptables-persistent
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: iptables-persistent
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Bloquer le SSH entrant depuis le load-balancer
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}/32"
|
||||||
|
destination_port: "22"
|
||||||
|
jump: DROP
|
||||||
|
action: insert
|
||||||
|
rule_num: 1
|
||||||
|
comment: "app-firewall: bloque SSH depuis le load-balancer"
|
||||||
|
loop:
|
||||||
|
- "{{ lb_vpn_ip }}"
|
||||||
|
- "{{ lb_public_ip }}"
|
||||||
|
|
||||||
|
- name: Sauvegarder les règles iptables (persistance au reboot)
|
||||||
|
ansible.builtin.command: netfilter-persistent save
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
# Le replica n'a besoin de parler à bdd-redis-prod que sur le port Postgres
|
||||||
|
# (5432, réplication). On bloque son SSH vers bdd-redis-prod (chaîne INPUT,
|
||||||
|
# en tête de chaîne pour passer avant l'ACCEPT VPN existant sur dpt:22) sans
|
||||||
|
# toucher au port 5432, déjà autorisé pour toute la plage VPN 10.0.0.0/24.
|
||||||
|
|
||||||
|
- name: Empêcher le replica de se connecter en SSH à bdd-redis-prod
|
||||||
|
hosts: bdd-redis-prod
|
||||||
|
become: true
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
replica_vpn_ip: "{{ hostvars['replica-prod-uber']['vpn_ip'] }}"
|
||||||
|
replica_public_ip: "{{ hostvars['replica-prod-uber']['ansible_host'] }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Installer iptables-persistent
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: iptables-persistent
|
||||||
|
state: present
|
||||||
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Bloquer le SSH entrant depuis le replica
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
source: "{{ item }}/32"
|
||||||
|
destination_port: "22"
|
||||||
|
jump: DROP
|
||||||
|
action: insert
|
||||||
|
rule_num: 1
|
||||||
|
comment: "app-firewall: bloque SSH depuis le replica"
|
||||||
|
loop:
|
||||||
|
- "{{ replica_vpn_ip }}"
|
||||||
|
- "{{ replica_public_ip }}"
|
||||||
|
|
||||||
- name: Sauvegarder les règles iptables (persistance au reboot)
|
- name: Sauvegarder les règles iptables (persistance au reboot)
|
||||||
ansible.builtin.command: netfilter-persistent save
|
ansible.builtin.command: netfilter-persistent save
|
||||||
|
|||||||
+19
-54
@@ -1,45 +1,4 @@
|
|||||||
---
|
---
|
||||||
# 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)
|
- name: Déploiement HAProxy (load-balancer)
|
||||||
hosts: load-balancer
|
hosts: load-balancer
|
||||||
become: true
|
become: true
|
||||||
@@ -48,7 +7,7 @@
|
|||||||
vars:
|
vars:
|
||||||
haproxy_cert_dir: /etc/haproxy/certs
|
haproxy_cert_dir: /etc/haproxy/certs
|
||||||
haproxy_cert_path: "{{ haproxy_cert_dir }}/{{ domain_name }}.pem"
|
haproxy_cert_path: "{{ haproxy_cert_dir }}/{{ domain_name }}.pem"
|
||||||
local_cert_sync_dir: /tmp/mln-uber-cert-sync
|
local_cert_sync_dir: ../certs
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Installer HAProxy
|
- name: Installer HAProxy
|
||||||
@@ -91,11 +50,24 @@
|
|||||||
group: root
|
group: root
|
||||||
mode: "0640"
|
mode: "0640"
|
||||||
|
|
||||||
- name: Ouvrir le port HTTPS dans UFW
|
- name: Installer iptables-persistent
|
||||||
ansible.builtin.ufw:
|
ansible.builtin.apt:
|
||||||
rule: allow
|
name: iptables-persistent
|
||||||
port: "443"
|
state: present
|
||||||
proto: tcp
|
update_cache: yes
|
||||||
|
|
||||||
|
- name: Autoriser le port HTTPS (443) entrant
|
||||||
|
ansible.builtin.iptables:
|
||||||
|
chain: INPUT
|
||||||
|
protocol: tcp
|
||||||
|
destination_port: "443"
|
||||||
|
jump: ACCEPT
|
||||||
|
action: insert
|
||||||
|
comment: "haproxy: autorise HTTPS entrant"
|
||||||
|
|
||||||
|
- name: Sauvegarder les règles iptables (persistance au reboot)
|
||||||
|
ansible.builtin.command: netfilter-persistent save
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
- name: Déployer la configuration HAProxy
|
- name: Déployer la configuration HAProxy
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
@@ -113,13 +85,6 @@
|
|||||||
state: started
|
state: started
|
||||||
enabled: yes
|
enabled: yes
|
||||||
|
|
||||||
- name: Nettoyer les fichiers temporaires locaux
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ local_cert_sync_dir }}"
|
|
||||||
state: absent
|
|
||||||
delegate_to: localhost
|
|
||||||
become: false
|
|
||||||
|
|
||||||
handlers:
|
handlers:
|
||||||
- name: reload haproxy
|
- name: reload haproxy
|
||||||
ansible.builtin.systemd:
|
ansible.builtin.systemd:
|
||||||
|
|||||||
@@ -67,6 +67,44 @@
|
|||||||
vpn_private_key: "+E1pcelkLIr0x6FcOofnAWAFr6g5qHu8QHpG1sY6mG4="
|
vpn_private_key: "+E1pcelkLIr0x6FcOofnAWAFr6g5qHu8QHpG1sY6mG4="
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
# ─── Dynamic debug WireGuard ────────────────────────────────────────────
|
||||||
|
# Le module kernel wireguard ne logge les handshakes/keepalives (utilisés
|
||||||
|
# par les decoders/rules Wazuh) que si son dynamic debug est activé. Ce
|
||||||
|
# flag n'est PAS persistant : il retombe à "désactivé" à chaque reboot ou
|
||||||
|
# rechargement du module, ce qui coupe silencieusement la remontée des
|
||||||
|
# handshakes vers Wazuh sans toucher au fonctionnement du VPN lui-même
|
||||||
|
# (constaté : coupure du 18 au 30/07/2026 après un reboot du serveur).
|
||||||
|
- name: Déployer le service systemd qui réactive le dynamic debug wireguard au boot
|
||||||
|
ansible.builtin.copy:
|
||||||
|
dest: /etc/systemd/system/wireguard-dyndbg.service
|
||||||
|
mode: "0644"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=Active le dynamic debug du module kernel WireGuard (logs handshakes pour Wazuh)
|
||||||
|
After=wg-quick@wg0.service sys-kernel-debug.mount
|
||||||
|
Requires=wg-quick@wg0.service
|
||||||
|
PartOf=wg-quick@wg0.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/bin/sh -c 'echo "module wireguard +p" > /sys/kernel/debug/dynamic_debug/control'
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
register: dyndbg_unit
|
||||||
|
tags: [vpn, logging]
|
||||||
|
|
||||||
|
- name: Activer et démarrer le service wireguard-dyndbg
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: wireguard-dyndbg.service
|
||||||
|
daemon_reload: "{{ dyndbg_unit.changed }}"
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
|
tags: [vpn, logging]
|
||||||
|
|
||||||
- name: Calculer la clé publique du client à partir de sa clé privée
|
- name: Calculer la clé publique du client à partir de sa clé privée
|
||||||
command: wg pubkey
|
command: wg pubkey
|
||||||
args:
|
args:
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ discord_infra_webhook_url: "https://discord.com/api/webhooks/1526937190410621032
|
|||||||
# (NAT des ports publiés) ou servent de relais VPN. Surchargé à true uniquement pour les hosts
|
# (NAT des ports publiés) ou servent de relais VPN. Surchargé à true uniquement pour les hosts
|
||||||
# sans aucun rôle de forwarding (voir group_vars/load-balancer).
|
# sans aucun rôle de forwarding (voir group_vars/load-balancer).
|
||||||
ip_forwarding_disabled: false
|
ip_forwarding_disabled: false
|
||||||
|
ssl_domain: "mln-uber.club"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
ip_forwarding_disabled: true
|
||||||
|
user_ssh: "omnex"
|
||||||
|
group_ssh: "ssh"
|
||||||
|
password_user_ssh: "$6$w6GBkTHgj8K84P7o$pToS4pRMGLKwfpRfnz6i.WpO72Lt5DLtFQWZJsKL2dKvQrdKdi2q8xRuWqq/W3ybFNLQapvAqN33HexVjajGw0" #aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
@@ -4,4 +4,5 @@ compose_project_dir: "../docker-prod/"
|
|||||||
# Utilisé uniquement par prod/playbook-s3-img.yml (les autres playbooks du groupe utilisent ansible_user)
|
# Utilisé uniquement par prod/playbook-s3-img.yml (les autres playbooks du groupe utilisent ansible_user)
|
||||||
user_deploy: "ubuntu"
|
user_deploy: "ubuntu"
|
||||||
docker_group: "docker"
|
docker_group: "docker"
|
||||||
docker_dir: "/home/ubuntu/docker/s3-img"
|
docker_dir: "/home/ubuntu/docker"
|
||||||
|
ssl_dir: "/home/ubuntu/docker/certs"
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
compose_project_dir: "../../docker-prod/"
|
compose_project_dir: "../../docker-prod/"
|
||||||
docker_group: "docker"
|
docker_group: "docker"
|
||||||
user_deploy: "ubuntu"
|
user_deploy: "ubuntu"
|
||||||
|
ssl_dir: "/home/ubuntu/docker/certs"
|
||||||
|
|||||||
+11
-8
@@ -8,26 +8,29 @@ pre-prod-uber ansible_host=131.123.39.112 ansible_user=omnex ansible_ssh_private
|
|||||||
bdd-redis-prod ansible_host=132.243.162.62 ansible_user=root ansible_ssh_private_key_file=../.ssh/key_bdd_redis vpn_ip=10.0.0.5
|
bdd-redis-prod ansible_host=132.243.162.62 ansible_user=root ansible_ssh_private_key_file=../.ssh/key_bdd_redis vpn_ip=10.0.0.5
|
||||||
|
|
||||||
[replica-prod]
|
[replica-prod]
|
||||||
replica-prod-uber ansible_host=132.243.162.161 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.9
|
replica-prod-uber ansible_host=132.243.162.161 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.9 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
|
|
||||||
[infra-monitoring-security]
|
[infra-monitoring-security]
|
||||||
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 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
|
|
||||||
[infra-runner]
|
[infra-runner]
|
||||||
runner-uber ansible_host=185.103.164.200 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex
|
runner-uber ansible_host=185.103.164.200 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
|
|
||||||
[infra-utils]
|
[infra-utils]
|
||||||
s3-uber ansible_host=80.96.58.164 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
s3-uber ansible_host=80.96.58.164 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm vpn_ip=10.0.0.14
|
||||||
|
|
||||||
[vpn-uber]
|
[vpn-uber]
|
||||||
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 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
|
|
||||||
[load-balancer]
|
[load-balancer]
|
||||||
load-balancer ansible_host=93.185.166.221 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.12
|
load-balancer ansible_host=143.246.199.221 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.12
|
||||||
|
|
||||||
|
[ota-uber]
|
||||||
|
ota-uber ansible_host=193.27.90.157 ansible_user=omnex ansible_ssh_private_key_file=../.ssh/omnex vpn_ip=10.0.0.10 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
|
|
||||||
[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 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
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 ansible_become_pass=aiQgIAcCVIy1E33ReRssfm414dm
|
||||||
backup-mln ansible_host=85.121.176.241 ansible_user=root ansible_ssh_private_key_file=../.ssh/key_backup vpn_ip=10.0.0.4
|
backup-mln ansible_host=85.121.176.241 ansible_user=root ansible_ssh_private_key_file=../.ssh/key_backup vpn_ip=10.0.0.4
|
||||||
|
|
||||||
[infra:children]
|
[infra:children]
|
||||||
|
|||||||
+31
-2
@@ -1,9 +1,13 @@
|
|||||||
---
|
---
|
||||||
- name: Installation et configuration du frontend et backend
|
- name: Installation et configuration du frontend et backend
|
||||||
hosts: replica-prod
|
hosts: prod-uber
|
||||||
become: true
|
become: true
|
||||||
gather_facts: true
|
gather_facts: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
ssl_dir: "{{ docker_dir }}/certs"
|
||||||
|
ssl_domain: mln-uber.club
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Update apt cache
|
- name: Update apt cache
|
||||||
apt:
|
apt:
|
||||||
@@ -169,4 +173,29 @@
|
|||||||
owner: "{{ docker_user }}"
|
owner: "{{ docker_user }}"
|
||||||
group: "{{ docker_group }}"
|
group: "{{ docker_group }}"
|
||||||
mode: "0750"
|
mode: "0750"
|
||||||
tags: project
|
tags: [certs]
|
||||||
|
|
||||||
|
- name: Générer la clé privée RSA 2048
|
||||||
|
community.crypto.openssl_privatekey:
|
||||||
|
path: "{{ ssl_dir }}/privkey.pem"
|
||||||
|
type: RSA
|
||||||
|
size: 2048
|
||||||
|
mode: "0600"
|
||||||
|
tags: [certs]
|
||||||
|
|
||||||
|
- name: Générer la CSR pour le certificat auto-signé
|
||||||
|
community.crypto.openssl_csr:
|
||||||
|
path: "{{ ssl_dir }}/selfsigned.csr"
|
||||||
|
privatekey_path: "{{ ssl_dir }}/privkey.pem"
|
||||||
|
common_name: "{{ ssl_domain }}"
|
||||||
|
tags: [certs]
|
||||||
|
|
||||||
|
- name: Générer le certificat auto-signé
|
||||||
|
community.crypto.x509_certificate:
|
||||||
|
path: "{{ ssl_dir }}/fullchain.pem"
|
||||||
|
privatekey_path: "{{ ssl_dir }}/privkey.pem"
|
||||||
|
csr_path: "{{ ssl_dir }}/selfsigned.csr"
|
||||||
|
provider: selfsigned
|
||||||
|
selfsigned_not_after: "+3650d"
|
||||||
|
mode: "0644"
|
||||||
|
tags: [certs]
|
||||||
|
|||||||
Reference in New Issue
Block a user