iRules
449 TopicsConditional XOR operations
I was working on an iRule that only needed an OR if I didn’t reverse the logic on of them. But when I looked at the original problem, it needed one condition or the other but not both. You can nest conditionals to accomplish this, but I wanted an XOR operator, and Tcl doesn't have one at the string level, only with bitwise operations. So here is what that looks like in a truth table, where A could be an IP address range, B could be a hostname, and Q would be the truth condition. A B Q 0 0 0 0 1 1 1 0 1 1 1 0 In an iRule, this would look like this structurally (but you would need to add your comparisons for each A/B variable to whatever makes them true: if { ($a || $b) && !($a && $b) } { # act on the XOR true condition } else { # act on the XOR false condition }45Views0likes0CommentsGTM return LDNS IP to client
Problem this snippet solves: We do a lot of our load balancing based on topology rules, so it's often very useful to know where the DNS request is actually coming from rather than just the client's IP and the DNS servers they have configured. Especially if they're behind an ADSL router doing NAT or some other similar set up. This rule simply returns the IP address of the LDNS that eventually made the query to the GTM device in the response to a lookup for the WideIP using the rule, as well as logging the response and perceived location. Code : rule "DNS_debug" partition "Common" { when DNS_REQUEST { host [IP::client_addr] log local0.err "Debug address : [IP::client_addr] [whereis [IP::client_addr]]" } }868Views1like2CommentsProxy Protocol v2 Initiator
Problem this snippet solves: Proxy Protocol v1 related articles have already been posted on DevCentral, but there is no v2 support iRule code available. A customer wanted to support Proxy Protocol v2, so I wrote an iRule code for supporting v2. Proxy protocol for the BIG-IP (f5.com) How to use this snippet: Back-end server must handle Proxy header prior data exchange. Code : when CLIENT_ACCEPTED { # DEBUG On/Off set DEBUG 0 set v2_proxy_header "0d0a0d0a000d0a515549540a" # v2 version and command : 0x21 - version 2 & PROXY command set v2_ver_command "21" # v2 address family and transport protocol : 0x11 - AF_INET (IPv4) & TCP protocol set v2_af_tp "11" # v2 Address Size : 0x000C - 12 bytes for IPv4 + TCP set v2_address_length "000c" # Get TCP port - 2 byte hexadecimal format set src_port [format "%04x" [TCP::client_port]] set dst_port [format "%04x" [TCP::local_port]] # Get Src Address and convert to 4 byte hexadecimal format foreach val [split [IP::client_addr] "."] { append src_addr [format "%02x" $val] } # Get Dst Address and convert to 4 byte hexadecimal format foreach val [split [IP::local_addr] "."] { append dst_addr [format "%02x" $val] } # Build proxy v2 data set proxy_data [binary format H* "${v2_proxy_header}${v2_ver_command}${v2_af_tp}${v2_address_length}${src_addr}${dst_addr}${src_port}${dst_port}"] if { $DEBUG } { binary scan $proxy_data H* proxy_dump log local0. "[IP::client_addr]:[TCP::client_port]_[IP::local_addr]:[TCP::local_port] - proxy_data dump : $proxy_dump" } } when SERVER_CONNECTED { TCP::respond $proxy_data }245Views2likes0CommentsFQDN nodes in non-default route domains
Problem this snippet solves: Currently there is no support for FQDN nodes in non-default route domains as per Article. With recent increase in cloud deployment, most of the time there is a requirement from F5 to load balance to servers or ELB in the cloud which has FQDN names as those are having dyanamic IP addresses. If you are using route domains in your BIGIP environment then this becomes a challenge. Below iRule script can be used in those scenerios to use F5 to send traffic to FQDN nodes in non-default route domains. How to use this snippet: If FQDN needs to be resolved by your internal DNS, create performance layer 4 VIP (dns_53) load balancing your DNS servers. DNS server can be used directly in the iRule itself, but it would be better to use a VIP to have redundancy. Create iRule and apply to the VIP Code : when CLIENT_ACCEPTED { set host [RESOLV::lookup @dns_53 "server.example.com"] set ip [getfield $host " " 1] node [lindex $ip 0]%<Rd> 443 } Tested this on version: 14.11.4KViews1like3CommentsBlock IP Addresses With Data Group And Log Requests On ASM Event Log
Problem this snippet solves: This is Irule which will block IP Addresses that are not allowed in your organization. instead of adding each IP Address in Security ›› Application Security : IP Addresses : IP Address Exceptions you can create a data group and use a simple IRULE to block hundreds of Addressess. Also,createing a unique signature to specify the request of the illigile IP Address. First, You will need to create Data Group under Local Traffic ›› iRules : Data Group List and add your illigile IP Addresses to the list. If you have hundreds of IP's that you want to block, you can to it in TMSH using this command: TMSH/modify ltm data-group internal <Data-Group-Name> { records add {IP-ADDRESS} } Now, We are ready to create the IRULE under Local Traffic ›› iRules : iRule List Last, Create violation list under Security ›› Options : Application Security : Advanced Configuration : Violations List Create -> Name:Illegal_IP_Address -> Type:Access Violation -> Severity:Critical -> Update Don't forgat to enable trigger ASM IRULE events with "Normal Mode" How to use this snippet: Code : when HTTP_REQUEST { set reqBlock 0 if { [class match [IP::remote_addr] equals ] } { set reqBlock 1 # log local0. "HTTP_REQUEST [IP::client_addr]" } } when ASM_REQUEST_DONE { if { $reqBlock == 1} { ASM::raise "Illegal_IP_Address" # log local0. "ASM_REQUEST_DONE [IP::client_addr]" } } Tested this on version: 13.01.6KViews1like5CommentsDNS Query Name Parsing iRule
Problem this snippet solves: This iRule will extract the DNS Query Name in the absence of a DNS profile being applied to a Virtual Server. How to use this snippet: # This is a shameless rip from an old Devcentral post DNS Hostname Parsing iRule that, to the best of my knowledge, never made it to a Code Share. To use this code, simply apply this to a UDP Virtual Server that processes DNS traffic. (No DNS Profile necessary). Code : when FLOW_INIT { #extract QNAME from QUESTION header #${i} is a sanity check so this logic won't spin on invalid QNAMEs set i 0 #initialize our position in the QNAME parsing and the text QNAME set offset 12 set length 1 set endlength 1 set name "" #/extract QNAME from QUESTION header while {${length} > 0 && ${i} < 10} { #length contains the first part length binary scan [string range [DATAGRAM::udp payload] ${offset} ${offset}]] c foo #make the length an unsigned integer set length [expr {${foo} & 0xff}] if {${length} > 0} { #grab a part and put it in our text QNAME section append name [string range [DATAGRAM::udp payload] [expr {${offset} + 1}] [expr {${offset} + ${length}}]] #Watch the DNS QNAME get built during the loop. Remove the following line for production use. log local0.info "BUILDING DNS NAME: [IP::client_addr] queried ${name} offset ${offset} length ${length}" #grab a part and put it in our text QNAME section set offset [expr {${offset} + ${length} +1}] #endlength contains the Last part length binary scan [string range [DATAGRAM::udp payload] ${offset} ${offset}]] c foo #make the length an unsigned integer set endlength [expr {${foo} & 0xff}] if { ${endlength} > 0} { #put a dot between parts like a normal DNS name append name "." } incr i } } #/extract QNAME from QUESTION header #Input the required action here, where "${name}" is the variable that is reviewed for decision making. #Sample action would be a pool statement. The below log statement should be removed for production use. log local0.info "FINAL DNS NAME: [IP::client_addr] queried ${name}" } Tested this on version: 12.1662Views2likes1CommentSession Table Export
Problem this snippet solves: This sample goes along with the Tech Tip titled Session Table Exporting With iRules . It creates a mechanism for you to export the data from your session tables for archiving or external reporting. NOTE: This functionality is included in the Session Table Control iRule and is partially rendering here so it has been removed.737Views0likes3CommentsSession Table Control
Problem this snippet solves: This sample goes along with the Tech Tip titled Session Table Control With iRules . It creates an iRules-based HTML application to allow you to view, edit, delete, import, and export your session subtable data. How to use this snippet: Apply to a virtual server with session table entries and you can import/export/edit/delete entries. Code (GitHub gist)1.4KViews0likes5CommentsAnchor Link Redirect
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description This code snippet can be used to interact with links that contain a hash sign (anchor link). Problem solved by this Code Snippet Links in websites that contain a hash sign will not be send from the browser to the server if they are used. That makes it impossible to match them in an iRule, because the F5 will never receive them. This code snippet injects a little bit of javascript and will redirect the browser to the F5 when a user clicks on a link that contains a hash sign. How to use this Code Snippet Attach the iRule to a server that has a STREAM-profile enabled. Modify the iRule to your needs. Code Snippet Meta Information Version: 1.0 Coding Language: TCL when HTTP_REQUEST { # Disable the stream filter by default STREAM::disable # LTM does not uncompress response content, so if the server has compression enabled # and it cannot be disabled on the server, we can prevent the server from # sending a compressed response by removing the compression offerings from the client HTTP::header remove "Accept-Encoding" if { [HTTP::uri] starts_with "/f5/anchor_link_redirect" } { set href [b64decode [URI::query [HTTP::uri] href]] HTTP::respond 200 content "<html><head><title>Anchor Link Redirect</title></head><body>User clicked on link that contains a hash sign: $href</body></html>" } } when HTTP_RESPONSE { if { ([HTTP::header "Content-Type"] starts_with "text/html") } { STREAM::expression {@</title>@</title> <script> document.addEventListener(`click`, e => { const origin = e.target.closest(`a`); if (origin && origin.href.indexOf('#') > -1) { const base64_href = btoa(origin.href); window.location.href = '/f5/anchor_link_redirect?href=' + base64_href; } }); </script>@} STREAM::enable } }407Views0likes0CommentsAPM Kerberos Auth or fallback to another authentication method
Problem this snippet solves: This iRule can be used when it is required to offer both Kerberos authentication and for example SAML or another authentication method in a mixed environment for devices that are domain joined and devices that are not domain joined. This iRule uses javascript and HTML5 Web Workers to determine if the browser can successfully authenticate by using Kerberos or will need to fallback to another authentication method. I've been testing this iRule with Internet Explorer, Edge, Firefox and Chrome. All these browsers seem to be working fine. Only Chrome seems to do things a bit differently and is showing a login prompt for a split second, but it's working. How to use this snippet: The screenshot below shows an example of an Access Policy that uses either Kerberos or SAML authentication. The first agent in the policy is an 'Empty Agent' which will read the session.custom.domainjoined variable to determine which authentication method to use. The session.custom.domainjoined variable is set by the kerberos_auth_or_fallback_auth iRule. Tested this on version: 13.0 Link to iRule https://github.com/nvansluis/f5.kerberos_auth_or_fallback_auth726Views1like0Comments