Forum Discussion

Chittaranjan_11's avatar
Chittaranjan_11
Icon for Nimbostratus rankNimbostratus
Jan 09, 2017

Limit number of requests based on pid

We have a requirement to restrict requests based on pid and device_id. We want to drop requests when we get more than 100 Request per second from a specific Pid or Devide_id. Is it possible to achieve this using irule on F5 Virtual edition product? If YES, please suggest how to write the the irule in order to achieve this.

 

Following is one sample request.

 

10.11.12.13 - - [04/Jan/2017:12:48:37 +0000] "GET /ad/med/ss?app_name=DU+Battery+Saver+-+Power+Saver&bundle_id=com.dianxinos.dxbs&ip=47.218.35.147&pid=aaaaaaaabbbc&ad_type=VPIMP4&ua=Mozilla%2F5.0+%28Linux%3B+Android+5.0.1%3B+LGLS990+Build%2FLRX21Y%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F54.0.2840.85+Mobile+Safari%2F537.36&adv_type=VIDEO&device_id=[IFA]&cb=3162388832 HTTP/1.1" 200 21 "-" "Mozilla/5.0 (Linux; Android 5.0.1; LGLS990 Build/LRX21Y; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/54.0.2840.85 Mobile Safari/537.36" 0.004 0.004

 

1 Reply

  • Hi Chittaranjan,

    you may try one of the iRules below as a staring point.

    The first iRule uses two independent counters to seperately track requests for a given PID or Device ID. And the second iRule uses a single counter to track requests for the combined PID and Device ID information.

    iRule 1:

    when HTTP_REQUEST {
    
         Track and enfoce request for specific PIDs
    
        if { [set pid [URI::query [HTTP::uri] "pid"]] ne "" } then {
            set count [table incr "PID_$pid"]
            if { $count == 1 } then {
                table set "PID_$pid" 1 indef 60
                 Initialize table data and allow the request
            } elseif { $count < 100 } then {    
                 Allow the request
            } elseif { $count == 100 } then {
                 Log and block the request
                log local0.debug "Blocked [IP::client_addr] with PID \"$pid\". Too much requests..."
                HTTP::respond 503 content "Service temporary unavailable - too much request"
                return
            } else {
                 Block the request
                HTTP::respond 503 content "Service temporary unavailable - too much request" 
                return
            }
        }
    
         Track and enfoce request for specific Device IDs
    
        if { [set did [URI::query [HTTP::uri] "device_id"]] ne "" } then {
    
        set count [table incr "PID_$did"]
        if { $count == 1 } then {
             Initialize table data and allow the request
            table set "DID_$did" 1 indef 60
        } elseif { $count < 100 } then {    
             Allow the request
        } elseif { $count == 100 } then {
             Log and block the request
            log local0.debug "Blocked [IP::client_addr] with Device ID \"$pid\". Too much requests..."
            HTTP::respond 503 content "Service temporary unavailable - too much request"
            return
        } else {
             Block the request
            HTTP::respond 503 content "Service temporary unavailable - too much request" 
            return
        }
    }
    

    iRule 2:

    when HTTP_REQUEST {
    
         Track and enfoce request for specific PID / Device ID combinations
    
        if { ( [set pid [URI::query [HTTP::uri] "pid"]] ne "" )
         and ( [set did [URI::query [HTTP::uri] "device_id"]] ne "" ) } then {
            set count [table incr "ID_$pid$did"]
            if { $count == 1 } then {
                table set "ID_$pid$did" 1 indef 60
                 Initialize table data and allow the request
            } elseif { $count < 100 } then {    
                 Allow the request
            } elseif { $count == 100 } then {
                 Log and block the request
                log local0.debug "Blocked [IP::client_addr] with PID \"$pid\" and Device ID \"$did\". Too much requests..."
                HTTP::respond 503 content "Service temporary unavailable - too much request"
                return
            } else {
                 Block the request
                HTTP::respond 503 content "Service temporary unavailable - too much request" 
                return
            }
        }
    }
    

    Cheers, Kai