20 Lines or Less #73: VIPs, SMTP Blocking and Responses
What could you do with your code in 20 Lines or Less? That's the question I like to ask for the DevCentral community, and every time 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 in what I believe to be 20LoL #73 (Lost track…but we’ll go with it) we've got a few more prime examples of iRules doing what iRules do best: solving problems. Whether you're trying to do some fancy footwork when it comes to traffic routing to multiple VIPs, or dealing with some SMTP requests you'd rather not have to, you'll find something handy in this week's 20 Lines or Less. Many thanks to the fine contributors of said examples, both F5ers and otherwise. VIP redirect to another VIP https://devcentral.f5.com/s/questions/vip-redirect-to-another-vip A question that comes in fairly often is how to bounce traffic from one location to another. A very specific version of that question is "How do I get traffic from one of my VIPs to another?". This has been addressed in the Q&A section more than once, but I wanted to put it here in the 20LoL as well, as it seems to be a common theme. As Kevin Stewart nicely put, there are basically two ways to do this. First is with a simple redirect. This is done either via the HTTP::redirect command or by responding with a 301. This will tell the client to seek the resource they're requesting from a different host, all you have to do is supply the address of the VIP you want to bounce them to. The other, more direct fashion is to use the VIP targeting VIP function within LTM to make the destination an internal VIP. This looks a bit different, and behaves a bit different, but the client will never see the redirect, which can be handy at times. I've included Kevin's examples of each option here: when HTTP_REQUEST { if { ...some condition... } { HTTP::redirect "https://somewhere.else.com" } } when HTTP_REQUEST { if { ...some condition... } { HTTP::respond 301 Location "https://somewhere.else.com" } } when HTTP_REQUEST { if { ...some condition... } { virtual internal-vs } } Block SMTP connections based on EHLO https://devcentral.f5.com/s/questions/need-help-blocking-smtp-connections-based-off-ehlo-name Pesky SMTP attackers getting you down? Coming from multiple different IP addresses? Looking for a way to stop them based on their connection strings? Well look no further, Cory's got your back. He shows us a simple way to check the EHLO info in an SMTP handshake to block unwanted bad guys from doing…bad guy things. Simple and clever and useful, very 20LoL-ish. Check it out. when CLIENT_ACCEPTED { TCP::respond "220\r\n" TCP::collect } when CLIENT_DATA { set clientpayload [string tolower[TCP::payload]] if { $clientpayload contains "ehlo abcd-pc" } { reject } } No HTTP Response Fired? https://devcentral.f5.com/s/questions/when-is-http_response-not-fired This one is less a trick in code, but a lesson in understanding how iRules play with other modules loaded on the LTM. A user was having some troubles with APM multi-domain and an iRule they wanted to use that fired on HTTP_RESPONSE. As Kevin so clearly explains, "The HTTP_RESPONSE is triggered for egress HTTP traffic through the box. The logon VIP in an APM multi-domain configuration doesn't trigger the HTTP_RESPONSE event because it handles all responses locally. Your best bet here, unfortunately, is to layer the APM logon VIP behind an LTM VIP that can see the HTTP response traffic from the APM VIP. You'd use a very simple iRule on the LTM VIP". And here is said iRule, for all those that might run into a similar situation. when HTTP_REQUEST { virtual [name of APM VIP] } when HTTP_RESPONSE { HTTP::header insert Strict-Transport-Security "max-age=31708800" }371Views0likes3Comments20 Lines or Less #74: ASP Session Persistence, Radius Auth, and Fancy URIs
What could you do with your code in 20 Lines or Less? That's the question I like to ask for the DevCentral community, and every time 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’s examples deal with things ranging from session persistence (And NOT for JSESSION!) to RADIUS authentication and beyond. Ask and the community shall provide, as is so often the case, adn this week was no different. Let’s see what we came up with in this week’s 20LoL: ASPSESSIONID Persistence https://devcentral.f5.com/s/questions/irule-required-to-persist-client-connections-that-get-proxied-from-a-single-client We’ve seen the JSESSIONID version enough times that it should be committed nearly to memory by now, I would think. This take, however, is a bit newer. It is of course the exact same concept, but rather than dealing with Java, user Nathan Andrews was looking for a way to persist data from Blackberries accessing an application. Source address wasn’t working since they were bouncing through a proxy inherent in such deployments. Fortunately he was able to identify a common attribute and persist based off of that. Enter ASPSESSIONID and handy, likely familiar chunk of code. when HTTP_RESPONSE { if { [HTTP::cookie exists "ASPSESSIONID"] } { persist add uie [HTTP::cookie "ASPSESSIONID"] } } when HTTP_REQUEST { if { [HTTP::cookie exists "ASPSESSIONID"] } { persist uie [HTTP::cookie "ASPSESSIONID"] } } Radius and WebApp Authentication https://devcentral.f5.com/s/questions/radius-and-webapp-authentication DC user Don Benson was looking to collect three bits of data to perform Radius Auth for a web app, using their BIG-IP to collect and pass through the required data. They were looking for username, password and a hardware token. The trouble in their testing came when the web app was expecting a POST and they were sending GETs (not sure quite what they were doing since they didn’t post their original iRule). Fortunately another helpful DC member chimed in with a suggestion that, if my math is correct…carry the one…should get them where they need to go. when ACCESS_POLICY_COMPLETED { set username [ACCESS::session data get "session.logon.last.username"] set content " < script type=text/javascript language=javascript> \ function s(){ document.f.submit(); } \ \ " ACCESS::respond 200 content $content } URI Queries and Fancy Footwork https://devcentral.f5.com/s/questions/how-to-destroy-and-replace-a-uri-query-value- While the original thread’s title was about destroying and replacing URIs, I thought this more appropriate. Nitass steps in with some handy dandy URI query shaping logic to make what sounded like a somewhat complex set of deliverables a snap. Looking to replace a query parameter with a specific value, or ensure said query param is in place if its missing? Well here you go. when HTTP_REQUEST { if { [HTTP::host] eq "red.x.com" } { set q [URI::query [HTTP::uri] code] if { $q ne "" } { HTTP::uri [string map "$q red" [HTTP::uri]] } else { HTTP::uri "[HTTP::uri]&code=red" } } }283Views0likes0Comments20 Lines or Less #70
What could you do with your code in 20 Lines or Less? That's the question we like to ask from, for, and of (feel free to insert your favorite preposition here) the DevCentral community, and every time we do, we go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head. Thus was born the 20LoL (20 Lines or Less) series many moons ago. Over the years we've highlighted hundreds of iRules examples, all of which were doing downright cool things in less than 21 lines of code. In this edition, I step in for Colin the Magnificent to bring you some iRules goodness in short form. New capabilities and a few cool iRules await you, so let's get going! Make Me a Sandwich! iRules Style... Flying well under the radar in the 11.4.1 TMOS release is a new iRules-capable layer in the BIG-IP Advance Firewall Manager module. With the introduction of the FLOW_INIT event and the ACL::action command, you can now sandwich some iRules logic goodness in between the packet filters at the front door and the beginning of the BIG-IP AFM processing. This gives you the capabilities of overriding ACL action, controlling bandwidth and QoS on client and/or server flows, and routing/blocking traffic. Sweet! New toys! Anyway, this first example is not so much eye-opening in complexity, just an example of reaching a new layer in the stack with which to control. when FLOW_INIT { set ipaddr [IP::client_addr] set locale [whereis $ipaddr country] log local0. "IP Address/Counry $ipaddr/$locale" switch $locale { "US" - "CA" { return } "GB" { ACL::action drop } default { ACL::action reset } } } It's Not Me, It's You(r Old Domain) Redirection is well covered in Q&A, with just a thousand (give or take a few hundred) or so different angles on the topic. Community member Martin Thomas asked how to send a permanent redirection from the requested old domain to a new domain, but keeping parts of it. That's pretty easy to manually, but if you have a lot of domains to do this for, it becomes not only tedious in writing the iRule, but, if using if/else statements, could be inefficient as well. Thankfully, IheartF5 came to the rescue, with not one, but yes, you read this correctly, two fine solutions! Solution 1 This solution uses the getfield command, which is a custom iRules command that essentially performs an lindex-split operation from the native Tcl library. when HTTP_REQUEST { if {[HTTP::host] ends_with ".olddomain.com"} { HTTP::respond 301 Location "https://[getfield [HTTP::host] . 1].newdomain.com[HTTP::uri]" } } Solution 2 This other solution is a little more efficient that then other, using the old faithful string map command. Nice work, IheartF5! when HTTP_REQUEST { if {[HTTP::host] ends_with ".olddomain.com"} { HTTP::respond 301 Location "https://[string map {olddomain newdomain} [HTTP::host]][HTTP::uri]" } } Me Want Cookie...Not So Much Winning this blog's "shortest iRule of the post" contest is also from IheartF5, answering a question on how to expire a cookie from member Abhishek. Short. Sweet. Powerful. I've used this one myself from time to time. Note that the path information should probably be adjusted accordingly to your app's needs. when HTTP_RESPONSE { HTTP::header insert Set-Cookie "mycookie=xx; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; HttpOnly" } Technorati Tags: iRules,20 lines or less,20LoL279Views0likes2CommentsDevCentral Top 5 04/06/2012
It's not uncommon in the slightest for various members of the DC team to work on projects of all kinds. Whether it's helping with a customer issue or creating a new, sleek, efficient skin for the site - we all tend to wear many hats and work on many things. When all of us go quiet for a while, however, that is a sure fire sign that there are many "super sekrit squirrel" (tm) things afoot. And boy, is that the case. Things deep inside the skunk works of the DevCentral team's imagination station castle (What..you don't have a castle?) have been blazing hot with all sorts of madness the past month or more. We're hard at work banging out what we hope proves to be the next dose of hawesome for the community as a whole. That being said, it's times like this that I'm even more grateful than usual (and I'm usually darn grateful) for the extended team of DC contributors. They've carried the torch and then some, putting out some wicked cool blogs and making sure DevCentralites (DevCentralers?) have plenty to keep up on. To that end, allow me to foist upon you my most recent favorites that have come about in the past couple of weeks. Here is this week's DevCentral Top 5: F5 Friday: Are You One of the 61 Percent? https://devcentral.f5.com/s/weblogs/macvittie/archive/2012/04/06/f5-friday-are-you-one-of-the-61-percent.aspx Lori, in her usual educational manner, points out to us that 61% of people recently polled aren't confident in their network when it comes to being ready for making the jump to light speed err ... the cloud. This is due to a lot of factors, but one of the most prevalent is pure performance. It takes a heck of a lot of juice to keep things moving when passing data in the volumes that some enterprises and certainly service providers do. There are just too many bits and bytes to process, send, receive and otherwise handle. ADCs play an amazing role in lightening the load on the back end servers with caching, compression, SSL offload, straight-up page replacement and serving content, etc. But as the needs of the many increase, so too does the load put on that magic middle tier of networking goodness that helps the servers serve. It should come as a relief, and exciting, then that F5 is now offering full 40GBE support. Not only that, but we're the first ADC out there to do so. How? Why? When? What wizardry is this you ask? Read the post and be enlightened dear reader. It's a whole new web, and we're intent on helping you (and your users) get where they need to go faster than ever. TLS 1.2 for ssldump data decrypt revisited https://devcentral.f5.com/s/weblogs/david/archive/2012/03/29/tls-1.2-for-ssldump-data-decrypt-revisited.aspx There are some sure signs that we have smart people working here. The products, certainly, the white papers and presentations of course, but to me, as the geek that I am, one of the things that convinces me the most quickly are things like David Holmes contributing source to the ssldump tool so that it would support TLS 1.2 decryption. Come on...that's just plain cool. David submitted the original patch a while back, it got rolled in, and there was a bit of tweaking that needed to be done. Said tweaking has been...well...tweaked, and things are now decrypting as expected. So if you've already got it, get it again. If you don't, you should get it. ssldump is a handy tool in the ever more encrypted world we live in, and it's just one more sign of the wicked smart people we have working here to better our products, and by doing so your apps, that people like David are contributing to widely used tools like this. Go read, grab it, and enjoy your decrypted goodness. Web App Performance: Think 1990s https://devcentral.f5.com/s/weblogs/dmacvittie/archive/2012/03/16/web-app-performance-think-1990s.aspx Don has a way of using an analogy to depict things so they really resonate, at least with me. He's done it again with his commentary on web application performance. The reality of the matter is, things right now are fast. Really fast. Blazingly, painfully, unprecedentedly fast. We, as users, however...we still want more. Web application performance is only as good as the user's perception, after all, and we are greedy. When things take more than a second or two to load (or at least appear to), the average user starts to get antsy. This is especially problematic with the mobile browsing sector, which is growing more rapidly than anything else right now. Referencing Don's reference to a Louis CK bit, after a couple of seconds of waiting, the average denizen of the cell phone browsing sector will respond with "it.. it’s not working!”. The reality is, as Don so clearly depicted, try to imagine yourself in the 90s, on your cell phone, streaming high definition video while on the go. Yeah, I couldn't do it without laughing either. Things are faster, way, way faster, but there is still more we have to do in the ever present race to keep users happy. As perceptions become more and more demanding on just what "fast" is, we have to find new ways to tilt the game in our favor, as content suppliers. Don talks about some of those things, and more in this post. Go take a read, it's worth the time. 20 Lines or Less #55: Redirection, Masking and Auth https://devcentral.f5.com/s/weblogs/cwalker/archive/2012/04/06/20-lines-or-less-55.aspx Coming up for air a bit from the afore mentioned super sekrit squirrel things we've been working on as a team, I managed to get out a 20LoL today. There has been so much traffic coming through the forums I couldn't resist, just too much good stuff to not pass it on. This week I specifically focused on some super easy to consume, simple snippets. iRules may be a 7th dan black belt with fists of steel and the ability to hack through network based badness faster than Chuck Norris' roundhouse, but that doesn't mean that there aren't some easy, approachable ways to use iRules too. That is kind of where the 20LoL started, and I figured I'd dial it back a bit this week. The examples are still cool and useful, but might be a little less scary for those of you that haven't been in the dojo recently, working on your iRules fu. Take a look and see for yourself. The Challenges of SQL Load Balancing https://devcentral.f5.com/s/weblogs/macvittie/archive/2012/04/02/the-challenges-of-sql-load-balancing.aspx Last but not least, we finish how we started, with another awesome post from Lori's blog. In this one she specifically talks about SQL load balancing, which is something that is of a lot of interest to me. Well...to me and about 75% of the admins out there responsible for running a dynamic web application. So you know, a few of us. This is a bit of a sticky topic and there isn't a single silver bullet. We're getting there, we can do some of it, and the landscape is changing, but the devil is in the details, as always. Go read through the post as Lori puts it far better than I could here. Trust me, you'll learn something, or at least stop and think about how you are or want to do things. I did. There you have it, another Top 5 filled with enough DevCentral goodness to warm your hearts and spread your networking cheer far and wide. Feel free, as always, to comment, ask for specifics or the like. And check out past Top 5s easily on DevCentral. #Colin169Views0likes0Comments20 Lines or Less #46: DNS, RPC and Classes
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. Continuing the long standing tradition, this week’s 20LoL brings to you DNS lookups with variable resolvers, avoiding RPC issues with ASM, and some advanced pool selection logic by way of class searching. Thanks go out to user Kent Perrier, mbamusa and ichalis for the examples or inspiration. Now let’s get to the code: Advanced Pool Selection http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/aft/1177260/showtab/groupforums/Default.aspx Kent was looking for a way to dynamically select the pool to which traffic would be directed by searching through a class, but didn’t have much experience dealing with classes. Since he’s running v10.2.1 he gets to make use of the awesome class command for searching/matching, and was able to piece together his own solution pretty quickly with a little care and feeding by way of link sharing from the community. His iRule checks for the class, compares the beginning of the incoming URI with the entries from the class, and selects a pool based on the results.Here’s what he ended up with. when RULE_INIT { # Log debug to /var/log/ltm? 1=yes, 0=no set static::debug 0 } when CLIENT_ACCEPTED { # Save the VS default pool name before it's changed set default_pool "defpool01" # set the data group name set clname "AppVersion[virtual name]" } when HTTP_REQUEST { # if there isn't a data group with the above name, set the pool to default and exit if {[class exists $clname]} { # Search the datagroup for a name that starts with the URI set pool_name [class search -value $clname starts_with [HTTP::uri]] if { $pool_name eq ""} { # we don't match the context roots in the data class if { $static::debug } { log local0. "fell through to the default pool" } pool $default_pool } else { if { $static::debug } { log local0. "Matched $app_pool" } pool $app_pool } } else { if { $static::debug } { log local0. "Data group $clame not found, using default_pool $default_pool" pool $default_pool } } RPC avoidance and ASM http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/aft/1178414/showtab/groupforums/Default.aspx User mbamusa deals with OWA, ActiveSync, and Outlook anywhere through a single VIP. When putting ASM in front of this VIP to protect these applications he needed a way to send RPC traffic elsewhere or disable ASM somehow. Fortunately he’s on version 10.2.1 so he’s able to use the ASM::disable/ASM::enable commands, which makes this trivial. Not a difficult iRule, but something good to keep in mind that can solve a major problem with a simple solution. when HTTP_CLASS_SELECTED { if { [string tolower [HTTP::uri]] starts_with "/rpc" } { ASM::disable } else { ASM::enable } } Selective DNS lookups via iRules http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/afpg/2/aft/8487/showtab/groupforums/Default.aspx We’ve covered doing DNS queries via iRule before. The difference this time is that the requirement is to check one of two different resolvers, based on which is available. This is a pretty common concept, backup resolvers, so I figured it was worth noting here. The solution is pretty straight-forward (until RESOLV::lookup interacts properly with a VIP as a target, then it' gets dead simple) with a couple of variables and an if statement doing the tiny amount of lifting necessary. Again, a simple iRule, but a problem that’s tough to resolve otherwise. set status1 [LB::status pool member ] set status2 [LB::status pool member ] if {$status1 eq "up"} { set ips [RESOLV::lookup @$static::DNS_RESOLVER $host] set _ipaddress [lindex $ips 0] } elseif {$status2 eq "up"}{ set ips [RESOLV::lookup @$static::DNS_RESOLVER_BACKUP $host] set _ipaddress [lindex $ips 0] } #Colin241Views0likes0Comments20 Lines or Less #44: Redirecting, Re-encrypting, and TCP fun
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 I’ve got some cool forum examples including Chris Miller’s awesome example of doing a redirect, but in an interesting way that includes an iRule generated HTML page with an in-line meta refresh, some cool SSL re-encryption logic, and a look at how you can use TCP and node commands to send TCP requests. HTTP Redirect with Holding Page http://bit.ly/h7Sq9Q Chris whipped up a cool example of HTTP redirection. The user wanted to be able to send users to a holding page for a given amount of time before redirecting them. Using HTTP::respond, this was pretty straight forward. A very cool example of controlling the user experience via iRules. And yes, I’m cheating slightly by doubling up braces to get this one down to 20 lines (I’m also counting the HTTP::respond as one line since it technically is, it’s just continued on multiple lines for readability). Sue me, it’s a cool rule. ;) when HTTP_REQUEST { if { [TCP::local_port] eq "80" } { persist source_addr 1800 HTTP::fallback http://support.com/ if { [HTTP::host] == "www.domain.co.uk" or "www.domain.com" or "www.domain.org" } { HTTP::respond 200 content \ " Apology pagehttp://www.domain.com/aba/>\ We are sorry, but the site you are looking for is temporarily out of service. " "Content-Type" "text/html" } else { pool Web_Farm_Front } } elseif { [TCP::local_port] eq "443" } { HTTP::header insert "BPL-SSL" "On" pool Web_Farm_Front } else { set srvr [findclass [TCP::local_port] $::Individual_Servers " "] if { $srvr ne "" } { node $srvr 80 } else { HTTP::redirect "http://www.domain.net/" } } } Selective SSL Re-encryption http://bit.ly/eyfxbV Another Chris Miller special, this iRule shows a good way to take HTTP traffic, decrypt it, analyze it, send it to the appropriate pool, and then re-encrypt only some of that traffic as needed. It’s not going to solve the user’s problem, unfortunately, but that’s because of specific app requirements. It’s still a pretty cool piece of code. when HTTP_REQUEST { set usessl 0 switch -glob [string tolower[HTTP::path]] { "/main*" { pool beta__pool set usessl 1 } default { pool alpha_pool set usessl 0 } } } when SERVER_CONNECTED { if { $usessl == 0 } { SSL::disable } } TCP Out of Band Send on Pool Down http://bit.ly/fMAp79 Thanks to some good ideas from Aaron, I put together what I think is a pretty interesting iRule that should (it’s untested) allow you to check for all pool members of a particular pool to be down, and if that’s the case, send a TCP request off to a node of your choosing with a custom message as sort of an alert to notify that the pool is down. Hopefully this solves the user’s issue, but regardless I like the concept and I’m now looking for a place to try it out. when CLIENT_ACCEPTED { if {[active_members yourpoolname] == 0 } { TCP::collect } } when CLIENT_DATA { TCP::payload replace 0 [TCP::payload length] "down" node 10.10.10.1 12000 TCP::release } There you are, another few iRules that can get some solid work done in less than 21 lines. #Colin282Views0likes0Comments20 Lines or Less #41 - When spark flies
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 I’m happy to bring you some very cool iRules dealing with client access to admin sections of an application, strict RR Load Balancing, and client connection limiting. Moreover, I’m even more pleased that two of the examples in this episode are from spark himself, one of the core Developers responsible for making iRules do the magic that it does. It’s always fun getting to see what kind of kung fu he comes up with in the forums, and he certainly didn’t disappoint this week. Strict Round Robin LB http://bit.ly/bsNsPV In this first example, spark chimes in to help user AppleBee set up some strict round robin load balancing via iRules and the table command. This is a great example of how to build more rigid, precise controls when your application calls for them. In this manner, AppleBee is able to have exact control over where the requests are trying to go so that even if CMP is enabled the load balancing rotation doesn’t change. when CLIENT_ACCEPTED { set poolname "test-pool" if { [active_members $poolname] < 1 } { # No active pool members; reset client reject return } set count [members $poolname] set attempt 0 while { $attempt < $count } { set num [expr {[table incr "round-robin:$poolname"] % $count}] set mbr [lindex [members -list $poolname] $num] set mbr_ip [lindex $mbr 0] set mbr_port [lindex $mbr 1] if { [LB::status pool $poolname member $mbr_ip $mbr_port up] } { pool $poolname member $mbr_ip $mbr_port return } incr attempt } } Request filtering based on URL http://bit.ly/cGEaob Next, Chris Miller helps out another user by showing them a quick and easy way to restrict access to specific URLs by IP address. This is a simple way to make sure no unwanted guests are trying to visit the admin section of your site, viewing sensitive data, etc. when HTTP_REQUEST { if { [HTTP::host] eq "www.admin.mysite.com" and ![IP::addr [IP::client_addr]/24 eq 192.168.1.0] } { discard } } CMP Compatible Connection Limiting per Pool Member http://bit.ly/b3Lb0k Last but certainly not least is another sparkism (hmm, I think I just coined a new term) that shows off yet another use for the wonderfully powerful and handy table command. This time spark is wielding its power to show a way to limit the number of requests to each pool member. It’s surprisingly easy thanks to the table command and a little help from an after –periodic to help with matching the timer to the connection. Very cool stuff. when CLIENT_ACCEPTED { set key "[IP::client_addr]:[TCP::client_port]" } when LB_SELECTED { set tbl "connlimit:[LB::server]" table set -subtable $tbl $key "ignored" 180 if { [table keys -subtable $tbl -count] > 5 } { table delete -subtable $tbl $key event CLIENT_CLOSED disable reject } else { set timer [after 60000 -periodic { table lookup -subtable $tbl $key }] } } when CLIENT_CLOSED { after cancel $timer table delete -subtable $tbl $key } There we go, three more awesome iRules to put in your quiver that are less than 21 lines each. Thanks much to all those contributing in the forums, keep that goodness coming. #Colin227Views0likes0Comments20 Lines or Less #40 – SSL payload searching, user info and ACLs
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 we dive into parsing SSL encrypted payloads until a given string is found, logging user login info as it comes across the wire, and enforcing a subsite ACL. http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/afv/topic/aft/1172756/aff/5/showtab/groupforums/Default.aspx#1175124 In this first, rather cool, example from user mattrm we get a peek at how he’s dealing with logging user info as they log in by making use of the stream profile, STREAM::match command and regular expressions. when STREAM_MATCHED { # log each match found by the stream filter log local0. "Stream filter matched:[STREAM::match]" set myvar [STREAM::match] set 4 "blah" regexp {Username=(.+)\sUserpassword=(.+)\sUseremail=(.+)\sUserhomefolder=(.+)\s} $myvar matched sub1 sub2 sub3 log local0. "Username=[b64decode $sub1] Userpassword=[b64decode $sub2] Usermail=[b64decode $sub3]" } when LB_SELECTED { set serverIP [LB::server addr] log local0. "LB Server IP $serverIP" } http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/afv/topic/aft/1174268/aff/5/showtab/groupforums/Default.aspx Bhattman and Chris Miller tag team to answer a thread talking about creating a sub-site ACL and provides this cool little chunk of code. The idea is pretty simple, block access to a specific section of an app unless the client is coming from a specific list of IP addresses. The implementation is wonderfully simple, though, complete with an Access Denied-esque message straight from the iRule. when HTTP_REQUEST { if { [class match [string tolower [HTTP::uri]] contains subsite] and !([[string tolower [HTTP::uri]] contains "/admin/upload") and ![class match [IP::addr [IP::client_addr]] eq allow] } { HTTP::respond 200 content " Forbidden Redirect From Remote Server\Acess is forbidden" } } http://devcentral.f5.com/s/Community/GroupDetails/tabid/1082223/asg/50/afv/topic/aft/1174288/aff/5/showtab/groupforums/Default.aspx Last but never least, spark rolls up his sleeves and flexes an ounce of his iRuling muscle to show how easy it can be to collect SSL payload data until a given string is found. He even goes one step further to discuss the difference in functionality between the TCP::collect and SSL::collect commands and how the base functionality is similar but not identical. Definitely a cool one. when CLIENTSSL_DATA { if { [SSL::payload] contains "the query string" } { log local0. "I got the query!" SSL::release } else { SSL::collect } } There you have it, three more examples of iRules coolness in less than 21 lines of code each. See you soon for more iRuling goodness. #Colin298Views0likes0Comments20 Lines or Less #39 – Selective SSL, Port Stripping and Headers
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. With the onslaught of work required to get DC5 up and running it’s been a while since I’ve offered some cool iRule goodness to the community from the community. There have been plenty of examples cruising through the forums, that’s for sure, I just haven’t had the time to comb through all of them or write them up. Now that I can again see the light of day, allow me to share a some good ones with you. Disabling SSL to one backend pool We’ve looked at ways to selectively disable SSL before, but this example had an interesting twist that I thought was…well…interesting. The idea here is to selectively disable SSL only on the back end of the connection, not the entire thing. The client should always be encrypted but the server can, in some cases, be plain-text to try and cut down on overhead. Cool idea, and here’s a look at how to make it work, according to a good example by user Alok. when HTTP_REQUEST { set my_uri [string tolower [HTTP::uri]] if { $my_uri starts_with "/secure" } { pool ssl__pool } else { SSL::disable serverside pool static_pool } } Hash persistence based on true-client IP Here’s a user that’s trying to work around a limitation in the content distribution service they’re using. They want to use an iRule to perform hash based persistence based on a header supplied giving the client’s IP address. Hoolio, as is often the case, springs into action and whips up a nifty little example making use of lindex and active_members –list that gets the job done. # Check if the active_members command returns an entry which can be split on a space into two variables if {[active_members app_http_pool]}{ if {[scan [lindex [active_members –list app_http_pool] [expr {[md5 $tcip_header] % [active_members app_http_pool]}]] {%s %s} ip port] == 2}{ # Select the pool member IP and port pool app_http_pool member $ip $port # Exit from this event in this rule return } # Take some default action if the pool is down or scan didn't parse the output? } Removing port numbers from redirects If you’re looking to strip port locations from your redirects, then boy do I have the rule for you. Well, it’s not my rule, really, but I get to share more of Aaron’s work with you, which is a regular and enjoyable part of my jobs these days, it seems. The one man juggernaut has knocked out a quick little header replacement rule using string map and the fun HTTP::is_redirect command to get this job done. when HTTP_RESPONSE { if { [HTTP::is_redirect] } { if { [HTTP::header Location] contains "www.acme.com:10040" } { log local0. "Original Location value: [HTTP::header Location]" HTTP::header replace Location [string map -nocase {www.acme.com:10400 www.acme.com} [HTTP::header value Location]] } } } when HTTP_RESPONSE priority 501 { if { [HTTP::is_redirect] } { # Debug logging only. Remove this event once done testing log local0. "Updated Location value: [HTTP::header Location]" } } Check back next week for some more examples of awesome things you can do with iRules in only a few lines of code. #Colin208Views0likes0Comments20 Lines or Less #38 – Classes, Encryption Detection & Caching
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 we’ve got a couple awesome new examples from two of the community all-stars, and one dusty old example from my archives. They’re all cool and useful, so take a peek and see what you think. If you want a problem solved or to submit an example, feel free, I’m always looking for feedback or ideas for the 20LoL, just drop me a line. Class field parsing & updating Host info http://devcentral.f5.com/s/Default.aspx?tabid=53&forumid=5&postid=1171133&view=topic Matt shows off why they call him L4L7 in this example of how to use some iRules fu to match class contents, parse it and then act on it. The requirement was updating the host header inline, while maintaining the mappings of what to change and what to change it to in a class, and that gets done in style. when HTTP_REQUEST { #find a match using host+uri against the class and #returns the whole string (field1 field2 field3)then #set it as newURI variable. set newURI "[findclass [HTTP::host][HTTP::uri] $::redlist]" if { $newURI ne "" } { # Parse the three fields in the matched datagroup line scan $newURI {%s %s %s} unused host uri #change host and uri if {$host ne ""}{ HTTP::header replace Host $host } if {$uri ne ""}{ HTTP::uri $uri } } } HTTP connections over 443 http://devcentral.f5.com/s/Default.aspx?tabid=53&forumid=5&postid=1171154&view=topic For a look at how to gracefully handle non encrypted HTTP traffic over port 443 (you know, just in case) hoolio has you covered this week. Basically this inspects the traffic and if there was an SSL cipher used, redirects requests to “/” to the login page. If there is no cipher used, meaning the traffic is not encrypted but is still coming over port 443, any requested URI is redirected to the SSL enabled login page. Handy stuff. when HTTP_REQUEST { # Check if the client used an SSL cipher if {not ([catch {SSL::cipher version} result]) && $result ne "none"}{ # Client did use a cipher log local0. "\$result: $result. Allowing encrypted request." if {[HTTP::path] eq "/"}{ HTTP::redirect "https://[getfield [HTTP::host] : 1]/Login.jsp" } } else { # Client did not use a cipher log local0. "\$result: $result. Redirecting unencrypted request." HTTP::redirect "https://[getfield [HTTP::host] : 1]/Login.jsp" } } Selective browser caching Taking a trip in the way-back machine I decided to dig into my archives of cool iRule goodness for our third example this week. Here’s a little iRule that I acquired along the way somewhere (I’m not going to claim I wrote it, since I can’t remember if it was me or someone else) that was simple but useful. Create two classes of file extensions, one to be cached long term (jpgs, gifs, pngs, etc) and one to be cached for a much shorter duration (css, html, whatever) then easily tell the client’s browser how to handle each. when HTTP_REQUEST { set uri [HTTP::uri] } when HTTP_RESPONSE { if { [matchclass $uri ends_with $::cache_5min] } { HTTP::header replace "Cache-Control" "max-age=500" } elseif { [matchclass $uri ends_with $::cache_60min] } { HTTP::header replace "Cache-Control" "max-age=3600" } } That’s the 20LoL this week, thanks for playing. I’ll be back next week with more iRules goodness, so make sure to check back in. #Colin198Views0likes0Comments