Forwarding TLS traffic to staging using spoa-mirror

Hi. I need to enable traffic mirroring from the production server to staging. We had this working in the past, but I’m unable to restore the setup, probably because of technical changes that happened in the meantime.

In the normal workflow, we do TLS termination in HAProxy and forward in plain HTTP to backend servers. I believe I’m not managing TLS correctly at SPOE level, but I cannot find what’s wrong.

I forward spoa-mirror traffic back in HAProxy again to alter the Host and Location headers, replacing production hosts with staging ones.

    mworker-max-reloads 3
    log   local0 info
    log   local1 notice
    maxconn 25000
    chroot /var/lib/haproxy
    user haproxy
    group haproxy
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private
    ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
    ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM
    ssl-default-bind-curves X25519:secp521r1:secp384r1:prime256v1
    tune.ssl.default-dh-param 2048

    log global
    mode        http
    option      httplog
    option      dontlognullmonitor probes)
    option      forwardfor
    option      log-separate-errors
    option      http-server-close
    retries     3
    timeout connect 20s
    timeout client 100s
    timeout server 100s
    timeout http-keep-alive 80s

frontend web
    bind *:80
    bind *:443 ssl crt /etc/haproxy/certs/ alpn h2,http/1.1
    http-request del-header Proxy
    http-request add-header X-Forwarded-Proto https
    http-response add-header X-Frame-Options DENY
    filter spoe  engine mirror  config /etc/haproxy/mirror.cfg

program mirror
   command /usr/local/bin/spoa-mirror --runtime 0 --mirror-url "" --logfile A:/var/log/haproxy-mirror.log

# We receive back SPOA's traffic and alter headers
frontend spoa_frontend
    log global
    bind *:9000
    http-request replace-value Location ^*)\1
    http-request del-header Proxy
    http-request add-header X-Forwarded-Proto http
    http-request add-header X-Is-Mirrored yes
    use_backend spoa_backend

# SPOA destination
backend mirroragents
    mode tcp
    balance roundrobin
    timeout connect 5s
    timeout server 1m
    server agent1

# Backend server where the SPOA mirrored traffic is delivered
backend spoa_backend
    mode http
    http-request set-header Host
    http-request replace-value Location ^*)$\1
    server stagingsrv stagingsrv:80 check inter 2000 rise 2 fall 3

And this is mirror.cfg

spoe-agent mirror
    log global
    messages mirror
    timeout hello 500ms
    timeout idle 10s
    timeout processing 100ms
    use-backend mirroragents

spoe-message mirror
    args arg_method=method arg_path=url arg_ver=req.ver arg_hdrs=req.hdrs_bin arg_body=req.body
    acl is_prod                hdr(host)  -m  str
    event on-frontend-http-request if is_prod

This is the log of a request performed with curl:

==> haproxy-mirror.log <==
[ 7][ 9366.125010] "GET HTTP/???" 0 0/0 0.000

==> haproxy-http.log <==
Feb 28 14:29:26 localhost haproxy[376208]: SPOE: [mirror] <EVENT:on-frontend-http-request> sid=40796 st=0 0/1/0/0/2 1/1 0/0 0/10
Feb 28 14:29:26 localhost haproxy[376208]: SPOE: [mirror] <EVENT:on-frontend-http-request> sid=40796 st=0 0/1/0/0/2 1/1 0/0 0/10
Feb 28 14:29:27 localhost haproxy[376208]: [28/Feb/2024:14:29:26.783] web~ backend_http_cluster/spain-01 2/0/1/549/567 200 14425 - - --NI 1/1/0/0/0 0/0 "GET HTTP/2.0"

I’m puzzled by the HTTP/??? output of spoa-mirror, that I found in curl.c for CURL_HTTP_VERSION_NONE.

Anyway, in the logs we never get a record for the spoa_frontend, that means the mirror agent is never forwarding the request there. But I haven’t found a verbose option for spoa-mirror