写点什么

通过 Nginx 和 Nginx Plus 阻止 DDoS 攻击

2016 年 1 月 29 日

分布式拒绝服务攻击(DDoS)指的是通过多台机器向一个服务或者网站发送大量看似合法的数据包使其网络阻塞、资源耗尽从而不能为正常用户提供正常服务的攻击手段。随着互联网带宽的增加和相关工具的不断发布,这种攻击的实施难度越来越低,有大量 IDC 托管机房、商业站点、游戏服务商一直饱受 DDoS 攻击的困扰,那么如何缓解甚至解决 DDoS 呢?最近 Rick Nelson 在 Nginx 的官方博客上发表了一篇文章,介绍了如何通过Nginx 和Nginx Plus 缓和DDoS 攻击

Rick Nelson 首先介绍了 DDoS 攻击的一些特点, 例如攻击的流量通常来源于一些固定的 IP 地址,每一个 IP 地址会创建比真实用户多得多的连接和请求;同时由于流量全部是由机器产生的,其速率要比人类用户高的多。此外,进行攻击的机器其 User-Agent 头也不是标准的值,Referer 头有时也会被设置成能够与攻击关联起来的值。针对这些特点,Rick Nelson 认为 Nginx 和 Nginx Plus 有很多能够通过调节或控制流量来应对或者减轻 DDoS 攻击的特性。

限制请求率
将 Nginx 和 Nginx Plus 可接受的入站请求率限制为某个适合真实用户的值。例如,通过下面的配置让一个真正的用户每两秒钟才能访问一次登录页面:

复制代码
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
...
location /login.html {
limit_req zone=one;
...
}
}

在该配置中,limit_req_zone指令配置了一个名为one的共享内存zone用来存储$binary_remote_addr的请求状态,location 块中 /login.html 的limit_req指令引用了共享内存zone

限制连接的数量
将某个客户端 IP 地址所能打开的连接数限制为真实用户的合理值。例如,限制每一个 IP 对网站 /store 部分打开的连接数不超过 10 个:

复制代码
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
...
location /store/ {
limit_conn addr 10;
...
}
}

该配置中,limit_conn_zone指令配置了一个名为addr的共享内存zone用来存储 $binary_remote_addr的请求,location 块中 /store/ 的limit_conn指令引用了共享内存zone,并将最大连接数设置为 10.

关闭慢连接
关闭那些一直保持打开同时写数据又特别频繁的连接,因为它们会降低服务器接受新连接的能力。Slowloris 就是这种类型的攻击。对此,可以通过client_body_timeoutclient_header_timeout指令控制请求体或者请求头的超时时间,例如,通过下面的配置将等待时间控制在 5s 之内:

复制代码
server {
client_body_timeout 5s;
client_header_timeout 5s;
...
}

设置 IP 黑名单
如果能识别攻击者所使用的客户端 IP 地址,那么通过deny指令将其屏蔽,让 Nginx 和 Nginx Plus 拒绝来自这些地址的连接或请求。例如,通过下面的指令拒绝来自 123.123.123.3、123.123.123.5 和 123.123.123.7 的请求:

复制代码
location / {
deny 123.123.123.3;
deny 123.123.123.5;
deny 123.123.123.7;
...
}

设置 IP 白名单
如果允许访问的 IP 地址比较固定,那么通过allowdeny指令让网站或者应用程序只接受来自于某个 IP 地址或者某个 IP 地址段的请求。例如,通过下面的指令将访问限制为本地网络的一个 IP 段:

复制代码
location / {
allow 192.168.1.0/24;
deny all;
...
}

通过缓存削减流量峰值
通过启用缓存并设置某些缓存参数让 Nginx 和 Nginx Plus 吸收攻击所产生的大部分流量峰值。例如,通过proxy_cache_use_stale指令的updating参数告诉 Nginx 何时需要更新过期的缓存对象,避免因重复发送更新请求对后端服务器产生压力。另外,proxy_cache_key指令定义的键通常会包含嵌入的变量,例如默认的键$scheme$proxy_host$request_uri包含了三个变量,如果它包含$query_string变量,那么攻击者可以通过发送随机的query_string值来耗尽缓存,因此,如果没有特别原因,不要在该键中使用$query_string变量。

阻塞请求
配置 Nginx 和 Nginx Plus 阻塞以下类型的请求:

  • 以某个特定 URL 为目标的请求
  • User-Agent 头中的值不在正常客户端范围之内的请求
  • Referer 头中的值能够与攻击关联起来的请求
  • 其他头中存在能够与攻击关联在一起的值的请求

例如,通过下面的配置阻塞以 /foo.php 为目标的攻击:

复制代码
location /foo.php {
deny all;
}

或者通过下面的配置阻塞已识别出的 User-Agent 头的值是 foo 或者 bar 的 DDoS 攻击:

复制代码
location / {
if ($http_user_agent ~* foo|bar) {
return 403;
}
...
}

限制对后端服务器的连接数
通常 Nginx 和 Nginx Plus 实例能够处理比后端服务器多得多的连接数,因此可以通过 Nginx Plus 限制到每一个后端服务器的连接数。例如,通过下面的配置限制 Nginx Plus 和每一台后端服务器之间建立的连接数不多于 200 个:

复制代码
upstream website {
server 192.168.100.1:80 max_conns=200;
server 192.168.100.2:80 max_conns=200;
queue 10 timeout=30s;
}

另外,Rick Nelson 还提到了如何处理基于范围的攻击如何处理高负载的问题,以及如何使用Nginx Plus Status 模块发现异常的流量模式,定位DDoS 攻击。


感谢魏星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。

2016 年 1 月 29 日 18:006383
用户头像

发布了 321 篇内容, 共 102.8 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

给计算机专业学生的几条建议

MySQL从删库到跑路

GitHub Linux vmware 大学生日常 计算机

一个草根的日常杂碎(10月2日)

刘新吾

随笔杂谈 生活记录 社会百态

小伙伴问我:如何搭建Maven私服?我连夜肝了这篇实战文章!!

冰河

maven 私服 仓库

VUE第一个项目怎么读懂

MySQL从删库到跑路

Java html5 Vue 前端 vux

架构师训练营 - 命题作业 - 第三周

徐时良

极客大学架构师训练营

架构师训练营第一期 - 第三周课后作业

卖猪肉的大叔

BigDecimal是如何搞定精度缺失的

hasWhere

Serverless与传统Web框架的迁移

刘宇

Serverless

LeetCode题解:49. 字母异位词分组,数组计数+哈希表,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

架构师训练营 - 学习笔记 - 第三周

徐时良

极客大学架构师训练营

架构师训练营 Week4 - 课后作业

缓存 自动化 异步 集群 冗余

一个草根的日常杂碎(10月3日)

刘新吾

随笔杂谈 生活记录 社会百态

架构师训练营第 1 期 - 第 3 周 - 作业

wgl

极客大学架构师训练营

【架构师训练营 1 期】第三周学习总结

诺乐

团队出游筹备清单

boshi

团队建设 团队文化

spring-boot-route(五)整合Swagger生成接口文档

Java旅途

Java springboot swagger

Web Storage API的介绍和使用

程序那些事

web tech web storage web storage api storage api

架构第三周总结

Geek_Gu

Appium之「元素定位和UiAutomator表达式」

清菡

CECBC区块链专委会副主任吴桐主讲光大证券法定数字货币讲座

CECBC区块链专委会

区块链 数字货币

【架构师训练营 1 期】第三周作业

诺乐

让人一夜暴富的区块链,新时代革命的开始

CECBC区块链专委会

区块链 时代革命

区块链与分布式存储构建数据要素市场基础设施

CECBC区块链专委会

区块链 分布式

架构师训练营第三周学习笔记

一马行千里

学习 极客大学架构师训练营

架构师训练营第一期-第三周学习总结

卖猪肉的大叔

极客大学架构师训练营

Serverless Frist 的渐进式应用开发框架 Malagu

木香丘

开源 Serverless 云原生 Malagu Framework

架构师训练营第 1 期 - 第 3 周 - 学习总结

wgl

极客大学架构师训练营

Week_03 学习总结

golangboy

极客大学架构师训练营

架构第三周作业

Geek_Gu

极客大学架构师训练营

一个草根的日常杂碎(10月4日)

刘新吾

随笔杂谈 生活记录 社会百态

理想的程序员

极客思享

微服务架构下如何保证事务的一致性

微服务架构下如何保证事务的一致性

通过Nginx和Nginx Plus阻止DDoS攻击-InfoQ