Operations 8 min read

How to Install Nginx+Lua and a Web Application Firewall (WAF) with OpenResty

This guide explains step‑by‑step how to set up a Web Application Firewall by installing LuaJIT, ngx_devel_kit, lua‑nginx‑module, compiling Nginx with Lua support, fixing common errors, and optionally using OpenResty, followed by configuring and testing the ngx_lua_waf module.

Raymond Ops
Raymond Ops
Raymond Ops
How to Install Nginx+Lua and a Web Application Firewall (WAF) with OpenResty

Web Application Firewall (WAF) protects web applications by applying security policies to HTTP/HTTPS traffic.

Method 1: Install Nginx with Lua module

Install LuaJIT

Clone the LuaJIT repository and build it.

<code>git clone https://github.com/openresty/luajit2.git
cd luajit2
make PREFIX=/usr/local/luajit
make install PREFIX=/usr/local/luajit</code>

Add the following environment variables to

/etc/profile

and source it:

<code>export LUAJIT_LIB=/usr/local/luajit/lib
export LUAJIT_INC=/usr/local/luajit/include/luajit-2.1</code>

Install ngx_devel_kit (NDK)

Download and extract version 0.3.1.

<code>cd /mnt
wget https://github.com/vision5/ngx_devel_kit/archive/v0.3.1.tar.gz
tar -xzvf v0.3.1.tar.gz</code>

Install latest lua-nginx-module

Download and extract version 0.10.15.

<code>cd /mnt
wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz
tar -xzvf v0.10.16rc5.tar.gz</code>

Compile Nginx with Lua module

<code>cd /mnt/nginx-1.18.0
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib64/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--with-http_gzip_static_module \
--with-http_realip_module \
--with-http_ssl_module \
--with-openssl=/mnt/openssl-1.1.1g \
--with-zlib=/mnt/zlib-1.2.11 \
--with-pcre=/mnt/pcre-8.44 \
--add-module=/mnt/lua-nginx-module-0.10.15 \
--add-module=/mnt/ngx_devel_kit-0.3.1</code>

Note: OpenSSL, PCRE and zlib must be downloaded and extracted to

/mnt

.

If Nginx fails with “cannot open shared object file libluajit-5.1.so.2”, add the library path:

<code>echo "/usr/local/luajit/lib/" >> /etc/ld.so.conf
ldconfig</code>

Test with a simple Lua content handler:

<code>content_by_lua 'ngx.say("hello, lua")';</code>
Installation successful
Installation successful

Method 2: Install OpenResty directly

OpenResty is a high‑performance web platform based on Nginx and Lua, bundling many Lua libraries and third‑party modules.
<code>cd /opt
tar -xzvf openresty-1.15.8.3.tar.gz
./configure \
--prefix=/opt/openresty \
--with-pcre=/opt/pcre-8.44 \
--with-zlib=/opt/zlib-1.2.11 \
--with-openssl=/opt/openssl-1.1.1g \
--with-poll_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_addition_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-http_ssl_module</code>
<code>gmake
gmake install</code>

After installation, the same test as method 1 can be used.

WAF Module Installation

Clone the ngx_lua_waf repository and add it to OpenResty.

<code>cd /opt/openresty/lualib
git clone https://github.com/loveshell/ngx_lua_waf.git waf</code>

Add the following directives to the OpenResty configuration:

<code>lua_package_path "/opt/openresty/lualib/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file /opt/openresty/lualib/waf/init.lua;
access_by_lua_file /opt/openresty/lualib/waf/waf.lua;</code>

The WAF directory structure:

<code>[root@k8s-node lualib]# tree waf
waf
├── config.lua
├── init.lua
├── wafconf
│   ├── args
│   ├── cookie
│   ├── post
│   ├── url
│   ├── user-agent
│   └── whiteurl
└── waf.lua

1 directory, 9 files</code>

Key configuration options in

config.lua

include rule path, attack logging, URL denial, cookie and POST protection, IP whitelist/blacklist, and CC attack rate.

Test the installation by sending a malicious request:

<code>curl http://www.example.com/test.php?id=../etc/passwd</code>

Sample log entry:

<code>192.168.0.101 [2020-06-20 01:44:01] "GET localhost/index.php?id=/../../../etc/passwd" "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36" "../"</code>
backendsecurityNginxInstallationLuaOpenRestywaf
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.