查看原文
其他

几种方法有效屏蔽国外IP恶意扫描

运维研习社 运维研习社 2022-11-05


最近有朋友说,查看nginx访问日志,发现大量的恶意扫描,分析发现比正常业务访问量都大,且IP大部分来自国外,服务器用的按量付费,这刷的都是白花花的银子,想问下有没有解决方案


今天就介绍几种方法,来屏蔽这些脚本小子的恶意扫描





GeoDNS



GeoDNS是基于地域的DNS解析,可以将DNS的解析,根据地域划分,解析到不同的IP地址,现在很多免费的运营商都支持GeoDNS,比如google的Route53、阿里云的智能dns、腾讯的DNSpod、华为云等,都有这种服务,通常我们是用来做地域访问控制的,不同的地区用户,访问就近地区部署的服务


对于上面提到的恶意请求,大多来源于国外,而业务根本不可能有国外用户的情况下,可以直接将国外的dns解析到随便找个国外的IP上面,可以是一些DNS节点IP或者其他,也就是将恶意请求的IP引入黑洞


这种方法不需要技术、不需要配置服务器,从根源上直接解决





防火墙屏蔽



这里说的防火墙是服务器内置防火墙,防火墙本身就是起屏蔽、拦截作用的,我们可以通过配置防火墙来进行屏蔽国外的IP,或恶意IP


在linux中我们通常都是通过iptables来封IP,首先我们需要获取所有的IP地址段,才能进行封IP的操作


IP地址段,我们可以通过APNIC获取,APNIC是全球5个地区级的Internet注册机构之一,主要负责亚太地区,而且每日更新,信息列表地址http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-late


思路就是使用Iptables添加CN部分的IP到ACCEPT规则中,其余的全部DROP,这里有个问题就是,即便只是添加CN部分的IP段,量也比较大,这样逐条添加和加载IPtables规则的时候,很影响并发性能


在iptables中,包含几个表,每个表由链组成,默认是filter表,最常用的也是filter表,另外一个比较常用的是nat表,封IP就是在filter表的INPOUT链添加规则


在进行规则匹配的时候,是从规则列表中从头到尾一条一条进行匹配,所以当规则太多的时候,加载就会影响性能,所以这里推荐用ipset的方式,ipset能把这种O(n)的操作变成O(1),就是把要处理的IP放进一个集合,对这个集合设置一条iptables规则


ipset可以直接通过yum安装,安装完成之后可以创建ip集合

通过创建一个ip集合,然后再通过iptables将来源为这个集合中的IP允许,其他的全部DROP掉


集合有了,内容还需要添加,ipset通过ipset add来添加ip,这里直接献上一个简单的脚本



脚本很简单,从APNIC下载最新的IP表,然后截取除CN部分的IPv4,然后保存为一个白名单列表,然后从白名单列表中遍历,通过ipset添加到ip集合中,把这个脚本定时任务做一下,就可以定时更新ipset的集合


ipset常用的几个命令这里简单说一下

  • ipset del yoda x.x.x.x # 从 yoda 集合中删除内容

  • ipset list yoda # 查看 yoda 集合内容

  • ipset list # 查看所有集合的内容

  • ipset flush yoda # 清空 yoda 集合

  • ipset flush # 清空所有集合

  • ipset destroy yoda # 销毁 yoda 集合

  • ipset destroy # 销毁所有集合

  • ipset save yoda # 输出 yoda 集合内容到标准输出

  • ipset save # 输出所有集合内容到标准输出

  • ipset restore # 根据输入内容恢复集合内容


通过这样的方式对恶意请求IP进行控制,可以相对更灵活的划分地区、国家、IP段等





Nginx的GeoIP



nginx中有一个GeoIP模块,也是用来做地域识别,该模块依赖于GeoIP,并且需要从geolite下载最新的IP数据包


nginx的geoip模块,默认未开启,需要重新编译添加该模块

编译之前,需要确保服务器已经安装了geoip和geoip-devel两个库


IP数据包,需要从geolite2下载,现在由于数据隐私法规的问题,需要注册账户才能免费下载,地址:https://dev.maxmind.com/geoip/geoip2/geolite2/


下载完成后,将包放在/usr/share/GeoIP下面即可,然后在nginx的http模块中配置ip数据包的地址


接着就可以通过geoip模块解析ip地址来进行操作,对于上面遇到的问题,我们可以通过设置geo_country_code=CN,以允许访问,其他则全部return 444来拒绝恶意访问


nginx中其他的geoip模块的指令还包括:

  • $geoip_country_code; – 两个字母的国家代码,如:”RU”, “US”

  • $geoip_country_code3; – 三个字母的国家代码,如:”RUS”, “USA”

  • $geoip_country_name; – 国家的完整名称,如:”Russian Federation”, “United States”

  • $geoip_region – 地区的名称(类似于省,地区,州,行政区,联邦土地等),如:”30”。30代码就是广州的意思

  • $geoip_city – 城市名称,如”Guangzhou”, “ShangHai”(如果可用)

  • $geoip_postal_code – 邮政编码

  • $geoip_city_continent_code

  • $geoip_latitude – 所在维度

  • $geoip_longitude – 所在经度

  • $geoip_org – 所在组织

  • $geoip_proxy – 定义可信地址

  • $geoip_proxy_recursive – 整个代理链中是否递归匹配,不递归的话,默认用x-forwarded-for中最后一个地址

所以还可以更精确或者更细致的通过地域来控制访问,这种方式虽然可以更细致的划分地域,但是请求也是到达nginx上的,虽然可以防范web的恶意扫描,但是更推荐在系统层直接iptables drop掉


nginx的geoip更合适的地方在于,根据用户地域,返回不同后端业务,做页面定制化等


对于没有国际业务的网站、应用等,通过屏蔽国外IP或者国内IP白名单的方式,可以屏蔽掉很大一部分恶意扫描,从根源上来降低被攻击面,可以起到一定的防护作用


gpreftools动态追踪nginx,进行性能分析 利用nginx流量镜像,优雅的接入waf Nginx/Openresty内存泄露及目录穿越漏洞复现 



更多精彩内容请扫描下方二维码关注公众号


扫描二维码关注我们吧



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存