HTTP/HTTPS data in HAProxy TCP mode

Published: by

  • Categories:

Intro

When working in TCP mode, HAproxy doesn't directly have access to any layers above L4 (tcp/udp etc) . However, HAproxy has a cool functionality of reading data from raw_sockets , which means HAproxy has the capability to extract information from sockets directly, in other words, fetching data from layers above tcp.

Some use-cases of this:-

  • Add more context like host or sni information in TCP logs which typically just contain IP/port information only.
  • Make backend decisions based on >L4 data in L4 mode. Example, routing based on domain, SNI in SSL handshakes etc.

We'll taking first use-case as an example which is about logging this data. Capturing is achieved by using tcp-request capture feature in HAproxy. We capture http/https data in their respective frontends and then use them in logging via variable %[capture.req.hdr(0)]

Steps

Extract L6/L7 information

  • For all frontends, add these tcp-request capture statements to instruct HAproxy to collect this data.
frontend public_tcp_http
    bind *:8080
    bind :::8080

    tcp-request inspect-delay 5s
    tcp-request content track-sc0 src table ip_table
    tcp-request content capture req.hdr(Host) len 100

    default_backend lx_http

frontend public_tcp_https
    bind *:8443
    bind :::8443

    tcp-request inspect-delay 5s
    tcp-request content track-sc0 src table ip_table
    tcp-request content capture req.ssl_sni len 100
    # Very important, it ensures that HAproxy waits for hello packet
    tcp-request content accept if { req.ssl_hello_type 1 } 
    
    default_backend lx_https

Log information to confirm the capture

  • Modify logging format to include this information.
log-format "%[capture.req.hdr(0)]