Press "Enter" to skip to content

为Nginx加入一个使用深度学习的软WAF

一、前言

 

本文介绍如何向Nginx增加了一个使用Tensorflow C库的软WAF模块,模块主体基于Naxsi。

 

二、获取数据及训练数据

 

这里,之前有Dalao发表过这样一篇文章: 基于卷积神经网络的SQL注入检测

 

这是一个开源的项目,但是由于速度的关系,我不打算使用这篇文章的模型,仅仅采用这篇文章使用的数据集。这样可以节省很多特征工程的时间。

 

数据训练并不是这篇文章的重点,这里仅仅说一下训练结果,这里为了防止CUDA周期对检测时间的影响,使用CPU跑推理过程。

 

如果您对数据的训练感兴趣,可以看我之前写的一篇文章: 使用CNN做SQL和XSS的识别

 

三、使用Tensorflow C库做推理

 

我们的目标是向Nginx加入一个使用Tensorflow C库的软WAF模块。如果从头开始写一个软WAF,想必会占用相当多的时间,并且这个也和这篇文章的主旨偏离。

 

在Nginx的开源的软WAF模块中,Naxsi是一个很受欢迎的模块。这个模块使用C作为主开发语言,因此,如果我们想基于这个模块加一个推理过程,很大可能性需要加入Tensorflow C库。那幺,首先应该做的是,试着使用Tensorflow C库做单次推理,并做好模块测试。

 

Main文件如下:

 

 

编译完成后,可以跑一下数据,这里为了节省篇幅,仅测试一条

 

 

可见这部分代码已经可以正常工作了。

 

四、向Naxsi内加入代码

 

首先,回忆下Nginx的一些原理,Nginx在运行时使用fork,创建了一个master进程和若干worker进程,worker进程是实际处理数据的进程。每个模块的初始化函数,实际上是由初始化的进程来完成的,在这之后,如果配置了daemon,初始化的进程自动退出。

 

同时,为了便于理解,我们可以把推理流程拆分成这样几个部分:

 

1. 初始化模型
2. 将输入转化为Tensorflow识别的格式
3. 运行模型,获取结果

 

其中,步骤1仅需运行一次,步骤2,3在每次运行这个模块时都需要进行。

 

我对于Nginx理解不深,DaLao轻拍。

 

由于worker进程是fork产生的,实际上是无法使用初始化进程产生的model,所以,每个worker进程需要自己初始化一次自己的model相关资源。因此,新加入的函数应该类似这样:

 

 

这里,我仅仅检测uri内部的注入请求,其它部分的检测代码应该是非常相似的,这里就不再重复罗嗦了。

 

由于tf_model是在第一次调用模块时才会自动载入,因此,在这个服务器的每个worker进程第一次接受到数据时,可能会稍卡顿一下。

 

五、编译运行

 

将Naxsi和Nginx的代码同时复制到编译服务器内部,然后在编译Nginx时,包含下Naxsi的代码部分。

 

 

由于Nginx在编译时是不使用Tensorflow库的,所以我们需要手动修改下Makefile,在链接时自动加入Tensorflow库,最后编译。

 

 

然后,需要将Naxsi的配置文件复制到Nginx的conf文件夹内,配置Naxsi,并修改Nginx的配置文件,加入Naxsi模块。自定义一个403的Page,作为注入发生时的替换界面。然后,运行Nginx。

 

六、手注测试

 

这里使用简单的手注,测试模块是否正常运行。这里实际是不可能出现注入的情况的,如果有兴趣的话,可以加入DVWA等靶机,使用sqlmap等工具实际攻击。

 

 

七、总结

 

经过以上几个步骤,我们就得到了一个使用DL的Nginx的软WAF模块,并把它加入到了Nginx内。相比普通的规则匹配类的引擎,一般而言,这种方法的防御效果更加优秀。考虑漏报和误报率的话,使用测试集测试,可靠性提高了数倍。

 

当然,推理流程会对服务器本身的性能造成一定的影响,因此在实际的环境中,可能需要使用Tensorflow C GPU库来跑运算,或者将Nginx作为代理使用。

 

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注