Simple Sideband - iRule sideband the easy way

Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’.

Short Description

Simple Sideband is a helper iRule which makes getting started with doing iRule based sideband fast and simple. 

Problem solved by this Code Snippet

Sideband can be difficult to get started - it requires knowledge of low-level networking, using the Sideband iRule commands, or possibly the HSSR plugin to do HTTP parsing for you. With simple sideband, you can add the iRule as a library and call the functions to do the hard work for you.

How to use this Code Snippet

Imagine you want to query a web server from your irule, you install the Simple Sideband iRule library on the platform as /Common/simple_sideband and use and iRule on your virtual server which calls the library like so:

 

when HTTP_REQUEST {
    # Create HTTP request
    set response [call /Common/simple_sideband::http_req 10.67.182.10:80 "/" {} ]
    if { [lindex $response 0] == 200 } {
        HTTP::respond 200 content $response
    } else {
        HTTP::respond 500 content $response
    }
}

 

Example output:

 

200 {Server BigIP Connection Keep-Alive Content-Length 20} {hello world! port:80}

 

You can easily access the response status code, the headers and the body with a few lines of code.

Or you may want to send a DNS request:

 

when HTTP_REQUEST {
    # Create DNS request
    set q [call /Common/simple_sideband::dns_query "www.example.com" ]
    binary scan $q H* qhex
    log local0.debug "query:$qhex"
    # Send request to DNS server
    set response [call /Common/simple_sideband::udp_req 10.67.182.10:53 $q {recv_bytes 1} ]
    if { [lindex $response 0] == 0 } {
        # Successful response - decode the DNS esponse
        set data [lindex $response 1]
        binary scan $data H* data_hex
        log local0.debug "Success!: $data_hex"
        set r [call /Common/simple_sideband::dns_response $data ]
        HTTP::respond 200 content $r
    } else {
        HTTP::respond 500 content {failure}
    }
}

 

Output:

 

# curl 10.67.182.40
{18766 32776 1 1 0 0} {www.example.com 1 1} {{1 1 12 1.2.3.4}} {} {}

 

Logs:

 

Jul 14 08:54:26 simple-sideband-bigip1.pwhite debug tmm[30491]: Rule /Common/sideband_test <HTTP_REQUEST>: query:494e0008000100000000000003777777076578616d706c6503636f6d0000010001
Jul 14 08:54:27 simple-sideband-bigip1.pwhite debug tmm[30491]: Rule /Common/sideband_test <HTTP_REQUEST>: Success!: 494e8008000100010000000003777777076578616d706c6503636f6d0000010001c00c000100010000000c000401020304

 

To download the code, to see the options and detailed examples, go to my Github page at Simple-Sideband 

Code Snippet Meta Information

  1. Version: v11+ 
  2. Coding Language: iRules
Published Jul 18, 2023
Version 1.0
  • xuwen  to clarify, this isn't trying to be httpdns. It is just doing sieband and it is simpler for me to call it using curl. Creating and handling JSON in iRules is also not simple so the procedure will respond in TCL and you can then create a JSON wrappper around that if required.

  • xuwen you are correct - the dns_query and dns_response functions only support A requests. To be honest, I included them as a way to demonstrate UDP functionality and how to create packets using binary format. You can easily modify the request by changing the QTYPE to be AAAA which is 28 [ List_of_DNS_record_types ]  - it is currently A, which is 1.  I suspect that dns_response may work anyway because the A and AAAA RR are formatted similarly, though you'd have to try it out yourself.

    I was considering adding more DNS functionality but it is difficult to add functionality while also keeping it simple to use. If i hear of other people requiring AAAA I may add it anyway, so watch this space!

  • CA_Valli the way that i restrict the helper virtual server is that I enable VLANs, and do not add any entries. In which case it is not listening on any VLANs. I normally assign it to some random TCP port as the ip address and port are never used. You can see that in my helper VS here 

    ltm virtual https_helper {
        destination 0.0.0.0:search-agent <-- address and port are irrelevant
        ip-protocol tcp
        mask 255.255.255.255
        pool https_pool
        profiles {
            http { }
            serverssl {
                context serverside
            }
            tcp { }
        }
        serverssl-use-sni disabled
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address enabled
        translate-port enabled
        vlans-enabled <--- VLANs enabled, but none set
    }
  • Thanks for sharing this. Can you please point out the main differences between this and the HSSR?

  • xuwen's avatar
    xuwen
    Icon for Cumulonimbus rankCumulonimbus

    After checking the source code, it seems that it does not support dns type AAAA dns answers IPv6 parsing

  • Thanks for sharing! I still have to test the code, but I'm guessing it should be possible to restrict vs_helper access, correct? I'm guessing only localhost/TMM should be calling it

  • Hi Juergen_Mang , the differences between this and HSSR is that this has less HTTP functionality, but is simpler to use and covers other UDP and TCP protocols. For instance, you can use it to perform a DNS query, interact via Telnet, FTP or suchlike. It assues that you will build the required functionality yourself, or assign F5 Professional Services to do so. For example, HSSR supports forms, tags, charsets, proxies, redirections, cookies, caching and many other HTTP-related features. Simple Sideband leaves you to do this by presenting the basic information - you manage cookies yourself based on the response headers.

  • xuwen I have now added the ability to set the query type in the dns_query function. 

    when HTTP_REQUEST {
        # Create DNS request
        set q [call /Common/simple_sideband::dns_query "www.example.com" 28 ] <-- set qtype to be 28 ie AAAA
        binary scan $q H* qhex
        log local0.debug "query:$qhex"
        # Send request to DNS server
        set response [call /Common/simple_sideband::udp_req 10.67.182.10:53 $q {recv_bytes 1} ]
        if { [lindex $response 0] == 0 } {
            # Successful response - decode the DNS esponse
            set data [lindex $response 1]
            binary scan $data H* data_hex
            log local0.debug "Success!: $data_hex"
            set r [call /Common/simple_sideband::dns_response $data ]
            HTTP::respond 200 content $r
        } else {
            HTTP::respond 500 content {failure}
        }
    }
  • xuwen's avatar
    xuwen
    Icon for Cumulonimbus rankCumulonimbus

    I think it's best to parse the dns response and return it in a readable JSON format when doing httpdns. The visualization of TCL's list mode is too poor,I have also written before about httpdns that return the JSON results below. Using TCL iRules or (tcl iRules + iRulesLX), a domain name request seems to http response have a delay of 100+ms(Viewing HTTP response time using browser F12), which is a bit high. The commercial version of httpdns is only below 30ms, and I think it may be a problem with the TCL language, especially the latency loss of sideband

     

     

     

    curl 'http://203.107.1.33/100000/d?host=www.taobao.com&query=4,6'
    {
        "ipsv6": [
            "240e:960:c00:5:3:0:0:3c8",
            "240e:960:c00:5:3:0:0:3c7"
        ],
        "host": "www.taobao.com",
        "client_ip": "101.83.47.9",
        "ips": [
            "106.227.21.185",
            "106.227.21.184"
        ],
        "ttl": 60,
        "origin_ttl": 60
    }