API Context and IP Blocker code

65 views
Skip to first unread message

Kamalkishor

unread,
Mar 19, 2018, 12:09:23 PM3/19/18
to openresty-en
Hello,
         I wish to do the following :
        1. Any visitor attempts an invalid login attempt and the upstream responds with a 403, LUA should block this IP for 24 hours (or configurable number of hours) at the particular location after 10 (or configurable number of) attempts
         - Managed to achieve this using :
                 access_by_lua_file {
                                                  ---- redis recording, incrementing a counter over host:IP as key, ngx.exit(403) after 10 invalid attempts
                                                 }

        2. Read a particular string value from the response body html ( ngx.arg[1] ) and send a 403 back to the client if the custom string found in ngx.arg[1]        (Suppose the html has a string "Invalid username/password")
        - Problem here is the API context for ngx. redirect/exit 

Could anyone please suggest a way to achieve this?

Thanks!

Kamalkishor

unread,
Mar 25, 2018, 10:43:46 AM3/25/18
to openresty-en
I'd truly appreciate if anyone can reply.

Thanks!

Hamish Forbes

unread,
Mar 26, 2018, 4:49:19 AM3/26/18
to openresty-en
For 1 I would probably use the header_filter phase to check for 403 status response and increment a shared dict key https://github.com/openresty/lua-nginx-module#ngxshareddict
You then simply lookup that key in the access phase and return a 403 if its >10.

You'd also need to put in a timestamp somewhere so you know when to reset the counter

2 is more tricky as you're going to have to buffer or proxy the response somehow. You can't modify the status code from the body filter phase as it's already been sent to the client.
If you know the responses are going to be small you could use ngx.location.capture and get the entire response as a Lua string.

Kamalkishor

unread,
Mar 26, 2018, 6:28:51 AM3/26/18
to openresty-en
Thank you Hamish, for your reply.
I have used a Redis cache for 1 instead of a shared dictionary. I have a few nginx servers distributed over a few nodes geographically. Hope that Redis thing is a good architecture in this context.

For 2, I will try buffering the response. That is something I haven't tried.

Kamalkishor

unread,
Mar 29, 2018, 12:54:36 PM3/29/18
to openresty-en
I tried buffering the response in a shared cache, but the decision has to be made over a dynamic response over the same request.
Can't seem to be able to do that with the existing framework.

Any suggestions are welcome!

Thanks,

Reply all
Reply to author
Forward
0 new messages