Chez DYB, nous auditons régulièrement des environnements de nos clients et il n’est pas rare de tomber sur la même erreur : un service exposé directement sur Internet via Docker, sans aucune restriction, simplement parce que le développeur a laissé un ports: "3000:3000"
dans son docker-compose.yml
.
Une mauvaise habitude, mais qui peut coûter cher.
⚠️ Le problème : ports: "3000:3000"
Dans un fichier docker-compose.yml
, on trouve souvent des lignes comme :
services:
app:
image: monapp
ports:
- "3000:3000"
Cela signifie : « ouvre le port 3000 du conteneur et rends-le accessible sur toutes les interfaces réseau du serveur (0.0.0.0
). »
👉 Résultat : si le serveur est un VPS avec une IP publique, le service est accessible à n’importe qui sur Internet en tapant http://ip_du_serveur:3000
.
🔍 Pourquoi c’est dangereux ?
- Bypass du firewall hôte : Docker ajoute automatiquement des règles
iptables
pour publier les ports. MĂŞme si vous pensiez avoir un pare-feu restrictif (ufw
,firewalld
), Docker peut l’outrepasser. - Exposition directe : votre API, base de données ou back-office peut se retrouver accessible sans authentification.
- Attaques automatisées : les scanners comme Shodan ou Censys trouvent très vite ces services, qui deviennent des cibles idéales pour des attaques par force brute, des injections ou des ransomwares.
- Erreur courante en prod : beaucoup de développeurs lancent leurs conteneurs sur un VPS de test… qui finit par héberger la prod, sans durcissement de la configuration.
âś… Les bonnes pratiques
1. Lier Ă localhost
si accès local uniquement
ports:
- "127.0.0.1:3000:3000"
👉 Le service n’est accessible que depuis la machine elle-même. Parfait si vous comptez y accéder via un reverse proxy (Nginx, Traefik, Caddy).
2. Ne pas publier de port du tout
Au lieu d’exposer le service, mettez-le sur un réseau Docker interne :
services:
app:
networks:
- internal
db:
networks:
- internal
networks:
internal:
driver: bridge
👉 Seul un reverse proxy exposé vers Internet doit avoir des ports publiés.
3. Utiliser un reverse proxy unique
Un seul point d’entrée (Traefik, Nginx, Caddy) → tous vos services passent par lui, avec HTTPS et filtrage.
👉 Ça simplifie la sécurité et centralise les règles d’accès.
4. Vérifier vos services
- Commande rapide :
ss -ltnp
pour voir quels services écoutent et sur quelles interfaces. - Ne jamais supposer que « Docker respecte mon firewall » → il écrit ses propres règles.
đź”’ Conclusion
L’erreur ports: "3000:3000"
paraît anodine… mais c’est l’une des principales causes d’exposition accidentelle de services en production.
Sur un VPS, cela peut transformer un simple test en porte d’entrée ouverte sur Internet.
Chez DYB, nous recommandons systématiquement :
- d’isoler vos services dans des réseaux internes,
- de limiter les bind Ă
127.0.0.1
si nécessaire, - et d’exposer uniquement un reverse proxy sécurisé.
C’est un petit effort de configuration qui peut éviter une grosse faille de sécurité.