What could you do with your code in 20 Lines or Less? That's the question I ask (almost) every week for the devcentral community, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head.

This week the answer to that question is a good one – Win the iRule do You? contest!  Rather than trolling the forums, CodeShare and my personal archives, this week I bring to you a special 20LoL edition. This week’s entries are pulled from the winners and honorable mentions of the recently completed iRule Do You? contest here on DevCentral.

I absolutely love that I get to show you some short iRules that are not only neat or interesting, but they’re so innovative, creative and powerful that they won (or almost won) prizes in our annual contest.  If that’s not proof that you can do amazing things in just a few lines of code with iRules, then I don’t know what is.  This wasn’t planned, I didn’t trim these down, the stars just aligned right for me to be able to spotlight a few super cool rules from this year’s contest.  For complete contest results & entries, as well as full descriptions of each rule, check out the contest pages on DC.

Today’s 20LoL is doubly special, though. Not only do I get to highlight some clearly awesome contest entries, this also marks the edition where the 20LoL eclipses the 100 examples mark.  Over 100 examples of iRules doing what iRules do in under 21 lines of code. I’m stoked that I’ve gotten to continue with this feature this long, and I’m looking forward to hundreds more. Thanks for reading.

 

RTSP-redirect – by Jari Leppälä

http://devcentral.f5.com/Default.aspx?tabid=2227

In an attempt to build hash based persistence, Jari built this cool iRule that not only performs the needed persistence, but does so without forcing the traffic to ever even flow through the BIG-IP.  Using the BIG-IP as a logic device but not bothering it with the traffic is a slick concept to me in this case. Gotta love it.

 

when RTSP_REQUEST {
if { [RTSP::method] contains "OPTIONS" } {
  RTSP::respond 200 OK "Server: F5-redirector\r\nPublic: OPTIONS, SETUP\r\n\r\n"
}
if { [RTSP::method] contains "SETUP" or [RTSP::method] contains "DESCRIBE" } {
  set client [IP::remote_addr]
  regexp "rtsp://.*/(.*)$" [RTSP::uri] url file
  # MD5 Hash & Persistence
  set S ""
  foreach N [active_members -list vod] {
    if { [md5 $N$file] > $S } {
      set S [md5 $N$file]
      set W $N
    }
  }
  set vod [lindex $W 0]
  set newuri "rtsp://$vod:554/$file"
  RTSP::respond 302 MOVED_TEMPORARILY "Server: F5-redirector\r\nLocation: $newuri\r\nConnection: close\r\n\r\n"
  log "Client ($client) request to $file redirected to $newuri"
}
}

 

 

Encrypt Outgoing Soa Request – by Sake Blok

http://devcentral.f5.com/Default.aspx?tabid=2228

Looking for a way to make his outbound SOA traffic more secure, Sake came up with yet another iRule contest winner this year. No stranger to the winner’s circle, Sake continues to be an awesome contributor with innovative, original ideas for how to bend iRules to his whims. I always love seeing what he comes up with and this was no exception.

 

when RULE_INIT {
   # Debug off (0), Errors-only(1), On(2) or Verbose(3)
   set ::debug 3
   if { $::debug>=2 } { log local0. "Log level set to $::debug" }
}
when CLIENT_ACCEPTED {
   # Remember the address of the destination SOA server
   set SoaServerIP [IP::local_addr]
   if { $::debug>=3 } { log local0. "$SoaServerIP: Outgoing connection requested" }
}

when HTTP_REQUEST {
   # Extract the hostname of the SOA server from the HTTP request
   # This name will must match the common name in the certificate
   # of the SOA server when the SSL session is set up.
   set SoaServerName [string tolower [substr [HTTP::host] 0 ":"]]
   if { $::debug>=3 } { log local0. "$SoaServerIP: Hostname = $SoaServerName" }

   # Overrule the dummy address in the default pool of the virtual
   # and change it to the address of the SoaServer. Also change the
   # destination port from 80 to 443.
   node $SoaServer 443
}

when SERVERSSL_HANDSHAKE {
   # Extract the server certificate from the SOA server ServerHello message
   set SoaServerCert [SSL::cert 0]

   # Extract the common name from the server certificate
   set CommonName [string tolower [findstr [X509::subject $SoaServerCert] "CN=" 3 ","]]
   if { $::debug>=3 } { log local0. "$SoaServerIP: Common Name = $CommonName" }

   if { $CommonName ne $SoaServerName } {
      clientside {TCP::respond "HTTP/1.1 403 WRONG CERTIFICATE\r\n\r\nThe common name $CommonName `
in the certificate at $SoaServerIP does not match to hostname $SoaServerName in the SOA request.\r\n"}
      TCP::close
      if { $::debug>=1 } { log local0. "$SoaServerIP: Name mismatch CN=$CommonName, Hostname=$SoaServerName" }
   } else {
      # Create a log entry for this (successful) request
      if { $::debug>=2 } { log local0. "$SoaServerIP: Request to $SoaServerName successfully forwarded" }
   }
}

 

 

DSL Setup DNS – by Christopher Wood

http://devcentral.f5.com/Default.aspx?tabid=2229

Even though Christopher didn’t quite claim victory this year, his entry was one of my personal favorites and showed that he absolutely has the ability to do so. I have no doubt that he’ll be a force to be reckoned with in coming contests.  This very cool iRule shows how he was able to make the process of getting users with newly installed DSL modems online much simpler. Not only did it solve an immediate problem (getting users online with ease) it reduced support calls too. That’s a double win.

 

when RULE_INIT  {
  # Header generation (in hexadecimal)
  # qr(1) opcode(0000) AA(1) TC(0) RD(1) RA(1) Z(000) RCODE(0000)
  set ::header "8580"
  # 1 question, 1 answer, 0 NS, 0 Addition
  set ::header "${::header}0001000100000000"
  # Type = A
  set ::answerz "0001"
  # Class = IN
  set ::answerz "${::answerz}0001"
  # TTL = 1 minute
  set ::answerz "${::answerz}0000003c"
  # Data length = 4
  set ::answerz "${::answerz}0004"
  # Address = 0.0.0.0 (in hex)
  set ::answerz "${::answerz}00000000"
}
when CLIENT_DATA {
  binary scan [UDP::payload] H4@12A*@12H* id dname question
  # the drop statement below has to be in an if context
  if { 1 } {
    set ::questionx "${question}"
    set ::myl [string range ${::questionx} 0 end-8]
    set ::myllower [string tolower ${::myl}]
    # this is the decimal representation of the hex for lowercased "fake.com"
    if { [ string match "*1234567890abcdef123456" ${::myllower} ] } {
      pool internal-DNS
    } else {
      set payload [binary format H* ${id}${::header}${question}${::myl}${::answerz} ]
      # drops the incoming connection
      drop
      UDP::respond $payload
    }
  }
}

 

Thanks again to everyone who participated in this year’s iRule Do You? contest. I hope to see even more entries next year, and more people doing hawesome things in just a few lines of code. Here’s your proof that it’s possible, see what you can do to top them.

#Colin