在容器化的 NGINX 反向代理中获取真实的请求者 IP

在容器化的 NGINX 反向代理中获取真实的请求者 IP

我在 OVH vps 上设置了 Docker Swarm 堆栈和 nginx 作为反向代理。我试图在位置中使用允许/拒绝指令,但如果我设置拒绝所有;它甚至对使用允许指令添加的 ip 也不起作用。查看访问日志后,我发现所有请求据称都来自 IP 10.0.0.2。现在我尝试先获取实际 IP 以至少显示在日志中,但没有成功。这是我的 nginx.conf:

events{}

http {

  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }
  error_log /dev/stdout info;
  log_format json_combined escape=json
    '{'
      '"time":"$time_local",'
      '"httpRequest":{'
        '"requestMethod":"$request_method",'
        '"requestUrl":"$scheme://$host$request_uri",'
        '"requestSize":$request_length,'
        '"status":"$status",'
        '"responseSize":$bytes_sent,'
        '"userAgent":"$http_user_agent",'
        '"remoteIp":"$remote_addr",'
        '"serverIp":"$server_addr",'
        '"referer":"$http_referer",'
        '"latency":"${request_time}s",'
        '"protocol":"$server_protocol"'
      '}'
    '}';

  resolver 127.0.0.11 valid=30s;

  include /etc/nginx/mime.types;
  include /etc/nginx/sites-enabled/*.*;
}

代理服务器配置文件(proxy.conf):

set_real_ip_from        10.0.0.0/8;
real_ip_header          X-Forwarded-For;
real_ip_recursive       on;
proxy_set_header        X-Real-IP           $remote_addr;
proxy_set_header        X-Forwarded-For     $proxy_add_x_forwarded_for;
proxy_set_header        Host                $http_host;
proxy_set_header        X-Forwarded-Host    $http_host;
proxy_set_header        X-Forwarded-Proto   $scheme;
proxy_set_header        X-Forwarded-Port    $server_port;
proxy_set_header        Upgrade             $http_upgrade;
proxy_set_header        Connection          $connection_upgrade;
proxy_set_header        X-NginX-Proxy       true;
proxy_cache_bypass      $http_upgrade;
proxy_http_version      1.1;
proxy_read_timeout      20d;
proxy_buffering         off;
proxy_request_buffering off;
proxy_intercept_errors  on;
http2_push_preload      on;

我的位置:

  location /api/ {
     allow XXX.XX.XX.X;
     deny  all;
     include /etc/nginx/proxy-options/proxy.conf;
     set $ocelot ocelot-service;
     proxy_pass http://$ocelot$uri$is_args$args;
     proxy_ssl_session_reuse off;
     proxy_redirect off;
     client_max_body_size 5M;
  }

我该怎么做才能让 nginx 记录请求者的实际 IP,并且如果可能的话,使用该 IP 与允许指令进行比较?

答案1

问题是由于 docker swarm 中附加的“覆盖”网络引起的;我通过使用“主机”网络绕过了这个问题。

services:
  nginx:
    ...
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host

相关内容