| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
jopen
10年前发布

记一次LVS/Nginx环境下的访问控制

原文  http://huoding.com/2015/01/23/412

偶然间,我发现 Graphite 显示服务器网卡流量呈锯齿状,于是查了一下 Nginx 日志,发现有人在周期性抓我们的接口数据。我这爆脾气自然不能容忍这种行径。

简单分析一下访问日志,很容易就能拿到了可疑的 IP 段,直接用 iptables 封杀:

shell> iptables -A INPUT -s x.y.z.0/24 -j DROP

本以为世界会就此清净,可没想到一点儿用都没有。莫非小偷已经突破锁头的限制?不能够啊!直觉告诉我问题应该和 LVS 有关,可惜我对 LVS 的了解极其匮乏,唯一知道的就是项目用的是 FULLNAT 模式,那就以此为切入点开始挖掘:

记一次LVS/Nginx环境下的访问控制

LVS FULLNAT

所谓 FULLNAT 模式,是指当用户请求经由 LVS 转发给 RS 服务器的时候,其来源 IP 会从用户 IP 改成 LVS 内网 IP,目标 IP 会从 LVS 的 VIP 改成 RS 服务器的 IP;当 RS 服务器生成响应数据经由 LVS 返回给用户的时候,其来源 IP 会从 RS 服务器 IP 改成 LVS 的 VIP,目标 IP 会从 LVS 内网 IP 改成用户 IP。

说明:关于 LVS 更详细的介绍请参考「 从一个开发的角度看负载均衡和LVS 」一文。

对于 RS 服务器而言,实际上它看到的是 LVS。可我们明明在 Nginx 日志里看到了客户端的 IP,而不是 LVS 的 IP,这又是什么原因呢?原来 LVS 为了解决 FULLNAT 模式下传递用户 IP 的问题,引入了一个名为 TOA 的补丁机制,在 TCP 的三次握手阶段,通过 TCP 的 options 来传递用户 IP 和端口等信息,继而覆盖 socket 的 IP 和端口数据。

换句话说,在 RS 服务器上,从 iptables 的角度看,因为 NAT 的缘故,来源 IP 都是 LVS 的 IP;而从 Nginx 的角度看,因为 TOA 的缘故,来源 IP 都是用户的 IP。关于这一点也可以通过 tcpdump 命令抓包来印证:

记一次LVS/Nginx环境下的访问控制

tcpdump

说明:如上图所示那一堆 254 开头的字符串里保存的就是用户 IP 和端口等信息。

于是乎可以得出结论:在 RS 服务器上通过 iptables 来封杀用户 IP 无疑是没有意义的,如果一定要用 iptables,应该在 LVS 服务器上用,但实际情况是我无权操作 LVS 服务器,只能在 RS 服务器上想办法。既然 Nginx 能拿到用户 IP,那么我们就可以在 Nginx 上解决问题,有 AccessGEO 等模块可供选择,这里我们选择的是 GEO 模块:

geo $bad {    default 0;    x.y.z.0/24 1;  }  location / {    if ($bad) {      return 403;    }  }

关于 GEO 模块的例子,有一些不错的 资料 可供参考,这里我就不多说了。

</div> </div>

 本文由用户 jopen 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!