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.

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

Add the following environment variables to /etc/profile and source it:

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

Install ngx_devel_kit (NDK)

Download and extract version 0.3.1.

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

Install latest lua-nginx-module

Download and extract version 0.10.15.

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

Compile Nginx with Lua module

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

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:

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

Test with a simple Lua content handler:

content_by_lua 'ngx.say("hello, lua")';
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.
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
gmake
gmake install

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.

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

Add the following directives to the OpenResty configuration:

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;

The WAF directory structure:

[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

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:

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

Sample log entry:

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" "../"
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendNginxLuaOpenRestyWAF
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

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.