You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
11 KiB
Markdown

2 years ago
# 36 | WAF保护我们的网络服务
在前些天的“安全篇”里我谈到了HTTPS它使用了SSL/TLS协议加密整个通信过程能够防止恶意窃听和窜改保护我们的数据安全。
但HTTPS只是网络安全中很小的一部分仅仅保证了“通信链路安全”让第三方无法得知传输的内容。在通信链路的两端也就是客户端和服务器它是无法提供保护的。
因为HTTP是一个开放的协议Web服务都运行在公网上任何人都可以访问所以天然就会成为黑客的攻击目标。
而且黑客的本领比我们想象的还要大得多。虽然不能在传输过程中做手脚,但他们还可以“假扮”成合法的用户访问系统,然后伺机搞破坏。
## Web服务遇到的威胁
黑客都有哪些手段来攻击Web服务呢我给你大概列出几种常见的方式。
第一种叫“**DDoS**”攻击distributed denial-of-service attack有时候也叫“洪水攻击”。
黑客会控制许多“僵尸”计算机向目标服务器发起大量无效请求。因为服务器无法区分正常用户和黑客只能“照单全收”这样就挤占了正常用户所应有的资源。如果黑客的攻击强度很大就会像“洪水”一样对网站的服务能力造成冲击耗尽带宽、CPU和内存导致网站完全无法提供正常服务。
“DDoS”攻击方式比较“简单粗暴”虽然很有效但不涉及HTTP协议内部的细节“技术含量”比较低不过下面要说的几种手段就不一样了。
网站后台的Web服务经常会提取出HTTP报文里的各种信息应用于业务有时会缺乏严格的检查。因为HTTP报文在语义结构上非常松散、灵活URI里的query字符串、头字段、body数据都可以任意设置这就带来了安全隐患给了黑客“**代码注入**”的可能性。
黑客可以精心编制HTTP请求报文发送给服务器服务程序如果没有做防备就会“上当受骗”执行黑客设定的代码。
“**SQL注入**”SQL injection应该算是最著名的一种“代码注入”攻击了它利用了服务器字符串拼接形成SQL语句的漏洞构造出非正常的SQL语句获取数据库内部的敏感信息。
另一种“**HTTP头注入**”攻击的方式也是类似的原理它在“Host”“User-Agent”“X-Forwarded-For”等字段里加入了恶意数据或代码服务端程序如果解析不当就会执行预设的恶意代码。
在之前的[第19讲](https://time.geekbang.org/column/article/106034)里也说过一种利用Cookie的攻击手段“**跨站脚本**”XSS攻击它属于“JS代码注入”利用JavaScript脚本获取未设防的Cookie。
## 网络应用防火墙
面对这么多的黑客攻击手段,我们应该怎么防御呢?
这就要用到“**网络应用防火墙**”Web Application Firewall简称为“**WAF**”。
你可能对传统的“防火墙”比较熟悉。传统“防火墙”工作在三层或者四层隔离了外网和内网使用预设的规则只允许某些特定IP地址和端口号的数据包通过拒绝不符合条件的数据流入或流出内网实质上是**一种网络数据过滤设备**。
WAF也是一种“防火墙”但它工作在七层看到的不仅是IP地址和端口号还能看到整个HTTP报文所以就能够对报文内容做更深入细致的审核使用更复杂的条件、规则来过滤数据。
说白了WAF就是一种“**HTTP入侵检测和防御系统**”。
![](https://static001.geekbang.org/resource/image/e8/a3/e8369d077454e5b92e3722e7090551a3.png)
WAF都能干什么呢
通常一款产品能够称为WAF要具备下面的一些功能
* IP黑名单和白名单拒绝黑名单上地址的访问或者只允许白名单上的用户访问
* URI黑名单和白名单与IP黑白名单类似允许或禁止对某些URI的访问
* 防护DDoS攻击对特定的IP地址限连限速
* 过滤请求报文,防御“代码注入”攻击;
* 过滤响应报文,防御敏感信息外泄;
* 审计日志,记录所有检测到的入侵操作。
听起来WAF好像很高深但如果你理解了它的工作原理其实也不难。
它就像是平时编写程序时必须要做的函数入口参数检查拿到HTTP请求、响应报文用字符串处理函数看看有没有关键字、敏感词或者用正则表达式做一下模式匹配命中了规则就执行对应的动作比如返回403/404。
如果你比较熟悉Apache、Nginx、OpenResty可以自己改改配置文件写点JS或者Lua代码就能够实现基本的WAF功能。
比如说在Nginx里实现IP地址黑名单可以利用“map”指令从变量$remote\_addr获取IP地址在黑名单上就映射为值1然后在“if”指令里判断
```
map $remote_addr $blocked {
default 0;
"1.2.3.4" 1;
"5.6.7.8" 1;
}
if ($blocked) {
return 403 "you are blocked.";
}
```
Nginx的配置文件只能静态加载改名单必须重启比较麻烦。如果换成OpenResty就会非常方便在access阶段进行判断IP地址列表可以使用cosocket连接外部的Redis、MySQL等数据库实现动态更新
```
local ip_addr = ngx.var.remote_addr
local rds = redis:new()
if rds:get(ip_addr) == 1 then
ngx.exit(403)
end
```
看了上面的两个例子你是不是有种“跃跃欲试”的冲动了想自己动手开发一个WAF
不过我必须要提醒你,在网络安全领域必须时刻记得“**木桶效应**”(也叫“短板效应”)。网站的整体安全不在于你加固的最强的那个方向,而是在于你可能都没有意识到的“短板”。黑客往往会“避重就轻”,只要发现了网站的一个弱点,就可以“一点突破”,其他方面的安全措施也就都成了“无用功”。
所以使用WAF最好“**不要重新发明轮子**”而是使用现有的、比较成熟的、经过实际考验的WAF产品。
## 全面的WAF解决方案
这里我就要“隆重”介绍一下WAF领域里的最顶级产品了ModSecurity它可以说是WAF界“事实上的标准”。
ModSecurity是一个开源的、生产级的WAF工具包历史很悠久比Nginx还要大几岁。它开始于一个私人项目后来被商业公司Breach Security收购现在则是由TrustWave公司的SpiderLabs团队负责维护。
ModSecurity最早是Apache的一个模块只能运行在Apache上。因为其品质出众大受欢迎后来的2.x版添加了Nginx和IIS支持但因为底层架构存在差异不够稳定。
所以这两年SpiderLabs团队就开发了全新的3.0版本移除了对Apache架构的依赖使用新的“连接器”来集成进Apache或者Nginx比2.x版更加稳定和快速误报率也更低。
ModSecurity有两个核心组件。第一个是“**规则引擎**”它实现了自定义的“SecRule”语言有自己特定的语法。但“SecRule”主要基于正则表达式还是不够灵活所以后来也引入了Lua实现了脚本化配置。
ModSecurity的规则引擎使用C++11实现可以从[GitHub](https://github.com/SpiderLabs/ModSecurity)上下载源码然后集成进Nginx。因为它比较庞大编译很费时间所以最好编译成动态模块在配置文件里用指令“load\_module”加载
```
load_module modules/ngx_http_modsecurity_module.so;
```
只有引擎还不够要让引擎运转起来还需要完善的防御规则所以ModSecurity的第二个核心组件就是它的“**规则集**”。
ModSecurity源码提供一个基本的规则配置文件“**modsecurity.conf-recommended**”使用前要把它的后缀改成“conf”。
有了规则集就可以在Nginx配置文件里加载然后启动规则引擎
```
modsecurity on;
modsecurity_rules_file /path/to/modsecurity.conf;
```
“modsecurity.conf”文件默认只有检测功能不提供入侵阻断这是为了防止误杀误报把“SecRuleEngine”后面改成“On”就可以开启完全的防护
```
#SecRuleEngine DetectionOnly
SecRuleEngine On
```
基本的规则集之外ModSecurity还额外提供一个更完善的规则集为网站提供全面可靠的保护。这个规则集的全名叫“**OWASP ModSecurity 核心规则集**”Open Web Application Security Project ModSecurity Core Rule Set因为名字太长了所以有时候会简称为“核心规则集”或者“CRS”。
![](https://static001.geekbang.org/resource/image/ad/48/add929f8439c64f29db720d30f7de548.png)
CRS也是完全开源、免费的可以从GitHub上下载
```
git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
```
其中有一个“**crs-setup.conf.example**”的文件它是CRS的基本配置可以用“Include”命令添加到“modsecurity.conf”里然后再添加“rules”里的各种规则。
```
Include /path/to/crs-setup.conf
Include /path/to/rules/*.conf
```
你如果有兴趣可以看一下这些配置文件里面用“SecRule”定义了很多的规则基本的形式是“SecRule 变量 运算符 动作”。不过ModSecurity的这套语法“自成一体”比较复杂要完全掌握不是一朝一夕的事情我就不详细解释了。
另外ModSecurity还有强大的审计日志Audit Log功能记录任何可疑的数据供事后离线分析。但在生产环境中会遇到大量的攻击日志会快速增长消耗磁盘空间而且写磁盘也会影响Nginx的性能所以一般建议把它关闭
```
SecAuditEngine off #RelevantOnly
SecAuditLog /var/log/modsec_audit.log
```
## 小结
今天我们一起学习了“网络应用防火墙”也就是WAF使用它可以加固Web服务。
1. Web服务通常都运行在公网上容易受到“DDoS”、“代码注入”等各种黑客攻击影响正常的服务所以必须要采取措施加以保护
2. WAF是一种“HTTP入侵检测和防御系统”工作在七层为Web服务提供全面的防护
3. ModSecurity是一个开源的、生产级的WAF产品核心组成部分是“规则引擎”和“规则集”两者的关系有点像杀毒引擎和病毒特征库
4. WAF实质上是模式匹配与数据过滤所以会消耗CPU增加一些计算成本降低服务能力使用时需要在安全与性能之间找到一个“平衡点”。
## 课下作业
1. HTTPS为什么不能防御DDoS、代码注入等攻击呢
2. 你还知道有哪些手段能够抵御网络攻击吗?
欢迎你把自己的学习体会写在留言区,与我和其他同学一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。
![unpreview](https://static001.geekbang.org/resource/image/b9/24/b9e48b813c98bb34b4b433b7326ace24.png)