您的位置:首页 > 新闻资讯 >文章内容
如何使用Nginx代理防止IP伪造?
来源: 作者:admin 时间:2020-01-16 15:42:01

    1  问题场景


    在解决Session劫持()的问题时,添加了客户端IP和user-agent的验证,使得攻击者在得到sessionId的同时还需要模拟IP和user-agent的信息,增加了破解难度。但是使用Postman等工具,还是很容易伪造IP。


如何使用Nginx代理防止IP伪造?


    为了弄清楚是怎样做到伪造IP的,我们首先看一下是怎样我们的代码中获取IP的方式。


    2  获取IP的方式


    我们首先来看一下在Java中获取客户端IP的方式:


    在中间没有代理时,直接使用request.getRemoteAddr() 获取;


    当有Nginx做反向代理和负载均衡时,使用request.getRemoteAddr() 得到的是代理Nginx所在服务器的IP。这是因为HTTP协议是基于TCP协议的,request.getRemoteAddr() 获取到的是TCP层直接连接的客户端的IP。为了解决这个问题,很多HTTP代理会在HTTP协议头中添加X-Forwarded-For头,用来追踪请求的来源。


    例如,我们做了两层代理,IP分别是proxy1和proxy2,客户端的IP为client。当我们分别在proxy1和proxy2中配置:


    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for


    这时使用request.getHeader("x-forwarded-for") 得到的值是”client, proxy1” 。这里可能会有疑问,感觉应该是”client, proxy1, proxy2”, 注意$proxy_add_x_forwarded_for会将和Nginx直接连接的客户端IP追加在请求原有X-Forwarded-For值的右边。即proxy1追加了client,proxy2追加了proxy1。因此我们直接取IP串中的第一个IP就得到了客户端IP。


    在了解了IP的获取方式以后,下面我们再看一下这样做有什么问题。


    3  漏洞展示


    上边我们知道了IP是从请求头的X-Forwarded-For中获取到的,而使用Postman也正是通过X-Forwarded-For来伪造IP的,如果客户端在发起请求时,请求头上带上一个伪造的X-Forwarded-For,由于后续每层代理只会追加而不会覆盖,那么最终到达应用服务器时,获取的左边第一个IP地址将会是客户端伪造的IP。如下图所示:


    这时我们拿到的IP串变成了”伪造IP, client1, proxy1”,这样攻击者就可以伪造我们的IP,sessionId等信息获取访问系统的权限了。


    那么怎样解决这个问题呢?


    4  解决方案


    方法一:Nginx


    在一级代理的Nginx中配置:


    proxy_set_header  X-Forwarded-For  $remote_addr;


    在次级代理的Nginx中配置:


    proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;


    这样使用request.getHeader("x-forwarded-for") 得到的值始终是”client, proxy1” 。


    $remote_addr是与Nginx直接TCP连接的客户端IP,这个是无法伪造的,$remote_addr会把X-Forwarded-For中的值直接替换掉,因此当一级代理配置了此值以后伪造的IP不会拼接,而且不能在次级代理配置,因为次级代理的IP会把客户端IP替换掉;


    5  Nginx配置效果展示


    先准备四个IP,分别是客户端client,代理一proxy1,代理二proxy2和伪造IP,我们分以下几种情况来查看X-Forwarded-For中的值。


    1) 代理一、二都不配置$remote_addr和$proxy_add_x_forwarded_for时:


    不伪造:null;


    伪造:伪造IP。


    2) 代理一、二都只配置$proxy_add_x_forwarded_for:


    不伪造:client, proxy1;


    伪造:伪造IP, client, proxy1。


    3) 代理一、二都只配置$remote_addr:


    不伪造:proxy1;


    伪造:proxy1。


    4) 代理一配置$remote_addr,代理二配置$proxy_add_x_forwarded_for:


    不伪造:client, proxy1;


    伪造:client, proxy1。


    5) 代理一配置$proxy_add_x_forwarded_for,代理二配置$remote_addr:


    不伪造:proxy1;


    伪造:proxy1。


    由此可见,我们使用4)的配置可以满足。


    6  说明


    使用上边所说的方法可以解决伪造IP的问题,但是对于获取真正发起请求的客户端IP仍然是有漏洞的,比如说如果攻击者自己搭建几台Nginx服务器代理,那么我们获取到的仍然是攻击者的代理IP。


相关文章内容简介
在线咨询
大客户经理
大客户经理
1829380381
13316264505

大客户经理微信

微信公众号

微信公众号

回到顶部