浅谈OpenResty在Web应用防火墙中的应用

开发 前端
随着互联网的兴起,Web应用也越来越多。企业Web应用功能丰富性的增加必然带来对应用统一管理的需求,如路由、权限管控、安全、日志监控分析等,这些管理需求由业务网关(API网关)来实现。作为企业Web应用的入口,这就要求网关具备高性能、高可靠性、开发和维护成本低等特性。

1、OpenResty起源

OpenResty是一个基于Nginx与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。Nginx由俄罗斯工程师Igor Sysoev于2002年基于C语言开始开发,并于2004年开源,目的是解决Apache HTTP服务器不能满足C10K(单个HTTP服务器处理10000并发连接)的问题。随着Web的快速发展普及,Nginx因为其开源、跨平台、可支持百万级别的TCP并发连接、高稳定性等优点迅速传播开来,当前全球有近三分之一的HTTP服务器使用的是Nginx。

Nginx生态的丰富性归功于由于它高内聚、低耦合的模块化设计。Nginx提供的主要模块包括Core模块、Event模块、Http模块、Mail模块、Stream模块等。开发者根据Nginx模块开发规范很容易能扩展Nginx的功能。

Nginx存在局限性:对于一般的业务系统使用Nginx,业务变动仅需要改动Nginx相关配置文件重启即可,但如果需要开发或者更新第三方模块则需要重新编译安装Nginx,这个对于线上系统是不太友好的,重新编译安装Nginx是个操作程度较麻烦和变更风险性较高的过程。由此Nginx对脚本语言的支持是有必要的,Perl、Python、Js、Lua都有C的API,这几年从开发者的应用来看,Lua这种天然就是C的脚本语言使用最广泛。Lua脚本可以很容易的被C/C++ 代码调用,也可以反过来调用C/C++的函数,一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。

OpenResty应运而生:基于Nginx,OpenResty通过LuaJIT扩展支持,让开发者可以使用Lua脚本语言调动Nginx支持的各种C以及Lua模块,大大提高了Nginx模块开发的生产力。

2、OpenResty工作原理

OpenResty本质是基于Nginx的单Master多Worker进程模型,将LuaVM嵌入到进程中,通过LuaVM来执行Lua代码获得高性能,同时LuaVM的自动内存管理也提高了开发者的开发效率。OpenResty的两大技术特点:(1)多阶段处理;(2)Lua协程与Nginx event的高效NIO结合。下面分别介绍。

2.1 OpenResty的多阶段处理

OpenResty的多阶段处理基于Nginx的HTTP多阶段处理。如前介绍,Nginx对Http的处理也是一个个HTTP模块协作完成的,对于HTTP模块,数据的流转,衔接等管理,Nginx将它划分成11个处理阶段,每个处理阶段由多个HTTP模块进行流水线处理:

typedef enum {
NGX_HTTP_POST_READ_PHASE = 0, //读取请求体阶段
NGX_HTTP_SERVER_REWRITE_PHASE, //server URI重写阶段
NGX_HTTP_FIND_CONFIG_PHASE, //location查找阶段
NGX_HTTP_REWRITE_PHASE, //location URI重写阶段
NGX_HTTP_POST_REWRITE_PHASE, //检查是否发生了URI重写
NGX_HTTP_PREACCESS_PHASE, //访问限制阶段
NGX_HTTP_ACCESS_PHASE, //访问权限控制阶段
NGX_HTTP_POST_ACCESS_PHASE, //检查请求权限处理阶段
NGX_HTTP_TRY_FILES_PHASE, //try_file配置处理静态文件阶段
NGX_HTTP_CONTENT_PHASE, //返回内容生成阶段
NGX_HTTP_LOG_PHASE //日志记录阶段
} ngx_http_phases;

OpenResty将这11个阶段简化成Rewrite/Access Phase、Content Phase、 LogPhase,加上进程启动初始化的Initialization Phase共四个大阶段11个*_by_lua可重写指令。

图片

每个阶段分工清晰,各个阶段处理http请求不同阶段的数据,分层更易于理解和开发。

图片

2.2 Lua协程与Nginx Event的NIO结合

对于Http请求的处理,性能消耗主要在网络IO处理,Nginx相对于Apache Server多线程模型处理效率高的原因就是在于Nginx的Event处理机制。具体到Linux,Event处理机制基于Epoll实现,所有读写事件不会阻塞主线程,而是注册到epoll,主线程通过调用epoll_wait来获取可读写事件,对准备好的事件进行相应的回调处理,实现非阻塞IO。回到OpenResty,每个Worker进程有一个LuaVM,OpenResty通过LuaVM来执行Lua代码,每个外部请求都通过一个Lua协程来处理,每个协程互不影响,每当Lua代码需要处理IO时,都会yield当前协程,将IO事件交给Nginx的Event处理,这样就不会阻塞Worker主线程,待Nginx的Event处理完毕,Resume协程继续处理。协程仅在用户态处理相对于多线程切换的开销少。通过协程结合和Nginx的非阻塞I/O模型,不仅仅对HTTP客户端请求,甚至于对远程后端诸如MySQL、PostgreSQL、Memcached以及Redis等都进行一致的高性能响应。

图片

3、OpenResty在网站安全建设中的应用

中国移动贯众安全云WAF是一款网站应用防火墙产品,通过对Http/Https流量的分析检测,拦截恶意流量,为Web业务安全运营提供保障。截至目前,中国移动贯众安全云WAF已为超2000家站点提供网站安全防护服务。团队在研发之初做技术选型时就采用了OpenResty,主要考虑它的一下优点

  • 降低开发门槛,Lua库极其丰富,研发效率高,能适应功能快速迭代的需求;
  • 很容易支持热更新,研发、测试、发布效率高,对业务无感知;
  • 云原生支持,裸机,容器等都可以部署维护;
  • 高性能,基于Nginx的高性能Http应用,对MySQL、Redis等也支持非阻塞IO。

贯众安全云WAF部署架构图大致如下:

图片

由于WAF节点是串接在系统内的,这对WAF节点的性能和稳定性有较高要求,如图所示,我们通过DPVS+KeepAlived做四层负载均衡保障包的高速转发和可靠性,后面直接通过OpenResty集群进行流量的分析。经过WAF的流量都经过了十几个步骤的检测,各个步骤相互独立,互不影响,非阻塞的IO保障了检测的性能。主要使用到的阶段如下:

图片


如上表所示,每个阶段互相配合,分工明确,配置和云WAF配置中心实时同步,能热更新业务配置、防护配置、规则库等,运维成本低。防护阶段对性能要求高的检测手段会用C写成动态库,Lua的ffi能很方便调用,和需要存储、统计运算的均采用cosocket和数据库交互,非阻塞的特性保障和数据库交互的高性能。

4、总结

OpenResty是一个基于Nginx和Lua的优秀开源组件,保留了Nginx的高性能的同时,引入Lua,降低了开发门槛,研发效率高,运维成本低。对于有大量Web平台需要治理的企业比较试用。可以基于OpenResty二次开发动态路由、限流、缓存、权限控制、安全防护等能力,替代Nginx管理企业内部站点。

参考文献

[1]OpenResty.http://openresty.org/cn/.

[2]陶辉. 深入理解nginx:模块开发与架构解析[M]. 机械工业出版社. 2013-4.

[3]Lua Nginx Module. https://github.com/openresty/lua-nginx-module.

责任编辑:庞桂玉 来源: 移动Labs
相关推荐

2011-03-25 11:18:51

2010-10-25 12:07:51

2011-03-25 11:06:46

2011-05-10 09:17:01

2011-02-15 18:38:49

2011-02-17 18:30:25

2010-08-30 10:18:24

2010-07-07 20:06:53

2010-07-12 11:33:52

2021-06-25 18:35:30

Web应用防火墙

2010-12-21 18:04:26

2011-03-15 10:32:05

2010-05-24 17:49:56

2010-07-12 11:41:55

2010-09-14 09:04:10

2009-04-29 14:51:18

2009-04-28 09:12:35

Web应用防火墙梭子鱼

2010-08-30 11:28:13

2012-02-24 15:34:39

2011-12-05 11:20:42

点赞
收藏

51CTO技术栈公众号