简体   繁体   English

使用 Nginx 反向代理时无法获取客户端的真实 IP

[英]Can't get client's real IP when using Nginx reverse proxy

Problem description:问题描述:
When I access Asp.net MVC Core 3.1 webpage that is supposed to return my remote client's ip address I instead get internal docker IP of Nginx container. When I access Asp.net MVC Core 3.1 webpage that is supposed to return my remote client's ip address I instead get internal docker IP of Nginx container. I'm not sure if the problem is my code in asp.net core, the Nginx reverse proxy configuration not forwarding my client ip to Kestrel container, or something else.我不确定问题是否是我在 asp.net 核心中的代码,Nginx 反向代理配置未将我的客户端 ip 转发到 Kestrel 容器,或其他东西。

Output: Output:

::ffff:172.23.0.3 ::ffff:172.23.0.3

Desired Output (example using random ip):所需的 Output(使用随机 ip 的示例):

231.43.6.124 231.43.6.124

Setup:设置:

  • Remote VPS using Ubuntu and running Docker (ie not running locally)使用 Ubuntu 并运行 Docker 的远程 VPS(即不在本地运行)
  • Kestrel docker container that has no public access没有公共访问权限的 Kestrel docker 容器
  • Nginx Docker container that has public access on port 80 and forwards requests to backend kestrel server. Nginx Docker 容器在端口 80 上具有公共访问权限并将请求转发到后端 kestrel 服务器。

nginx.conf nginx.conf

http {
        upstream backendservers {
                server kestrel:80;
        }
        server {
                listen 80;
                location / {
                        proxy_pass http://backendservers/;
                        proxy_set_header Host $host;
                        proxy_set_header X-Real-IP $remote_addr; 
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Host $host:443;
                        proxy_set_header X-Forwarded-Server $host;
                        proxy_set_header X-Forwarded-Port 443;
                        proxy_set_header X-Forwarded-Proto https;
                }
        }
}

events {

}

asp.net core code asp.net核心代码

// controller
public IActionResult GetIP()
{
   var ip = HttpContext.Connection.RemoteIpAddress.ToString();
   ViewBag.ip = ip;
   return View();
}

// view
@{
    ViewData["Title"] = "Get IP";
}

<div class="text-center">
   <p>@ViewBag.ip</p>
</div>

Docker startup: Docker 启动:

docker network create --driver=bridge stacknet
docker run -d --name=kestrel --restart=always -h kestrel.local --network=stacknet mykestrelimage
docker run -d --name=nginx --restart=always  -p 80:80 -h nginx.local --network=stacknet mynginximage

UPDATE 1: As a test I opened the Kestrel 80 port.更新 1:作为测试,我打开了 Kestrel 80 端口。 I can get client IP when I hit Kestrel directly I just can't get it when it's coming via Nginx reverse proxy.当我直接点击 Kestrel 时,我可以获得客户端 IP 当它通过 Nginx 反向代理来时我无法获得它。

UPDATE 2: Added some lines to ngix.conf as per suggestion of one of replies below but didn't seem to make a difference.更新 2:根据以下回复之一的建议,在 ngix.conf 中添加了一些行,但似乎没有什么不同。

I had similar issue this is what i tried and it fixed my issue..我有类似的问题,这是我尝试过的,它解决了我的问题..

  1. go to /etc/nginx/sites-available/ you will found default file where you had configured your servers like this. go 到/etc/nginx/sites-available/你会发现你已经像这样配置你的服务器的默认文件。
 server{ server_name example.com; location / { proxy_pass http://localhost:4000; proxy_set_header X-Real-IP $remote_addr; <---Add this line proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; <---this line too }

2.there will be one more file named proxy_params in /nginx folder make sure you have below lines in this file. 2. /nginx 文件夹中还有一个名为 proxy_params 的文件,请确保您在此文件中有以下行。

 proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  1. Most important in your back-end code get the IP like this.在您的后端代码中最重要的是像这样获得 IP。
 const ipAddress = req.headers['x-forwarded-for'] as string;

You can also check the request ip through this command.您也可以通过此命令查看请求 ip。

 $ sudo tail -f /var/log/nginx/access.log

You may need to forward the original IP.您可能需要转发原始 IP。 Here is NGinx's doc on the subject: https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/这是 NGinx 关于该主题的文档: https://www.nginx.com/resources/wiki/start/topics/examples/forwarded/

And an example of the older x-forwarded-for from: https://plone.lucidsolutions.co.nz/web/reverseproxyandcache/setting-nginx-http-x-forward-headers-for-reverse-proxy还有一个较旧的 x-forwarded-for 示例来自: https://plone.lucidsolutions.co.nz/web/reverseproxyandcache/setting-nginx-http-x-forward-headers-for-reverse-proxy

location / {
  proxy_pass              http://upstream/;
  proxy_set_header        Host               $host;
  proxy_set_header        X-Real-IP          $remote_addr;
  proxy_set_header        X-Forwarded-For    $proxy_add_x_forwarded_for;
  proxy_set_header        X-Forwarded-Host   $host:443;
  proxy_set_header        X-Forwarded-Server $host;
  proxy_set_header        X-Forwarded-Port   443;
  proxy_set_header        X-Forwarded-Proto  https;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM