记一次LVS/Nginx环境下的访问控制
偶然间,我发现 Graphite 显示服务器网卡流量呈锯齿状,于是查了一下 Nginx 日志,发现有人在周期性抓我们的接口数据。我这爆脾气自然不能容忍这种行径。
简单分析一下访问日志,很容易就能拿到了可疑的 IP 段,直接用 iptables 封杀:
shell> iptables -A INPUT -s x.y.z.0/24 -j DROP
本以为世界会就此清净,可没想到一点儿用都没有。莫非小偷已经突破锁头的限制?不能够啊!直觉告诉我问题应该和 LVS 有关,可惜我对 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 命令抓包来印证:
说明:如上图所示那一堆 254 开头的字符串里保存的就是用户 IP 和端口等信息。
于是乎可以得出结论:在 RS 服务器上通过 iptables 来封杀用户 IP 无疑是没有意义的,如果一定要用 iptables,应该在 LVS 服务器上用,但实际情况是我无权操作 LVS 服务器,只能在 RS 服务器上想办法。既然 Nginx 能拿到用户 IP,那么我们就可以在 Nginx 上解决问题,有 Access,GEO 等模块可供选择,这里我们选择的是 GEO 模块:
geo $bad { default 0; x.y.z.0/24 1; } location / { if ($bad) { return 403; } }
关于 GEO 模块的例子,有一些不错的资料可供参考,这里我就不多说了。
建议继续学习:
- LVS hash size解决4096个并发的问题 (阅读:5442)
- LVS & MySQL NDB Cluster (阅读:4065)
- LVS & MySQL NDB Cluster (阅读:3732)
- 利用MySQL Cluster 7.0 + LVS 搭建高可用环境 (阅读:3455)
- 怎么样让 LVS 和 realserver 工作在同一台机器上 (阅读:3161)
- 在LVS上实现SNAT网关 (阅读:1361)
- 一些LVS实验配置、工具和方案 (阅读:1217)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:老王 来源: 火丁笔记
- 标签: LVS 访问控制
- 发布时间:2015-01-23 23:47:26
- [69] IOS安全–浅谈关于IOS加固的几种方法
- [68] Twitter/微博客的学习摘要
- [63] 如何拿下简短的域名
- [62] android 开发入门
- [61] Go Reflect 性能
- [60] find命令的一点注意事项
- [58] 流程管理与用户研究
- [57] 图书馆的世界纪录
- [55] Oracle MTS模式下 进程地址与会话信
- [55] 读书笔记-壹百度:百度十年千倍的29条法则