Sécuriser MySQL avec HAProxy + ProxySQL : Le Guide de Survie
Protéger MySQL en production avec deux proxies en cascade : HAProxy pour le rate limiting réseau, ProxySQL pour le cache SQL. Spoiler : j'ai galéré 6h sur ProxySQL qui ignorait mon fichier de config. Voici comment j'ai résolu.
Sécuriser MySQL avec HAProxy + ProxySQL : Le Guide de Survie
> TL;DR : Protéger MySQL en production nécessite plusieurs couches de sécurité. J'ai déployé HAProxy (rate limiting) + ProxySQL (cache SQL) devant MySQL. Mais attention : ProxySQL a un piège vicieux qui ignore votre fichier de config après le premier démarrage. Voici comment j'ai résolu avec tmpfs + entrypoint custom.
🎯 Pourquoi Deux Proxies ?
Question légitime : Pourquoi pas juste HAProxy ? Ou juste ProxySQL ?
Réponse : Parce que chacun excelle dans SON domaine :
HAProxy = Sécurité Réseau
- ✅ Rate limiting par IP : max 5 connexions simultanées, 10 nouvelles/3s
- ✅ Load balancing : répartition de charge entre serveurs MySQL
- ✅ Healthchecks : retire automatiquement les backends down
- ✅ SSL termination : déchiffrement HTTPS en amont
ProxySQL = Sécurité Applicative
- ✅ Cache SQL : queries en mémoire, moins de charge MySQL
- ✅ Query rewriting : bloquer les DROP/DELETE dangereux
- ✅ Connection pooling : réutiliser les connexions MySQL
- ✅ Firewall SQL : filtrer par pattern de requête
Architecture finale :
Internet (clients malveillants)
↓
HAProxy :6033 (bloque les IPs agressives)
↓
ProxySQL :6032 (bloque les requêtes dangereuses)
↓
MySQL :3306 (bien protégé)🐛 Le Piège ProxySQL (6h de Debug)
Le problème n°1 que j'ai rencontré : ProxySQL ignore TOTALEMENT le fichier de config après le premier démarrage.
Situation Initiale
Je crée un proxysql.cnf avec mes credentials. Premier démarrage : ✅ Connexion OK. Redémarrage du container : ❌ Access denied !
WTF ?! 🤯
J'ai perdu 2h à tester différentes solutions sans succès.
La Vérité (Doc Officielle)
> "After first startup the DB file is used instead of the config file"
ProxySQL crée une base SQLite /var/lib/proxysql/proxysql.db au premier démarrage. Ensuite, il LIT CETTE BASE, pas le fichier .cnf.
✅ Solution : tmpfs + Entrypoint Custom
services:
proxysql:
image: proxysql/proxysql:2.6.0
volumes:
- ./proxysql/proxysql.cnf:/etc/proxysql.cnf.template:ro
- ./proxysql/entrypoint-wrapper.sh:/entrypoint-wrapper.sh:ro
# 🔥 Le secret : tmpfs (RAM, non persistent)
- type: tmpfs
target: /var/lib/proxysql
entrypoint: ["/entrypoint-wrapper.sh"]Pourquoi tmpfs ?
- La base SQLite est créée en RAM
- Elle disparaît au redémarrage du container
- ProxySQL est FORCÉ de relire le fichier config
🚧 Autre Galère : HAProxy Healthcheck
Problème : HAProxy marque ProxySQL comme DOWN avec "Access denied for user 'monitor'"
Solution : TCP Check Basique au lieu de mysql-check
backend proxysql-back
mode tcp
balance roundrobin
option tcp-check
server proxysql1 proxysql:6032 check inter 5s fall 3 rise 2🎓 Ce que J'ai Appris
- Lire la doc officielle en cas de blocage : La phrase "DB file is used instead of config file" était LA clé
- Les healthchecks Docker peuvent bloquer des dépendances
- Les timings d'init comptent : ProxySQL met ~25 secondes à démarrer
- ProxySQL n'est PAS fait pour des configs dynamiques
---
Des questions ? Contactez-nous via le formulaire de contact DockSky.