首页 网络安全——DDoS拒绝访问攻击与防御
文章
取消

网络安全——DDoS拒绝访问攻击与防御

网络安全——拒绝访问攻击与防御

[TOC]

前置工作

实验系统设计

实验系统架构设计如下图所示。攻击集群由两台本地机器和⼀个云服务器节点组成。其中⽤于攻击的服务器节点配置为1C2G,带宽4Mbps,流量上限500GB/⽉。具体攻击⽅式和过程将在后续章节描述。攻击流量将经由互联⽹到达⼀台位于阿里云的服务器节点。该服务器配置为1C2G,带宽5Mbps,流量上限1000GB/月。 在被攻击⼀侧,设置有基于Oracle Apex的简单Web服务程序。该程序基于Tomcat服务器,通过ORDS与Apex Engine访问Oracle数据库。应用提供⼀些简单的RESTful接⼝。该程序默认监听8080端⼝,当8080端口并不对外网开放。同时有Nginx监听80端⼝反向代理该Web服务器。此外,配置有 CentOS默认的firewall防⽕墙。 为实现对被攻击节点和攻击流量的实时监控和可视化,被攻击节点同时配置有 Prometheus的Node Exporter,在9100端⼝提供当前服务器节点的负载和⽹络连接数 据。Web服务程序通过引⼊Prometheus的micrometer提供服务层⾯的流量和负载数 据。监控平台节点是⼀台位于阿里云的1C2G服务器,带宽上限1Mbps,设置有 Prometheus实时采集和存储上述数据,配置Grafana作为监控数据可视化的⼯作平台。

绘图2

被攻击应用介绍

为实现分布式拒绝服务攻击的真实模拟,我们选用了一款在企业中实际使用的Web应用——进销存系统。该应用基于Oracle Apex等框架和⼯具实现。为模拟攻击的真实性,服务器程序初始运⾏时将数千条销售单数据员写⼊数据库。在校园实验室内的⼀般网络条件下,耗时低的接口响应时间约50ms,耗时高接口响应时间在500ms以上。应用页面如下图所示。

image-20220315191831248

image-20220315191903081

节点监控

为便捷监控节点负载,实时显示攻击流量和效果,我们额外使⽤⼀台服务器节点部署 Prometheus实时收集被攻击节点的负载以及Tomcat内存使用和GC频率等数据,并部署Grafana作为数据可视化的平台。

部署启动后,我们使用社区设计提供的 Node Exporter for Prometheus Dashboard、 和 SLS JVM监控⼤盘分别展示服务器节点、⽹络和应用程序负载数据。部分界⾯效果如下。

image-20220313204719416

image-20220313213329998

网络攻击

HTTP泛洪攻击(HTTP Flood)

HTTP泛洪攻击简介

  • 定义
    • HTTP 洪水攻击是一种大规模分布式拒绝服务 (DDoS)攻击,旨在利用HTTP 请求使目标服务器不堪重负。目标因请求而达到饱和,且无法响应正常流量后,将出现拒绝服务,拒绝来自实际用户的其他请求。
    • HTTP 洪水攻击
  • 原理
    • HTTP 洪水攻击是“第 7 层”DDoS 攻击的一种。第 7 层是 OSI 模型的应用程序层,指的是 HTTP 等互联网协议。HTTP 是基于浏览器的互联网请求的基础,通常用于加载网页或通过互联网发送表单内容。缓解应用程序层攻击特别复杂,因为恶意流量和正常流量很难区分。

      为了获得最大效率,恶意行为者通常会利用或创建僵尸网络,以最大程度地扩大攻击的影响。通过利用感染了恶意软件的多台设备,攻击者可以发起大量攻击流量来进行攻击。

  • 分类

    • HTTP GET 攻击
      • 在这种攻击形式下,多台计算机或其他设备相互协调,向目标服务器发送对图像、文件或其他资产的多个请求。当目标被传入的请求和响应所淹没时,来自正常流量源的其他请求将被拒绝服务。
    • HTTP POST 攻击
      • 一般而言,在网站上提交表单时,服务器必须处理传入的请求并将数据推送到持久层(通常是数据库)。与发送 POST 请求所需的处理能力和带宽相比,处理表单数据和运行必要数据库命令的过程相对密集。这种攻击利用相对资源消耗的差异,直接向目标服务器发送许多 POST 请求,直到目标服务器的容量饱和并拒绝服务为止。

HOIC工具介绍

  • 简介

    • HOIC(The high orbit ion cannon)是一款基于HTTP 协议开源的DDOS 攻击工具,可用于内部网络或者外部服务器的安全性和稳定性的测试等等。
  • 特点
    • 高速多线程的HTTP 洪水攻击。
    • 一次可同时洪水攻击高达256 个网站。
    • 内置脚本系统,允许自行修改设置脚本,用来阻挠DDoS 攻
    • 击的防御措施,并增加DOS 输出。
    • 简单且易于使用的界面。
    • 可移植到Linux/ Mac。
    • 能够选择攻击的线程数。
    • 可设置三种攻击强度:低,中,高。
    • 用REALbasic 这种极其书面的语言写成,简单易修改。
  • 关键功能界面

    image-20220317112331519

实验内容

我们从HOIC的维基百科主页提供的下载地址中将HOIC下载到本地windows电脑当中。这个软件提供win、mac和linux不同版本。

HOIC的使用对于普通用户来说也十分容易上手,打开下载压缩包中的exe文件,我们就能看到软件的用户界面。在这个用户界面当中,我们点击“+”按钮就可以添加攻击的目标,在弹出的窗口当中,我们将攻击目标的url填入输入框当中,下面两个选项允许用户选择攻击的强度以及模式。另外,在软件界面上,用户还可以选择使用到的攻击线程的数量。值得一提的是,HOIC会自动适配用户本地的机器配置,当所选线程超过机器的支持时,显示数量将变为红色。

image-20220317112934145

在本次实验当中,我们分别使用 ”Low强度 + 2线程“ 和 “High强度 + 4线程”对目标进行攻击。

image-20220317113406339

image-20220317113501597

从实验当中我们观察到,哪怕只是采用一台普通的家用笔记本电脑,也可以在几分钟的时间里向攻击目标发送上百兆字节,这对于小型的服务器而言已经是很大的负担。在初次实验当中,目标服务器没有配置防御措施,高强度的HTTP洪泛攻击直接导致了目标网页的后台宕机,服务器的CPU占用率和内存使用率都达到了90%以上,此时其他的普通用户已经完全无法访问该网页。

HTTP慢速攻击(low and slow attack)

HTTP慢速攻击简介

定义:HTTP慢速度攻击是DoS或DDoS攻击的一种。攻击者会向目标服务器非常缓慢地发送一小段数据流来占用服务器的连接会话,从而使服务器停止或无法快速地对真实用户进行响应。

原理:服务器与客户端建立的每一个会话都依赖于一个线程。而线程资源是有限的,如果其被大量的慢速会话占用,会使得正常的HTTP被阻塞。

类比:想象一座四车道的桥,每条车道都有一个收费站。司机把车停在收费亭前,交上一张钞票或一把硬币,然后开车过桥,为下一个司机腾出车道。现在想象一下,四名司机同时出现,占据了每一条开放的车道,他们每个人都慢慢地把硬币交给收费站操作员,一次一枚硬币,把所有可用的车道堵上几个小时,阻止其他司机通过。这种令人难以置信的令人沮丧的场景与慢速攻击的工作原理非常相似。

特点:1. 与传统的蛮力攻击(例如泛洪攻击)相比,慢速度攻击占用的带宽更少,且其产生的流量与正常访问产生的流量相当,故很难被发现。2. 不需要很多资源(例如僵尸网络)来完成,使用一台计算机就可以成功地发起慢攻击。

注意:服务器一般会配置会话的最长时间,故攻击者在缓慢发送数据时要确保不要让会话超时。

HTTP慢速攻击分类

攻击者可以通过使用HTTP头部、HTTP POST请求、TCP请求来实施攻击,具体如下:

  • HTTP头部:攻击者缓慢地发送HTTP请求的头部信息,这会使得服务器一直保持连接以接受剩余头部。
  • HTTP POST请求:攻击者制造这样一种POST请求,该请求表示在body中会有很长的数据要发送,然后缓慢地发送body中的数据。
  • TCP请求:利用TCP三次握手的漏洞,创建一个不确定的连接,使该连接既不会断开也不可使用。

slowhttptest工具简介

slowhttptest是⼀个灵活易用的HTTP慢速攻击模拟⼯具,其支持客户线程数量、攻击时长、间隔时间等诸多配置,可选择基于HTTP头部或BODY部分的慢速攻击。

该工具可通过Linux命令行启动并运行,命令参数如下所示:

 -g      在测试完成后,以时间戳为名生成一个CVS和HTML文件的统计数据
 -H      SlowLoris模式
 -B      Slow POST模式
 -R      Range Header模式
 -X      Slow Read模式
 -c      number of connections 测试时建立的连接数
 -d      HTTP proxy host:port  为所有连接指定代理
 -e      HTTP proxy host:port  为探测连接指定代理
 -i      seconds 在slowrois和Slow POST模式中,指定发送数据间的间隔。
 -l      seconds 测试维持时间
 -n      seconds 在Slow Read模式下,指定每次操作的时间间隔。
 -o      file name 使用-g参数时,可以使用此参数指定输出文件名
 -p      seconds 指定等待时间来确认DoS攻击已经成功
 -r      connections per second 每秒连接个数
 -s      bytes 声明Content-Length header的值
 -t      HTTP verb 在请求时使用什么操作,默认GET
 -u      URL  指定目标url
 -v      level 日志等级(详细度)
 -w      bytes slow read模式中指定tcp窗口范围下限
 -x      bytes 在slowloris and Slow POST tests模式中,指定发送的最大数据长度
 -y      bytes slow read模式中指定tcp窗口范围上限
 -z      bytes 在每次的read()中,从buffer中读取数据量

实验内容

我们从https://github.com/shekyan/slowhttptest中下载slowhttptest工具至linux服务器上并根据官方教程进行安装。并运行如下命令:

slowhttptest -c 10000 -l 3000 -u <url>。其中-c 10000表示攻击者将尝试建立10000个缓慢的连接,-l 3000表示攻击时间最多持续3000秒,-u <url>表示被攻击者的地址。控制台展示如下:

slowhttptest_1

从上图可以看出,同一时刻下平均有一千个正在工作的慢速连接。这时被攻击者开启防御模式,以限制单一客户端能够建立的连接个数,这时运行结果展示如下:

slowhttptest_2

可以看到同一时刻下平均只有一百个正在工作的慢速连接,说明被攻击者的防御方式已经生效。

网络防御

总体分析

要防御DDOS分布式拒绝服务攻击,首先要从网络请求的处理过程进行分析。针对各个处理环节做出针对性防御措施。网络流量从客户端出发到请求结果返回,将依次通过服务器中多个节点。各个节点对流量进行分工处理,具体如下:

  • 防火墙:根据防火墙规则过滤流量
  • Nginx:负责处理静态资源(例如图片、视频、CSS、JavaScript文件等),将动态请求交给Tomcat处理。
  • Tomcat:接收来自Nginx的流量,将请求包装为Http调用交给后端应用,并接收后端应用返回的结果。
  • Ords + Apex engin:接收Tomcat请求,负责后端逻辑处理,查询修改数据库并返回结果。
  • Oracle数据库:接收后端数据查询请求,查询磁盘数据并返回结果。

img

在不同节点可以做出的针对性防御不同

防火墙端

  • 将恶意IP加入黑名单
  • 只允许信任用户IP加入白名单
  • 自动识别异常流量,并将异常IP加入黑名单。

Web服务器端(Nginx和Tomcat)

  • 限制接口的访问频率,文件下载速率。
  • 限制TCP连接数,连接时长。
  • 配置定制化的网络参数限制恶意攻击。

应用后端(ORDS和APEX)

  • 在应用层面对可疑用户进行限制,对重要接口访问做限流。
  • 使用缓存来提高吞吐率

Nginx是⼀个非常高效的网页服务器,通过配置可使⽤反向代理、负载均衡等多种功能。我们使⽤Nginx在80端口代理8080端口的全部请求,静态资源访问直接由Nginx处理,动态请求将交由Tomcat处理。本次实验主要使用Nginx来防御恶意攻击。

泛洪攻击防御

HTTP Flood 攻击模拟正常⽤户的浏览器浏览过程,⼤量向服务器发送请求以耗尽带 宽、CPU等资源。为减少泛洪攻击的影响,Nginx配置的核心思路是控制每个用户使用的资源大小。具体包括限制每个IP的速率,TCP连接数量,带宽大小。

控制速率

nginx.conf http 中添加限流配置:

格式:limit_req_zone key zone rate

1
2
3
    http {
        limit_req_zone $binary_remote_addr zone=myRateLimit:10m rate=10r/s;
    }

配置 server,使用 limit_req 指令应用限流。

1
2
3
4
5
6
    server {
        location / {
            limit_req zone=myRateLimit;
            proxy_pass http://my_upstream;
        }
    }
  • key :定义限流对象,binary_remote_addr 是一种key,表示基于 remote_addr(客户端IP) 来做限流,binary_ 的目的是压缩内存占用量。
  • zone:定义共享内存区来存储访问信息, myRateLimit:10m 表示一个大小为10M,名字为myRateLimit的内存区域。1M能存储16000 IP地址的访问信息,10M可以存储16W IP地址访问信息。
  • rate 用于设置最大访问速率,rate=10r/s 表示每秒最多处理10个请求。Nginx 实际上以毫秒为粒度来跟踪请求信息,因此 10r/s 实际上是限制:每100毫秒处理一个请求。这意味着,自上一个请求处理完后,若后续100毫秒内又有请求到达,将拒绝处理该请求。

处理突发流量

在正常业务使用中,业务也可能某一段时间中操作较为频繁。为避免速率控制对正常业务造成影响,需要配置Nginx处理突发流量。

burst 译为突发、爆发,表示在超过设定的处理速率后能额外处理的请求数。当 rate=10r/s 时,将1s拆成10份,即每100ms可处理1个请求。

此处,burst=20 ,若同时有21个请求到达,Nginx 会处理第一个请求,剩余20个请求将放入队列,然后每隔100ms从队列中获取一个请求进行处理。若请求数大于21,将拒绝处理多余的请求,直接返回503.

不过,单独使用 burst 参数并不实用。假设 burst=50 ,rate依然为10r/s,排队中的50个请求虽然每100ms会处理一个,但第50个请求却需要等待 50 * 100ms即 5s,这么长的处理时间自然难以接受。

因此,burst 往往结合 nodelay 一起使用。

1
2
3
4
5
6
    server {
        location / {
            limit_req zone=myRateLimit burst=20 nodelay;
            proxy_pass http://my_upstream;
        }
    }

nodelay 针对的是 burst 参数,burst=20 nodelay 表示这20个请求立马处理,不能延迟,相当于特事特办。不过,即使这20个突发请求立马处理结束,后续来了请求也不会立马处理。burst=20 相当于缓存队列中占了20个坑,即使请求被处理了,这20个位置这只能按 100ms一个来释放。

这就达到了速率稳定,但突然流量也能正常处理的效果

限制连接数

ngx_http_limit_conn_module 提供了限制连接数的能力,利用 limit_conn_zonelimit_conn 两个指令即可。下面是 Nginx 官方例子:

1
2
3
4
5
6
7
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;
    server {
        ...
        limit_conn perip 10;
        limit_conn perserver 100;
    }

limit_conn perip 10 作用的key 是 $binary_remote_addr,表示限制单个IP同时最多能持有10个连接。

limit_conn perserver 100 作用的key是 $server_name,表示虚拟主机(server) 同时能处理并发连接的总数。

需要注意的是:只有当 request header 被后端server处理后,这个连接才进行计数。

限制带宽

以下示例显示了用于限制连接数和带宽的组合配置。允许的最大连接数设置为5 每个客户端地址的连接数,这适合大多数情况,因为现代浏览器通常一次最多打开3个连接。同时,提供下载的位置仅允许一个连接:

1
2
3
4
5
location /download/ {
    limit_conn       addr 1;
    limit_rate_after 1m;
    limit_rate       50k;
}

防御效果

系统负载和磁盘读写对比

image-20220315201100305

网络情况对比

image-20220315200950740

实测发现:防御前系统服务完全不可用,tomcat处于down机状态。防御后系统服务虽会出现些许卡顿,但仍能够正常使用。可以发现防御对防洪攻击有不错的抵抗效果,

慢速攻击防御

慢速攻击者会向目标服务器非常缓慢地发送一小段数据流来占用服务器的连接会话,从而使服务器停止或无法快速地对真实用户进行响应。为抵御慢速攻击,Nginx可以从三个方面入手进行配置。首先是Nginx的超时设置,请求时长限制在合理范围内。其次是禁用静态文件的访问日志,避免大量慢速攻击对磁盘IO的影响。最后是修改内核参数,对处于Time Wait的TCP连接进行限制,并允许系统服用已有连接

Nginx的超时设置

减少Nginx的最长请求时长,将请求时长限制在合理范围内,断开长期的死连接。

  • keepalive_timeout用于设置keepalive连接的超时时间,默认为65秒。若将它设置为0,那么就禁止了keepalive连接。它在http, server 和 location模块中定义。
  • send_timeout指定了向客户端传输数据的超时时间。默认值为60秒,可以在http, server 和 location模块中定义。
  • client_body_timeout设定客户端与服务器建立连接后发送request body的超时时间。如果客户端在此时间内没有发送任何内容,那么Nginx返回HTTP 408错误(Request Timed Out)。它的默认值是60秒,在http, server 和 location模块中定义。
  • client_header_timeout设定客户端向服务器发送一个完整的request header的超时时间。如果客户端在此时间内没有发送一个完整的request header,那么Nginx返回HTTP 408错误(Request Timed Out)。它的默认值是60秒,在http 和 server模块中定义。
1
2
3
4
keepalive_timeout 30s;
send_timeout 10s;
client_body_timeout 5s;
client_header_timeout 3s;

Nginx禁用静态文件日志

禁用Nginx静态文件的访问日志,避免大量慢速攻击对磁盘IO的影响,具体如下

  • 提升 IO 性能
  • 避免无意义的写入磁盘操作 便于实时查看 nginx 日志

在Nginx 的配置文件中加入

1
2
3
4
5
6
7
8
9
10
log_format compression '$remote_addr - $remote_user [$time_local] '
                '"$request" $status $body_bytes_sent '
                '"$http_referer" "$http_user_agent" "$gzip_ratio"';

map $uri $loggable {
    default                                             1;
    ~*\.(ico|css|js|gif|jpg|jpeg|png|svg|woff|ttf|eot)$ 0;
}

access_log /var/log/nginx/access.log compression if=$loggable;

修改Linux内核参数

慢速攻击的原理是产生大量请求,占用服务器连接资源。并且这个TCP连接不能被正常用户使用。

执行以下命令,编辑系统内核配置。

1
vi /etc/sysctl.conf
  • net.ipv4.tcp_syncookies=1:开启SYN的cookies,当出现SYN等待队列溢出时,启用cookies进行处理。

  • net.ipv4.tcp_tw_reuse=1:允许将TIME-WAIT的socket重新用于新的TCP连接。如果新请求的时间戳,比存储的时间戳更大,则系统将会从TIME_WAIT状态的存活连接中选取一个,重新分配给新的请求连接。
  • net.ipv4.tcp_fin_timeout=30:如果socket由服务端要求关闭,则该参数决定了保持在FIN-WAIT-2状态的时间。

修改或加入以下内容。

1
2
3
net.ipv4.tcp_syncookies = 1 
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_fin_timeout = 30

防御效果

系统负责和磁盘读写

image-20220315204801308

网络情况

image-20220315204557428

防御前后TCP连接对比

image-20220315205324039

image-20220315205339751

实测发现:可以发现,防御后磁盘io有所下降。网络情况虽然处于等待的TCP请求增多,但实际占用的TCP连接却显著减少。可以发现防御对慢速攻击有不错的抵抗效果。

本文由作者按照 CC BY 4.0 进行授权

软件建模——分享我的业务建模经历

白盒Space-Hardness 论文阅读笔记