• BIGIP F5 iRule — Server Selection based on Client Source Address and Port

    A interesting request came up today regarding a Web Service we provide to multiple clients, all of whom have peering points connecting their IP network to ours using private address. The request was to have certain clients hit a particular Web box in a Server Pool, while others hitting the other. At the same time only for certain ports. Some of our web applications use a variety of ports because of the proprietary application running. Ports include, all TCP, 80, 443, 5555, 6050.  So I set off to create an iRule to handle this and have it log to show how everything is being mapped, start to finish for each connection.

    A Service little info:

    • Client PAT = 10.99.29.10
    • PrimaryWebCluster = 10.43.1.6
    • Web01 = 10.43.4.231
    • Web02 = 10.43.4.232
    • Ports = 80, 443, 5555, 6050

    iRule: irule_SrvSelection_byClientSrcAndPort

    when CLIENT_ACCEPTED {    
         if { [TCP::local_port] == 80 } {  
            if { [IP::addr [IP::client_addr] equals 10.99.29.10] } {        
            pool pool_ct_primarywebcluster_80 member 10.43.4.231 80
            log local0. "[IP::client_addr] is Web01"            
            } else {        
             pool pool_ct_primarywebcluster_80 member 10.43.4.232 80    
            log local0. "[IP::client_addr] is Web02"          
            }
        }
        if { [TCP::local_port] == 443 } {
            if { [IP::addr [IP::client_addr] equals 10.99.29.10] } {        
            pool pool_ct_primarywebcluster_443 member 10.43.4.231 443
            log local0. "[IP::client_addr] is Web01"            
            } else {        
             pool pool_ct_primarywebcluster_443 member 10.43.4.232 443
            log local0. "[IP::client_addr] is Web02"  
            }
        }
    if { [TCP::local_port] == 5555 } {
            if { [IP::addr [IP::client_addr] equals 10.99.29.10] } {        
            pool pool_ct_primarywebcluster_5022 member 10.43.4.231 5022
            log local0. "[IP::client_addr] is Web01"   
            } else {        
             pool pool_ct_primarywebcluster_5022 member 10.43.4.232 5022
            log local0. "[IP::client_addr] is Web02"  
            }
        }
    }
    
    if { [TCP::local_port] == 6050 } {
            if { [IP::addr [IP::client_addr] equals 10.99.29.10] } {        
            pool pool_ct_primarywebcluster_5022 member 10.43.4.231 5022
            log local0. "[IP::client_addr] is Web01"   
            } else {        
             pool pool_ct_primarywebcluster_5022 member 10.43.4.232 5022
            log local0. "[IP::client_addr] is Web02"  
            }
        }
    }
    when SERVER_CONNECTED {
      log local0. "Connection from [IP::client_addr]:[TCP::client_port]. \
        Mapped to F5 Floating IP [serverside {IP::local_addr}]:[serverside {TCP::local_port}] \
        -->> [IP::server_addr]:[serverside {TCP::remote_port}]"
    }

    And to check, SSH into the Primary F5 in the pair and type bash to give you shell access. (BIGIP v11.5+),

    tailf /var/log/ltm
    
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:22524. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:10972. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:53187. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm2[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm2[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:15709. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:62364. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:62496. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:42691. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm1[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm1[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:28510. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm3[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:40464. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm1[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
     tmm1[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : Connection from 10.99.29.10:4082. to VIP 10.43.1.6  -->> 10.43.4.232:443
     tmm[14225]: Rule /Common/irule_SrvSelection_byClientSrcAndPort : 10.99.29.10 is Web02
    

    Nice!!

     

  • BIGIP F5 iRule — Block URI for external Client’s only

    So, I had a cool question asked to me today regarding an F5 VIP used by a web application.
    “Can we block a certain URI from external client’s but allow internal client’s to visit it?”

    Of course there is!! Now there are probably a billion different ways to do this, but this is what I came up with.

    First the condition, we want only 10.0.0.0/8 hosts to be able to access this restricted URI. Anyone else should be dropped. I say dropped and not denied, because that way if a user tries to navigate to the URI that shouldn’t it just timesout, and doesn’t give them any more information then they need. Second, I want to log blocks, so I can see it working and get an idea of how many times it gets hit. Lastly we need to know the Virtual server to apply the iRule to.

    Here is the finished iRule, hope it helps!

    when RULE_INIT {
    	set static::drop_notallowed 0
    
    }
    
    when CLIENT_ACCEPTED {
    	if {not [IP::addr [IP::client_addr] equals 10.0.0.0/8]} {
                    log local0. "[IP::client_addr] does not match 10.0.0.0/8 AND access URI = /restricted-URI/"
    		set static::drop_notallowed 1
    	}
    }
    
    when HTTP_REQUEST {
    	if { [string tolower [HTTP::uri]] starts_with "/restricted-URI" }{
    		if {$static::drop_notallowed==1}{
    			drop
    		}
    	}
    
    }

     

    [Read More…]

  • BIGIP F5 iRules — What are they?

    What is an iRule? What are iRules? What can I do with iRules? What is an iRule example?

    One of the most advantageous features that an BIG IP F5 Local Traffic Manager brings is it’s iRule feature. This feature allows the F5 to manipulate and perform event driven functions to the application traffic as it passes through the F5 LTM. This is very useful and has many use cases. For example, a common iRule is as follows. Let’s say you have a typical load balancing setup, with 5 web servers being balanced in a round robin fashion. The traffic that passes through is HTTP. For security purposes only HTTP-SSL is allowed to this site, however you don’t want users to have to remember to put https:// rather than http:// in their internet browser’s address bar. Instead of putting a redirect page on the port 80(insecure) instance on each of the 5 web servers, a simple iRule will take care of that!

    Example HTTP to HTTPS redirect iRule:

    #my first iRule
    when HTTP_REQUEST {
        HTTP::redirect "https://[HTTP::host][HTTP::uri]"
    }

    When we look at this iRule we see a few things. We see an event that must be triggered in order to for the iRule to execute, “when HTTP_REQUEST“. Next we see a HTTP redirect function being performed with a few parameters. HTTP::redirect is the function and the target URL string “https://[HTTP::host][HTTP::uri]”. Let’s break this statement down as it is the meat and potatoes of the iRule.

    https:// is what protocol to send the users browser when it performs the redirect.

    [HTTP::host] which is derived from the clients host-header as it comes across to the F5 LTM. The host header is set when you open a new browser and type the domain/host you are requesting to go to. For example, if you type http://www.google.com in your browser, when you hit enter in the HTTP stream the host-header is set to www.google.com. This is essential when using SSL, but more on that in another post.

    [HTTP::uri] the last part is the URI the user is trying to GET. If this is a standalone site such as www.mysite.com, usually users will hit that first and be redirect already via our iRule before they browse to any URIs. However, perhaps a user tries to go to http://yousite.com/URI, they are not coming across HTTPS so the iRule will intercept it and redirect them to https://yoursite.com, but wait we don’t want them to get kicked back to the root of the site, so the [HTTP::uri] is appended to the redirect target string.

    URIs vs URLs:
    You will see people use these interchangeably, or used in-properly. Even Wikipedia’s article on them is confusing. A URI is what is appended at the end of the host or FQDN, and a URL is the whole thing.

    So,
    http://en.wikipedia.org/wiki/Computer

    FQDN = en.wikipedia.org
    URI = wiki/Computer
    URL = http://en.wikipedia.org/wiki/Computer