19 posts categorized "irule"


There is an Introduction to iRules Book Out

Steven Iveson has published the eBook, An Introduction to F5 Networks LTM iRules, available in Kindle Reader format on Amazon. Presently, the U.S. price is $9.99. 

The 138 page book is geared towards networking professionals who are beginners with iRules and need to get a solid introduction to iRules commands, statements, tcl syntax, etc. There is supposed to be a second edition released soon that expands the topics covered in the book and the author expects that the second edition will be delivered for free to purchasers of the first edition.


iRule Fun Fact - HTTP::uri Doesn't Decode

Here's something unpleasant I learned recently. Take the following sample irule, which looks at the incoming URI of a request and rejects the connection if /jmx-console/ is matched:

    switch -glob [HTTP::uri] {
        "/jmx-console*" {
            reject }

It's one of those irules where you say, "Golly...I did that with just 5 lines! That's awesome! I am going to add other well-known, exploitable URIs and then roll this out everywhere!!"

There's a couple of problems with the pattern matching above. First, HTTP::uri only matches the literal string "/jmx-console*" What if one were to URL encode the request so that /jmx-console/ becomes /%6A%6D%78%2D%63%6F%6E%73%6F%6C%65/. Well, that gets right through. HTTP::uri doesn't decode the URI before handling like mod_proxy does so any URL encoded portion of jmx-console is not going to be matched.

The second issue: /JMX-CONSOLE != /jmx-console, which makes sense because URI's are case-sensivite after all. So, that will get through, (although you'll get a blank page in jboss for requests matching /JMX-CONSOLE) but if you've got some passionate security folks on your team, you'd probably want to handle that consistently.

The third issue: Place a couple of slashes in front of your url encoded jmx-console URI and that will go through, too. I think that requests for ///jmx-console are going to get through, too, but I don't recall testing that specific case.

Here's an updated version of the above sample rule:

    set tmpUri [string tolower [HTTP::uri]]
    set uri [URI::decode $tmpUri]
    switch -glob $uri { 
    "*/jmx-console*" {
            HTTP::respond 404 content {<html><head><title>Page Not Found</title></head><body>Page Not Found</body></html> }

The updated rule does a few things. First, it sets a temporary variable tmpUri, which sets the value of the incoming request's HTTP::uri to a lower case value. In the second line, I then decode that URI and set that to a second variable uri. The nice thing about URI::decode is that it doesn't matter if the request comes in as jmx-console, /%6A%6D%78%2D%63%6F%6E%73%6F%6C%65/, or even /j%6Dx%2Dc%6Fn%73o%6Ce/—it will still decode to jmx-console. (There might be a way to do this all in one line with one variable but this is what I've got so far.) Once all this business is worked out, then the switch statement evaluates the value of $uri instead of HTTP::uri to see if a pattern is matched. Note that I've prepended an asterisk in front of the slash in order to pick up those cases where multiple slashes are placed in front of the resource name.

Finally, don't reject or drop requests. Worms, vulnerability scanners, and script kiddies might be fooled/satisfied/fooled but folks that are determined may have their interests piqued if they send a bunch of requests to your web site and some of them result in a tcp reset while others result in a 404.

More investigation continues to see whether I can find other ways to get jmx-console requests through but this is a big improvement over what I was doing in the past.


BigIP V11 Upgrade Reminder: "$::" in iRules Will Not Work

A reminder to myself and others who are scheduling upgrades to version 11 of the BigIP software: Although the matchclass (DevCentral login required) command is deprecated (but will still work as of v11.2.0), data groups referenced in your irules using the $::data_group_name syntax will result in TCL errors written to your ltm logs and Connection Resets to your end-users.

If you come across some error messages in the ltm logs like this:

MMM DD HH:MM:SS tmm err tmm[PID]: 01220001:3: TCL error: /Partition/the_offending_irule - can't read "::your_data_group": no such variable while executing "matchclass [IP::client_addr] equals $::your_data_group"

The quickest way to fix and restore service is to remove the '$::' from in front of your Data Group in your irule and then wrap it in double quotes. (For example, $::your_data_group becomes "your_data_group"

To avoid future matchclass incompatibilities, it might be wise to modify those rules using matchclass to the new class match functions. Migrating matchclass functions to class match syntactically looks to be just as easy—replace matchclass with class match (although I personally haven't done this yet in my rules using matchclass).