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

HTTPS REDIRECTION : Specific NODE using iRULE

Deepak_Nair
Cirrus
Cirrus

Hi Experts ,

i am working on one requirement where i need to redirect https://www.example.com needs to redirect to specific NODES ( 8 nos ) based on URI PATH .

i have created a layer 7 virtual server with SSL profile and attach it with following irule :

when HTTP_REQUEST { 
 
        if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/m2p/"} 
        {
        node 10.30.214.1 2783
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/aps/"}
        {
        node 10.30.230.31 7001
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/bmx/"} 
        {
        node 10.30.214.38 61648
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/cts/"}
        {
        node 10.30.214.236 4515
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/mii/"} 
        {
        node 10.30.215.174 50000
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/ampla-bma/"}
	{
        node 10.30.222.43 8889
        return 
    }
	
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/ampla-bmc/"} 
	{
        node 10.38.2.48 8889
        return 
    }
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/iqt-bma/"} 
	{
        node 10.30.215.208 8889
        return 
    }
	if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and [HTTP::path] eq "/iqt-bmc/"}
	{
        node 10.30.222.230 8889
        return 
    }
	
	
}

when i try to access the VIP IP using its DNS name https://TEST-ESB-VIP-BMA.example.com/m2p as an example , BIG-IP is sending me RST back stating no Server selected . I can see hit on irule in the statistic TAB . 

Here is the packet capture from the BIG-IP : 

10.30.230.58.https > 10.139.153.195.53666: Flags [.], cksum 0x94c1 (incorrect -> 0x7121), ack 1352, win 5449, length 0 out slot1/tmm0 lis=/Common/VS_MULE_BMA_TEST_HTTPS_443 flowtype=64 flowid=560000E1C600 peerid=0 conflags=4000024 inslot=63 inport=23 haunit=1 priority=3 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0
02:14:04.293589 00:50:56:ba:17:86 > 54:7f:ee:09:d8:c1, ethertype 802.1Q (0x8100), length 176: vlan 2200, p 0, ethertype IPv4, (tos 0x0, ttl 255, id 44631, offset 0, flags [DF], proto TCP (6), length 40)
    10.30.230.58.https > 10.139.153.195.53666: Flags [.], cksum 0x94c1 (incorrect -> 0x7121), ack 1352, win 5449, length 0 out slot1/tmm0 lis=/Common/VS_MULE_BMA_TEST_HTTPS_443 flowtype=64 flowid=560000E1C600 peerid=0 conflags=4000024 inslot=63 inport=23 haunit=1 priority=3 peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0
02:14:04.293640 00:50:56:ba:17:86 > 54:7f:ee:09:d8:c1, ethertype 802.1Q (0x8100), length 246: vlan 2200, p 0, ethertype IPv4, (tos 0x0, ttl 255, id 44633, offset 0, flags [DF], proto TCP (6), length 83)
    10.30.230.58.https > 10.139.153.195.53666: Flags [R.], cksum 0x94ec (incorrect -> 0xc3d1), seq 148:191, ack 1352, win 0, length 43 [RST+ BIG-IP: [0x29b630c:4504] No se] out slot1/tmm0 lis=/Common/VS_MULE_BMA_TEST_HTTPS_443 flowtype=64 flowid=560000E1C600 peerid=0 conflags=4800024 inslot=63 inport=23 haunit=1 priority=3 rst_cause="[0x29b630c:4504] No server selected" peerremote=00000000:00000000:00000000:00000000 peerlocal=00000000:00000000:00000000:00000000 remoteport=0 localport=0 proto=0 vlan=0

I am NOT sure what i am doing wrong here .If anyone can guide me what i am doing wrong will be much appreciated .

Thanks in advance .

21 REPLIES 21

Hi,

Could you add this in a seperate irule?

when HTTP_REQUEST {
         log local0. "This is the HTTP Host [HTTP::host]"
         log local0. "This is the HTTP Path [HTTP::path]"
}

And past the logging here?

Because it looks like there is no match.

Cheers,

Kees

Deepak_Nair
Cirrus
Cirrus

Hi Kees van den Bos ,

 

I have the created the irule logging , here is the logs :

 

Jan 21 11:44:50 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:50 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:51 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:51 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:55 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:55 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:55 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:55 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:56 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:56 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:57 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:57 BNE1PLBVENT01 info tmm[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:44:57 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:44:57 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

Jan 21 11:45:02 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Jan 21 11:45:02 BNE1PLBVENT01 info tmm1[16685]: Rule /Common/irule_Logging <HTTP_REQUEST>: This is the HTTP Path /m2p/

 

The irule is hitting as expected BUT its not taking any ACTION . Not sure if my iRule is wrong or something else .

Deepak_Nair
Cirrus
Cirrus

The requirement is to HIT via LB so that SSL can be performed via F5 . i will remove "return" statement and see how it goes .

Deepak_Nair
Cirrus
Cirrus

Ok removed the "Return" statement from iRule but no luck , Still says no server selected .

Daniel_Wolf
Nacreous
Nacreous

I wrote a simplified variant of your iRule. Tested and works as expected.

when HTTP_REQUEST {
    if { [HTTP::host] equals "www.myfancydomain.com" && [HTTP::uri] starts_with "/test" } {
        node 10.100.153.40 3000
    }
}

Note that I am matching the HTTP::host with equals, not with contains, because HTTP::host should be an exact match anyways.

Also I used HTTP::uri instead of HTTP::path and, but more important, I use starts_with, because HTTP::uri might also be /test/image1.jpg, test/index.html...

Differences between are explained here:

https://clouddocs.f5.com/api/irules/HTTP__path.html

https://clouddocs.f5.com/api/irules/HTTP__uri.html

Differences between contains, equals, starts_with and so on here:

https://devcentral.f5.com/s/articles/irules-101-02-if-and-expressions

And since you are always matching the same HTTP::host value, you might want to remove that check from your iRule logic and go for a switch statement to only match the HTTP::uri. Something like this.

switch -glob [HTTP::uri] {
  "/foo*" {
    # this will match on any string that starts with "/foo"
  }
  "*bar" {
    # this will match on any string that ends with "bar"
  }....

For details see here: https://devcentral.f5.com/s/articles/irules-101-04-switch

Daniel_Wolf
Nacreous
Nacreous

And another thing I noticed is:

You match for

if {[HTTP::host] contains "TEST-ESB-VIP-BMA.example.com" and

and you log:

<HTTP_REQUEST>: This is the HTTP Host test-esb-vip-bma.example.com

Notice a difference in CAPITALIZATION. Maybe better try

if {([string tolower [HTTP::host]] equals "www.myfancydomain.com") 

Hi,

As Daniel stated, the host is in lower case, not upper.

Could you test this irule:

when HTTP_REQUEST { 
    if {([string tolower [HTTP::host]] equals "test-esb-vip-bma.example.com") } {
        if {[HTTP::uri] starts_with "/m2p" } 
        {
        node 10.30.214.1 2783
        return 
        }
	    if {[HTTP::uri] starts_with "/aps"}
        {
        node 10.30.230.31 7001
        return 
        }
	    if {[HTTP::uri] starts_with "/bmx"} 
        {
        node 10.30.214.38 61648
        return 
        }
	    if {[HTTP::uri] starts_with "/cts"}
        {
        node 10.30.214.236 4515
        return 
        }
	    if {[HTTP::uri] starts_with "/mii"} 
        {
        node 10.30.215.174 50000
        return 
        }
	    if {[HTTP::uri] starts_with "/ampla-bma"}
	    {
        node 10.30.222.43 8889
        return 
        }
		if {[HTTP::uri] starts_with "/ampla-bmc"} 
	    {
        node 10.38.2.48 8889
        return 
        }
        if {[HTTP::uri] starts_with "/iqt-bma"} 
	    {
        node 10.30.215.208 8889
        return 
        }
        if {[HTTP::uri] starts_with "/iqt-bmc"}
	    {
        node 10.30.222.230 8889
        return 
        }
    }    	
}

Cheers,

Kees

Deepak_Nair
Cirrus
Cirrus

Hi Kees ,

 

Thanks for the code . it work for "/m2p" and other NOT working . Now I removed RETURN at the end of each NODE . Looks likes its Working . I am doing more TESTING .

 

Can you please ADVISE on this Irule .

 

when HTTP_REQUEST { 

  if {([string tolower [HTTP::host]] equals "test-esb-vip-bma.bhp.com") } {

    if {[HTTP::uri] starts_with "/m2p" } 

    {

    node 10.30.214.1 2783

     

    }

  if {[HTTP::uri] starts_with "/aps"}

    {

    node 10.30.230.31 7001

     

    }

  if {[HTTP::uri] starts_with "/bmx"} 

    {

    node 10.30.214.38 61648

     

    }

  if {[HTTP::uri] starts_with "/cts"}

    {

    node 10.30.214.236 4515

     

    }

  if {[HTTP::uri] starts_with "/mii"} 

    {

    node 10.30.215.174 50000

     

    }

  if {[HTTP::uri] starts_with "/ampla-bma"}

  {

    node 10.30.222.43 8889

     

    }

if {[HTTP::uri] starts_with "/ampla-bmc"} 

  {

    node 10.38.2.48 8889

     

    }

    if {[HTTP::uri] starts_with "/iqt-bma"} 

  {

    node 10.30.215.208 8889

     

    }

    if {[HTTP::uri] starts_with "/iqt-bmc"}

  {

    node 10.30.222.230 8889

     

    }

  }  

}

 

 

Many Thanks for Helping me OUT .

Hi,

 

This rule looks fine to me.

 

Cheers,

 

Kees

joyride_us
Altostratus
Altostratus

Yes, you had strictly defined your URI path at the first attempts : "eq". Please note that the last script states "start with" which offers more flexibility...but less security.

Deepak_Nair
Cirrus
Cirrus

Thanks Kees and All for helping me OUT on this . Much appreciated .

Deepak_Nair
Cirrus
Cirrus

Ok , i ran into problem . The iRULE work fine but the requirement is to replace the host header from test-esb-vip-bma.example.com/m2p to a new url "www.newurl.com/m2p when the LB initiate the request to the server end .

 

 

what is mean to say is for example as per the irule /m2p is pointing to node 10.30.214.1 2783 . So when the LB initiate the HTTP Get request , it rebuilt the URL with new HOST 10.30.214.1 with URI /m2p . Is this achievable ?

 

 

the scenario is as below

 

from CLIENT_TO_LB ---> https://test-esb-vip-bma.bhp.com/m2p

 

from LB_To_SERVER. ----> http://10.30.214.1:2783/m2p

 

I am trying to TWEAK my irule . Any help in this regard how to replace the HOST header when the LB initiate the request and change with NODE IP AND PORT and append the URI ?

 

 

Deepak_Nair
Cirrus
Cirrus

This URL test-esb-vip-bma.example.com  should only be visible to CLIENT and URL header replacement shouldn't be visible to CLIENT .

Deepak_Nair
Cirrus
Cirrus

i Wrote a sample to see if this work .

 

when HTTP_REQUEST { 

  if {([string tolower [HTTP::host]] equals "test-esb-vip-bma.bhp.com") && 

    [HTTP::uri] starts_with "/cts" } 

{

HTTP::header replace "Host" "10.30.230.15:4515"

HTTP::uri 

}

}

 

The Irule is hitting BUT connection is getting RESET .

 

 

But now the BIG-IP doesn't know where to send the request...

when HTTP_REQUEST { 
          if {([string tolower [HTTP::host]] equals "test-esb-vip-bma.bhp.com") &&  [HTTP::uri] starts_with "/cts" }  {
                   HTTP::header replace "Host" "10.30.230.15:4515"
                  node 10.30.230.15 4515
           }
}

Sorry for the formatting..... Can you try the above irule?

Cheers,

Kees

Deepak_Nair
Cirrus
Cirrus

Hi Kees ,

 

This works !!! thanks alot .

 

Sorry for my trouble Question again !

 

The actual URI PATH is HP01/CtsConsignment?wsdl . SO with the ABOVE iRULE the actual URL && URI PATH it take is 10.30.230.15:4515/cts/HP01/CtsConsignment?wsdl .

 

BUT there is no resource exist in cts/HP01/CtsConsignment?wsdl . The Resource actually exist in URI HP01/CtsConsignment?wsdl .

 

So i want to STRIP OUT /cts from the URI path once the Host Header is replaced with 10.30.230.15:4515 .

 

In summary when client request to LB with https://est-esb-vip-bma.bhp.com/cts and request accepted

then LB rebuild the URL with http://10.30.230.15:4515//HP01/CtsConsignment?wsdl

 

Can this be achieved using irule or i should ask application team to create a URi PATH with cts/HP01/CtsConsignment?wsdl on the server .

 

Thanks .

 

Hi Deepak,

 

I think you need an irule development course 😉

 

Is the only uri behind /cts/ /hp01/ctsconsigment?wsdl or are the more?

 

Cheers,

 

Kees

Deepak_Nair
Cirrus
Cirrus

Hi Kees ,

 

I am currently Working towards to get friendly with IRULES . Really sorry for hitting with many question . My bad 😐

 

There are like 200 URLS served from different HOSTS ( around 8 or 9 in nos ) . we want to ROUTE the application based on URI PATH which we discussed with ABOVE iRULE .

 

So for example , when client comes with https://est-esb-vip-bma.bhp.com/cts it should go to  http://10.30.230.15:4515/HP01/CtsConsignment?wsdl or some other URI based on data they NEED . Here with VIP IP and URI PATH , IRULE we defined selects the desired HOSTS .

 

if client comes with https://est-esb-vip-bma.bhp.com/m2p it should route to http://10.30.215.16/Integration1.0/MaterialsServices.svc etc etc

 

So in general , i want to STRIP OUT the first URI in request and APPEND REST to the selected NODE within the iRULE .

 

I am doing some reading BUT not sure if this is achievable via IRULE . So reaching out for help from experts .

 

If NOT achievable then i will ask the APPS team to locate the content BUILD during HHTP get request from F5 based on iRULE .

 

 

 

Thanks /

 

 

 

 

 

Hi Deepak,

 

It is ok, that is what devcentral is also for. To help.

 

Ok, so you need code to strip off a part of the uri.

Use this:

when HTTP_REQUEST { 
          if {([string tolower [HTTP::host]] equals "test-esb-vip-bma.bhp.com") &&  [HTTP::uri] starts_with "/cts" }  {
                   HTTP::header replace "Host" "10.30.230.15:4515"
                  HTTP::uri [string map [list "/cts" "" ] [HTTP::uri]]
                  node 10.30.230.15 4515
           }
}

 

Deepak_Nair
Cirrus
Cirrus

Thanks Kees . This Works .

 

Thanks Alot for helping me OUT . Much Appreciated .

 

I really need some irule development course .

Your welcome Deepak!​