Forum Discussion

ant77's avatar
ant77
Icon for Cirrostratus rankCirrostratus
Jan 27, 2022

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

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 doi...
  • JRahm's avatar
    Jan 28, 2022

    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? 

  • Joseph_Martin's avatar
    Jan 29, 2022

    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"
            }
        }
    }