Forum Discussion

Icemanii_116694's avatar
Icemanii_116694
Icon for Nimbostratus rankNimbostratus
Jan 02, 2014

Block Opera Mini users using true client IP

I'm trying to restrict users from certain countries using Opera Mini browser from accessing my server. I'm using the following irule to replace the IP::client_addr field with the XFF IP:

 

when HTTP_REQUEST { if { [string tolower [HTTP::header "User-Agent"]] contains "mini opera" } { if {[HTTP::header exists "X-Forwarded-For"]} { HTTP::header remove [IP::client_addr] HTTP::header insert [IP::client_addr] X-Forwarded-For } } }

 

The syntax and all is working but I get the XFF IP as the client_addr. Any help is highly appreciated.

 

16 Replies

  • mikeshimkus_111's avatar
    mikeshimkus_111
    Historic F5 Account

    Hi Icemanii, I think you could accomplish this by creating an LTM datagroup with the IPs you want to block (named "banned_addresses" in my example) and creating an iRule similar to this one to respond to blocked requests. You shouldn't need to use X-forwarded-for at all if this BIG-IP can see the true client IP address.

    when HTTP_REQUEST { 
    if { [string tolower [HTTP::header "User-Agent"]] contains "mini opera" } { 
        if { [class match [IP::client_addr] equals "banned_addresses"] } { 
            set response "Access Denied
            We are sorry, but access to the  is
            restricted to approved client IP addresses. Your IP address, 
            [IP::client_addr], is not approved."
            HTTP::respond 200 content $response
        } 
    } 
    

    }

    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      Hi, thanks for the response. The opera mini browser acts like a proxy replacing the true client IP with a US based IP. I have another rule which drops all request from US country using the geoip targeting restriction. As such, I need to check the client's true country of origin to allow or drop the request. if {([class match [whereis [IP::client_addr] country] equals BlockedCountry]) } { drop} So I need to check for mobile users using opera mini as a browser and determining their real client ip instead of the IP from the Opera Mini.
  • mikeshimkus_111's avatar
    mikeshimkus_111
    Historic F5 Account

    Ah, I see. I didn't know that about Opera Mini. I thought you were looking at the X-Forwarded-For header as inserted by BIG-IP.

    Couldn't you do something like this, then:

    when HTTP_REQUEST { 
    if { [string tolower [HTTP::header "User-Agent"]] contains "mini opera" } { 
        if {[HTTP::header exists "X-Forwarded-For"]} {
            set real_ip [HTTP::header value "X-Forwarded-For"]
            if { [class match [whereis $real_ip country] equals BlockedCountry]] } { 
                drop
                } 
            }
        }
    }
    
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      I've amended my iRule to iclude checking for whitelist IP and blacklist IP as well as the blocked country. I am able to hit the blockedcountry but unable to match the whitelist or blacklist lines. when CLIENT_ACCEPTED { Save the name of the VS default pool set default_pool [LB::server pool] } when HTTP_REQUEST { if { [string tolower [HTTP::header "User-Agent"]] contains "opera mini"} { if {[HTTP::header exists "X-Forwarded-For"]} { set real_ip [HTTP::header value "X-Forwarded-For"] if {([class match [$real_ip] equals WhitelistIP]) } { pool $default_pool} elseif {([class match [$real_ip] equals BlacklistIP]) } { HTTP::redirect "http://0.0.0.0"} elseif { [class match [whereis $real_ip country] equals BlockedCountry]} { HTTP::redirect "http://myforbiddenpage.com"} } else { pool $default_pool} } } The syntax seems ok but I'm not sure if the real_ip is pulling the correct IP from the X-Forwarded-For value.
  • Hi,

    I would do a "foreach" to check WFF value, because your request can travel through multiples proxies.

    when CLIENT_ACCEPTED {
     Save the name of the VS default pool
    set default_pool [LB::server pool]
    }
    
    when HTTP_REQUEST {
    if { [string tolower [HTTP::header "User-Agent"]] contains "opera mini"} {
        if {[HTTP::header exists "X-Forwarded-For"]} {
            foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] {
                if {([class match [$real_ip] equals WhitelistIP]) } {
                    pool $default_pool}
                elseif {([class match [$real_ip] equals BlacklistIP]) } {
                    HTTP::redirect "http://0.0.0.0"}
                elseif { [class match [whereis $real_ip country] equals BlockedCountry]} {
                        HTTP::redirect "http://myforbiddenpage.com"}
                    }
                else {
                        pool $default_pool}
                }
           }
    }
    
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      I've tried using the foreach, but I'm hitting Connection closed by remote server when using the opera mini browser trying to access my server.
  • Hi,

    I would do a "foreach" to check WFF value, because your request can travel through multiples proxies.

    when CLIENT_ACCEPTED {
     Save the name of the VS default pool
    set default_pool [LB::server pool]
    }
    
    when HTTP_REQUEST {
    if { [string tolower [HTTP::header "User-Agent"]] contains "opera mini"} {
        if {[HTTP::header exists "X-Forwarded-For"]} {
            foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] {
                if {([class match [$real_ip] equals WhitelistIP]) } {
                    pool $default_pool}
                elseif {([class match [$real_ip] equals BlacklistIP]) } {
                    HTTP::redirect "http://0.0.0.0"}
                elseif { [class match [whereis $real_ip country] equals BlockedCountry]} {
                        HTTP::redirect "http://myforbiddenpage.com"}
                    }
                else {
                        pool $default_pool}
                }
           }
    }
    
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      I've tried using the foreach, but I'm hitting Connection closed by remote server when using the opera mini browser trying to access my server.
  • Could you log real_ip after foreach statement with this line :

    log local0. "IP matched is : $real_ip"
    
  • I've tried using the foreach, but I'm hitting Connection closed by remote server when using the opera mini browser trying to access my server.

    can you post your latest irule?

    by the way, i think $real_ip does not need square brackets, does it?

    e.g.

    [class match $real_ip equals WhitelistIP]
    
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      when CLIENT_ACCEPTED { Save the name of the VS default pool set default_pool [LB::server pool] } when HTTP_REQUEST { if { [string tolower [HTTP::header "User-Agent"]] contains "opera mini"} { if {[HTTP::header exists "X-Forwarded-For"]} { foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] { log local0. "IP matched is : $real_ip" if {([class match [$real_ip] equals WhitelistIP]) } { pool $default_pool} elseif {([class match [$real_ip] equals BlacklistIP]) } { HTTP::redirect "http://0.0.0.0"} elseif { [class match [whereis $real_ip country] equals BlockedCountry]} { HTTP::redirect "http://myforbiddenpage.com" } else { pool $default_pool } } } } }
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      Now I'm getting this in my log. Jan 9 18:37:30 LTM02 err tmm[9115]: 01220001:3: TCL error: /Common/BlockedCountry_OperaMini_iRule - invalid command name "141.0.8.244" while executing "$real_ip" ("foreach" body line 3) invoked from within "foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] { log local0. "IP matched is : $real_ip" if {([class m..."
  • I've tried using the foreach, but I'm hitting Connection closed by remote server when using the opera mini browser trying to access my server.

    can you post your latest irule?

    by the way, i think $real_ip does not need square brackets, does it?

    e.g.

    [class match $real_ip equals WhitelistIP]
    
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      when CLIENT_ACCEPTED { Save the name of the VS default pool set default_pool [LB::server pool] } when HTTP_REQUEST { if { [string tolower [HTTP::header "User-Agent"]] contains "opera mini"} { if {[HTTP::header exists "X-Forwarded-For"]} { foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] { log local0. "IP matched is : $real_ip" if {([class match [$real_ip] equals WhitelistIP]) } { pool $default_pool} elseif {([class match [$real_ip] equals BlacklistIP]) } { HTTP::redirect "http://0.0.0.0"} elseif { [class match [whereis $real_ip country] equals BlockedCountry]} { HTTP::redirect "http://myforbiddenpage.com" } else { pool $default_pool } } } } }
    • Icemanii_116694's avatar
      Icemanii_116694
      Icon for Nimbostratus rankNimbostratus
      Now I'm getting this in my log. Jan 9 18:37:30 LTM02 err tmm[9115]: 01220001:3: TCL error: /Common/BlockedCountry_OperaMini_iRule - invalid command name "141.0.8.244" while executing "$real_ip" ("foreach" body line 3) invoked from within "foreach real_ip [split [string map [list " " ""] [HTTP::header "X-Forwarded-For"]] ","] { log local0. "IP matched is : $real_ip" if {([class m..."