Forum Discussion

ukitsysadmin_95's avatar
ukitsysadmin_95
Icon for Nimbostratus rankNimbostratus
Aug 18, 2009

Redirect accourding to source IP ranges

Referring to the previous post: http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=34863

 

 

I'm looking to create an iRule whereby visitors to a specific website are redirected if they do not come from particular ranges of source IP addresses. The range of IP addresses will be large (IP by country); is there a way to refer the source to a file? Anybody created such a rule previously? Advice much appreciated.

7 Replies

  • If you want to make decisions based on location, the following may help:

     

     

    http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&postid=21847&view=topic
  • ukstin's avatar
    ukstin
    Icon for Nimbostratus rankNimbostratus
    I think the best way to do it is with a dataclass, an example of rule could be this:

    class class_ips_country1 { 
        network 150.1.1.1 mask 255.255.255.248 
     } 
      
     when HTTP_REQUEST { 
        if { ([matchclass [IP::client_addr] equals $::class_ips_country1]) } { 
           pool pool_country1 
        } elseif { (matchclass [IP::client_addr] equals $::class_ips_country2]) } { 
           pool pool_country2 
        } 
     }
  • A colleague of mine subscribes to a service where he downloads the list of IP addresses per country. In his iRule he created a datagroup listing all the ranges in each country and then he wrote up an Irule using Matchclasses Click here and IP::client_addr Click here. It can be quite time consuming because of the data entry. A file can be used as the source within an iRule. Click here to take a look at an example where a source file is used to read the entries into the iRule.

     

     

    Hope this helps

     

    CB

     

  • You can use the format of the preconfigured AOL datagroup as a reference:

     
      b class aol list 
     class aol { 
        network 64.12.96.0/19 
        network 149.174.160.0/20 
        network 152.163.96.0/22 
        network 152.163.100.0/23 
        network 152.163.240.0/21 
        network 152.163.248.0/22 
        network 152.163.252.0/23 
        network 195.93.16.0/20 
        network 195.93.32.0/22 
        network 195.93.48.0/22 
        network 195.93.64.0/19 
        network 195.93.96.0/19 
        network 198.81.0.0/22 
        network 198.81.8.0/23 
        network 198.81.16.0/20 
        network 202.67.64.128/25 
        network 205.188.112.0/20 
        network 205.188.146.144/30 
        network 205.188.192.0/20 
        network 205.188.208.0/23 
        network 207.200.112.0/21 
     } 
     

    For an external file, I think the format would be the same (minus the name definition line and the closing curly brace, plus commas):

    cat /var/class/external.networks.class

    host 1.1.1.1,

    host 1.2.2.3,

    network 64.12.96.0/19,

    network 149.174.160.0/20,

    network 152.163.96.0/22,

    network 152.163.100.0/23,

    network 152.163.240.0/21,

    The datagroup definition would be External; Type: Address.

    Aaron
  • Hi

     

    Spoke to soon about it working a treat. We cannot get the rule to work any more and need some clarification please.

     

    our irule is thus:

     

     

    when HTTP_REQUEST {

     

    if {[matchclass [IP::client_addr] equals $::UK_Allowed_IP]}{

     

    } else { HTTP::redirect http://redirect.test.com

     

    }

     

    }

     

     

     

    The problems is that the irule is redirecting ALL traffic and seems to be ignoring the data group list.

     

    We've tried the data group external file as a string - example:

     

     

    "138.198.0.0/16",

     

    "141.97.0.0/16",

     

    "145.229.0.0/16",

     

    "145.233.0.0/16",

     

     

     

    and as an address - example

     

     

    network 62.23.0.0/16,

     

    network 62.24.32.0/19,

     

    network 62.24.128.0/17,

     

    network 62.30.0.0/16,

     

    network 62.31.0.0/16,

     

     

     

    Neither of these are being picked up. Could it be that the irule is looking for IP addresses rather than networks, so the list isn't matching the query?

     

    Again, any help would be hugely appreciated,

     

    Many thanks!
  • Hi,

     

     

    Can you use the second format, trim out all but a handful of entries, reload your configuration using 'b load', and then test the iRule further? I believe that if you modify the external class file, the change isn't read into memory until the config is reloaded.

     

     

    Try adding a log statement of the client IP address, the datagroup contents and the value of the matchclass command. This should give you a good indication of all the relevant data.

     

     

    log local0. "[IP::client_addr]:[TCP::client_port]: class contents: $::UK_Allowed_IP, matchclass result: [matchclass [IP::client_addr] equals $::UK_Allowed_IP]"

     

     

    Also, once you have the class check working, you could move it to CLLIENT_ACCEPTED and set a variable if the client needs to be redirected. That way you do the check once per TCP connection instead of for every HTTP request. You could also forcibly close the TCP connection with TCP::close after the HTTP redirect to ensure the client doesn't retry the request on the same TCP connection if they'll never be allowed to reach the pool.

     

     

    Aaron
  • I would like to add you could change the logic to something like this to eliminate else statement.

     
     when HTTP_REQUEST { 
       if { ![matchclass [IP::client_addr] equals $::UK_Allowed_IP]}{ 
            HTTP::redirect http://redirect.test.com 
          } 
      } 
     

    Hope this helps

    CB