Technical Forum
Ask questions. Discover Answers.
cancel
Showing results for 
Search instead for 
Did you mean: 

Irule based on source IP and URI request

Jean_Mamène
Altostratus
Altostratus

Hi,

I want to redirect on pool the request if the IP source and URI request match to the condition.

On version BIG-IP 11.5.4 I think it's better to do with iRule.

Regards

7 REPLIES 7

Kai_Wilke
MVP
MVP

Hi Jean, 

A redirect is always URL related, and a forward is pool related. You somehow mixed redirect and pool in your question which makes no sense for me.

Could you clarify you current setup slightly more in detail?

You have a VS which is serving content from lets say Pool_A? Now you want to forward requests to Pool_B, if known Client IPs requesting a specific /path? Or do you want to HTTP redirect the requests to an external site (e.g. https://sitename/ ), if known Clients requesting a specific /path?

Cheers, Kai

 


iRule can do… 😉

Jean_Mamne_0-1670252027815.png

Actually I have iRule1
I need iRule2. two source IP different but same request URI, and if source IP is 10.0.0.1 I need to go on pool1 and pool2 if 10.0.0.2


HI Jean,

Ideally you could integrate the Source IP Condition to your existing iRule. If you attach a second iRule to your setup without knowing what the first iRule does, it may have some side effects. But lets give it a try with a carefully choosen syntax...

 

 

when HTTP_REQUEST priority 750 {

	# Check if iRule 1 has already responded the request...

	if { [HTTP::has_responded] == 1 } then {
	
		# iRule 1 has already HTTP::responded the request. We abort iRule execution...

	} elseif { not [string tolower [HTTP::path]] starts_with "/uri1/test" } then {

		# HTTP request is for a different path. We should not care...

	} elseif {  [IP::client_addr] equals "10.0.0.1" } then {
	
		# Client 10.0.0.1 is sending requests to /uri1/test. We forward to pool1

		pool pool1
	
	} elseif { [IP::client_addr] equals "10.0.0.2" } then {

		# Client 10.0.0.2 is sending requests to /uri1/test. We forward to pool2
		
		pool pool2
		
	} else {
	
		# We dont care for remaining clients...
		
	}

}

 

The provided iRule uses "priority 750" and should therefor most likely execute after your first iRule (default priority is 500 unless specified otherwise) finished. The provided iRule checks at first if your first iRule has already HTTP::responded the incomming request and aborts further processing if this is true. It will then filter out every HTTP::path not starting_with /uri1/test and abort further processing. Requests starting_with /uri1/test will be further analysed, to see if the client is 10.0.0.1 or 10.0.0.2 and request from those clients will be then forwarded either to pool1 or pool2. The iRule does nothing for remaining client IPs...

HTH and Cheers, Kai


iRule can do… 😉

Thank's ! 
But I think it's better to swap irule order.
Because in this state, iRule1 match all time if 10.0.0.1 want to go on /uri1/test1. iRule1 don't have source IP condition.
I think it's better to have iRule2 more strict in first place and if it's not IP 10.0.0.1 or 10.0.0.2 iRule1 in second place match with.

regards

@Jean_Mamèneyou are better off combining the two iRules rather than having 2 different rules because of iRule priority and unaccounted for behavior when jumping from one iRule to another. This is even more important because you have matches for the same destination URI path and having that in two locations will most likely cause unnecessary confusion in future troubleshooting and changes. In addition to that I would use a switch statement match with each path match having its own source IP match as an if statement within that string. Depending on how large your source IP list becomes for each URI path you might consider using a data-group to perform the matching and pool selection and a data group for URI matching for the overall URI match in the switch statement because of iRule line limits.

when CLIENT_ACCEPTED {

    set DEFAULT_POOL [LB::server pool]

}

when HTTP_REQUEST {

    set URI [string tolower [HTTP::uri]]

    switch -glob $URI {
        "/uri1/test1"
        {
            if { [IP::client_addr] eq 10.0.0.1 } {
                pool pool1
            } elseif { [IP::client_addr] eq 10.0.0.2 } {
                pool pool2
            } else {
                pool pool1
            }
        }
        "/uri2/test2"
        {
            pool pool2
        }
        "/uri3/test3"
        {
            pool pool3
        }
        "/uri4/test4"
        {
            pool pool4
        }
        default
        {
            pool $DEFAULT_POOL
        }
    }

}

The provided iRule will simply overwrite any decission made by Rule 1. If you flip the order then iRule 1 would overwrite the iRule I've provided...

Cheers, Kai


iRule can do… 😉

Paulius
MVP
MVP

You might be able to do something similar to the following. If it ends up being a long list I would recommend using a data group and using that to limit your lines of code because iRules do have a line limit.

when CLIENT_ACCEPTED {

    set DEFAULT_POOL [LB::server pool]

}

when HTTP_REQUEST {

    set URI [string tolower [HTTP::uri]]

    if { [IP::addr [IP::client_addr] eq 10.10.10.10] } {
        if { $URI eq "/my/uri/path" } {
            pool my_pool_for_this_uri
        } elseif { $URI eq "/my/other/uri/path" }
            pool my_pool_for_other_uri
        else {
            $DEFAULT_POOL
        }
    } else {
        $DEFAULT_POOL
    }

}