IP黑白名单

1、ddos攻击

DDOS又称为分布式拒绝服务,全称是Distributed Denial of Service。DDOS本是利用合理的请求造成资源过载,导致服务不可用。

比如一个停车场总共有100个车位,当100个车位都停满车后,再有车想要停进来,就必须等已有的车先出去才行。如果已有的车一直不出去,那么停车场的入口就会排起长队,停车场的负荷过载,不能正常工作了,这种情况就是“拒绝服务”。我们的系统就好比是停车场,系统中的资源就是车位。资源是有限的,而服务必须一直提供下去。如果资源都已经被占用了,那么服务也将过载,导致系统停止新的响应。

分布式拒绝服务攻击,将正常请求放大了若干倍,通过若干个网络节点同时发起攻击,以达成规模效应。这些网络节点往往是黑客们所控制的“肉鸡”,数量达到一定规模后,就形成了一个“僵尸网络”。大型的僵尸网络,甚至达到了数万、数十万台的规模。如此规模的僵尸网络发起的ddos攻击,几乎是不可阻挡的。

常见的DDOS攻击有SYN flood、UDP flood、ICMP flood等。其中SYN flood是一种最为经典的DDOS攻击,其发现于1996年,但至今仍然保持着非常强大的生命力。SYN flood如此猖獗是因为它利用了TCP协议设计中的缺陷,而TCP/IP协议是整个互联网的基础,牵一发而动全身,如今想要修复这样的缺陷几乎成为不可能的事情。

Syn_Flood攻击原理:

攻击者首先伪造地址对服务器发起SYN请求(我可以建立连接吗?),服务器就会回应一个ACK+SYN(可以+请确认)。而真实的IP会认为,我没有发送请求,不作回应。服务器没有收到回应,会重试3-5次并且等待一个SYNTime(一般30秒-2分钟)后,丢弃这个连接。

如果攻击者大量发送这种伪造源地址的SYN请求,服务器端将会消耗非常多的资源来处理这种半连接,保存遍历会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试。TCP是可靠协议,这时就会重传报文,默认重试次数为5次,重试的间隔时间从1s开始每次都番倍,分别为1s+ 2s + 4s + 8s +16s = 31s,第5次发出后还要等32s才知道第5次也超时了,所以一共是31 + 32 = 63s。

也就是说一个假的syn报文,会占用TCP准备队列63s之久,也就是说在没有任何防护的情况下,频繁发送伪造的伪造syn包,就会耗尽连接资源,从而使真正的连接无法建立,无法响应正常请求。 最后的结果是服务器无暇理睬正常的连接请求—拒绝服务。

Syn_Flood防御:

cookie源认证:

原理是syn报文首先由ddos防护系统来响应syn_ack。带上特定的sequencenumber (记为cookie)。真实的客户端会返回一个ack 并且Ack number为cookie+1。 而伪造的客户端,将不会作出响应。这样我们就可以知道那些IP对应的客户端是真实的,将真实客户端IP加入白名单。下次访问直接通过,而其他伪造的syn报文就被拦截。

reset认证:

Reset认证利用的是TCP协议的可靠性,也是首先由DDOS防护系统来响应syn。防护设备收到syn后响应syn_ack,将Ack number (确认号)设为特定值(记为cookie)。当真实客户端收到这个报文时,发现确认号不正确,将发送reset报文,并且sequence number 为cookie + 1。 而伪造的源,将不会有任何回应。这样我们就可以将真实的客户端IP加入白名单。

在很多对抗DDOS的产品中,一般会综合使用各种算法,结合一些DDOS攻击的特征,对流量进行清洗。对抗DDOS的网络设备可以串联或者并联在网络出口处。但DDOS仍然是业界的一个难题,当攻击流量超过了网络设备,甚至带宽的最大负荷时,网络仍将瘫痪。一般来说,大型网站之所以看起来比较能“抗”DDOS攻击,是因为大型网站的带宽比较充足,集群内服务器的数量也比较多。但一个集群的资源毕竟是有限的,在实际的攻击中,DDOS的流量甚至可以达到数G到几十G,遇到这种情况,只能与网络运营商合作,共同完成DDOS攻击的响应。

2、cc攻击

CC攻击是DDOS攻击的一种方式,可以理解为是应用层的DDOS攻击。

攻击者借助代理服务器生成指向受害主机的合法请求,实现DDOS和伪装就叫:CC(Challenge Collapsar)。

CC攻击的原理非常简单,就是对一些消耗资源较大的应用页面不断发起正常的请求,以达到消耗服务端资源的目的。在Web应用中,查询数据库、读/写硬盘文件等操作,相对都会消耗比较多的资源。一个很典型的例子:

String sql = " select * from post where targid=${targid} order by postid desc limit ${start},30";

当post表数据庞大,翻页频繁,${start}数字急剧增加时,查询结果集=${start}+30;该查询效率呈明显下降趋势,而多并发频发调用,因查询无法立即完成,资源无法立即释放,会导致数据库请求连接过多,数据库阻塞,网站无法正常打开。

CC就是充分利用了这个特点,模拟多个用户不停的进行访问那些高计算、高IO的数据。为什么要使用代理呢?因为代理可以有效地隐藏自己的身份,也可以绕开所有的防火墙,因为基本上所有的防火墙都会检测并发的TCP/IP连接数目,超过一定数目一定频率就会被认为是Connection-Flood。

在互联网中充斥着各种搜索引擎、信息收集等系统的爬虫(spider),爬虫把小网站直接爬死的情况时有发生,这与应用层DDOS攻击的结果很像。

应用层DDOS攻击还可以通过以下方式完成:在黑客入侵了一个流量很大的网站后,通过篡改页面,将巨大的用户流量分流到目标网站。

<!--那么访问该页面的用户,都将对target发起一个get请求,这可能直接导致target拒绝服务--> <iframe src="http://target" height="0" width="0"> </iframe>

应用层DDOS攻击是针对服务器性能的一种攻击,那么许多优化服务器性能的方法,都或多或少地能缓解此种攻击。比如将使用频率高的数据放在memcache中,相对于查询数据库所消耗的资源来说,查询memcache所消耗的资源可以忽略不计。

但很多性能优化的方案并非是为了对抗应用层DDOS攻击而设计的,因此攻击者想要找到一个资源消耗大的页面并不困难。比如当memcache查询没有命中时,服务器必然会查询数据库,从而增大服务器资源的消耗,攻击者只需要找到这样的页面即可。

同时攻击者除了触发“读”数据操作外,还可以触发“写”数据操作,“写”数据的行为一般都会导致服务器操作数据库。

3、cc防护

应用层DDOS攻击并非一个无法解决的难题,一般来说,我们可以从以下几个方面着手。

首先,应用代码要做好性能优化。 合理地使cache就是一个很好的优化方案,将数据库的压力尽可能转移到内存中。此外还需要及时地释放资源,比如及时关闭数据库连接,减少空连接等消耗。

其次,在网络架构上做好优化。 善于利用负载均衡分流,避免用户流量集中在单台服务器上。同时可以充分利用好cdn和镜像站点的分流作用,缓解主站的压力。

再有,使用页面静态化技术,利用客户端浏览器的缓存功能或者服务端的缓存服务,以及CDN节点的缓冲服务,均可以降低服务器端的数据检索和计算压力,快速响应结果并释放连接进程。

最后,也是最重要的一点,实现一些对抗手段,比如限制每个IP地址的请求频率,超出限制策略后动态加入黑名单

(1)验证码

比如下是一个用户提交评论的页面,嵌入验证码能够有效防止资源滥用,因为通常脚本无法自动识别出验证码。但验证码也分三六九等,有的验证码容易识别,有的则较难识别。验证码发明的初衷,是为了识别人与机器。但验证码如果设计得过于复杂,那么人也很难辨识出来,所以验证码是一把双刃剑。

(2)Detecting system abuse

Yahoo为我们提供了一个解决思路。如果发起应用层DDOS攻击的IP地址都是真实的,所以在实际情况中,攻击者的IP地址其实也不可能无限制增长。假设攻击者有1000个IP地址发起攻击,如果请求了10000次,则平均每个IP地址请求同一页面达到10次,攻击如果持续下去,单个IP地址的请求也将变多,但无论如何变,都是在这1000个IP地址的范围内做轮询。

为此Yahoo实现了一套算法,根据IP地址和Cookie等信息,可以计算客户端的请求频率并进行拦截。Yahoo设计的这套系统也是为Web Server开发的一个模块,但在整体架构上会有一台master服务器集中计算所有IP地址的请求频率,并同步策略到每台Webserver上。

Yahoo设计的这套防御体系,经过实践检验,可以有效对抗应用层DDOS攻击和一些类似的资源滥用攻击。但Yahoo并未将其开源,因此对于一些研发能力较强的互联网公司来说,可以根据专利中的描述,实现一套类似的系统。

4、IP黑白名单方式

IP黑白名单

  • Web 应用防火墙 – IP黑白名单配置
  • CDN – 配置IP黑白名单
  • DDoS防护 – 配置黑白名单
  • 开发IP黑白名单功能

(1)OpenResty

OpenResty是一个基于 Nginx的可伸缩的 Web 平台,由中国人章亦春发起,提供了很多高质量的第三方模块。OpenResty 是一个强大的 Web 应用服务器,Web 开发人员可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua模块,更主要的是在性能方面,OpenResty可以快速构造出足以胜任 10K 以上并发连接响应的超高性能 Web 应用系统。360,UPYUN,阿里云,新浪,腾讯网,去哪儿网,酷狗音乐等都是 OpenResty 的深度用户。

(2)Lua

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。Lua 是巴西里约热内卢天主教大学里的一个研究小组于 1993 年开发的。

通过Lua编写限流、权限认证、黑白名单等功能

Lua 特性:

轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。

可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。

5、动态黑名单实现

(1)安装OpenResty

# 下载 wget https://openresty.org/download/ngx_openresty-1.9.7.1.tar.gz # 解压 tar xzvf ngx_openresty-1.9.7.1.tar.gz cd ngx_openresty-1.9.7.1/ # 配置 ./configure # 编译 make # 安装 make install # 配置 nginx profile PATH PATH=/usr/local/openresty/nginx/sbin:$PATH export PATH # 指定配置 nginx -c /usr/local/openresty/nginx/conf/nginx.conf

(2)配置

用 OpenResty 以及下面的 redis 组件,配置redis数据库信息及黑名单策略

set $redis_service "127.0.0.1"; set $redis_port 6380; set $redis_db 0; # 1 second 50 query set $black_count 50; set $black_rule_unit_time 1; set $black_ttl 3600; set $auto_blacklist_key blackkey;

redis_service: redis 服务器 ip 地址

redis_port: redis 服务器端口

redis_db:所使用的redis db

black_count:拉黑限制的最大访问次数

black_rule_unit_time:拉黑限制次数的保存时间,即保存访问次数的 kv 的ttl

black_ttl:黑名单的存活时间

auto_blacklist_key: kv 的部分 key

重点控制好 black_count 和 black_rule_unit_time

(3)lua 脚本

ip_blacklist.lua,从 ip 及 token(访问凭证) 入手来控制

local redis_service = ngx.var.redis_service local redis_port = tonumber(ngx.var.redis_port) local redis_db = tonumber(ngx.var.redis_db) local black_count = tonumber(ngx.var.black_count) local black_rule_unit_time =tonumber(ngx.var.black_rule_unit_time) local cache_ttl = tonumber(ngx.var.black_ttl) local remote_ip = ngx.var.remote_addr -- 计数 function my_count(redis, status_key, count_key) local key = status_key local key_connect_count = count_key local Status = redis:get(key) local count = redis:get(key_connect_count) if Status ~= ngx.null then -- 状态为connect 且 count不为空 且 count <= 拉黑次数 if (Status == "Connect" and count ~= ngx.null and tonumber(count) <= black_count) then -- 再读一次 count = redis:incr(key_connect_count) ngx.log(ngx.ERR, "count:", count) if count ~= ngx.null then if tonumber(count) > black_count then redis:del(key_connect_count) redis:set(key,"Black") -- 永久封禁 -- Redis:expire(key,cache_ttl) else redis:expire(key_connect_count,black_rule_unit_time) end end else ngx.log(ngx.ERR,"The visit is blocked by the blacklist because it is too frequent. Please visit later.") return ngx.exit(ngx.HTTP_FORBIDDEN) end else local count = redis:get(key) if count == ngx.null then redis:del(key_connect_count) end redis:set(key,"Connect") redis:set(key_connect_count,1) redis:expire(key,black_rule_unit_time) redis:expire(key_connect_count,black_rule_unit_time) end end -- 读取token local token local header = ngx.req.get_headers()["Authorization"] if header ~= nil then token = string.match(header, 'token (%x+)') end local redis_connect_timeout = 60 local redis = require "resty.redis" local Redis = redis:new() local auto_blacklist_key = ngx.var.auto_blacklist_key Redis:set_timeout(redis_connect_timeout) local RedisConnectOk,ReidsConnectErr = Redis:connect(redis_service,redis_port) local res = Redis:auth("password"); if not RedisConnectOk then ngx.log(ngx.ERR,"ip_blacklist connect Redis Error :" .. ReidsConnectErr) else -- 连接成功 Redis:select(redis_db) local key = auto_blacklist_key..":"..remote_ip local key_connect_count = auto_blacklist_key..":key_connect_count:"..remote_ip my_count(Redis, key, key_connect_count) if token ~= nil then local token_key, token_key_connect_count token_key = auto_blacklist_key..":"..token token_key_connect_count = auto_blacklist_key..":key_connect_count:"..token my_count(Redis, token_key, token_key_connect_count) end end 

至于对于添加到黑名单的 ip 及 token,需要怎么做下一步的处理,这边就给服务器下的具体应用来处理,在这里不阐述。

(4)配置到 nginx 的 conf 当

server { listen 80; server_name edu.lagou.com; root /~/public; # 加载配置文件 include /etc/nginx/conf.d/blacklist_params; # 指定请求中需要执行的 lua 脚本 access_by_lua_file /etc/nginx/conf.d/ip_blacklist.lua; location / { } error_log /etc/nginx/conf.d/log/error.log; access_log /etc/nginx/conf.d/log/access.log; }

配置就完成了,在 console 中重启下 nginx nginx -s reload ,就可以实现动态添加黑名单的需要了。至于对于添加到黑名单的 ip 及 token,需要怎么做下一步的处理,这边就给服务器下的具体应用来处理,在这里不阐述。

API 网关Kong,基于OpenResty,开源于2015年,核心价值在于其高性能和跨站性。从全球500强的组织统计数据来看,Kong现在是维护的、在生产环境使用最广泛的网关。Plugin IP Restriction通过设置IP白名单和黑名单,根据客户端IP来对一些请求进行拦截和防护。

原文链接:https://blog.csdn.net/weixin_52851967/article/details/126027692?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169114731016800225514831%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=169114731016800225514831&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~times_rank-7-126027692-null-null.268%5Ev1%5Ekoosearch&utm_term=cc%E9%98%B2%E6%8A%A4

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/22208

(0)
上一篇 2024年3月15日 13:34
下一篇 2024年3月15日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml