Here, I'm trying to accomplish calling a Lua script from modsecurity rules.

There are 2 components:-

1.example.com (WAF)

2.test.com (Web Application)

test.com contains pages:-


If user accesses http://example.com/protectedpage.php the rule loads the lua script and writes data to lua_output.txt .

I have been stuck here for past 2 days trying several variations.

Contents of /etc/apache2/sites-enabled/example.com.conf

<VirtualHost *:80>
    ServerAdmin [email protected]
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    ProxyPreserveHost On
    ProxyRequests Off

    LoadModule security3_module /home/testuser/spiderlabs/ModSecurity-apache/src/.libs/mod_security3.so
    <IfModule security3_module>
            modsecurity_rules 'SecRuleEngine On'
            modsecurity_rules 'SecRequestBodyAccess On'
            modsecurity_rules 'SecResponseBodyAccess On'
            modsecurity_rules_file "/etc/apache2/modsecurity.d/include.conf"
            modsecurity_rules 'SecAuditLogFormat JSON'

    #Access to /getprotected 
    modsecurity_rules 'SecRule REQUEST_FILENAME "^/getprotected.php$" "phase:2, t:none, t:normalisePath, t:lowercase, t:urlDecodeUni, chain, deny, log, id:1301"'
    modsecurity_rules 'SecRuleScript /etc/apache2/lua/checkaccess.lua \

    ProxyPass /getprotected.php !
    ProxyPass /getpassword.php !
    ProxyPass / http://test.com:8080/
    ProxyPassReverse / http://test.com:8080/

Contents of /etc/apache2/lua/checkaccess.lua


    function main()
        local f = assert(io.open('/etc/apache2/lua/lua_output.txt','a'))
        f:write("--- Hello world ---\n")

The Rule is executed. But the script is not. I'm not sure whether its chaining or not. please Let me know how to fix this. Thanks,

References so far:- 1. ModSecurity Documentation

  1. Lua scripting blog 1

  2. blog 2

  • So the SecRule doesn't look right to me. In chain rules, the phase and ID needs to only be specified in the first rule. Also, since the rule is only checking the requested URI, it should be shifted to phase 1.
    – void_in
    Commented Aug 10, 2018 at 8:08
  • Yes i knew it.. But without Id in chained rule i use to get compilation errors which vanished once i used id...
    – Gowtham
    Commented Aug 10, 2018 at 8:30
  • If that is the case, please paste the error message you are getting. Also, I don't understand what is modsecurity_rules directive is. The ModSecurity SecRule directives should work if the module is loaded without needing any modsecurity_rules line.
    – void_in
    Commented Aug 10, 2018 at 10:22
  • Actually I'm using modsecurity version 3.0... so that's the new syntax ...
    – Gowtham
    Commented Aug 10, 2018 at 10:24

1 Answer 1


This is a lua script, why are you doing first a secrule then chain, you better call the script and get the var REQUEST_FILENAME and check it matches your pattern or add a Location/LocationMatch for the path and add the SecRuleScript inside.

The first rule is incomplete as it is a chain start that has no end as the next one is not a rule is a script call.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .