cancel
Showing results for 
Search instead for 
Did you mean: 

Monitor two pool maintenance page iRule using XFF not working...

ant77
Cirrus
Cirrus

Does anyone know why if either the  "INTERNAL" server pool goes down, the traffic for internal users still works? Is there a better way to group these monitors up? 

Please let me know what I am doing wrong...When I disable all nodes in the internal POOL, traffic to the internal pool works and they get sent there...It seems that only the monitor for the External Pool works...Can you have two monitors in the same iRULE? Does this iRule care about the secondary monitor for the internal pool?

Note: When I disable the EXTERNAL pool members, the external users gets sent to the correct maintenace page, while the internal users still works as it should...But we need to have the same thing happen when the INTERNAL pool goes down....

Objective:

1. Using XFF, if the "EXTERNAL" pool goes down, and the XFF IP of the client "Does Not" match the IP in the"DG-INTERNAL-USERS-XFF" data group, send the
users to "http://maintenace-page.com/external"

2.  Using XFF, if the "INTERNAL" pool goes down, and the XFF IP of the client "Matches" the IP in the"DG-INTERNAL-USERS-XFF" data group, send the users
to "http://maintenace-page.com/external"

 

when HTTP_REQUEST {
set CHECK_IP [lindex [lsearch -all -inline -not -exact [split [HTTP::header values X-Forwarded-For] "\{\} ,"] {}] 0] 
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
       if { [class match -- [HTTP::uri] eq DG-ALLOWED-URI-LIST] } {
          reject
          log local0. "Client IP Discard: \ [HTTP::host][HTTP::uri]->[IP::client_addr]" 
           }              
   if { [active_members EXTERNAL-POOL] < 1 } {
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
    HTTP::redirect "http://maintenance-page.com/external" 
    return
   
  
  if { [active_members INTERNAL-POOL] < 1 } {
   if { ([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
    HTTP::redirect "http://maintenance-page.com/internal" 
   return
   
    pool EXTERNAL-POOL
    
   } else {
   
     pool INTERNAL-POOL
log local0. "the X-Forwarded-For header value is $CHECK_IP"
        
     }
    }
   }
  }
 }
}

 

 

 

 

2 ACCEPTED SOLUTIONS

JRahm
Community Manager
Community Manager

before working on this, it's very similar to your other one and I was curious if this is on the same virtual? If so, is the other logic in this rule as well or a different rule? 

View solution in original post

Joseph_Martin
F5 Employee
F5 Employee

I am not sure if the new site is formatting your iRule incorrectly or what but, it does not appear that the iRule will function as you want in the state I see it right now.

There are several things wrong with the logic so I am re-posting it here with clearing formatting and commented with the logic as it is:

when HTTP_REQUEST {
    set CHECK_IP [lindex [lsearch -all -inline -not -exact [split [HTTP::header values X-Forwarded-For] "\{\} ,"] {}] 0] 
    # Check if userds are NOT in internal user DG
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
        # Check if uri is in allowed list
        if { [class match -- [HTTP::uri] eq DG-ALLOWED-URI-LIST] } {
            #blocks external users (i.e. IPs  Not in Interal Users DG)
            reject
            log local0. "Client IP Discard: \ [HTTP::host][HTTP::uri]->[IP::client_addr]" 
        }
        # Check if External Pool has zero active members
        if { [active_members EXTERNAL-POOL] < 1 } {
            #IF so, check if they are "external" users (i.e. NOt in Internal users DG 
            if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
                #redirect external users to maintenance-page
                HTTP::redirect "http://maintenance-page.com/external" 
                # returns form proccessing this event ####  No other code in this iRuel will run!!!!!!!
                return
                ######  Rest of this logic will never be processed!!!!   ####################
                
                # Check if internal Pool is down
                if { [active_members INTERNAL-POOL] < 1 } {
                    # Check if IP IS in the Internal Uers group  
                    if { ([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
                        #  redirect internal users to the maiantinace page if the internal pool is down
                        HTTP::redirect "http://maintenance-page.com/internal"
                        # returns form proccessing this event ####  No other code in this iRuel will run!!!!!!!  But we would never get this far anyway.
                        return
                        ######  Rest of this logic will never be processed!!!!   ####################
                        
                        # Send traffic to external pool
                        pool EXTERNAL-POOL
                    # IF you are NOT in Internal Users DG
                    } else {
                        # Send to Internal Pool
                        pool INTERNAL-POOL
                        log local0. "the X-Forwarded-For header value is $CHECK_IP"
                    }
                }
            }
        }
    }
}


It is diffiucult to tell from the current logic exactly what you were trying to accomplish But this is my best guess at what it SHOULD look like:

when HTTP_REQUEST {
    set CHECK_IP [lindex [lsearch -all -inline -not -exact [split [HTTP::header values X-Forwarded-For] "\{\} ,"] {}] 0] 
    # Block external IPs form getting to ALLOWED-URI-LiST
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
        if { [class match -- [HTTP::uri] eq DG-ALLOWED-URI-LIST] } {
            reject
            log local0. "Client IP Discard: \ [HTTP::host][HTTP::uri]->[IP::client_addr]" 
        }
    }
    # If External Pool is down, redirect enternal users, and send internal users to Internal Pool
    if { [active_members EXTERNAL-POOL] < 1 } {
        if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
            HTTP::redirect "http://maintenance-page.com/external" 
            return
        } else {
            pool INTERNAL-POOL
            log local0. "the X-Forwarded-For header value is $CHECK_IP"
        }
    }
    # Check if Internal Pool is down, redirect External users to maintiencace page, and allow everyone else to External Pool
    if { [active_members INTERNAL-POOL] < 1 } {
        if { (![class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
            HTTP::redirect "http://maintenance-page.com/internal"
            return
        } else {
            pool EXTERNAL-POOL
            log local0. "the X-Forwarded-For header value is $CHECK_IP"
        }
    }
}



View solution in original post

4 REPLIES 4

JRahm
Community Manager
Community Manager

before working on this, it's very similar to your other one and I was curious if this is on the same virtual? If so, is the other logic in this rule as well or a different rule? 

ant77
Cirrus
Cirrus

Hi Jason,

Yes, this is similar to the previous iRule, but for a different Virtual. We need to do this for the other one also...It seems that you can't have two monitor in one iRule, one monitoring an external pool, and the other monitoring the internal Pool...We need to use XFF to distinguish what traffic is what....I have tried re-ording the monitors, and when you disable the members for the "internal" pool, traffic still gets sent there...Is this a bug or something? This has nothing to do with the irule, but more of a pool configuration/disabling member...why does the website still comes up...and when you add the secondary monitor in the script in, external users will be routed to the internal pool instead of the external pool....Right now, i only have the script to include the external monitor...we can't have two for some reason..not sure if this is a bug or not...

Thanks!

Joseph_Martin
F5 Employee
F5 Employee

I am not sure if the new site is formatting your iRule incorrectly or what but, it does not appear that the iRule will function as you want in the state I see it right now.

There are several things wrong with the logic so I am re-posting it here with clearing formatting and commented with the logic as it is:

when HTTP_REQUEST {
    set CHECK_IP [lindex [lsearch -all -inline -not -exact [split [HTTP::header values X-Forwarded-For] "\{\} ,"] {}] 0] 
    # Check if userds are NOT in internal user DG
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
        # Check if uri is in allowed list
        if { [class match -- [HTTP::uri] eq DG-ALLOWED-URI-LIST] } {
            #blocks external users (i.e. IPs  Not in Interal Users DG)
            reject
            log local0. "Client IP Discard: \ [HTTP::host][HTTP::uri]->[IP::client_addr]" 
        }
        # Check if External Pool has zero active members
        if { [active_members EXTERNAL-POOL] < 1 } {
            #IF so, check if they are "external" users (i.e. NOt in Internal users DG 
            if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
                #redirect external users to maintenance-page
                HTTP::redirect "http://maintenance-page.com/external" 
                # returns form proccessing this event ####  No other code in this iRuel will run!!!!!!!
                return
                ######  Rest of this logic will never be processed!!!!   ####################
                
                # Check if internal Pool is down
                if { [active_members INTERNAL-POOL] < 1 } {
                    # Check if IP IS in the Internal Uers group  
                    if { ([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
                        #  redirect internal users to the maiantinace page if the internal pool is down
                        HTTP::redirect "http://maintenance-page.com/internal"
                        # returns form proccessing this event ####  No other code in this iRuel will run!!!!!!!  But we would never get this far anyway.
                        return
                        ######  Rest of this logic will never be processed!!!!   ####################
                        
                        # Send traffic to external pool
                        pool EXTERNAL-POOL
                    # IF you are NOT in Internal Users DG
                    } else {
                        # Send to Internal Pool
                        pool INTERNAL-POOL
                        log local0. "the X-Forwarded-For header value is $CHECK_IP"
                    }
                }
            }
        }
    }
}


It is diffiucult to tell from the current logic exactly what you were trying to accomplish But this is my best guess at what it SHOULD look like:

when HTTP_REQUEST {
    set CHECK_IP [lindex [lsearch -all -inline -not -exact [split [HTTP::header values X-Forwarded-For] "\{\} ,"] {}] 0] 
    # Block external IPs form getting to ALLOWED-URI-LiST
    if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
        if { [class match -- [HTTP::uri] eq DG-ALLOWED-URI-LIST] } {
            reject
            log local0. "Client IP Discard: \ [HTTP::host][HTTP::uri]->[IP::client_addr]" 
        }
    }
    # If External Pool is down, redirect enternal users, and send internal users to Internal Pool
    if { [active_members EXTERNAL-POOL] < 1 } {
        if { !([class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
            HTTP::redirect "http://maintenance-page.com/external" 
            return
        } else {
            pool INTERNAL-POOL
            log local0. "the X-Forwarded-For header value is $CHECK_IP"
        }
    }
    # Check if Internal Pool is down, redirect External users to maintiencace page, and allow everyone else to External Pool
    if { [active_members INTERNAL-POOL] < 1 } {
        if { (![class match -- $CHECK_IP eq DG-INTERNAL-USERS-XFF]) } {
            HTTP::redirect "http://maintenance-page.com/internal"
            return
        } else {
            pool EXTERNAL-POOL
            log local0. "the X-Forwarded-For header value is $CHECK_IP"
        }
    }
}



Joe/Jason -

thanks for your guidence. I have modified the irule a bit and got it working.

Thanks again guys!