Tag Archives: Layer 6

7.3.5. Fetching samples from buffer contents (Layer 6)



Fetching samples from buffer contents is a bit different from the previous sample fetches above because the sampled data are ephemeral. These data can only be used when they’re available and will be lost when they’re forwarded.
For this reason, samples fetched from buffer contents during a request cannot be used in a response for example. Even while the data are being fetched, they can change. Sometimes it is necessary to set some delays or combine multiple sample fetch methods to ensure that the expected data are complete and usable, for example through TCP request content inspection. Please see the “tcp-request content” keyword for more detailed information on the subject.

payload(<offset>,<length>) : binary (deprecated)
This is an alias for “req.payload” when used in the context of a request (eg: “stick on”, “stick match”), and for “res.payload” when used in the context of a response such as in “stick store response”.

payload_lv(<offset1>,<length>[,<offset2>]) : binary (deprecated)
This is an alias for “req.payload_lv” when used in the context of a request (eg: “stick on”, “stick match”), and for “res.payload_lv” when used in the context of a response such as in “stick store response”.

req.len : integer
req_len : integer (deprecated)
Returns an integer value corresponding to the number of bytes present in the request buffer. This is mostly used in ACL. It is important to understand that this test does not return false as long as the buffer is changing. This means that a check with equality to zero will almost always immediately match at the beginning of the session, while a test for more data will wait for that data to come in and return false only when haproxy is certain that no more data will come in. This test was designed to be used with TCP request content inspection.

req.payload(<offset>,<length>) : binary
This extracts a binary block of <length> bytes and starting at byte <offset> in the request buffer. As a special case, if the <length> argument is zero, the the whole buffer from <offset> to the end is extracted. This can be used with ACLs in order to check for the presence of some content in a buffer at any location.

ACL alternatives :

    payload(<offset>,<length>) : hex binary match

req.payload_lv(<offset1>,<length>[,<offset2>]) : binary
This extracts a binary block whose size is specified at <offset1> for <length> bytes, and which starts at <offset2> if specified or just after the length in the request buffer. The <offset2> parameter also supports relative offsets if prepended with a ‘+’ or ‘-‘ sign.

ACL alternatives :

    payload_lv(<offset1>,<length>[,<offset2>]) : hex binary match

Example : please consult the example from the “stick store-response” keyword.

req.proto_http : boolean
req_proto_http : boolean (deprecated)
Returns true when data in the request buffer look like HTTP and correctly parses as such. It is the same parser as the common HTTP request parser which is used so there should be no surprises. The test does not match until the request is complete, failed or timed out. This test may be used to report the protocol in TCP logs, but the biggest use is to block TCP request analysis until a complete HTTP request is present in the buffer, for example to track a header.

Example:

        # track request counts per "base" (concatenation of Host+URL)
        tcp-request inspect-delay 10s
        tcp-request content reject if !HTTP
        tcp-request content track-sc0 base table req-rate

req.rdp_cookie([<name>]) : string
rdp_cookie([<name>]) : string (deprecated)
When the request buffer looks like the RDP protocol, extracts the RDP cookie <name>, or any cookie if unspecified. The parser only checks for the first cookie, as illustrated in the RDP protocol specification. The cookie name is case insensitive. Generally the “MSTS” cookie name will be used, as it can contain the user name of the client connecting to the server if properly configured on the client. The “MSTSHASH” cookie is often used as well for session stickiness to servers.

This differs from “balance rdp-cookie” in that any balancing algorithm may be used and thus the distribution of clients to backend servers is not linked to a hash of the RDP cookie. It is envisaged that using a balancing algorithm such as “balance roundrobin” or “balance leastconn” will lead to a more even distribution of clients to backend servers than the hash used by “balance rdp-cookie”.

ACL derivatives :

    req_rdp_cookie([<name>]) : exact string match

Example :

   listen tse-farm
       bind 0.0.0.0:3389
       # wait up to 5s for an RDP cookie in the request
       tcp-request inspect-delay 5s
       tcp-request content accept if RDP_COOKIE
       # apply RDP cookie persistence
       persist rdp-cookie
       # Persist based on the mstshash cookie
       # This is only useful makes sense if
       # balance rdp-cookie is not used
       stick-table type string size 204800
       stick on req.rdp_cookie(mstshash)
       server srv1 1.1.1.1:3389
       server srv1 1.1.1.2:3389

See also : “balance rdp-cookie”, “persist rdp-cookie”, “tcp-request” and the “req_rdp_cookie” ACL.

req.rdp_cookie_cnt([name]) : integer
rdp_cookie_cnt([name]) : integer (deprecated)
Tries to parse the request buffer as RDP protocol, then returns an integer corresponding to the number of RDP cookies found. If an optional cookie name is passed, only cookies matching this name are considered. This is mostly used in ACL.

ACL derivatives :

    req_rdp_cookie_cnt([<name>]) : integer match

req.ssl_hello_type : integer
req_ssl_hello_type : integer (deprecated)
Returns an integer value containing the type of the SSL hello message found in the request buffer if the buffer contains data that parse as a complete SSL (v3 or superior) client hello message. Note that this only applies to raw contents found in the request buffer and not to contents deciphered via an SSL data layer, so this will not work with “bind” lines having the “ssl” option. This is mostly used in ACL to detect presence of an SSL hello message that is supposed to contain an SSL session ID usable for stickiness.

req.ssl_sni : string
req_ssl_sni : string (deprecated)
Returns a string containing the value of the Server Name TLS extension sent by a client in a TLS stream passing through the request buffer if the buffer contains data that parse as a complete SSL (v3 or superior) client hello message. Note that this only applies to raw contents found in the request buffer and not to contents deciphered via an SSL data layer, so this will not work with “bind” lines having the “ssl” option. SNI normally contains the name of the host the client tries to connect to (for recent browsers). SNI is useful for allowing or denying access to certain hosts when SSL/TLS is used by the client. This test was designed to be used with TCP request content inspection. If content switching is needed, it is recommended to first wait for a complete client hello (type 1), like in the example below. See also “ssl_fc_sni”.

ACL derivatives :

    req_ssl_sni : exact string match

Examples :

     # Wait for a client hello for at most 5 seconds
     tcp-request inspect-delay 5s
     tcp-request content accept if { req_ssl_hello_type 1 }
     use_backend bk_allow if { req_ssl_sni -f allowed_sites }
     default_backend bk_sorry_page

res.ssl_hello_type : integer
rep_ssl_hello_type : integer (deprecated)
Returns an integer value containing the type of the SSL hello message found in the response buffer if the buffer contains data that parses as a complete SSL (v3 or superior) hello message. Note that this only applies to raw contents found in the response buffer and not to contents deciphered via an SSL data layer, so this will not work with “server” lines having the “ssl” option. This is mostly used in ACL to detect presence of an SSL hello message that is supposed to contain an SSL session ID usable for stickiness.

req.ssl_ver : integer
req_ssl_ver : integer (deprecated)
Returns an integer value containing the version of the SSL/TLS protocol of a stream present in the request buffer. Both SSLv2 hello messages and SSLv3 messages are supported. TLSv1 is announced as SSL version 3.1. The value is composed of the major version multiplied by 65536, added to the minor version. Note that this only applies to raw contents found in the request buffer and not to contents deciphered via an SSL data layer, so this will not work with “bind” lines having the “ssl” option. The ACL version of the test matches against a decimal notation in the form MAJOR.MINOR (eg: 3.1). This fetch is mostly used in ACL.

ACL derivatives :

    req_ssl_ver : decimal match

res.len : integer
Returns an integer value corresponding to the number of bytes present in the response buffer. This is mostly used in ACL. It is important to understand that this test does not return false as long as the buffer is changing. This means that a check with equality to zero will almost always immediately match at the beginning of the session, while a test for more data will wait for that data to come in and return false only when haproxy is certain that no more data will come in. This test was designed to be used with TCP response content inspection.

res.payload(<offset>,<length>) : binary
This extracts a binary block of <length> bytes and starting at byte <offset> in the response buffer. As a special case, if the <length> argument is zero, the the whole buffer from <offset> to the end is extracted. This can be used with ACLs in order to check for the presence of some content in a buffer at any location.

res.payload_lv(<offset1>,<length>[,<offset2>]) : binary
This extracts a binary block whose size is specified at <offset1> for <length> bytes, and which starts at <offset2> if specified or just after the length in the response buffer. The <offset2> parameter also supports relative offsets if prepended with a ‘+’ or ‘-‘ sign.

Example : please consult the example from the “stick store-response” keyword.

wait_end : boolean
This fetch either returns true when the inspection period is over, or does not fetch. It is only used in ACLs, in conjunction with content analysis to avoid returning a wrong verdict early. It may also be used to delay some actions, such as a delayed reject for some special addresses. Since it either stops the rules evaluation or immediately returns true, it is recommended to use this acl as the last one in a rule. Please note that the default ACL “WAIT_END” is always usable without prior declaration. This test was designed to be used with TCP request content inspection.

Examples :

     # delay every incoming request by 2 seconds
     tcp-request inspect-delay 2s
     tcp-request content accept if WAIT_END
     # don't immediately tell bad guys they are rejected
     tcp-request inspect-delay 10s
     acl goodguys src 10.0.0.0/24
     acl badguys  src 10.0.1.0/24
     tcp-request content accept if goodguys
     tcp-request content reject if badguys WAIT_END
     tcp-request content reject
Share Button