Traefik Docker Swarm 模式背后的 Nginx 真实 ip [英] Nginx behind Traefik Docker Swarm mode real ip

查看:223
本文介绍了Traefik Docker Swarm 模式背后的 Nginx 真实 ip的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 docker swarm 环境中使用 Traefik 作为 nginx 服务前的反向代理.这是我的 docker-stack.yml:

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"

一切正常,但我的 Nginx 访问日志中需要真实的客户端 IP,而不是 10.0.1.37

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

如何获取真实的客户端ip?

How get I can the real client ip?

谢谢,

推荐答案

此问题已在 github 上讨论#614.

当上游服务收到从 Traefik 转发的请求时,X-Forwarded-For 标头包含来自覆盖网络的 IP 地址,而不是实际的客户端地址.

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.

为了克服这个,你可以使用新的方式在docker中声明服务端口-撰写 >=3.2(长句法).

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

然后确保 traefik 连接到主机网络,并将发送正确的 X-Forwarded-For 标头(参见下面的 mode: host 80 端口):

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"
    ...

最后,您必须更改 http {} 部分 中的 nginx log_format.这可以通过 nginx.conf 配置文件的卷绑定来完成:

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

你应该有 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)日志如下:

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"

这篇关于Traefik Docker Swarm 模式背后的 Nginx 真实 ip的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆