博客被攻击之后,我部署雷池防火墙给网站穿上防弹衣

前言

上次博客评论区被植入恶意代码,虽然做了应急处理,封 IP、删评论、修复模板漏洞,但总觉得不够踏实。

攻击者换个 IP 就能再来,每次手动封太被动了。

我需要一个能自动拦截恶意请求的防火墙,在攻击到达应用之前就把它挡在外面。

调研了一圈,选了长亭科技的雷池 WAF(Web 应用防火墙),社区版免费,功能够用,还能和我现有的 APISIX 网关集成。

这篇文章记录完整的部署和集成过程。

雷池是什么

雷池(SafeLine)是长亭科技开源的 Web 应用防火墙,社区版完全免费。

它的核心是语义分析检测引擎,不是简单的正则匹配,而是真正理解 HTTP 请求的内容,误报率低,拦截准。

能防的东西很多:SQL 注入、XSS 跨站脚本攻击、代码执行、目录遍历、文件上传攻击,还有 CC 攻击防护和 Bot 机器人防护。

对我的一人企业场景来说,社区版的能力已经够用了。

手动部署雷池

雷池推荐 Docker 部署,官方提供一键安装脚本,但如果你和我一样喜欢掌控每个配置细节,走手动部署更合适。

前提是服务器已经装好 Docker,版本不低于 20.10.14,Docker Compose 不低于 2.0.0。

创建安装目录:

1
2
mkdir -p "/data/safeline"
cd "/data/safeline"

下载 Docker Compose 编排脚本:

1
wget "https://waf-ce.chaitin.cn/release/latest/compose.yaml"

创建环境变量配置文件 .env,写入以下内容:

1
2
3
4
5
6
7
8
9
10
SAFELINE_DIR=/data/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD=your_password # 自定义密码,数字加英文大小写
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=swr.cn-east-3.myhuaweicloud.com/chaitin-safeline
ARCH_SUFFIX=
RELEASE=
REGION=
MGT_PROXY=0

几个要点。

ARM 架构的服务器需要把 ARCH_SUFFIX 改成 -arm

海外服务器建议把 IMAGE_PREFIX 改成 chaitin,直接从 Docker Hub 拉镜像。

国内服务器保持默认的华为云镜像源就行。

启动雷池:

1
docker compose up -d

容器启动后,浏览器访问 https://服务器IP:9443 就能看到雷池控制台。

首次访问会提示证书不安全,点继续即可。

PS:由于我服务器并没有放开9443端口,需要通过APISIX网关来暴露雷池控制台了,配置参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"uri": "/*",
"name": "waf",
"host": "your-waf-domain",
"plugins": {
"proxy-rewrite": {
"headers": {
"X-Forwarded-For": "$remote_addr",
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:9443": 1
},
"tls": {
"verify": false
},
"scheme": "https"
}
}

另外首次访问还需要执行命令: docker exec safeline-mgt resetadmin 获取管理员密码。

切换检测引擎为 TCP 模式

到这里雷池已经能独立工作了,可以直接在控制台添加站点进行防护。

但我的架构里前面有一层 APISIX 网关,需要把雷池的检测引擎接入 APISIX,让所有请求先过雷池再转发到后端。

问题是雷池检测引擎默认用 Unix Socket 提供服务,只能在容器内部调用。

要和 APISIX 集成,得改成 TCP 模式。

进入检测引擎的配置目录:

1
cd /data/safeline/resources/detector/

编辑 detector.yml,添加两行配置:

1
2
bind_addr: 0.0.0.0
listen_port: 8000

然后回到雷池安装目录,编辑 compose.yaml,给 detector 容器加上端口映射:

1
2
3
detect:
ports:
- 8000:8000

重启雷池让配置生效:

1
2
3
cd /data/safeline
docker compose down
docker compose up -d

还有一步:雷池和 APISIX 默认都用 9443 端口,装在同一台机器上会冲突。

.env 文件里把 MGT_PORT 改成别的端口(比如 9444),再重启雷池就行。

需要注意的是,切换 TCP 模式后雷池控制台本身配置的站点防护会失效,需要同步把雷池的 NGINX 配置从 unix socket 改成 http 方式。
具体做法是拷贝 safeline_unix.confsafeline_http.conf,在 nginx.conf 中切换 include,再把 upstream 地址指向检测引擎的 IP 加端口。

在 APISIX 中接入雷池

由于我的网站平台是统一使用 APISIX 做的网关,APISIX 从 3.5.0 版本开始就内置了 chaitin-waf 插件,集成起来非常方便,只需要简单配置就可以给全站平台都加上安全防护啦。

配置 APISIX 指向雷池检测引擎的地址:

1
2
3
4
5
6
7
8
9
10
curl http://127.0.0.1:9180/apisix/admin/plugin_metadata/chaitin-waf \
-H 'X-API-KEY: your-key-here' -X PUT -d '
{
"nodes":[
{
"host": "127.0.0.1",
"port": 8000
}
]
}'

host 填雷池所在服务器的 IP,同一台机器就是 127.0.0.1

然后创建一条路由,把流量经过雷池检测后转发到后端业务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
curl http://127.0.0.1:9180/apisix/admin/routes/1 \
-H 'X-API-KEY: your-key-here' -X PUT -d '
{
"uri": "/*",
"plugins": {
"chaitin-waf": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"127.0.0.1:9080": 1
}
}
}'

upstream 里的地址换成你的实际业务服务器。

测试防护效果

配置完成后验证一下。

正常访问能返回页面:

1
curl http://127.0.0.1:9080/

模拟一个 SQL 注入攻击:

1
curl http://127.0.0.1:9080/ -d 'a=1 and 1=1'

返回 HTTP 403,说明雷池成功拦截了:

1
2
3
4
5
6
{
"code": 403,
"success": false,
"message": "blocked by Chaitin SafeLine Web Application Firewall",
"event_id": "18e0f220f7a94127acb21ad3c1b4ac47"
}

打开雷池控制台的日志中心,能看到完整的攻击记录,包括请求 IP、攻击类型和拦截时间。

从此以后,恶意请求在到达博客之前就被雷池自动挡住,不用再每次手动封 IP 了。

定时报告

最后还可以通过 hermes 调用 WAF OpenAPI 定时获取安全报告,如下是我的每小时安全报告:

看起来还不错吧,下一篇再来介绍如何通过 hermes 获取安全报告和自定义规则设置。

你的网站有没有做过安全防护?用的什么方案?评论区聊聊。