Nginx за Traefik Docker Swarm mode real ip

Я использую Traefik в качестве обратного прокси-сервера перед службой nginx в среде docker swarm. Вот мой docker-stack.yml:

traefik:
    image: traefik
    command: -c /dev/null --web --docker --docker.swarmmode --docker.watch --docker.domain=domain --logLevel=DEBUG
    ports:
      - "8080:8080"
      - "80:80"
      - "443:443"
    networks:
       - app
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
        constraints: [node.role == manager]

nginx:
    image: nginx
    networks:
      - app
    deploy:
      labels:
        traefik.port: 80
        traefik.docker.network: app
        traefik.frontend.rule: "Host:app.domain"

Все работает нормально, но мне нужен реальный IP-адрес клиента в моем журнале доступа Nginx, вместо этого я получаю что-то вроде 10.0.1.37

Как я могу получить реальный IP клиента?

Спасибо,


person ninja_dev    schedule 19.06.2017    source источник


Ответы (1)


Эта проблема обсуждалась на github # 614.

Когда вышестоящая служба получает запросы, перенаправленные от Traefik, заголовок X-Forwarded-For содержит IP-адрес из оверлейной сети, а не фактический адрес клиента.

Чтобы преодолеть это, вы можете использовать новый способ объявления сервисных портов в docker-compose> = 3.2 (ДЛИННЫЙ СИНТАКСИС).

Затем вы убедитесь, что traefik подключен к сети хоста и отправит правильный заголовок X-Forwarded-For (см. Ниже mode: host для порта 80):

version: "3.2"
services:
  traefik:
    ...
    ports:
      - "8080:8080"
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - "443:443"
    ...

Наконец, вам нужно изменить log_format nginx в файле http {} section. Это можно сделать через привязку тома файла конфигурации nginx.conf:

nginx:
  ..
  volumes:
    - /data/nginx/nginx.conf:/etc/nginx/nginx.conf

у вас будет nginx.conf с этим:

http {
  ...
  log_format main '$http_x_forwarded_for - $remote_user [$time_local] '
  '"$request" $status $body_bytes_sent "$http_referer" '
  '"$http_user_agent"' ;

При тестировании на AWS ec2 сервис traefik_nginx (я назвал свой стек traefik) ведет журнал следующим образом:

$ docker service logs -f traefik_nginx
...
traefik_nginx.1.qpxyjheql5uk@xxx    | 82.253.xxx.xxx - - [20/Jun/2017:08:46:51 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36"
person François Maturel    schedule 20.06.2017
comment
Спасибо за ответ, пока это может сработать. Я думаю, что режим 'host' предотвращает механизм маршрутизации Swarm: если у меня есть 2 узла в моем Swarm, только 1 узел фактически раскрывает traefik, верно? - person ninja_dev; 26.06.2017
comment
Я думаю, что вы правы (не проверял), но поскольку сетка маршрутизации использует входящую сеть (оверлейная сеть, которую мы обходим с помощью сети host), traefik должен отображаться только на том хосте, на котором он развернут. Если вы его протестируете, я буду рад, если вы обновите меня. - person François Maturel; 27.06.2017