mirror of
https://github.com/zhwei820/learn.lianglianglee.com.git
synced 2025-09-17 08:46:40 +08:00
737 lines
27 KiB
HTML
737 lines
27 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
||
<head>
|
||
|
||
<head>
|
||
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
|
||
|
||
<link rel="icon" href="/static/favicon.png">
|
||
|
||
<title>36 WAF:保护我们的网络服务.md.html</title>
|
||
|
||
<!-- Spectre.css framework -->
|
||
|
||
<link rel="stylesheet" href="/static/index.css">
|
||
|
||
<!-- theme css & js -->
|
||
|
||
<meta name="generator" content="Hexo 4.2.0">
|
||
|
||
</head>
|
||
<body>
|
||
<div class="book-container">
|
||
|
||
<div class="book-sidebar">
|
||
|
||
<div class="book-brand">
|
||
|
||
<a href="/">
|
||
|
||
<img src="/static/favicon.png">
|
||
|
||
<span>技术文章摘抄</span>
|
||
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<div class="book-menu uncollapsible">
|
||
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="/" class="current-tab">首页</a></li>
|
||
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
|
||
<li><a href="../">上一级</a></li>
|
||
|
||
</ul>
|
||
<ul class="uncollapsible">
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/00 开篇词|To Be a HTTP Hero.md.html">00 开篇词|To Be a HTTP Hero.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/01 时势与英雄:HTTP的前世今生.md.html">01 时势与英雄:HTTP的前世今生.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/02 HTTP是什么?HTTP又不是什么?.md.html">02 HTTP是什么?HTTP又不是什么?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/03 HTTP世界全览(上):与HTTP相关的各种概念.md.html">03 HTTP世界全览(上):与HTTP相关的各种概念.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/04 HTTP世界全览(下):与HTTP相关的各种协议.md.html">04 HTTP世界全览(下):与HTTP相关的各种协议.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/05 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?.md.html">05 常说的“四层”和“七层”到底是什么?“五层”“六层”哪去了?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/06 域名里有哪些门道?.md.html">06 域名里有哪些门道?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/07 自己动手,搭建HTTP实验环境.md.html">07 自己动手,搭建HTTP实验环境.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/08 键入网址再按下回车,后面究竟发生了什么?.md.html">08 键入网址再按下回车,后面究竟发生了什么?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/09 HTTP报文是什么样子的?.md.html">09 HTTP报文是什么样子的?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/10 应该如何理解请求方法?.md.html">10 应该如何理解请求方法?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/11 你能写出正确的网址吗?.md.html">11 你能写出正确的网址吗?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/12 响应状态码该怎么用?.md.html">12 响应状态码该怎么用?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/13 HTTP有哪些特点?.md.html">13 HTTP有哪些特点?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/14 HTTP有哪些优点?又有哪些缺点?.md.html">14 HTTP有哪些优点?又有哪些缺点?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/15 海纳百川:HTTP的实体数据.md.html">15 海纳百川:HTTP的实体数据.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/16 把大象装进冰箱:HTTP传输大文件的方法.md.html">16 把大象装进冰箱:HTTP传输大文件的方法.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/17 排队也要讲效率:HTTP的连接管理.md.html">17 排队也要讲效率:HTTP的连接管理.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/18 四通八达:HTTP的重定向和跳转.md.html">18 四通八达:HTTP的重定向和跳转.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/19 让我知道你是谁:HTTP的Cookie机制.md.html">19 让我知道你是谁:HTTP的Cookie机制.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/20 生鲜速递:HTTP的缓存控制.md.html">20 生鲜速递:HTTP的缓存控制.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/21 良心中间商:HTTP的代理服务.md.html">21 良心中间商:HTTP的代理服务.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/22 冷链周转:HTTP的缓存代理.md.html">22 冷链周转:HTTP的缓存代理.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/23 HTTPS是什么?SSLTLS又是什么?.md.html">23 HTTPS是什么?SSLTLS又是什么?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/24 固若金汤的根本(上):对称加密与非对称加密.md.html">24 固若金汤的根本(上):对称加密与非对称加密.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/25 固若金汤的根本(下):数字签名与证书.md.html">25 固若金汤的根本(下):数字签名与证书.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/26 信任始于握手:TLS1.2连接过程解析.md.html">26 信任始于握手:TLS1.2连接过程解析.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/27 更好更快的握手:TLS1.3特性解析.md.html">27 更好更快的握手:TLS1.3特性解析.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/28 连接太慢该怎么办:HTTPS的优化.md.html">28 连接太慢该怎么办:HTTPS的优化.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/29 我应该迁移到HTTPS吗?.md.html">29 我应该迁移到HTTPS吗?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/30 时代之风(上):HTTP2特性概览.md.html">30 时代之风(上):HTTP2特性概览.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/31 时代之风(下):HTTP2内核剖析.md.html">31 时代之风(下):HTTP2内核剖析.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/32 未来之路:HTTP3展望.md.html">32 未来之路:HTTP3展望.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/33 我应该迁移到HTTP2吗?.md.html">33 我应该迁移到HTTP2吗?.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/34 Nginx:高性能的Web服务器.md.html">34 Nginx:高性能的Web服务器.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/35 OpenResty:更灵活的Web服务器.md.html">35 OpenResty:更灵活的Web服务器.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
<a class="current-tab" href="/专栏/透视HTTP协议/36 WAF:保护我们的网络服务.md.html">36 WAF:保护我们的网络服务.md.html</a>
|
||
|
||
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/37 CDN:加速我们的网络服务.md.html">37 CDN:加速我们的网络服务.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/38 WebSocket:沙盒里的TCP.md.html">38 WebSocket:沙盒里的TCP.md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/39 HTTP性能优化面面观(上).md.html">39 HTTP性能优化面面观(上).md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/40 HTTP性能优化面面观(下).md.html">40 HTTP性能优化面面观(下).md.html</a>
|
||
</li>
|
||
|
||
<li>
|
||
|
||
|
||
<a href="/专栏/透视HTTP协议/结束语 做兴趣使然的Hero.md.html">结束语 做兴趣使然的Hero.md.html</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
|
||
|
||
<div class="sidebar-toggle-inner"></div>
|
||
|
||
</div>
|
||
<script>
|
||
|
||
function add_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.add('show')
|
||
|
||
}
|
||
function remove_inner() {
|
||
|
||
let inner = document.querySelector('.sidebar-toggle-inner')
|
||
|
||
inner.classList.remove('show')
|
||
|
||
}
|
||
function sidebar_toggle() {
|
||
|
||
let sidebar_toggle = document.querySelector('.sidebar-toggle')
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let content = document.querySelector('.off-canvas-content')
|
||
|
||
if (sidebar_toggle.classList.contains('extend')) { // show
|
||
|
||
sidebar_toggle.classList.remove('extend')
|
||
|
||
sidebar.classList.remove('hide')
|
||
|
||
content.classList.remove('extend')
|
||
|
||
} else { // hide
|
||
|
||
sidebar_toggle.classList.add('extend')
|
||
|
||
sidebar.classList.add('hide')
|
||
|
||
content.classList.add('extend')
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
function open_sidebar() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.add('show')
|
||
|
||
overlay.classList.add('show')
|
||
|
||
}
|
||
|
||
function hide_canvas() {
|
||
|
||
let sidebar = document.querySelector('.book-sidebar')
|
||
|
||
let overlay = document.querySelector('.off-canvas-overlay')
|
||
|
||
sidebar.classList.remove('show')
|
||
|
||
overlay.classList.remove('show')
|
||
|
||
}
|
||
</script>
|
||
<div class="off-canvas-content">
|
||
|
||
<div class="columns">
|
||
|
||
<div class="column col-12 col-lg-12">
|
||
|
||
<div class="book-navbar">
|
||
|
||
<!-- For Responsive Layout -->
|
||
|
||
<header class="navbar">
|
||
|
||
<section class="navbar-section">
|
||
|
||
<a onclick="open_sidebar()">
|
||
|
||
<i class="icon icon-menu"></i>
|
||
|
||
</a>
|
||
|
||
</section>
|
||
|
||
</header>
|
||
|
||
</div>
|
||
|
||
<div class="book-content" style="max-width: 960px; margin: 0 auto;
|
||
|
||
overflow-x: auto;
|
||
|
||
overflow-y: hidden;">
|
||
|
||
<div class="book-post">
|
||
|
||
<p id="tip" align="center"></p>
|
||
|
||
<div><h1>36 WAF:保护我们的网络服务</h1>
|
||
|
||
<p>在前些天的“安全篇”里,我谈到了 HTTPS,它使用了 SSL/TLS 协议,加密整个通信过程,能够防止恶意窃听和窜改,保护我们的数据安全。</p>
|
||
|
||
<p>但 HTTPS 只是网络安全中很小的一部分,仅仅保证了“通信链路安全”,让第三方无法得知传输的内容。在通信链路的两端,也就是客户端和服务器,它是无法提供保护的。</p>
|
||
|
||
<p>因为 HTTP 是一个开放的协议,Web 服务都运行在公网上,任何人都可以访问,所以天然就会成为黑客的攻击目标。</p>
|
||
|
||
<p>而且黑客的本领比我们想象的还要大得多。虽然不能在传输过程中做手脚,但他们还可以“假扮”成合法的用户访问系统,然后伺机搞破坏。</p>
|
||
|
||
<h2>Web 服务遇到的威胁</h2>
|
||
|
||
<p>黑客都有哪些手段来攻击 Web 服务呢?我给你大概列出几种常见的方式。</p>
|
||
|
||
<p>第一种叫“<strong>DDoS</strong>”攻击(distributed denial-of-service attack),有时候也叫“洪水攻击”。</p>
|
||
|
||
<p>黑客会控制许多“僵尸”计算机,向目标服务器发起大量无效请求。因为服务器无法区分正常用户和黑客,只能“照单全收”,这样就挤占了正常用户所应有的资源。如果黑客的攻击强度很大,就会像“洪水”一样对网站的服务能力造成冲击,耗尽带宽、CPU 和内存,导致网站完全无法提供正常服务。</p>
|
||
|
||
<p>“DDoS”攻击方式比较“简单粗暴”,虽然很有效,但不涉及 HTTP 协议内部的细节,“技术含量”比较低,不过下面要说的几种手段就不一样了。</p>
|
||
|
||
<p>网站后台的 Web 服务经常会提取出 HTTP 报文里的各种信息,应用于业务,有时会缺乏严格的检查。因为 HTTP 报文在语义结构上非常松散、灵活,URI 里的 query 字符串、头字段、body 数据都可以任意设置,这就带来了安全隐患,给了黑客“<strong>代码注入</strong>”的可能性。</p>
|
||
|
||
<p>黑客可以精心编制 HTTP 请求报文,发送给服务器,服务程序如果没有做防备,就会“上当受骗”,执行黑客设定的代码。</p>
|
||
|
||
<p>“<strong>SQL 注入</strong>”(SQL injection)应该算是最著名的一种“代码注入”攻击了,它利用了服务器字符串拼接形成 SQL 语句的漏洞,构造出非正常的 SQL 语句,获取数据库内部的敏感信息。</p>
|
||
|
||
<p>另一种“<strong>HTTP 头注入</strong>”攻击的方式也是类似的原理,它在“Host”“User-Agent”“X-Forwarded-For”等字段里加入了恶意数据或代码,服务端程序如果解析不当,就会执行预设的恶意代码。</p>
|
||
|
||
<p>在之前的[第 19 讲]里,也说过一种利用 Cookie 的攻击手段,“<strong>跨站脚本</strong>”(XSS)攻击,它属于“JS 代码注入”,利用 JavaScript 脚本获取未设防的 Cookie。</p>
|
||
|
||
<h2>网络应用防火墙</h2>
|
||
|
||
<p>面对这么多的黑客攻击手段,我们应该怎么防御呢?</p>
|
||
|
||
<p>这就要用到“<strong>网络应用防火墙</strong>”(Web Application Firewall)了,简称为“<strong>WAF</strong>”。</p>
|
||
|
||
<p>你可能对传统的“防火墙”比较熟悉。传统“防火墙”工作在三层或者四层,隔离了外网和内网,使用预设的规则,只允许某些特定 IP 地址和端口号的数据包通过,拒绝不符合条件的数据流入或流出内网,实质上是<strong>一种网络数据过滤设备</strong>。</p>
|
||
|
||
<p>WAF 也是一种“防火墙”,但它工作在七层,看到的不仅是 IP 地址和端口号,还能看到整个 HTTP 报文,所以就能够对报文内容做更深入细致的审核,使用更复杂的条件、规则来过滤数据。</p>
|
||
|
||
<p>说白了,WAF 就是一种“<strong>HTTP 入侵检测和防御系统</strong>”。</p>
|
||
|
||
<p><img src="assets/e8369d077454e5b92e3722e7090551a3.png" alt="img" /></p>
|
||
|
||
<p>WAF 都能干什么呢?</p>
|
||
|
||
<p>通常一款产品能够称为 WAF,要具备下面的一些功能:</p>
|
||
|
||
<ul>
|
||
|
||
<li>IP 黑名单和白名单,拒绝黑名单上地址的访问,或者只允许白名单上的用户访问;</li>
|
||
|
||
<li>URI 黑名单和白名单,与 IP 黑白名单类似,允许或禁止对某些 URI 的访问;</li>
|
||
|
||
<li>防护 DDoS 攻击,对特定的 IP 地址限连限速;</li>
|
||
|
||
<li>过滤请求报文,防御“代码注入”攻击;</li>
|
||
|
||
<li>过滤响应报文,防御敏感信息外泄;</li>
|
||
|
||
<li>审计日志,记录所有检测到的入侵操作。</li>
|
||
|
||
</ul>
|
||
|
||
<p>听起来 WAF 好像很高深,但如果你理解了它的工作原理,其实也不难。</p>
|
||
|
||
<p>它就像是平时编写程序时必须要做的函数入口参数检查,拿到 HTTP 请求、响应报文,用字符串处理函数看看有没有关键字、敏感词,或者用正则表达式做一下模式匹配,命中了规则就执行对应的动作,比如返回 403/404。</p>
|
||
|
||
<p>如果你比较熟悉 Apache、Nginx、OpenResty,可以自己改改配置文件,写点 JS 或者 Lua 代码,就能够实现基本的 WAF 功能。</p>
|
||
|
||
<p>比如说,在 Nginx 里实现 IP 地址黑名单,可以利用“map”指令,从变量 $remote_addr 获取 IP 地址,在黑名单上就映射为值 1,然后在“if”指令里判断:</p>
|
||
|
||
<pre><code>map $remote_addr $blocked {
|
||
|
||
default 0;
|
||
|
||
"1.2.3.4" 1;
|
||
|
||
"5.6.7.8" 1;
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
if ($blocked) {
|
||
|
||
return 403 "you are blocked.";
|
||
|
||
}
|
||
|
||
</code></pre>
|
||
|
||
<p>Nginx 的配置文件只能静态加载,改名单必须重启,比较麻烦。如果换成 OpenResty 就会非常方便,在 access 阶段进行判断,IP 地址列表可以使用 cosocket 连接外部的 Redis、MySQL 等数据库,实现动态更新:</p>
|
||
|
||
<pre><code>local ip_addr = ngx.var.remote_addr
|
||
|
||
|
||
|
||
local rds = redis:new()
|
||
|
||
if rds:get(ip_addr) == 1 then
|
||
|
||
ngx.exit(403)
|
||
|
||
end
|
||
|
||
</code></pre>
|
||
|
||
<p>看了上面的两个例子,你是不是有种“跃跃欲试”的冲动了,想自己动手开发一个 WAF?</p>
|
||
|
||
<p>不过我必须要提醒你,在网络安全领域必须时刻记得“<strong>木桶效应</strong>”(也叫“短板效应”)。网站的整体安全不在于你加固的最强的那个方向,而是在于你可能都没有意识到的“短板”。黑客往往会“避重就轻”,只要发现了网站的一个弱点,就可以“一点突破”,其他方面的安全措施也就都成了“无用功”。</p>
|
||
|
||
<p>所以,使用 WAF 最好“<strong>不要重新发明轮子</strong>”,而是使用现有的、比较成熟的、经过实际考验的 WAF 产品。</p>
|
||
|
||
<h2>全面的 WAF 解决方案</h2>
|
||
|
||
<p>这里我就要“隆重”介绍一下 WAF 领域里的最顶级产品了:ModSecurity,它可以说是 WAF 界“事实上的标准”。</p>
|
||
|
||
<p>ModSecurity 是一个开源的、生产级的 WAF 工具包,历史很悠久,比 Nginx 还要大几岁。它开始于一个私人项目,后来被商业公司 Breach Security 收购,现在则是由 TrustWave 公司的 SpiderLabs 团队负责维护。</p>
|
||
|
||
<p>ModSecurity 最早是 Apache 的一个模块,只能运行在 Apache 上。因为其品质出众,大受欢迎,后来的 2.x 版添加了 Nginx 和 IIS 支持,但因为底层架构存在差异,不够稳定。</p>
|
||
|
||
<p>所以,这两年 SpiderLabs 团队就开发了全新的 3.0 版本,移除了对 Apache 架构的依赖,使用新的“连接器”来集成进 Apache 或者 Nginx,比 2.x 版更加稳定和快速,误报率也更低。</p>
|
||
|
||
<p>ModSecurity 有两个核心组件。第一个是“<strong>规则引擎</strong>”,它实现了自定义的“SecRule”语言,有自己特定的语法。但“SecRule”主要基于正则表达式,还是不够灵活,所以后来也引入了 Lua,实现了脚本化配置。</p>
|
||
|
||
<p>ModSecurity 的规则引擎使用 C++11 实现,可以从<a href="https://github.com/SpiderLabs/ModSecurity">GitHub</a>上下载源码,然后集成进 Nginx。因为它比较庞大,编译很费时间,所以最好编译成动态模块,在配置文件里用指令“load_module”加载:</p>
|
||
|
||
<pre><code>load_module modules/ngx_http_modsecurity_module.so;
|
||
|
||
</code></pre>
|
||
|
||
<p>只有引擎还不够,要让引擎运转起来,还需要完善的防御规则,所以 ModSecurity 的第二个核心组件就是它的“<strong>规则集</strong>”。</p>
|
||
|
||
<p>ModSecurity 源码提供一个基本的规则配置文件“<strong>modsecurity.conf-recommended</strong>”,使用前要把它的后缀改成“conf”。</p>
|
||
|
||
<p>有了规则集,就可以在 Nginx 配置文件里加载,然后启动规则引擎:</p>
|
||
|
||
<pre><code>modsecurity on;
|
||
|
||
modsecurity_rules_file /path/to/modsecurity.conf;
|
||
|
||
</code></pre>
|
||
|
||
<p>“modsecurity.conf”文件默认只有检测功能,不提供入侵阻断,这是为了防止误杀误报,把“SecRuleEngine”后面改成“On”就可以开启完全的防护:</p>
|
||
|
||
<pre><code>#SecRuleEngine DetectionOnly
|
||
|
||
SecRuleEngine On
|
||
|
||
</code></pre>
|
||
|
||
<p>基本的规则集之外,ModSecurity 还额外提供一个更完善的规则集,为网站提供全面可靠的保护。这个规则集的全名叫“<strong>OWASP ModSecurity 核心规则集</strong>”(Open Web Application Security Project ModSecurity Core Rule Set),因为名字太长了,所以有时候会简称为“核心规则集”或者“CRS”。</p>
|
||
|
||
<p>CRS 也是完全开源、免费的,可以从 GitHub 上下载:</p>
|
||
|
||
<pre><code>git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
|
||
|
||
</code></pre>
|
||
|
||
<p>其中有一个“<strong>crs-setup.conf.example</strong>”的文件,它是 CRS 的基本配置,可以用“Include”命令添加到“modsecurity.conf”里,然后再添加“rules”里的各种规则。</p>
|
||
|
||
<pre><code>Include /path/to/crs-setup.conf
|
||
|
||
Include /path/to/rules/*.conf
|
||
|
||
</code></pre>
|
||
|
||
<p>你如果有兴趣可以看一下这些配置文件,里面用“SecRule”定义了很多的规则,基本的形式是“SecRule 变量 运算符 动作”。不过 ModSecurity 的这套语法“自成一体”,比较复杂,要完全掌握不是一朝一夕的事情,我就不详细解释了。</p>
|
||
|
||
<p>另外,ModSecurity 还有强大的审计日志(Audit Log)功能,记录任何可疑的数据,供事后离线分析。但在生产环境中会遇到大量的攻击,日志会快速增长,消耗磁盘空间,而且写磁盘也会影响 Nginx 的性能,所以一般建议把它关闭:</p>
|
||
|
||
<pre><code>SecAuditEngine off #RelevantOnly
|
||
|
||
SecAuditLog /var/log/modsec_audit.log
|
||
|
||
</code></pre>
|
||
|
||
<h2>小结</h2>
|
||
|
||
<p>今天我们一起学习了“网络应用防火墙”,也就是 WAF,使用它可以加固 Web 服务。</p>
|
||
|
||
<ol>
|
||
|
||
<li>Web 服务通常都运行在公网上,容易受到“DDoS”、“代码注入”等各种黑客攻击,影响正常的服务,所以必须要采取措施加以保护;</li>
|
||
|
||
<li>WAF 是一种“HTTP 入侵检测和防御系统”,工作在七层,为 Web 服务提供全面的防护;</li>
|
||
|
||
<li>ModSecurity 是一个开源的、生产级的 WAF 产品,核心组成部分是“规则引擎”和“规则集”,两者的关系有点像杀毒引擎和病毒特征库;</li>
|
||
|
||
<li>WAF 实质上是模式匹配与数据过滤,所以会消耗 CPU,增加一些计算成本,降低服务能力,使用时需要在安全与性能之间找到一个“平衡点”。</li>
|
||
|
||
</ol>
|
||
|
||
<h2>课下作业</h2>
|
||
|
||
<ol>
|
||
|
||
<li>HTTPS 为什么不能防御 DDoS、代码注入等攻击呢?</li>
|
||
|
||
<li>你还知道有哪些手段能够抵御网络攻击吗?</li>
|
||
|
||
</ol>
|
||
|
||
<p>欢迎你把自己的学习体会写在留言区,与我和其他同学一起讨论。如果你觉得有所收获,也欢迎把文章分享给你的朋友。</p>
|
||
|
||
<p><img src="assets/b9e48b813c98bb34b4b433b7326ace24.png" alt="unpreview" /></p>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div>
|
||
|
||
<div style="float: left">
|
||
|
||
<a href="/专栏/透视HTTP协议/35 OpenResty:更灵活的Web服务器.md.html">上一页</a>
|
||
|
||
</div>
|
||
|
||
<div style="float: right">
|
||
|
||
<a href="/专栏/透视HTTP协议/37 CDN:加速我们的网络服务.md.html">下一页</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
|
||
|
||
</div>
|
||
|
||
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70997d31e9ef3cfa","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
|
||
|
||
</body>
|
||
|
||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||
|
||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
|
||
|
||
<script>
|
||
|
||
window.dataLayer = window.dataLayer || [];
|
||
function gtag() {
|
||
|
||
dataLayer.push(arguments);
|
||
|
||
}
|
||
gtag('js', new Date());
|
||
|
||
gtag('config', 'G-NPSEEVD756');
|
||
|
||
var path = window.location.pathname
|
||
|
||
var cookie = getCookie("lastPath");
|
||
|
||
console.log(path)
|
||
|
||
if (path.replace("/", "") === "") {
|
||
|
||
if (cookie.replace("/", "") !== "") {
|
||
|
||
console.log(cookie)
|
||
|
||
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
setCookie("lastPath", path)
|
||
|
||
}
|
||
function setCookie(cname, cvalue) {
|
||
|
||
var d = new Date();
|
||
|
||
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
|
||
|
||
var expires = "expires=" + d.toGMTString();
|
||
|
||
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
|
||
|
||
}
|
||
function getCookie(cname) {
|
||
|
||
var name = cname + "=";
|
||
|
||
var ca = document.cookie.split(';');
|
||
|
||
for (var i = 0; i < ca.length; i++) {
|
||
|
||
var c = ca[i].trim();
|
||
|
||
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
|
||
|
||
}
|
||
|
||
return "";
|
||
|
||
}
|
||
</script>
|
||
</html>
|
||
|