跳转至

自定义waf日志格式

waf日志配置在init.lua

默认配置如下

Bash
function log(method,url,data,ruletag)
    if attacklog then
        local realIp = getClientIp()
        local ua = ngx.var.http_user_agent
        local servername=ngx.var.server_name
        local time=ngx.localtime()
        if ua  then
            line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\"  \""..ua.."\" \""..ruletag.."\"\n"
        else
            line = realIp.." ["..time.."] \""..method.." "..servername..url.."\" \""..data.."\" - \""..ruletag.."\"\n"
        end
        local filename = logpath..'/'..servername.."_"..ngx.today().."_sec.log"
        write(filename,line)
    end
end

调用需要输入参数

log(method,url,data,ruletag),比如在URL规则函数下配置

Bash
function url()
    if UrlDeny then
        for _,rule in pairs(urlrules) do
            if rule ~="" and ngxmatch(ngx.var.request_uri,rule,"isjo") then
                log('GET',ngx.var.request_uri,"-",rule)
                say_html()
                return true
            end
        end
    end
    return false
end

日志打印如下

日志以域名+日期命名文件

Bash
1
2
3
4
root@pts/0 # ll ../../logs/hack/
总用量 20
-rw-rw-rw-. 1 root root 6835 8月   7 17:18 db2.kuaiban.cn_2025-08-07_sec.log
-rw-rw-rw-. 1 root root 1504 8月   5 14:36 www.kuaiban.cn_2025-08-05_sec.log

日志输出字段:ip time mothod servername/uri data ua ruletag

Bash
1
2
3
4
root@pts/0 # tail -2 ../../logs/hack/www.kuaiban.cn_2025-08-05_sec.log 
172.16.1.201 [2025-08-05 10:06:14] "GET www.kuaiban.cn/index.html?from=../etc/passwd" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15" "\.\./"
172.16.1.201 [2025-08-05 10:52:34] "GET www.kuaiban.cn/index.html?from=../etc/passwd" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15" "\.\./"
172.16.1.201 [2025-08-05 14:36:59] "GET www.kuaiban.cn/index.html?from=../etc/passwd" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)" "\.\./"

日志记录格式修改

Bash
function log(method,url,data,ruletag)
    if attacklog then
        local realIp = getClientIp()
        local ua = ngx.var.http_user_agent or "-"
        local host = ngx.var.host or "-"
        local servername=ngx.var.server_name or "-"
        local time=ngx.localtime()
        line = realIp.." ["..time.."] \""..method.." "..url.."\" \""..data.."\"  \""..ua.."\" \""..servername.."\" \""..host.."\" \""..ruletag.."\"\n"
        local filename = logpath..'/'..ngx.today().."_sec.log"
        write(filename,line)
    end
end

修改介绍:

  • 添加or "-":防止数据为nil时脚本报错,如果获取参数是已经做了判断,则可以不用or
  • 添加host参数:获取真实的请求域名,因为server_name 只打印第一个配置域名
  • 日志添加host打印,参数放置顺序调整,方便logstash过滤
  • 有ELK日志分析,将日志改为一个文件,方便filebeat数据获取

修改后日志按照日期输出

Bash
1
2
3
4
root@pts/0 # ll
总用量 20
-rw-rw-rw-. 1 root root 3338 8月   7 19:12 2025-08-07_sec.log
-rw-rw-rw-. 1 root root  469 8月   8 09:48 2025-08-08_sec.log

日志内容将server_nameurl分开记录,并且打印实际请求的host地址

Bash
1
2
3
root@pts/0 # tail -2 2025-08-08_sec.log 
172.16.1.201 [2025-08-08 09:47:24] "GET /wpad.dat" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15" "db2.kuaiban.cn" "db2.kuaiban.cn" "wpad\.dat"
172.16.1.201 [2025-08-08 09:48:11] "GET /.bash_history" "-"  "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Safari/605.1.15" "db2.kuaiban.cn" "db2.kuaiban.cn" "\.(svn|htaccess|bash_history)"

denycc 日志添加

默认denycc 是不记录日志的,我们可以参照其他方法添加 需注意,线上如果遭受攻击,记录日志可能加大系统负载,取消say_html(),修改状态退出码为444,在nginx日志access.log查看status:444 可以分析攻击行为

Bash
function denycc()
    if CCDeny then
        local uri=ngx.var.uri
        CCcount=tonumber(string.match(CCrate,'(.*)/'))
        CCseconds=tonumber(string.match(CCrate,'/(.*)'))
        local token = getClientIp()..uri
        local limit = ngx.shared.limit
        local req,_=limit:get(token)
        if req then
            if req > CCcount then
                 --添加日志
                 log('CC',ngx.var.request_uri,"CC Attack blocked: count="..req.." rate="..CCrate,"CCDENY")
                 say_html()
                 --ngx.exit(444)
                return true
            else
                 limit:incr(token,1)
            end
        else
            limit:set(token,1,CCseconds)
        end
    end
    return false
end

修改后日志记录如下:

Bash
127.0.0.1 [2025-08-12 17:24:14] "CC /asd.html" "CC Attack blocked: count=3 rate=2/60"  "curl/7.29.0" "db2.kuaiban.cn" "db2.kuaiban.cn" "CCDENY"

logstash过滤规则如下:

Bash
1
2
3
root@pts/1 # cat /usr/share/logstash/patterns/nginx 

NGWAF %{IPV4:realip}\s+\[%{TIMESTAMP_ISO8601:time}\]\s+"%{WORD:method}\s+(?<url>[^"]+)"\s+"(?<data>[^"]+)"\s+"(?<useragent>[^"]+)"\s+"(?<server_name>[^"]+)"\s+"(?<rhost>[^"]+)"\s+"(?<ruletag>[^"]+)"