Destination not resolving

I’ve got HAProxy running as a forwarding SSH proxy:

resolvers internal
  hold nx 30s
  hold obsolete 30s
  hold other 30s
  hold refused 30s
  hold timeout 30s
  hold valid 30ss
  timeout resolve 1s
  timeout retry 1s
  accepted_payload_size 8192
  resolve_retries 3
  parse-resolv-conf

frontend fe_ssh from unnamed_defaults_1
  mode tcp
  bind *:22 ssl crt /etc/haproxy/ssl/mu-ssh.crt
  acl valid_payload req.payload(0,7) -m str "SSH-2.0"
  log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq dstName:%[var(sess.dstName)] dstIP:%[var(sess.dstIP)] "
  timeout client 15m
  tcp-request inspect-delay 5s
  tcp-request content do-resolve(sess.dstIP,internal,ipv4) ssl_fc_sni
  tcp-request content set-var(sess.dstName) ssl_fc_sni
  default_backend ssh-all

backend ssh-all from unnamed_defaults_1
  mode tcp
  tcp-request content set-dst var(sess.dstIP)

  acl allowed_destinations var(sess.dstName) -m sub  .mu.svc.cluster.local
  tcp-request content accept if allowed_destinations
  tcp-request content reject

  server ssh 0.0.0.0:22

I’m attempting to connect to a backend both using ssh and a script in GoLang.

With SSH, this works: ssh -o ProxyCommand="openssl s_client -quiet -connect haproxy:22 -servername int.mu.svc.cluster.local 2>/dev/null", however in Go, where I’m establishing a TLS connection first, then an SSH connection atop that, it fails.

The logs indicate that the SNI resolution isn’t happy; in the successful scenario:

fe_ssh~ ssh-all/ssh 220/0/434 2769 -- 1/1/0/0/0 0/0 dstName:int.mu.svc.cluster.local dstIP:10.152.183.251

Whereas in my script, HAProxy logs:

fe_ssh~ ssh-all/<NOSRV> -1/-1/14 0 CR 1/1/0/0/0 0/0 dstName:int.mu.svc.cluster.local dstIP:-

For some reason, even though the dstName is the same, dstIP isn’t being correctly resolved, and thus the connection is failing.

Any ideas?

SSH is not SSL/TLS. There is no SNI in SSH.

I am aware, however, the SSH connection is happening over TLS, per the config above.

Then the client_hello in the TLS handshake does not have the SNI value you are expecting.