Nginx IP属地

通过HttpServletRequest得到的IP统一: 127.0.0.1
因为使用了Nginx反射代理,修改Nginx的配置并重载Nginx即可

项目中使用request.getRemoteAddr();对来源IP进行了判断,相同IP地址半小时只能上传一次数据,我测试的时候本机访问次数没有这么多次,而且这个数据初次访问时间是项目正式部署上线的时间,是生产环境产生的日志,生产环境怎么会拿到本机地址呢?
经过一番研究

解决办法: 在nginx配置文件nginx.conf

proxy_set_header Host $http_host;//包含客户端真实的域名和端口号
proxy_set_header X-Real-IP $remote_addr;//表示客户端真实的IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;//这个Header和X-Real-IP类似,但它在多层代理时会包含真实客户端及中间每个代理服务器的IP。
proxy_set_header X-Forwarded-Proto $scheme;//表示客户端真实的协议(http还是https)


# Nginx设置如下

location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header REMOTE-HOST $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

过程:

使用Github Search:
  1. 基于qqwry.dat查找ip归属地的java程序 miraclesu/IPLocator

    使用17moncnIP专属查询库 ,年代久远,DAT文件已未更新。通过IP地址本地解析

    使用纯真IP库,下载离线版EXE,安装后文件夹中存在 qqwry.dat 文件

    直接调用(推荐,效率最高):

    String ip = "202.108.22.5";
    QQWryFile qqWryFile = QQWryFile.getInstance();
    RandomAccessFile ipFile = qqWryFile.getIpFile();
    QQWryRecord record = qqWryFile.find(ip, ipFile);
    System.out.println(Utils.ipToStr(record.getBeginIP()));
    System.out.println(Utils.ipToStr(record.getEndIP()));
    System.out.println(record.getCountry());
    System.out.println(record.getArea());
    

    想要直接调用成功,需要将项目中的类都导入到项目中

  2. 使用ip2region -> 需要生成 xdb。

    ip2region 是什么?
    官方:ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java,php,c,python,nodejs,golang,c#等查询绑定和Binary,B树,内存三种查询算法

    其实就是一个库,用于 IP地址解析定位用的,支持很多客户端,速度很快也不占内存,目前github已经到了10k star 了

    特性:

    准确率高,数据聚合多个供应商的数据
    体积小,空间优化形成了仅仅几兆的 ip2region.db 文件
    速度快,内置三种查询算法,支持毫秒级查询
    支持多客户端,支持很多客户端,java、C#、php、c、python、nodejs、php扩展(php5和php7)、golang、rust、lua、lua_c, nginx
    它的数据聚合了一些知名ip到地名查询提供商的数据,例如:(如果一下开放API或者数据都不给开放数据时ip2region将停止数据的更新服务)

    淘宝IP地址库, http://ip.taobao.com/
    GeoIP, https://geoip.com/
    纯真IP库, http://www.cz88.net/

    mica,在 mvnrepository 中发现,相较于org.lionsoul 更快捷。 使用的版本为 2.6.3

    <!-- IP属地 https://gitee.com/lionsoul/ip2region -->
            <!--<dependency>-->
                <!--<groupId>org.lionsoul</groupId>-->
                <!--<artifactId>ip2region</artifactId>-->
                <!--<version>2.6.5</version>-->
            <!--</dependency>-->
    
    <!-- IP属地 无需生成xdb -->
            <dependency>
                <groupId>net.dreamlu</groupId>
                <artifactId>mica-ip2region</artifactId>
                <version>2.6.3</version>
            </dependency>
    

    导入Maven后直接 @Autowired 或者 @Resource,调用查询

     @Resource
     Ip2regionSearcher ip2regionSearcher;
    // 通过工具类得到请求的真实IP
    ip = getIpAddress();
    
     // 根据ip地址获取到address
    IpInfo ipInfo = ip2regionSearcher.memorySearch(ip);
    if (null != ipInfo){
        System.out.println(ipInfo.getAddress());
        System.out.println(ipInfo.getIsp());
    }
    

相关使用参考:

ip2region - 基础篇

ip2region - 使用篇

更新2022年08月03日 21:20:45
发现IP属地大部分都能成功获取,存在部分传递过来还是127.0.0.1,查看了 HttpServletRequest 获取的IP并没有问题,Nginx配置也没有问题。

image-20220802095259666

那么这个获取到的内网IP的通过什么形式获取到的呢?百思不得其解

隔天一觉睡醒幡然醒悟,127.0.0.1 则等于 localhost ,也就是服务器本身直接发送甚至未经过Nginx代理转发。

情景复现,通过公网IP直接访问并执行操作,发现果然如此,解析获取到的是内网IP。

怀疑:公网IP泄漏,从行为上来看直接通过公网IP访问网站的几率很小。可以PASS

回头一想,Https和Http的默认端口分别是 443 、80。

而我Https安全证书SSL 443的端口在Nginx已经配置完成,而80端口,非安全访问没有进行配置。

很明显部分用户是通过Http协议访问的网站,80端口转发直接是内网IP。

在80端口下设置好Nginx.conf

proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

再次查看

image-20220802115124642

已可以正确获取到对应的IP属地

自此引申出另外一个问题:禁止通过公网IP直接访问网站。

通过公网IP直接访问网站其实是需要禁止的,这样做是为了避免别人把未备案的域名解析到自己的服务器IP而导致服务器被断网

在使用的时候会遇到很多的恶意IP攻击,这个时候就要用到Nginx 禁止IP访问了。

Nginx禁止IP访问

Nginx禁止IP直接访问

止IP访问](https://developer.aliyun.com/article/548497?spm=a2c6h.12873639.article-detail.28.122af1ccGxZn81)

Nginx禁止IP直接访问

  • 18
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值