Search code examples
pythonnginxflaskvirtual-machinegunicorn

limit client ip address connections, nginx


i'm in the middle of learning the basics of deployment of a simple weather web app using VM, flask, Nginx and gunicorn. i've been told to limit the amount of connections from the same ip address to 5. meaning - i would like that each ip client could open only 5 connections to my site. according to this link: Manual for limiting number of connections

i'm supposed to add this line in the http part:

limit_conn_zone $binary_remote_addr zone=limitconnbyaddr:20m;

then add this line to my location block:

limit_conn   limitconnbyaddr  5;

and afterwards, of course, test nginx, restart the service and check myself. my question is: how can i check myself? i can't figure out a way to test if my actions were good or not. (BTW, if i'm wrong - i'd like to have a good explanation to the correct way to solve it, if anyone can) the website is made using python (as flask mentioned above)


Solution

  • A quick tool to test rate limit scenarios is siege. Assuming you're using Debian-base distributions, install it using:

    sudo apt-get install siege
    

    Usage:

    # -v - verbose logging
    # -r 2 - run two tests
    # -c 5 - open 5 concurrent connections
    siege -v -r 2 -c 5 http://localhost:8080/static/img/logo.png
    

    Sample output (the failed requests will appear in red):

    ** SIEGE 4.0.7
    ** Preparing 5 concurrent users for battle.
    The server is now under siege...
    HTTP/1.1 200     0.84 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.96 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     1.02 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     1.02 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     1.02 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.92 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.93 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.90 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.96 secs:   84987 bytes ==> GET  /static/img/logo.png
    HTTP/1.1 200     0.97 secs:   84987 bytes ==> GET  /static/img/logo.png
    
    Transactions:                 10 hits
    Availability:             100.00 %
    Elapsed time:               1.99 secs
    Data transferred:           0.81 MB
    Response time:              0.95 secs
    Transaction rate:           5.03 trans/sec
    Throughput:             0.41 MB/sec
    Concurrency:                4.79
    Successful transactions:          10
    Failed transactions:               0
    Longest transaction:            1.02
    Shortest transaction:           0.84
    
    

    Sidenote: if the verbose format (-v) still shows you a JSON output, edit the siege configuration file (located at ~/.siege/siege.conf) and set the json_output directive to false; this should solve the issue.