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 #8
What could you do with your code in 20 Lines or Less? That's the question I ask every week, 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. For this week's 20LoL sampling I've dipped into my own private stash of iRule goodness. Some of these are oldies but goodies, one of them I actually just wrote yesterday as an example for Lori's Blog. As such the newly written example is the only one with a URI. The others will just have a description and the iRule source. I'm sure I'll be diving back into the Forums and CodeShare in the coming weeks as there just seems to be an endless stream of cool stuff to dig through out there, but I wanted to toss up a few of my own rules this week. Be gentle with comments, some of these are old as I said. ;) Content Scrubbing for Adobe Flash Exploit http://devcentral.f5.com/s/weblogs/macvittie/archive/2008/05/29/3309.aspx This iRule digs through the contents of the HTTP responses being sent out from your servers and looks for known exploit sites, then blocks those responses from going to your users. In this way it attempts to help protect them from the spread of the Adobe Flash exploit Lori's been talking about. when HTTP_RESPONSE { HTTP::collect } when HTTP_RESPONSE_DATA { switch -glob [string tolower [HTTP::payload]] { "*0novel.com*" - "*dota11.cn*" - "*wuqing17173.cn*" - "*woai117.cn*" - "*guccime.net*" - "*play0nlnie.com*" { HTTP::respond 200 content "The server is currently unable to serve the requested content. Please try again later." log local0. "Adobe Flash exploit infected Server IP: [IP::server_addr]." } } HTTP::release } IP Client Limiting via Array This iRule was written to deal with a very high-volume need for client limiting. By storing the IPs in an array and accessing them in the most optimized format I could come up with, this rule was able to stand up to some pretty impressive numbers. If memory serves it was somewhere near 200K connections per second with nearly 3 million concurrent connections. Not too shabby! when RULE_INIT { array set connections { } } when CLIENT_ACCEPTED { if { [info exists ::connections([IP::client_addr])] } { if { [incr ::connections([IP::client_addr])] > 1000 } { reject } } else { set ::connections([IP::client_addr]) 1 } } when CLIENT_CLOSED { if { [incr ::connections([IP::client_addr]) -1] unset ::connections([IP::client_addr]) } } Selective HTTPS Redirect This is a slight variant on a popular concept. This iRule does a selective redirect to HTTPS by checking a given class to see if the incoming URI is one that should be served via HTTPS. The neat part here is that it also does a port check and a preventative else statement, meaning this iRule should be able to be deployed on a global virtual, serving all ports, where most examples like this require the traffic to be broken up into two VIPS, port 80 and port 443, to avoid infinite looping. when HTTP_REQUEST { if { [TCP::local_port] == 80 } { log local0. "connecting on HTTP server" if { [matchclass [HTTP::uri] starts_with $::secure_uris] } { HTTP::redirect "http://[HTTP::host][HTTP::uri]" } } } So there you have it, another few examples of what can be done via iRules in less than 21 lines of code. This 20 LoL brought to you from my personal vault, so I hope you enjoy. As always, please let me know if you have any feedback, comments, questions, suggestions, musical recommendations or other pertinent information to share. See you next week. #Colin522Views0likes2Comments20 Lines or Less #1
Yesterday I got an idea for what I think will be a cool new series that I wanted to bring to the community via my blog. I call it "20 lines or less". My thought is to pose a simple question: "What can you do via an iRule in 20 lines or less?". Each week I'll find some cool examples of iRules doing fun things in less than 21 lines of code, not counting white spaces or comments, round them up, and post them here. Not only will this give the community lots of cool examples of what iRules can do with relative ease, but I'm hoping it will continue to show just how flexible and light-weight this technology is - not to mention just plain cool. I invite you to follow along, learn what you can and please, if you have suggestions, contributions, or feedback of any kind, don't hesitate to comment, email, IM, whatever. You know how to get a hold of me...please do. ;) I'd love to have a member contributed version of this once a month or quarter or ... whatever if you guys start feeding me your cool, short iRules. Ok, so without further adieu, here we go. The inaugural edition of 20 Lines or Less. For this first edition I wanted to highlight some of the things that have already been contributed by the awesome community here at DevCentral. So I pulled up the Code Share and started reading. I was quite happy to see that I couldn't even get halfway through the list of awesome iRule contributions before I found 5 entries that were neat, and under 20 lines (These are actually almost all under 10 lines of code - wow!) Kudos to the contributors. I'll grab another bunch next week to keep highlighting what we've got already! Cipher Strength Pool Selection Ever want to check the type of encryption your users are using before allowing them into your most secure content? Here's your solution. when HTTP_REQUEST { log local0. "[IP::remote_addr]: SSL cipher strength is [SSL::cipher bits]" if { [SSL::cipher bits] < 128 }{ pool weak_encryption_pool } else { pool strong_encryption_pool } } Clone Pool Based On URI Need to clone some of your traffic to a second pool, based on the incoming URI? Here you go... when HTTP_REQUEST { if { [HTTP::uri] starts_with "/clone_me" } { pool real_pool clone pool clone_pool } else { pool real_pool } } Cache No POST Have you been looking for a way to avoid sending those POST responses to your RAMCache module? You're welcome. when HTTP_REQUEST { if { [HTTP::method] equals "POST" } { CACHE::disable } else { CACHE::enable } } Access Control Based on IP Here's a great example of blocking unwelcome IP addresses from accessing your network and only allowing those Client-IPs that you have deemed trusted. when CLIENT_ACCEPTED { if { [matchclass [IP::client_addr] equals $::trustedAddresses] }{ #Uncomment the line below to turn on logging. #log local0. "Valid client IP: [IP::client_addr] - forwarding traffic" forward } else { #Uncomment the line below to turn on logging. #log local0. "Invalid client IP: [IP::client_addr] - discarding" discard } } Content Type Tracking If you're looking to keep track of the different types of content you're serving, this iRule can help in a big way. # First, create statistics profile named "ContentType" with following entries: # HTML # Images # Scripts # Documents # Stylesheets # Other # Now associate this Statistics Profile to the virtual server. Then apply the following iRule. # To view the results, go to Statistics -> Profiles - Statistics when HTTP_RESPONSE { switch -glob [HTTP::header "Content-type"] { image/* { STATS::incr "ContentType" "Images" } text/html { STATS::incr "ContentType" "HTML" } text/css { STATS::incr "ContentType" "Stylesheets" } *javascript { STATS::incr "ContentType" "Scripts" } text/vbscript { STATS::incr "ContentType" "Scripts" } application/pdf { STATS::incr "ContentType" "Documents" } application/msword { STATS::incr "ContentType" "Documents" } application/*powerpoint { STATS::incr "ContentType" "Documents" } application/*excel { STATS::incr "ContentType" "Documents" } default { STATS::incr "ContentType" "Other" } } } There you have it, the first edition of "20 Lines or Less"! I hope you enjoyed it...I sure did. If you've got feedback or examples to be featured in future editions, let me know. #Colin4.5KViews1like1Comment20 Lines or Less #83
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 do downright cool things in less than 21 lines of code. Poodle Mitigation but Can't Disable SSLv3 https://devcentral.f5.com/s/questions/poodle-mitigation-but-cant-disable-sslv3 Community member Christopher faced a situation where he could not disable SSLv3 for a clients in a certain IP range. I suggested a direction but his final solution was even more simple than the path I was encouraging him down. Nice job! when CLIENT_ACCEPTED { if { [class match [IP::client_addr] equals "sslv3_allowed"] } { SSL::profile sslv3_enabled } else { SSL::profile sslv3_disabled } } when HTTP_REQUEST { SSL::renegotiate } Rewrite a Part of the Query String https://devcentral.f5.com/s/questions/i-need-to-rewrite-a-portion-of-a-query-string-while-preserving-all-other-components-how-can-i-do-this Nitass takes advantage of the new write capability (as of version 11.5) in the HTTP::query command to help member jmartineau9 rewrite the query with an alternative query key. String map to the rescue! when HTTP_REQUEST { set qry [HTTP::query] set id [URI::query "?$qry" "id"] if { $id ne "" } { HTTP::query [string map [list id=$id entityid=$id] $qry] } } HSRP and VRRP Optimization https://devcentral.f5.com/s/wiki/iRules.HSRP_and_VRRP_SmartHOP_iRule_Optimization.ashx This rule has been around for a while in the codeshare, but I ran across it looking for something else and thought it warranted inclusion. Originally crafted by Michael Earnhart, I updated it for v10+ systems. Basically, it takes the virtual mac for a router pair from a data-group defined by an admin and sets the lasthop to that instead of the hardware mac the traffic originated from, alleviating black holed traffic during gateway failover events. when CLIENT_ACCEPTED { set entry [class lookup [format %s [LINK::lasthop]] RouterA] if { $entry ne "" } { lasthop [lindex $entry 1] [lindex $entry 0] } } And that's a wrap! Super powered functionality featured in less than 60 lines of code.493Views0likes0Comments20 Lines or Less # 42 – Secret list … OF DOOM
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 bring to you two cool iRules from the forums and one from a secret squirrel internal mailing list OF DOOM!!!. Okay, maybe not of doom, but it’s a list with some wicked smart people on it and I’m lucky to get to harvest good stuff out of there sometimes. We’ll cover handling HTTP and HTTPS on a single VIP, stream matching TCP data, and HTTP rate limiting with the table command in yet another variation. TCP Payload Matching and Logging http://bit.ly/efMH9z User mattrm was kind enough to post back to this thread started a few months back to show us exactly how he got this stream match solution working in his environment. A very cool example of how to search and replace a string in-line. In this case he’s dealing with straight TCP traffic, but just about any non encrypted traffic (including traffic decoded on the LTM) would work. Using the stream profile: @Username.*Userpassword=\n@@ : when STREAM_MATCHED { # log each match found by the stream filter scan [STREAM::match] "Username=%s" user log local0. "Username [b64decode $user] had password replaced" STREAM::replace "Username=$user\nUserpassword=0000=\n" } when LB_SELECTED { set serverIP [LB::server addr] log local0. "LB Server IP $serverIP" } Selective HTTP redirection based on SSL http://bit.ly/g6bCbG In this interesting iRule user Dave Hatfield is looking to redirect traffic that is not using SSL to an HTTPS link, while dealing with non SSL traffic differently, but on the same virtual and in the same iRule. That poses an interesting problem of identifying SSL vs non SSL traffic in a single virtual / iRule. There are a couple of ways to go about this, and I think he chose a solid one. Simple and easy to follow, yet effective. Cool stuff. when CLIENT_ACCEPTED { # Set a variable to track whether this is an HTTPS request set https 0 } when CLIENTSSL_HANDSHAKE { # There was a client side SSL handshake, so update the variable set https 1 } when HTTP_REQUEST { # Check if referrer is eschool if {!([HTTP::header "Referer"] starts_with "https://eschool.mysite.org/webapps/")}{ # If there is no URI redirect to portal if {[HTTP::path] eq "/" }{ HTTP::redirect "https://portal.mysite.org/eschool" } } if {not ($https)}{ # If it's not an HTTPS connection, send a redirect HTTP::redirect https://[HTTP::host][HTTP::uri] } } HTTP Request limiting via tables One of the engineers here at F5, Christian Koenning spawned a cool example iRule showing off how to achieve a stable 3000 requests per second threshold by making use of the table command and some logic inside an iRule. The illustrious Kirk Bauer then tweaked it a bit and twisted it into an HTTP example, which is what I’m posting below. when HTTP_REQUEST timing on { set request_limit_reached [ table lookup "request_limit_reached" ] if { [expr [table incr "counter_all_requests"] % 15] == 0 } { if { $request_limit_reached < 2 } { set request_limit_reached [ table incr "request_limit_reached" ] table timeout "request_limit_reached" 1 table lifetime "request_limit_reached" 1 } } if { $request_limit_reached >= 2 } { HTTP::respond 500 } } There we go, another three killer iRules in less than 21 lines. Thanks as always to the community for doing that thing you do. Keep on rockin’, and posting those iRules. If you have any questions or comments, never hesitate to drop me a line. #Colin341Views0likes1Comment20 Lines or Less #82
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 do downright cool things in less than 21 lines of code. iRule to Stop SSLv3 Connections https://devcentral.f5.com/s/articles/irule-to-stop-sslv3-connections This iRule is pertinent for protecting your back end servers from POODLE attacks for ssl traffic delivered through but not terminated on the BIG-IP. As usual, Jeff Costlow is all over these various ssl vulnerabilities. when SERVER_CONNECTED { set Debug 1 set Collect_Len 3 TCP::collect $Collect_Len } when SERVER_DATA { set Buf_Len [TCP::offset] if { $Buf_Len < 3 } { incr Collect_Len -$Buf_Len TCP::collect $Collect_Len return } binary scan [TCP::payload] cS Rec_Type Version if { $Version <= 768 } { log local0. "stop_ssl3: Rejecting SSL3 or lower connection attempt from [IP::client_addr]" reject } else { TCP::release } } Select Pool Based on Http Payload https://devcentral.f5.com/s/questions/how-to-select-pool-based-on-http-payload- This is slick. Sergio is taking post data to select pools. Not sure if this is for a better level of service, or for heightened security screening, but a really useful scenario none the less. The astute among you will notice that there are 22 lines instead of 20. Well, Colin's rules don't count the lines wasted by a single bracket, so I'm just toeing the line here. Take it up with Colin! when HTTP_REQUEST { if { ([HTTP::method] eq "POST") } { HTTP::collect [HTTP::header Content-Length] } } when HTTP_REQUEST_DATA { set decoded [decode_uri [HTTP::payload]] set ini [string first "\"idBiller\"" $decoded] if { $ini != -1 } { set end [string first "," $decoded $ini] set value [string range $decoded $ini [expr {$end-1}]] set idBiller [lindex [split $value ":"] 1] switch -exact $idBiller { 11111111 { pool Pool_XXX } default { pool Pool_YYY } } } } iRule Environment Variables https://devcentral.f5.com/s/questions/irule-environment-variables-any This might be a first, in that there isn't really an iRule featured here. But the concept is important, so I'm breaking rank. Jie asked about environment variables. THi weighed in with one, but here's the comprehensive list of tcl_platform options. $static::tcl_platform(os) $static::tcl_platform(osVersion) $static::tcl_platform(tmmVersion) $static::tcl_platform(byteOrder) $static::tcl_platform(platform) $static::tcl_platform(wordsize) $static::tcl_platform(machine) cpu Another useful set of commands not directly environment variables but system related are in the TMM namespace. TMM::cmp_cluster_primary TMM::cmp_count TMM::cmp_group TMM::cpm_unit And that's a wrap! Super powered functionality featured in less than 60 lines of code.355Views0likes1Comment20 Lines or Less #80
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 do downright cool things in less than 21 lines of code. Restricting Access to VIP Restrict users from browsing directly to VIP BIG-IP is built to deliver traffic. Yes, it's a default deny device, but once you configure a vip, traffic that matches will flow until you set a policy to restrict it. John asked if it was possible to make sure requests to a certain vip are targeting the fqdn, not the IP. This is a simple problem that has several solutions, two of which are detailed in the post above and are just a few lines actually. Rather than share those here, I thought I'd point out a third solution that doesn't require iRules at all, and is still 20 lines or less! (Ok, busted. It's 24 lines or less. But the real good squishy stuff, the RULES, are 20 lines or less, so let's all play nicely here and pretend the rules don't matter.) This LTM policy aligns with Hamish's iRules solution, checks to see if the specified fqdn is present in the host header and resets the connection if not. ltm policy http.redirects { controls { forwarding } requires { http } rules { require_fqdn { actions { 0 { forward reset } } conditions { 0 { http-host host not values { my.domain.com } } } ordinal 1 } } strategy all-match } Select ASM Policy by Charset? iRule for selecting ASM policy There currently isn't an iRule solution on this thread, but member MiLK_MaN suggested a vip targeting vip solution where the analysis could be done on the front vip and the traffic direction done in the iRule to select a variety of back end vips. Continuing the theme of policies, however, I can get the details of one of these charsets handled in less than 20 lines as well. Based on the presence of the request header Accept-Charset, the ASM policy will be selected to match the charset. Note you will also need a default case specified. The full policy is posted on this thread linked above. win1252 { actions { 0 { asm enable policy /Common/asm_win1252_policy } } conditions { 0 { http-header name Accept-Charset values { Windows-1252 } } } ordinal 1 } Adding a Port to the Host Header How to redirect from port to another port and to hide the port from the url of client side? And the award for wordiest title in a question goes to....Mahmoud! I kid, I kid. Buried in the obscure title is a slick one liner header replacement (complete with two lines of event wrapper.) Please note that the HTTP::host command will return a non-standard port. So if you request http://my.domain.com:9000, the host header would have a value of my.domain.com:9000, but if you request standard http/https, the port is not included. when HTTP_REQUEST { HTTP::header replace Host "[HTTP::host]:9000" }285Views0likes0Comments20 Lines or Less #75: URIs, URIs and more 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. One of the most common things manipulated by iRules out in the wild is the Host or URI HTTP header values. This is done for a myriad of reasons ranging from routing to obfuscating portions of an application to… you name it. Given that it’s so common amongst iRulers worldwide it’s noshock that I managed to track down three recent examples of people doing URI-ish things with iRules. So in the first of what I hope to be several“themed” 20 Lines or Less installments, here are three ways that people are using iRules to handle their URI needs. Lowercase URI https://devcentral.f5.com/s/questions/lowercase-uri Ensuring that comparisons are done in a single case is one of those basic but super important things that we all do when we’re writing code. As such precisely no one is surprised that it’s also extremely common, and important, in iRules. The string command has a tolower function that takes care of this for us in TCL. Making sure we’re only using it when and how we want, however, sometimes takes inspection of the URI. In this case the OP was looking for a way to only modify the URI for any incoming “.aspx” requests. The below iRule should was the solution posted by a helpful community member that should get them there. Note the handy "Only re-write if the URI contains uppercase characters" logic with string match to prevent recursion! Tasty. when HTTP_REQUEST { if { ([string match {[A-Z]} [HTTP::uri]] and [[HTTP::path] ends_with ".aspx"])} { set hostname [string tolower [HTTP::host]] set uriname [string tolower [HTTP::uri]] log local0. "Request is $hostname$uriname" HTTP::redirect "http://$hostname$uriname" } } Append Text to a URI https://devcentral.f5.com/s/questions/append-text-to-a-uri Apart from inspecting the URI and modifying case, modifying the actual contents of the URI is the next most common action on my completely unofficial or scientific list of “Things User do with URIs”. As such, here’s a simple example of a user conditionally appending a slash to the inbound URI. when HTTP_REQUEST { if {!([HTTP::path] ends_with "/")} { HTTP::path "[HTTP::path]/" HTTP::redirect [HTTP::uri] } } Switch on HTTP::host and HTTP::uri https://devcentral.f5.com/s/questions/how-to-use-an-irule-switch-to-match-httphost-and-httpuri Sliding ever so slightly higher on the “How scary can URIs actually be?” scale (Hint: the answer is generally ‘not very scary…mostly’) we have a user looking to perform a switch on a Host/URI combo. Still not tough, but super handy and worth seeing in case you’re new or rusty, this switch will give you the full host/uri/path of the inbound request and let you take separate actions on any particular match. when HTTP_REQUEST { switch -glob [string tolower [getfield [HTTP::host] ":" 1][HTTP::uri]] { "www.liveapp.customer.co.uk/app2easypath_" { HTTP::path [string map { /app2easypath /realpath } [HTTP::path]] }; SSL::disable serverside; pool CUST1-WEB-PROD-APP2-Pool; } "www.testapp.customer.co.uk/app2easypath_" { HTTP::path [string map { /app2easypath /realpath } [HTTP::path]] }; SSL::disable serverside; pool CUST1-WEB-PROD-APP2-test-Pool; } default { HTTP::redirect http://www.google.com} } } }890Views0likes5Comments20 Lines or Less #79
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 do downright cool things in less than 21 lines of code. Logging Client IP in NAT Scenarios BIG-IP 11.3.1 LTM connection session logs to syslog server This is a common question, but typically, the problem is solved in-line with header replacement, or even fancier solutions like embedding IPs in tcp options and such. For this case, member Tabish is content to just have the data offline in log files as the app developers don't want to modify the header. This can be logged in several ways, and two were proposed as answers. One was to log to the local syslog instance (that can also be configured to log off box) and the other was to use high speed logging. when HTTP_REQUEST { set host [HTTP::host] set username [HTTP::username] set client_IP [IP::client_addr] set request "\"[HTTP::method] [HTTP::uri] HTTP/[HTTP::version]\"" set request_time [clock clicks -milliseconds] set referer [HTTP::header "Referer"] set ua [HTTP::header "User-Agent"] set xff [HTTP::header "X-Forwarded-For"] } when HTTP_RESPONSE { set response_time [expr [clock clicks -milliseconds] - $request_time] set now [clock format [clock seconds] -format "%d/%b/%Y:%H:%M:%S %z"] set contentlength [HTTP::header "Content-Length"] set status [HTTP::status] HSL::send [HSL::open -proto TCP -pool /CLI01_COPR/POOL_SYSLOG] "$host $client_IP $username $now $request $status $contentlength \"$referer\" \"$ua\" \"$xff\" $response_time" } Reverse Proxy iRule for a reverse Proxy This iRule solution would qualify for 5 Lines or Less, if such a series existed! Member Nikhil is just looking for reverse proxy support, with the BIG-IP handling host and uri rewriting. Simple task, provided in two forms in the thread, which I've combined into a form you can use on all systems version 10.0+, though in reality, one or the other is sufficient for the version you have and eats less memory. I just wanted an opportunity to show off the infrequently used tcl_platform command! Hit the link above for the primitives for each version. when HTTP_REQUEST { set ver tcl_platform(osVersion) if { ($ver starts_with "11.5") or ($ver starts_with "11.6") { HTTP::host "nik-int.test.com" } else { HTTP::header replace Host "nik-int.test.com" } HTTP::uri "/media[HTTP::uri]" } A Walk in the Park with the Stream Profile STREAM::EXPRESSION and characters that may not allow a match Member Steve was stuck on a stream expression not exactly matching properly. Nitass shared an example escaping the question marks (in the static::search variable) and it worked a treat. when RULE_INIT { set static::search "http://web.site.com/fd/qalogon.php\\?groupid=aaa_library&using sql35\\?=" set static::replace "http://new.site.com:8080/share/page/site/directory/dashboard" } when HTTP_REQUEST { STREAM::disable HTTP::header remove "Accept-Encoding" } when HTTP_RESPONSE { if {[HTTP::header value Content-Type] contains "text"}{ STREAM::expression @${static::search}@${static::replace}@ STREAM::enable } }254Views0likes0Comments20 Lines or Less #78: Host confirmation, Message LB, and CNAME Mods
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. Verify Host Header and Request URL Match https://devcentral.f5.com/s/questions/verify-host-header-and-request-url-match User “Server.Team” – no seriously, that’s the user, which makes me feel like maybe we are solving the problems of every server team everywhere, all at once – has an issue that is a bit troublesome. You see, their SharePoint installation is a bit…accessible, for their tastes. Specifically there is no restriction on the hostname requested when accessing SharePoint in their deployment. This means that, were a user to be disgruntled, they could whip up a custom hostname pointing to the known SharePoint IP address via a host entry and wreak all forms of havoc. The bad kind of havoc. To prevent something like this all they were looking for was a way for BIG-IP to ensure that the host name actually is what it’s supposed to be for a request inbound on SharePoint's IP address in their system. A super simple thing to do in an iRule but apparently, under the right circumstances, extremely useful. So here you go, in case something like this might apply in your world. if {not ([HTTP::host] eq "www.example.com")} { reject } One Virtual, Many Ports https://devcentral.f5.com/s/questions/ltm-with-virtual-server-with-pool-member-listensing-on-different-port-numbers Here’s a darn cool example brought about by a question from user karan12. The idea is that they want to be able to have a single virtual server that rations out traffic to nodes listening on different ports, based on the inbound URI. This is possible, assuming you’ve got the right options selected (such as OneConnect), and have a fancy iRule in place like this one. Very handy message based load balancing setup in a simple package. Take a peak and store this one on the shelf for later. when HTTP_REQUEST { switch -glob [string tolower [HTTP::uri]] { "*hypplanning*" { node 10.x.x.x%x:x } "*drmservice*" { node 10.x.x.x%x:y } } } Limited CNAME Modification https://devcentral.f5.com/s/questions/irule-trouble-dns_request Looking to re-write DNS responses for a particular subnet? Have I got the iRule for you. User Jessica asked for something simple to help them ensure traffic from their 192.168.1.0/24 network was getting different responses than the rest of the world for a particular CNAME. That’s not a tall order as long as you’ve got iRules working for you. Here’s a look at the simple chunk of code that’ll accomplish just that. Alternatively, or if you’re looking to do modifications for more than one subnet, you could build out the code to read from a datagroup quite easily. when DNS_REQUEST { if { [IP::addr [IP::client_addr] equals 192.168.1.0/24] } { cname www.redirect.domain.ipn.mx } }299Views0likes0Comments