手动扩展长亭雷池WAF社区版本之全量日志及可视化大屏

前言

自从长亭开放了雷池社区版,一直没找到机会尝试。最近刚好有需求,随即进行了一轮测试。
雷池是长亭基于nginx(tenginx)做的一款waf(web 应用防火墙),和openresty差不多,只是增强了安全相关的功能,并增加了UI。
测试发现,社区版功能受限,很多基础功能都没有,UI上可自定义的东西也不够多,而且发现未编译lua引擎,所以openresty中用到的语法不支持(或者说有相关语法并没有响应的文档)。
基于技术探索和实际业务需求,随即开始尝试将雷池社区版增加一些企业版才有的功能。

全量日志

环境

  • 4C/8G/256GSSD
  • Ubuntu2004
  • Docker一键安装模式

需求

  • 记录所有request
  • 截断记录request body
  • 统一日志管理(打入elasticSearch)

友情提示

如在生产环境做修改时,请做好配置文件的备份

打开雷池日志功能并自定义nginx日志格式

1. 打开雷池日志功能

默认安装的雷池日志功能是关闭的,首先需要将开关打开。
找到 /data/safeline/resources/nginx/nginx.conf 文件
access_log off;'' 改为 access_log on;‘’

2.自定义访问日志格式

nginx默认的日志格式是不满足我们信息安全需求的,他只记录了最基本的信息。
我需要更全面的request信息,用于分析和决策。

log_format json escape=json '{"@timestamp":"$time_iso8601",'
                      '"server_addr":"$server_addr",'
                      '"remote_addr":"$http_x_forwarded_for",'
                      '"scheme":"$scheme",'
                      '"request_method":"$request_method",'
                      '"request_uri": "$request_uri",'
                      '"request_length": "$request_length",'
                      '"uri": "$uri", '
                      '"request_time":$request_time,'
                      '"body_bytes_sent":$body_bytes_sent,'
                      '"request_body":"$request_body_short",'
                      '"bytes_sent":$bytes_sent,'
                      '"status":"$status",'
                      '"upstream_time":"$upstream_response_time",'
                      '"upstream_host":"$upstream_addr",'
                      '"upstream_status":"$upstream_status",'
                      '"host":"$host",'
                      '"http_referer":"$http_referer",'
                      '"http_user_agent":"$http_user_agent"'
                      '}';

将以上代码片段插入默认的log_format main片段之后,记住main不能删除,直接加到后面去
这样记录之后, 相对完整了很多,满足了我们信息安全的溯源和审计的基本需求。

3. 截断request_body信息

有body信息,更多的信息就有更多的参考纬度,这样才能方便人工进行数据分析。
而Body信息可能存在非常巨大的情况,比如用户或管理员进行图片上传,日志将会变得非常巨大。
并且考虑到性能问题,这个时候我们需要截取body信息,截取body信息很简单用雷池自带的lua语法就能做到.
上面增加的 $request_body_short 变量,在nginx标准变量中是不存在的,标准变量(ngx_http_core)中只有 $request_body 变量.
我们需要将$request_body截断变成 $request_body_short ,以下是代码:

lua_need_request_body   on;
set $request_body_short      "";
            content_by_lua_block {
                ngx.req.read_body()
                local   req_body = ngx.req.get_body_data()
                ngx.var.request_body_short =  req_body:sub(1,1000)
            }

为了能全局通用和数据持久化, 我们将以上代码保存在nginx根目录下文件名为 custom_params/backend_xxx ,xxx为你的域名ID

4. 应用&验证

现在我们为各个域名配置全量日志,进入 nginx/custom_params 目录,编辑 backend_xxx 文件,xxx为你对应的域名编号。
将以下内容写入该文件

include proxy_params;
access_log /data/safeline/logs/nginx/domain_access.log json;

然后使用命令检查我们的配置文件是否正确:

docker exec safeline-tengine nginx -t

如果没有问题,可使用下面命令让nginx重新加载配置文件

docker exec safeline-tengine nginx -s reload

然后去你配置的地方检查是否有请求日志落地,我们可使用命令

tail /data/safeline/logs/nginx/domain_access.log

进行检查

日志写入性能优化

nginx日志的写入,可根据硬件条件及负载进行日志落地的优化,详情可查看nginx官网。

日志统一管理

由于有统一日志管理的需求,需要将雷池的日志打入ElasticSearch中,官方也没有相关操作UI。
也就只有手动撸起来。

可视化大屏

参考