{"id":1290,"date":"2025-09-22T15:48:47","date_gmt":"2025-09-22T13:48:47","guid":{"rendered":"https:\/\/dyb.fr\/?p=1290"},"modified":"2025-09-22T15:48:47","modified_gmt":"2025-09-22T13:48:47","slug":"docker-et-lexposition-involontaire-des-ports-une-faille-que-lon-retrouve-trop-souvent-en-production","status":"publish","type":"post","link":"https:\/\/dyb.eu\/blog\/docker-et-lexposition-involontaire-des-ports-une-faille-que-lon-retrouve-trop-souvent-en-production\/","title":{"rendered":"\ud83d\udea8 Docker et l\u2019exposition involontaire des ports : une faille que l\u2019on retrouve (trop) souvent en production"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Chez <strong>DYB<\/strong>, nous auditons r\u00e9guli\u00e8rement des environnements de nos clients et il n\u2019est pas rare de tomber sur la m\u00eame erreur : un service expos\u00e9 <strong>directement<\/strong> sur Internet via Docker, sans aucune restriction, simplement parce que le d\u00e9veloppeur a laiss\u00e9 un <code>ports: \"3000:3000\"<\/code> dans son <code>docker-compose.yml<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Une mauvaise habitude, mais qui peut co\u00fbter cher.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u26a0\ufe0f Le probl\u00e8me : <code>ports: \"3000:3000\"<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dans un fichier <code>docker-compose.yml<\/code>, on trouve souvent des lignes comme :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  app:\n    image: monapp\n    ports:\n      - \"3000:3000\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Cela signifie : \u00ab ouvre le port 3000 du conteneur et rends-le accessible sur <strong>toutes les interfaces r\u00e9seau<\/strong> du serveur (<code>0.0.0.0<\/code>). \u00bb<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc49 R\u00e9sultat : si le serveur est un <strong>VPS avec une IP publique<\/strong>, le service est accessible \u00e0 n\u2019importe qui sur Internet en tapant <code>http:\/\/ip_du_serveur:3000<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd0d Pourquoi c\u2019est dangereux ?<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Bypass du firewall h\u00f4te<\/strong> : Docker ajoute automatiquement des r\u00e8gles <code>iptables<\/code> pour publier les ports. M\u00eame si vous pensiez avoir un pare-feu restrictif (<code>ufw<\/code>, <code>firewalld<\/code>), Docker peut l\u2019outrepasser.<\/li>\n\n\n\n<li><strong>Exposition directe<\/strong> : votre API, base de donn\u00e9es ou back-office peut se retrouver accessible sans authentification.<\/li>\n\n\n\n<li><strong>Attaques automatis\u00e9es<\/strong> : les scanners comme Shodan ou Censys trouvent tr\u00e8s vite ces services, qui deviennent des cibles id\u00e9ales pour des attaques par force brute, des injections ou des ransomwares.<\/li>\n\n\n\n<li><strong>Erreur courante en prod<\/strong> : beaucoup de d\u00e9veloppeurs lancent leurs conteneurs sur un VPS de test\u2026 qui finit par h\u00e9berger la prod, sans durcissement de la configuration.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\u2705 Les bonnes pratiques<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Lier \u00e0 <code>localhost<\/code> si acc\u00e8s local uniquement<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>ports:\n  - \"127.0.0.1:3000:3000\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc49 Le service n\u2019est accessible que depuis la machine elle-m\u00eame. Parfait si vous comptez y acc\u00e9der via un reverse proxy (Nginx, Traefik, Caddy).<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">2. Ne pas publier de port du tout<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Au lieu d\u2019exposer le service, mettez-le sur un <strong>r\u00e9seau Docker interne<\/strong> :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  app:\n    networks:\n      - internal\n  db:\n    networks:\n      - internal\n\nnetworks:\n  internal:\n    driver: bridge\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ud83d\udc49 Seul un reverse proxy expos\u00e9 vers Internet doit avoir des ports publi\u00e9s.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">3. Utiliser un reverse proxy unique<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Un seul point d\u2019entr\u00e9e (Traefik, Nginx, Caddy) \u2192 tous vos services passent par lui, avec HTTPS et filtrage.<br>\ud83d\udc49 \u00c7a simplifie la s\u00e9curit\u00e9 et centralise les r\u00e8gles d\u2019acc\u00e8s.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">4. V\u00e9rifier vos services<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Commande rapide : <code>ss -ltnp<\/code> pour voir quels services \u00e9coutent et sur quelles interfaces.<\/li>\n\n\n\n<li>Ne jamais supposer que \u00ab Docker respecte mon firewall \u00bb \u2192 il \u00e9crit ses propres r\u00e8gles.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd12 Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019erreur <code>ports: \"3000:3000\"<\/code> para\u00eet anodine\u2026 mais c\u2019est l\u2019une des principales causes d\u2019exposition accidentelle de services en production.<br>Sur un VPS, cela peut transformer un simple test en <strong>porte d\u2019entr\u00e9e ouverte sur Internet<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Chez DYB, nous recommandons syst\u00e9matiquement :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>d\u2019isoler vos services dans des r\u00e9seaux internes,<\/li>\n\n\n\n<li>de limiter les bind \u00e0 <code>127.0.0.1<\/code> si n\u00e9cessaire,<\/li>\n\n\n\n<li>et d\u2019exposer uniquement un reverse proxy s\u00e9curis\u00e9.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">C\u2019est un petit effort de configuration qui peut \u00e9viter une grosse faille de s\u00e9curit\u00e9.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chez DYB, nous auditons r\u00e9guli\u00e8rement des environnements de nos clients et il n\u2019est pas rare de tomber sur la m\u00eame erreur : un service expos\u00e9 directement sur Internet via Docker, sans aucune restriction, simplement parce que le d\u00e9veloppeur a laiss\u00e9 un ports: \u00ab\u00a03000:3000\u00a0\u00bb dans son docker-compose.yml. Une mauvaise habitude, mais qui peut co\u00fbter cher. \u26a0\ufe0f [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1293,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26,22,34],"tags":[21,33,43,29],"class_list":["post-1290","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-adminsys","category-cybersecurite","category-dev","tag-cybersecurite","tag-dev","tag-docker","tag-linux"],"_links":{"self":[{"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/posts\/1290","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/comments?post=1290"}],"version-history":[{"count":0,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/posts\/1290\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/media\/1293"}],"wp:attachment":[{"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/media?parent=1290"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/categories?post=1290"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dyb.eu\/blog\/wp-json\/wp\/v2\/tags?post=1290"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}