Forum Discussion
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_111Historic 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
Nimbostratus
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_111Historic 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
Nimbostratus
Thanks. I'll try it out to see if it works. - Icemanii_116694
Nimbostratus
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.
- Thomas_Gobet_91
Cirrostratus
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
Nimbostratus
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.
- Thomas_Gobet
Nimbostratus
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
Nimbostratus
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.
- Thomas_Gobet
Nimbostratus
Could you log real_ip after foreach statement with this line :
log local0. "IP matched is : $real_ip" - nitass
Employee
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
Nimbostratus
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
Nimbostratus
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..."
- nitass_89166
Noctilucent
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
Nimbostratus
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
Nimbostratus
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..."
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com