• Nginx+Docker部署模式下 asp.net core 获取真实的客户端ip


    Nginx+Docker部署模式下 asp.net core 获取真实的客户端ip

    场景

    线上环境使用Nginx(安装在宿主机)+Docker进行部署,应用获取客户端ip地址不正确,获取客户端IP的代码为Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4()

    过程还原

    搭建一个webapi示例环境

    创建一个新项目

    dotnet new webapi -o getRealClientIp
    

    修改模板中的ValuesControllerGet方法

    // GET api/values
    [HttpGet]
    public ActionResult<string> Get()
    {
       return this.Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
    }
    

    容器相关配置

    docker-compose.yml

    version: '2'
    services:
        web:
          image: microsoft/dotnet:2.1-aspnetcore-runtime
          volumes:
            - ./publish:/app #站点文件
          command: dotnet /app/getRealClientIp.dll
          ports:
              - "5000:80"
          networks:
              test:
                  ipv4_address: 172.200.0.101
        nginx:
          image: nginx
          networks:
              test:
                  ipv4_address: 172.200.0.102
          volumes:
            - ./nginx.conf:/etc/nginx/nginx.conf:ro # nginx配置文件
          ports:
              - "5001:80"
    networks:
       test:
          ipam:
             config:
             - subnet: 172.200.0.0/16
               gateway: 172.200.0.1
    

    nginx.conf

    http {
        server {
            listen 80;
            access_log off;
            location / {
                proxy_pass http://172.200.0.101:80;
                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 Via "nginx";
            }
        }
    }
    events {
      worker_connections  1024;
    }
    

    运行查看效果

    运行
    dotnet publish -c Release -o ./publish #编译
    docker-compose up #运行容器
    
    直接访问站点
    curl http://localhost:5000/api/values
    172.200.0.1
    

    返回的ip地址172.200.0.1是配置的容器的网关地址,能获取到正确的ip

    访问通过nginx代理的地址
    curl http://localhost:5001/api/values
    172.200.0.102
    

    返回的ip地址172.200.0.102是nginx容器的地址,没有获取到正确的ip
    上面的nginx配置已经相关的转发参数,并且该参数配置之前能正常运行在php的环境;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    

    推断必须修改 asp.net core 相关代码,才能获取到真实的客户端ip地址,一番google之后,

    修改代码如下
    // GET api/values
    [HttpGet]
    public ActionResult<string> Get()
    {
        var ip = this.Request.Headers["X-Forwarded-For"].FirstOrDefault();
        if (string.IsNullOrEmpty(ip))
        {
            ip = this.Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
        }
        return ip;
    }
    

    重新编译运行

    dotnet publish -c Release -o ./publish #编译
    docker-compose up #运行容器
    
    curl http://localhost:5001/api/values
    172.200.0.1
    
    curl http://localhost:5000/api/values
    172.200.0.1
    

    直接访问和通过nginx代理访问返回的ip地址均为172.200.0.1,获取正确。

    结论

    asp.net core 使用 Request.HttpContext.Connection.RemoteIpAddress.MapToIPv4()获取客户端ip,不会自动取Header中X-Forwarded-For的值,需求单独处理。

    参考资料

  • 相关阅读:
    设置和查看时间
    通过linux ssh远程登录另一台Linux,无需密码,用证书验证
    openssl生成自签名证书
    技术集锦
    centos系统安装中文字体几种方法
    集群中几种session同步解决方案的比较
    leetcode 88. C++ 合并两个有序数组
    CycleGAN --- Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks
    剑指offer---二叉树的深度
    C++基础(2)
  • 原文地址:https://www.cnblogs.com/attackingmilo/p/docker-nginx-aspnetcore-realip.html
Copyright © 2020-2023  润新知