From: Willy Tarreau Date: Tue, 22 Sep 2026 04:10:31 +0000 (+0000) Subject: REGTESTS: sample_fetches: test the raw TLS hello fetches X-Git-Tag: v3.5-dev8~39 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=a946b58c693a6dfded519d4ef314531febcf0369;p=haproxy.git REGTESTS: sample_fetches: test the raw TLS hello fetches req.ssl_hello_type, req.ssl_ver, req.ssl_ec_ext, req.ssl_st_ext and res.ssl_hello_type had no coverage, nor had the deprecated req_ssl_hello_type, req_ssl_ver, req_ssl_sni and rep_ssl_hello_type aliases. They parse the raw buffer of a TCP proxy without any SSL data layer, so the handshake messages are crafted by hand with sendhex the same way the other ClientHello tests do, and a server answers each of them with a ServerHello so that the response side is covered too. Three ClientHellos are used: one carrying server_name, supported_groups and an empty session ticket, one carrying a session ticket with data and no supported_groups, and one carrying a single unrelated extension so that req.ssl_st_ext reports its documented zero. --- diff --git a/reg-tests/sample_fetches/ssl_hello_type.vtc b/reg-tests/sample_fetches/ssl_hello_type.vtc new file mode 100644 index 000000000..8256baae4 --- /dev/null +++ b/reg-tests/sample_fetches/ssl_hello_type.vtc @@ -0,0 +1,103 @@ +varnishtest "Test the raw TLS hello fetches of the TCP rule sets" + +# req.ssl_hello_type, req.ssl_ver, req.ssl_ec_ext, req.ssl_st_ext and +# res.ssl_hello_type had no coverage, nor had the deprecated +# req_ssl_hello_type, req_ssl_ver, req_ssl_sni and rep_ssl_hello_type +# aliases. They all parse the raw buffer of a TCP proxy, without any SSL +# data layer, so the handshake messages are crafted by hand here. + +feature ignore_unknown_macro + +# the server answers every ClientHello with the same ServerHello +server s1 -repeat 3 { + recv 47 + sendhex "16030300 2c 02000028 0303 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 00 1302 00 0000" +} -start + +syslog S1 -level info { + # supported_groups and an empty session ticket extension + recv + expect ~ "type=1 ver=196611 ec=1 st=1 sni=www.example.com dtype=1 dver=196611 dsni=www.example.com rtype=2 drtype=2 bytes=[0-9]+$" + # a session ticket carrying data, and no supported_groups + recv + expect ~ "type=1 ver=196611 ec=0 st=2 sni=- dtype=1 dver=196611 dsni=- rtype=2 drtype=2 bytes=[0-9]+$" + # one unrelated extension: no supported_groups and no session ticket + recv + expect ~ "type=1 ver=196611 ec=0 st=0 sni=- dtype=1 dver=196611 dsni=- rtype=2 drtype=2 bytes=[0-9]+$" +} -start + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + chroot / + nbthread 1 + + defaults + mode tcp + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe1 + bind "fd@${fe1}" + log ${S1_addr}:${S1_port} local0 + # %B is only there to delay the message until the response rules + # have run + log-format "type=%[var(txn.t)] ver=%[var(txn.v)] ec=%[var(txn.e)] st=%[var(txn.s)] sni=%[var(txn.n)] dtype=%[var(txn.dt)] dver=%[var(txn.dv)] dsni=%[var(txn.dn)] rtype=%[var(txn.rt)] drtype=%[var(txn.drt)] bytes=%B" + + tcp-request inspect-delay 100ms + tcp-request content set-var(txn.t) req.ssl_hello_type + tcp-request content set-var(txn.v) req.ssl_ver + tcp-request content set-var(txn.e) req.ssl_ec_ext + tcp-request content set-var(txn.s) req.ssl_st_ext + tcp-request content set-var(txn.n) req.ssl_sni + # the deprecated spellings must report the same values + tcp-request content set-var(txn.dt) req_ssl_hello_type + tcp-request content set-var(txn.dv) req_ssl_ver + tcp-request content set-var(txn.dn) req_ssl_sni + tcp-request content accept if { req.ssl_hello_type 1 } + + default_backend be + + backend be + tcp-response inspect-delay 100ms + tcp-response content set-var(txn.rt) res.ssl_hello_type + tcp-response content set-var(txn.drt) rep_ssl_hello_type + tcp-response content accept if { res.ssl_hello_type 2 } + server s1 ${s1_addr}:${s1_port} +} -start + +# The ClientHellos share the 43-byte body of the other ClientHello tests: +# 16 03 01 LL LL TLS record: handshake, TLSv1.0 +# 01 00 00 LL Handshake: ClientHello +# 03 03 client_version, TLSv1.2 +# 00 .. 1f Random[32] +# 00 session_id_len = 0 +# 00 02 13 02 cipher_len = 2, one cipher suite +# 01 00 compression_len = 1, method 0 +# LL LL extensions_len +# and only differ by the extensions which follow. + +# server_name, supported_groups and an empty session_ticket (0023) +client c1 -connect ${h1_fe1_sock} { + sendhex "160301 0055 01000051 0303 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 00 00021302 0100 0026 00000014001200000f 7777772e6578616d706c652e636f6d 000a00060004001d0017 00230000" + recv 49 +} -run + +# a session_ticket holding four bytes, and no supported_groups +client c2 -connect ${h1_fe1_sock} { + sendhex "160301 0037 01000033 0303 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 00 00021302 0100 0008 0023 0004 aabbccdd" + recv 49 +} -run + +# a single unrelated extension (renegotiation_info). Note that an empty +# extension block is not accepted by the parser, which requires at least +# two bytes past the extension list length. +client c3 -connect ${h1_fe1_sock} { + sendhex "160301 0034 01000030 0303 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 00 00021302 0100 0005 ff01000100" + recv 49 +} -run + +syslog S1 -wait