CodeShare
Have some code. Share some code.
cancel
Showing results for 
Search instead for 
Did you mean: 
PeteWhite
F5 Employee
F5 Employee
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
Comments

Thanks for sharing this. Can you please point out the main differences between this and the HSSR?

xuwen
MVP
MVP

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

CA_Valli
MVP
MVP

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

PeteWhite
F5 Employee
F5 Employee

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.

PeteWhite
F5 Employee
F5 Employee

@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!

PeteWhite
F5 Employee
F5 Employee

@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
}
PeteWhite
F5 Employee
F5 Employee

@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
MVP
MVP

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
}

 

 

 

 

PeteWhite
F5 Employee
F5 Employee

@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.

Version history
Last update:
‎18-Jul-2023 16:16
Updated by:
Contributors