本文最后更新于 2024-09-12,文章内容可能已经过时。

一、什么是OpenRestry

OpenResty 是一个基于Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。

OpenResty通过汇聚各种设计精良的Nginx模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。

OpenRestry 中文文档 http://openresty.org/cn/components.html

二、什么是VeryNginx

VeryNginx是基于lua_nginx_module(openrestry)开发的,可以实现高级防火墙、访问统计和一些其他的功能,强化了Nginx本身的功能,并提供了友好的web交互界面

github中文文档 https://github.com/alexazhou/VeryNginx/blob/master/readme_zh.md

三、VeryNginx的安装

1.下载安装包,准备依赖包

从https://github.com/alexazhou/VeryNginx 直接下载

yum -y install gcc gcc-c++ autoconf automake make unzip perl wget
yum -y install zlib zlib-devel openssl openssl-devel pcre pcre-devel

2.解压并安装

cd /tools
unzip VeryNginx-0.3.3.zip
cd VeryNginx-0.3.3
python install.py install

安装之后会显示

*** All work finished successfully, enjoy it~

3.检查配置文件

安装完成之后检查配置文件,有三个配置文件需要在/opt/verynginx/openresty/nginx/conf/nginx.conf的里边

include /opt/verynginx/verynginx/nginx_conf/in_external.conf; 添加到http上面

include /opt/verynginx/verynginx/nginx_conf/in_http_block.conf;添加到http里面

include /opt/verynginx/verynginx/nginx_conf/in_server_block.conf;添加到server里面

image-20240717225202788

image-20240717225222264

4.修改用户

如果直接使用/opt/verynginx/openresty/nginx/sbin/nginx启动nginx会出现报错

nginx: [emerg] getpwnam("nginx") failed in /opt/verynginx/openresty/nginx/conf/nginx.conf:2

有两种解决方案

(1)可以使用 useradd nginx 添加nginx用户,但是在文件操作的时候会出现

image-20220916132703293

保存配置失败,用户权限不够,所以还需要给文件更高的权限

(2)直接vi /opt/verynginx/openresty/nginx/conf/nginx.conf 修改nginx.conf 文件,将user 从nginx改成root

image-20240717224400744

然后/opt/verynginx/openresty/nginx/sbin/nginx -s reload 重启就不会出现文件的权限问题

image-20220916133007764

5.启动服务

#Start Service 启动
/opt/verynginx/openresty/nginx/sbin/nginx
#Stop Service 停止
/opt/verynginx/openresty/nginx/sbin/nginx -s stop
#Restart Service 重启
/opt/verynginx/openresty/nginx/sbin/nginx -s reload

直接访问http://ip 就可以看到默认页面

image-20220916104349262

6.进入VeryNginx页面

访问http://ip/verynginx/index.html 进入VeryNginx的管理界面

image-20220916104857185

用户和密码都是verynginx,登陆进去就可以看到操作的主界面了,有中文和英文界面,比较友好

image-20220916105308844

image-20220916105417969

四、VeryNginx功能介绍

github 使用手册

https://github.com/alexazhou/VeryNginx/wiki/%E7%9B%AE%E5%BD%95

1.功能简介

VeryNginx 包含强大的自定义功能,可以做很多的事情

能够自定义的包括两个部分:Matcher 和 Action

Matcher 对请求进行匹配,Action 是要执行的操作

可以比较直观的将一些复杂的组合规则实现应用

2.Matcher

Matcher用来判断http请求是否符合指定的条件,如果Matcher是空的,就没有包含任何的条件,就会匹配上所有的请求

一个Matcher 可以包含一个或者多个的约束条件,支持几个常见的约束

  • Client IP,对应Nginx 变量 remote_addr
  • Host ,对应Nginx变量 host
  • UserAgent ,对应Nginx变量http_user_agent
  • URI,对应Nginx变量 uri,表示访问地址域名之后的部分
  • Referer,对应Nginx变量http_referer
  • Request Args 请求参数匹配,只支持content-type为application/x-www-form-urlencoded

当我们的行为可以和约束条件相匹配的时候,就可以进行相关的操作

3.Action

在Matcher可以匹配的时候Action就会被执行,现在可以实现的Action如下

(1)协议锁定(Scheme Lock)

将访问的协议锁定为Https或者Http

执行的规则为每收到请求,VeryNginx按照从上倒下的顺序,取出每条规则的Mathcer进行匹配测试,符合的时候这条规则处理,后续的停止匹配

当http请求使用的协议和scheme设置不一样就会自动返回302重定向,将浏览器重定向到正确的协议+当前的地址

注意事项:

防止严格的Matcher被宽松的Matcher覆盖,一般严格的写在前边

如果向外提供api的话,可能不支持302重定向

(2)重定向(Redirect)

对请求进行重定向的操作

执行的规则为每收到请求,VeryNginx按照从上倒下的顺序,取出每条规则的Mathcer进行匹配测试,符合的时候这条规则处理,后续的停止匹配

当Regex为空的时候,将重定向到Redict to填写的地址,Regex不为空的时候,新的地址由gsub算法提供

new_address = gsub( uri, re,redirect_to )

注意事项:

Redict to的地址可以是带http或https和域名的,也可以不带域名如/aaa/bbb

要防止前边的规则覆盖了后边的规则

(3)URI重写(URI Rewrite)

对请求的URI 进行内部的重写

执行的规则为每收到请求,VeryNginx按照从上倒下的顺序,取出每条规则的Mathcer进行匹配测试,符合的时候这条规则处理,后续的停止匹配

当Regex为空,重定向到Redirect to的地址,不为空的时候新的地址由gsub算法生成

new_address = gsub( uri, re,redirect_to )

比如我们要访问控制台的话默认的就是/verynginx/index.html,我们就可以做以下配置

Matcher: URI ≈ ^/vn

Regex: ^/vn/(.*)

Redirect to: /verynginx/$1

就可以访问/vn/index.html来访问控制面板了

注意事项:

Redict to只是/ 开头的地址,重定向后查询字符串参数会被保留

(4)浏览器验证(Browser Verify )

通过set-cookies 和 js 验证客户端是不是浏览器,从而可以拦截非浏览器的流量,因为可能会阻止搜索引擎的爬虫,所以建议在被攻击的时候开启,或者针对搜索引擎编写特别的规则

执行的规则为每收到请求,VeryNginx按照从上倒下的顺序,取出每条规则的Mathcer进行匹配测试,符合的时候这条规则处理,后续的停止匹配

原理就是收到请求的时候,VeryNginx会通过算法得到一个token,下面可以选择Cookie或者JavaScript的方式进行验证

  • 使用Cookie,用户的Cookie中没有带有这个Token时,将会返回一个302重定向,将用户重定向到当前地址,并在http响应头中设置cookies。如果客户端是浏览器,将自动带上这个Token再继续访问,此时将被放行。如果客户端是其他工具,并且该工具不支持302以及http响应头中的set cookies字段,将无法继续访问
  • 使用JavaScript的话会返回一个网页,并通过内嵌在网页中的JavaScript来设置Cookies并发起重定向。需要浏览器支持JavaScript才可以验证通过

Token的生成过程如下:

Token = hash( client_ip + UserAgent + key )

其中Key为VeryNginx第一次运行时产生的随机数

这样可以为每个用户和浏览器产生不同的Token,并且无法伪造

(5)访问频率限制(Frequency Limit)

执行的规则为每收到请求,VeryNginx按照从上倒下的顺序,取出每条规则的Mathcer进行匹配测试,符合的时候这条规则处理,后续的停止匹配

每条规则会对命中的请求进行计数,单位时间( Time ) 内最多放行指定次数( Max Request Times ) 的请求,单位时间内超过次数的请求将返还指定的状态码。

  • 未设置单独统计( Count Alone )的情况下,匹配这条规则的所有请求最多为 Max Request Times 次。
  • 通过设置单独统计( Count Alone )选项,可以根据 IP (或 URI)分别进行计数,即命中 Matcher 情况下,相同 IP (或 URI)单位时间内请求不超过指定次数。

(6)过滤器(Filter)

当 Action 项为 accept 时, 不进行任何动作,继续按照正常流程处理

当 Action 项为 block 时,拦截请求,并返回 Return code 项指定的状态码

4.执行顺序

所有的Action执行的顺序为:协议锁定 -> 重定向 -> URI 重写 -> 浏览器认证 -> 访问频率限制 -> 过滤器

5.请求统计

  • 当配置为Enable状态时,本功能对每一次访问进行统计。如果Enable不勾选,则不记录任何数据

    统计数据有两组:

    • All Nginx启动后所有的数据

    • Temporary 每分钟清空的统计数据

      统计结果如下:

    • Count 请求总次数

    • Success rate 请求成功率,状态码在400以下都认为是成功

    • Time 请求总耗费时间

    • Avg time 请求平均耗费时间

    • Size 总响应大小

    • Avg Size 平均响应大小

目前使用了10M大小的共享内存来存储访问统计信息,据实际测试大约可存储10000条URI的统计数据。当共享内存存储满之后,最早的数据将会被丢失(LRU算法)

五、VeryNginx 界面介绍

VeryNginx使用Matcher结合Filter Action可以实现一个功能比较完全的waf,利用Matcher的条件对请求进行过滤,并返回指定的状态码

已经预设的规则可以在一定程度上对SQL注入、Git 和 SVN文件泄露、目录遍历进行阻止,并拦截常见的扫描工具

配置界面中有常见的一些设置如下

基本设置

里边可以对匹配规则进行设置,通过直等或者正则表达式的方式对规则进行匹配

image-20220916140945808

响应规则就是响应之后的页面,后边在Matcher匹配成功之后可以选择响应的页面

image-20220916141141882

自定义动作

可以执行Action里边的系列操作,执行顺序按照协议锁定 -> 重定向 -> URI 重写 -> 浏览器认证 -> 访问频率限制 -> 过滤器 进行检查和执行,可以进行规则和执行动作的添加、调整和删除

image-20220916141243876

后端

在后端中可以直接通过Nginx 设置反向代理,也可以设置静态文件的过期时间,保障文件的安全性

image-20220916141404688

概况

对统计信息进行设置,设置保留时间、是否开启等

image-20220916141506954

系统

对ip 、登录用户和系统配置进行设置

image-20220916141543422

六、VeryNginx实战

在使用过程中,如果因为配置问题出现后台登陆不进去或者配置错误的情况,只需要删除/opt/verynginx/verynginx/configs/config.json,然后再重启就可以了

1.禁止访问robots.txt

/opt/verynginx/openresty/nginx/html目录中新建一个文件,robots.txt,内容可以随便写点什么。

在网站中加入robots.txt 文件 可以看到正常访问

image-20240718100108876

在规则名称中填写名称,点击下面的添加新规则

image-20220916142911990

弹出的规则框中选 = 下边的value填写 /robots.txt ,点击添加后添加就可以添加这条规则到规则库中

image-20220916142946384

然后点击右下角的保存设置进行保存,一般每做一步操作都会提示保存一次

image-20220916143115198

然后在拦截规则中使用新建的robots 规则 执行工作为block 上边开启勾选上就可以了

image-20240718100444171

可以在上边选择返回http状态码为503,再次访问就会被拦截

image-20240718100531210

2.对xss攻击进行防护

模拟进行xss 攻击

参考最后的附二,先安装php解析引擎

然后在目录/opt/verynginx/openresty/nginx/html中创建一个1.php文件,内容如下


<?php

$id = $_GET['id'];
echo $id;
?>

访问地址,可以看到弹出了一个提示框,说明有xss注入攻击

http://192.168.248.128/1.php?id=<script>alert(111)</script>

新增一个xss的规则,xss的添加在参数里边,key为id,value里边正则匹配到script即可

拦截规则里边直接设置400就可以了

image-20240718102224577

image-20240718102320358

image-20240718102508099

image-20240718102551068

访问一下

http://192.168.248.128/1.php?id=<script>alert(111)</script>

已经被拦截

image-20240718102648309

3.访问频率限制

在访问的频率限制中进行设置,所有的请求在1秒内超过3次访问就会封禁访问者的ip

image-20240718104809985

image-20240718104904162

此时如果非常快速点击访问主页,就会被拦截住。

image-20240718105034240

4.反向代理

在另外一台主机/opt/lampp/htdocs/proxy目录中创建一个hello.php

<?php

echo "hello php";
?>

测试一下确保能访问到

image-20240718111019131

先添加一个路径匹配规则,只要路径中有proxy的就代理转发给后面的服务器

image-20240718110236671

image-20240718110337449

接着转到Backend–》proxy pass,注意这个实验中,我们的verynginx在主机192.168.248.128中,在verynginx中配置一个反向代理,把请求转到上面的hello.php中

image-20240718105840707

image-20240718105928901

image-20240718110734102

点Add后,注意点击右下角的Save按钮

image-20240718110756739

最后我们来访问一下,注意这里我们访问的ip地址是verynginx的主机ip,不是hello.php所在的主机ip

http://192.168.248.128/proxy/hello.php

image-20240718111215082

附一:页面出现乱码问题解决

/opt/verynginx/openresty/nginx/conf/nginx.conf 修改代码,加入charset即可

location = / {
            charset utf-8;
            root   html;
            index  index.html index.htm;
 }

附二:在Nginx中配置PHP:

(1)安装php-fpm解析引擎,用于解析PHP脚本

yum install php-fpm
systemctl start php-fpm

启动9000端口

(2)在Nginx中配置针对php页面的处理

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

意思是指当访问后续名为.php的文件时,将其转交给php-fpm引擎进行处理

(3)正常编写PHP代码,实现访问