Une histoire qui résout le problème que REMOTE_ADDR ne peut pas être acquis dans un cluster construit avec Docker Swarm + Traefik (1.7).

Sur le cluster Docker Swarm, j'ai configuré un conteneur Traefik en tant que proxy inverse et j'ai essayé de le faire fonctionner avec une configuration qui distribue le contenu avec un conteneur de nœuds, mais j'avais des problèmes car je ne pouvais pas obtenir REMOTE_ADDR.

Notez ce qu'il faut faire dans ce cas.

Version Docker: 19.03.12

Le fichier d'origine docker-compose.yml est:

version: '3.4'

services:

  socket-proxy:
    image: tecnativa/docker-socket-proxy
    networks:
      - internal
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - SERVICES=1
      - TASKS=1
      - NETWORKS=1
      - LOGSPOUT=ignore
    deploy:
      placement:
        constraints:
          - node.hostname == manager

  traefik:
    image: traefik:1.7-alpine
    command:
      - "--logLevel=error"
      - "--entryPoints=Name:http Address::80 Redirect.EntryPoint:https"
      - "--entryPoints=Name:https Address::443 TLS"
      - "--defaultentrypoints=http,https"
      - "--web"
      - "--web.address=:8080"
      - "--acme"
      - "--acme.storage=certs.json"
      - "--acme.entrypoint=https"
      - "--acme.httpchallenge.entrypoint=http"
      - "--acme.onHostRule=true"
      - "[email protected]"
      - "--docker"
      - "--docker.endpoint=tcp://socket-proxy:2375"
      - "--docker.swarmMode"
      - "--docker.watch"
    ports:
      - 80:80
      - 443:443
    networks:
      - internal
      - overlay
    volumes:
      - ./certs/certs.json:/certs.json
    deploy:
      placement:
        constraints:
          - node.hostname == web
      restart_policy:
        condition: on-failure

  web:
    image: hoge/fuga:dev
    networks:
      - overlay
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname == web
      labels:
        - "traefik.enable=true"
        - "traefik.backend=web"
        - "traefik.frontend.rule=Host:sample.com"
        - "traefik.frontend.entryPoints=https"
        - "traefik.frontend.passHostHeader=true"
        - "traefik.docker.network=overlay"
        - "traefik.protocol=http"
        - "traefik.port=3000"

networks:
  overlay:
    external: true
  internal:
    internal: true

Bien que ce ne soit pas le sujet principal de cette fois, dans le paramètre ci-dessus, "docker-socket-proxy" est utilisé pour allouer le point final de Traefik à un autre conteneur. Généralement, Traefik est exécuté sur le nœud du gestionnaire et docker.sock est spécifié comme point de terminaison, mais si une faille de sécurité est trouvée dans Traefik, il y a un risque que le cluster entier soit détourné. .. En utilisant docker-socket-proxy, Traefik peut être exécuté sur le nœud worker, et en réduisant l'autorité avec docker-socket-proxy, il est possible de fonctionner avec une sécurité améliorée.

J'ai déjà exploité un site et j'ai souffert d'un accès malveillant, donc je veux vraiment garder REMOTE_ADDR comme journal, mais je ne peux pas l'obtenir.

Traefik doit envoyer les informations d'en-tête, etc. au backend tel quel si vous spécifiez "traefik.frontend.passHostHeader = true" dans chaque conteneur. User-Agent, etc. peuvent être acquis correctement, il semble donc que ce paramètre soit actif.

Cause

Après de nombreuses recherches, j'ai trouvé des informations sur les tableaux d'affichage à l'étranger que le réseau de superposition Docker Swarm ne semble pas porter REMOTE_ADDR. Et, dans le cas de Nginx, il y avait aussi une solution pour monter le port en mode hôte.

Solution

J'ai donc réécrit les paramètres du port Traefik comme suit.

    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80
      - mode: host
        protocol: tcp
        published: 443
        target: 443

Après les tests, j'ai pu obtenir REMOTE_HOST en toute sécurité.

Je pense que Nginx etc. peut le résoudre avec la même correspondance. Si vous rencontrez des problèmes avec le même problème, essayez-le.

Recommended Posts

Une histoire qui résout le problème que REMOTE_ADDR ne peut pas être acquis dans un cluster construit avec Docker Swarm + Traefik (1.7).
Le problème selon lequel la page localhost lancée par Docker ne peut pas être confirmée dans le navigateur lorsque le pare-feu ESET fonctionne
Une histoire sur une erreur lors de la migration dans docker PHP Laravel
L'histoire que .java est également construite dans Unity 2018
J'ai essayé de créer un programme en Java qui résout le problème du voyageur de commerce avec un algorithme génétique
[Docker] Une histoire sur une erreur dans la composition de docker
[rails] Problèmes qui ne peuvent pas être enregistrés / connectés avec l'appareil
Évitez le problème que la session ne peut pas être obtenue lorsque Canary est libéré lors de la mise à niveau de Rails 4.2.x vers 5.0.x
Une histoire qui a eu du mal avec l'introduction de Web Apple Pay
L'histoire que Tomcat a souffert d'une erreur de timeout dans Eclipse
L'histoire de rendre possible la construction d'un projet qui a été construit par Maven avec Ant
Comment résoudre le problème selon lequel la notification ne peut pas être demandée sur iOS14
L'histoire selon laquelle le servlet n'a pas pu être chargé dans l'application Web Java
767 JSON :: ParserError se produit et le serveur local ne peut pas être démarré.
Après avoir vérifié le problème de Montyhall avec Ruby, c'était une histoire que je pouvais bien comprendre et que je ne comprenais pas bien