For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

Dianna_129659's avatar
Dianna_129659
Icon for Nimbostratus rankNimbostratus
Mar 05, 2014

Whitelist a user agent

We use Pingdom to alert us when our site is down. We also block most IP Addresses that are not within the United States (we do business only within the US). Is there a way that I can whitelist the Pingdom User-Agent so that the IP Addresses for the Pingdom servers outside of the US will be allowed past F5? Thank you for any suggestions or ideas.

 

10 Replies

  • Something like this perhaps:

    when CLIENT_ACCEPTED {
        if { ( [class match [IP::client_addr] equals pingdom_list] ) or ( [whereis $ip country] equals "US" ) } {
            return
        } else {
            drop
        }
    }
    

    where "pingdom_list" is an address-based data group of Pingdom source addresses (and/or source networks). You can also perform this function in an HTTP_REQUEST event, in case you want to send an HTML response for requests not allowed.

  • I would really like to get away from using addresses if possible. However, I don't think there is a way to simply use the user agent

    You could certainly evaluate on HTTP User-Agents headers for the Pingdom clients.

    when HTTP_REQUEST {
        if { ( [class match [string tolower [HTTP::header User-Agent]] contains pingdom_ua_list] ) or ( [whereis $ip country] equals "US" ) } {
            return
        } else {
            drop
        }
    }
    
  • Could I change the HTTP user agent header, to simply contain pingdom?

     

    Absolutely. The "pingdom_ua_list" would be a string-based data group that contains a list of possible Pingdom User-Agent header values (assuming there's more than one).

     

  • Maybe put "pingdom" in double quotes, but otherwise it looks good. I'd also comment that a User-Agent header is pretty easy to spoof, if that matters to you.

     

  • There are tons of browser-based tools to manipulate HTTP headers, as well as simply doing something like this:

    curl -k -H "User-Agent: pingdom" https://yoursite.domain.com    
    

    Filtering on IP addresses would be much harder to spoof, but still not completely impossible.

  • It was this:

    [class match [string tolower [HTTP::header User-Agent]] contains "Pingdom"]
    

    You're doing a [string tolower ] evaluation of the User-Agent header but giving it a mixed-case string ("Pingdom" vs. "pingdom").

  • I didn't check this yesterday, but you're still doing a class match (which is likely failing).

    when HTTP_REQUEST {
        if { ( [string tolower [HTTP::header User-Agent]] contains "pingdom" ) or ( [whereis $ip country] equals "US" ) or ( [whereis $ip country] equals "CA" ) } {
            return
        } else {
            drop
        }
    }
    
  • No worries. Your previous iRule was still doing this:

    [class match [string tolower [HTTP::header User-Agent]] contains "pingdom"]
    

    which is a data group lookup that attempts to match the User-Agent header value to a value in the "pingdom" data group. In this case, and the part I didn't catch yesterday, is that "pingdom" is the name of the data group. For the above to work, the values inside the data group must all be lower cased. But aside from that, you expressed that you just wanted to evaluate the User-Agent locally, assuming that there was just one User-Agent presented by the Pingdom clients. So we changed the above to this:

    [string tolower [HTTP::header User-Agent]] contains "pingdom"
    

    which is basically lower casing the incoming User-Agent header and comparing it to the string "pingdom". If the User-Agent contains the work "pingdom", then it should evaluate to TRUE. So...

    If the UA header contains "pingdom" or the country is "US" or the country is "CA" - let them in. Otherwise drop the request.

    Also, and not trying to complicate this further, since you're doing this in the HTTP_REQUEST event, you have an opportunity to get really creative with your deny. For example, instead of just dropping the request, you could send back some formatted HTML:

    drop
    HTTP::respond 200 content "...html document..."
    
  • Worst case, remove the whereis conditions and leave only the User-Agent evaluation to see if that is working on its own.

     

  • Solution: The iRule was correct and should have worked except that (I checked with an F5 engineer), it seems that there is no way in the configuration to bypass a violation if the geolocation matches and you are in blocking mode. I also learned that this was a problem with Pingdom's scheduling which caused Pingdom to ping us multiple times a minute.