DEV Community

Laurent Quastana
Laurent Quastana

Posted on

Sécuriser HL7/MLLP avec Stunnel (mTLS)

Vous échangez des flux HL7 en clair entre EAI et DPI ?
Voici comment les sécuriser avec TLS mutuel sans toucher au code source, en 4 commandes et un Docker Compose.


🌍 Contexte

Les messages HL7 sont souvent véhiculés via MLLP (Minimal Lower Layer Protocol)… sans chiffrement.
C’est encore toléré dans certains SIH, mais difficilement défendable en 2025 :

  • Exposition des données patients (PHI) en clair
  • Absence d’authentification forte entre systèmes

Alors comment ajouter une couche TLS mutuelle sans casser un lien MLLP existant ?
Réponse : Stunnel + Docker.


🚀 Objectif du projet

Le dépôt mllp-safetunnel fournit un environnement de test pour :

  • encapsuler HL7/MLLP en TLS (avec authentification mutuelle)
  • simuler des flux EAI ⇄ DPI via deux conteneurs Docker
  • tester la réception, les ACKs, et l’interopérabilité

🎯 Sans changer le code du DPI ou de l’EAI.


📦 Contenu du dépôt

Répertoire / fichier Rôle
eai/ Dockerfile + scripts Python simulant l’envoi HL7
dpi/ Idem côté DPI (réception + retour)
stunnel/ Certificats X.509 de test + script gen-certs.sh
docker-compose.yml Orchestration complète
docs/ Diagrammes, bonnes pratiques sécurité, cheatsheets HL7

Les conteneurs utilisent deux réseaux internes (net_eai, net_dpi).
Seuls les ports TLS (32100, 32200) sont exposés à l’hôte.


⚙️ Prérequis

  • Docker ≥ 24.0
  • Docker Compose v2
  • OpenSSL (si vous régénérez les certificats)
  • Ports TCP disponibles : 32100, 32200

🔧 Démarrage rapide

# 1. Cloner le dépôt
git clone https://github.com/votre_org/mllp-safetunnel.git
cd mllp-safetunnel

# 2. (Optionnel) régénérer les certificats
./stunnel/gen-certs.sh

# 3. Lancer l’environnement
docker compose up -d

# 4. Suivre les logs
docker compose logs -f eai
Enter fullscreen mode Exit fullscreen mode

Des messages HL7 (MDM^T02, ADT^A01) sont simulés toutes les 20 secondes, avec accusé de réception (ACK).


📡 Détail des tunnels Stunnel

🔁 EAI → DPI (client TLS)

Étape Port Protocole
Envoi MLLP clair 21010 TCP
Tunnel TLS sortant 32100 TLS mutuel
Redirection vers DPI (clair) 21010 TCP interne

🔁 DPI → EAI (retour)

Même logique, avec les ports 22010 (clair) → 32200 (TLS) → 22010 (clair).


🧪 Simulation HL7

Chaque conteneur embarque :

Script Rôle
send.sh Envoie un fichier HL7, logue le résultat
send_loop.sh Envoi auto toutes les 20 s (actif par défaut)
listen.sh Écoute MLLP, affiche + ACK
server.log Démarrage du service HL7

Exemple de test manuel :

# Depuis EAI vers DPI
docker compose exec eai /app/send.sh
docker compose exec dpi /app/listen.sh

# Depuis DPI vers EAI
docker compose exec dpi /app/send.sh
docker compose exec eai /app/listen.sh
Enter fullscreen mode Exit fullscreen mode

🛠️ Personnalisation

Besoin À modifier
Certificats de prod Remplacer les fichiers dans stunnel/
Autres ports Modifier stunnel.conf et docker-compose.yml
Remplacer simulateurs Monter vos conteneurs EAI / DPI réels
Logs plus verbeux Ajouter debug = 7 dans les confs

🔐 Bonnes pratiques sécurité

  • TLS mutuel obligatoire (verify = 2)
  • Limiter l’exposition aux ports 32100 / 32200 uniquement
  • Automatiser la rotation des certificats (gen-certs.sh)
  • Surveiller stunnel.log, surtout en cas d’erreurs handshake

📈 Envisager la production

Ce projet est une base pour :

  • Démonstrateur sécurité avant mise en production
  • Formation des équipes DevOps santé

Il peut être adapté en k8s, supervisé avec Prometheus, ou branché sur un EAI Mirth/Rhapsody.


🧾 Licence

MIT — libre d’usage et d’adaptation, y compris en contexte hospitalier.


👉 Repo GitHub : github.com/lquastana/mllp-safetunnel
📢 Questions ? Ouvert aux PR / issues / idées !

Top comments (0)