Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx behind Traefik Docker Swarm mode real ip

I'm using Traefik as a reverse proxy in front of nginx service on a docker swarm environment. Here's my 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"

Everything works fine but I need the real client IP in my Nginx access log, instead I get something like 10.0.1.37

How get I can the real client ip?

Thanks,

like image 200
ninja_dev Avatar asked Jun 19 '17 21:06

ninja_dev


People also ask

Is Traefik better than nginx?

Yes, it is operating slower then Nginx, but adding Traefik to project is so simple that you can win any deadlines, especially if you are using Docker/Compose/K8S. It also already has internal analytics.

Is Traefik a reverse proxy?

What is Traefik? Traefik is a leading modern reverse proxy and load balancer that makes deploying microservices easy. Traefik integrates with your existing infrastructure components and configures itself automatically and dynamically.

What is Swarmpit?

What is Swarmpit ? Swarmpit provides simple and easy to use interface for your Docker Swarm cluster. You can manage your stacks, services, secrets, volumes, networks etc. After linking your Docker Hub account or custom registry, private repositories can be easily deployed on Swarm.

Does Docker swarm load balancer?

Yes, Docker Swarm does load balancing. Docker Swarm's load balancer runs on every node and is capable of balancing load requests across multiple containers and hosts.


1 Answers

This issue was discussed on github #614.

When the upstream service receives requests forwarded from Traefik, the X-Forwarded-For header contains an IP address from the overlay network, not the actual client address.

To overcome this, you can use the new way of declaring service ports in docker-compose >=3.2 (LONG SYNTAX).

Then you ensure that traefik is attached to host network and will send the right X-Forwarded-For header (see below mode: host for the 80 port):

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

Finally, you have to change the nginx log_format in the http {} section. That can be done through volume binding of a nginx.conf configuration file:

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

you'd have nginx.conf with this:

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

Tested on an AWS ec2, the traefik_nginx service (I called my stack traefik) logs like this:

$ 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"
like image 152
François Maturel Avatar answered Sep 30 '22 04:09

François Maturel