Service Introduction#
More and more people are using VPS hosting to build websites, but compared to virtual hosting or managed servers, personal VPS hosting is basically unmanaged, meaning the host provider is only responsible for the network connectivity of the VPS, and any technical issues must be resolved by the user. Websites often face automated tools that scan, inject, overflow, and compromise security.
Commercial virtual hosting has dedicated operations engineers to ensure security, whereas, as mentioned, VPS and other virtual cloud machines do not have specialized personnel for operations and maintenance, which requires us to handle it ourselves. Today, I will introduce a very good Nginx (openresty) WEB application firewall module, ngx_lua_waf. ngx_lua_waf is a web application firewall based on ngx_lua, with very simple code. The developer's intention is to make it easy to use while maintaining its lightweight characteristics alongside high performance.
Main Functions of Ngx_lua_waf#
Prevent SQL injection, local file inclusion, some buffer overflow, fuzzing tests, XSS, SSRF, and other web attacks
Prevent leakage of files like svn/backups
Prevent attacks from stress testing tools like ApacheBench
Block common scanning hacker tools and scanners
Block abnormal network requests
Block PHP execution permissions in image attachment directories
Prevent web shell uploads
Here we can see that the functions of Ngx_lua_waf are quite rich and can effectively deny most scanning attacks, playing a significant role in preventing websites from being compromised.
Installation Requirements#
The author of Ngx_lua_waf recommends using lujit2.1 for Lua support. If ngx_lua is version 0.9.2 or above, it is recommended to change the regex filtering function to ngx.re.find, which will increase matching efficiency by about three times. Our Nginx only needs to compile Lua support to deploy this WEB application firewall, adding a security layer to our server.
Usage Instructions#
Assuming the nginx installation path is: /usr/local/nginx/conf/
We just need to download ngx_lua_waf to the conf directory, unzip it, and rename it to waf. Then, add the following in the http section of nginx.conf, or write it as a separate conf file and include it in nginx.conf.
lua_package_path "/usr/local/nginx/conf/waf/?.lua";
lua_shared_dict limit 10m;
init_by_lua_file /usr/local/nginx/conf/waf/init.lua;
access_by_lua_file /usr/local/nginx/conf/waf/waf.lua;
Configure the waf rule directory in config.lua (usually in the waf/conf/ directory)
RulePath = "/usr/local/nginx/conf/waf/wafconf/"
Then, according to the debugging guidelines, run nginx -t to check if the configuration is correct. If it indicates successful loading, we can restart nginx.
Detailed Explanation of Configuration File:#
- RulePath = "/usr/local/nginx/conf/waf/wafconf/"
- -- Directory for storing rules
- attacklog = "off"
- -- Whether to enable attack information logging, requires logdir configuration
- logdir = "/usr/local/nginx/logs/hack/"
- -- Log storage directory, this directory needs to be created by the user and must have write permissions for the nginx user
- UrlDeny="on"
- -- Whether to intercept URL access
- Redirect="on"
- -- Whether to intercept and redirect
- CookieMatch = "on"
- -- Whether to intercept cookie attacks
- postMatch = "on"
- -- Whether to intercept POST attacks
- whiteModule = "on"
- -- Whether to enable URL whitelist
- black_fileExt={"php","jsp"}
- -- Specify disallowed file upload extensions
- ipWhitelist={"127.0.0.1"}
- -- IP whitelist, separate multiple IPs with commas
- ipBlocklist={"1.0.0.1"}
- -- IP blacklist, separate multiple IPs with commas
- CCDeny="on"
- -- Whether to enable interception of CC attacks (requires adding lua_shared_dict limit 10m; in the http section of nginx.conf)
- CCrate = "100/60"
- -- Set the frequency of CC attacks, in seconds.
- -- By default, the same IP can only request the same address 100 times in one minute
- html=[[Please go away~~]]
- -- Warning content, customizable within the brackets
- Note: Do not alter the double quotes, as they are case-sensitive