Haproxy as ssh proxy

Hi!

I want to route my IPv4/6 SSH clients over a OPNsense HAproxy

#
# Automatically generated configuration.
# Do not edit this file manually.
#

global
    uid                         80
    gid                         80
    chroot                      /var/haproxy
    daemon
    stats                       socket /var/run/haproxy.socket group proxy mode 775 level admin
    nbproc                      1
    nbthread                    4
    hard-stop-after             60s
    no strict-limits
    maxconn                     10000
    tune.ssl.default-dh-param   4096
    spread-checks               2
    tune.bufsize                16384
    tune.lua.maxmem             0
    log                         /var/run/log local0 info
    lua-prepend-path            /tmp/haproxy/lua/?.lua

defaults
    log     global
    option redispatch -1
    maxconn 5000
    timeout client 1000s
    timeout connect 1000s
    timeout server 1000s
    retries 3
    default-server init-addr libc,last
    default-server maxconn 5000

# autogenerated entries for ACLs

# userlists generated from groups
userlist Allowedusers
    user joel insecure-password XXX
    user mopidy insecure-password XXX
    # NOTE: UserlistAddUsers called with empty group data


# autogenerated entries for config in backends/frontends
userlist list_6245eeb66d3ab2.08976803
    # Origin: MOPIDY_backend
    user mopidy insecure-password XXX
    user joel insecure-password XXX
    # WARNING: skipping duplicate username (mopidy)


# autogenerated entries for stats




# Frontend: SNI_frontend (Listening on http&https)
frontend SNI_frontend
    bind 0.0.0.0:443 name 0.0.0.0:443 
    bind 0.0.0.0:80 name 0.0.0.0:80 
    bind :::80 name :::80 
    bind :::443 name :::443 
    mode tcp
    default_backend SSL_backend
    # tuning options
    timeout client 1000s

    # logging options

# Frontend: HTTP_frontend (Listening 127.0.0.1:80)
frontend HTTP_frontend
    bind 127.0.0.1:80 name 127.0.0.1:80 accept-proxy 
    bind [::1]:80 name [::1]:80 accept-proxy 
    mode http
    option http-keep-alive
    option forwardfor
    # tuning options
    timeout client 1000s

    # logging options
    # ACL: NoSSL_condition
    acl acl_621d0b77c74989.24704837 ssl_fc

    # ACTION: HTTPtoHTTPS_rule
    http-request redirect scheme https code 301 if !acl_621d0b77c74989.24704837

# Frontend: HTTPS_frontend (Listinging on 127.0.0.1:443)
frontend HTTPS_frontend
    http-response set-header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    bind 127.0.0.1:443 name 127.0.0.1:443 accept-proxy ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/621d11c7cad951.61400293.certlist 
    bind [::1]:443 name [::1]:443 accept-proxy ssl curves secp384r1  no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384 ciphersuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 alpn h2,http/1.1 crt-list /tmp/haproxy/ssl/621d11c7cad951.61400293.certlist 
    mode http
    option http-keep-alive
    default_backend WEBSERVER_backend
    option forwardfor
    # tuning options
    timeout client 15m

    # logging options

    # ACTION: PUBLIC_SUBDOMAINS_map-rule
    # NOTE: actions with no ACLs/conditions will always match
    use_backend %[req.hdr(host),lower,map_dom(/tmp/haproxy/mapfiles/621d0c7054ddb7.46420139.txt)] 
    # WARNING: pass through options below this line
      # Matrix client traffic
      acl matrix-host hdr(host) -i chat.joelmueller.ch chat.joelmueller.ch:443
      acl matrix-path path_beg /_matrix
      acl matrix-path path_beg /_synapse/client
    
      use_backend MATRIX_backend if matrix-host matrix-path

# Frontend: MATRIX_frontend (Listining * Port 8448)
frontend MATRIX_frontend
    bind *:8448 name *:8448 alpn h2,http/1.1 ssl  crt-list /tmp/haproxy/ssl/6256daae2378c2.17892750.certlist 
    bind [::]:8448 name [::]:8448 alpn h2,http/1.1 ssl  crt-list /tmp/haproxy/ssl/6256daae2378c2.17892750.certlist 
    mode http
    option http-keep-alive
    default_backend MATRIX_backend
    # tuning options
    timeout client 1000s

    # logging options
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
      http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
      http-request set-header X-Forwarded-For %[src]

# Frontend: SSH_frontend (Listining * Port 22)
frontend SSH_frontend
    bind *:22 name *:22 alpn h2,http/1.1 
    bind [::]:22 name [::]:22 alpn h2,http/1.1 
    mode tcp
    default_backend ROUTER_SSH_backend
    # tuning options
    timeout client 1000s

    # logging options

# Backend: SSL_backend ()
backend SSL_backend
    # health checking is DISABLED
    mode tcp
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    server SSL_server 127.0.0.1 send-proxy-v2 check-send-proxy

# Backend: WEBSERVER_backend ()
backend WEBSERVER_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    acl restricted_page path_beg /wp-admin
    acl auth_ok http_auth(Allowedusers)
    http-request auth if restricted_page !auth_ok
    
    http-reuse safe
    server WEBSERVER_server 192.168.1.100:80 send-proxy-v2 check-send-proxy
    server WEBSERVER_server_ipv6 2a02:168:a774::2000:80 send-proxy-v2 check-send-proxy

# Backend: NAS_backend ()
backend NAS_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    http-reuse safe
    server NAS_server 192.168.1.118:80 
    server NAS_server_ipv6 2a02:168:a774::1000:80 

# Backend: WEBSERVER_SSL_backend ()
backend WEBSERVER_SSL_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    
    http-reuse safe
    server WEBSERVER_server_ssl 192.168.1.100:443 
    server WEBSERVER_server_ssl_ipv6 2a02:168:a774::2000:443 

# Backend: MOPIDY_backend ()
backend MOPIDY_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    acl auth_ok http_auth(list_6245eeb66d3ab2.08976803)
    http-request auth if !auth_ok
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    acl is_root path -i /
    redirect code 301 location /iris if is_root
    http-reuse safe
    server MOPIDY_server 192.168.1.100:6680 

# Backend: MATRIX_backend ()
backend MATRIX_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
      http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
      http-request set-header X-Forwarded-For %[src]
    http-reuse safe
    server MATRIX_server 192.168.1.100:8008 
    server MATRIX_server_ipv6 2a02:168:a774::2000:8008 

# Backend: KVM_backend ()
backend KVM_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    http-reuse safe
    server KVM_server 192.168.1.105:80 
    server KVM_server_ipv6 2a02:168:a774::3000:80 

# Backend: SYNC_backend ()
backend SYNC_backend
    # health checking is DISABLED
    mode http
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    # WARNING: pass through options below this line
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
      http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
      http-request set-header X-Forwarded-For %[src]
    http-reuse safe
    server SYNC_server 192.168.1.100:5050 

# Backend: ROUTER_SSH_backend ()
backend ROUTER_SSH_backend
    # health checking is DISABLED
    mode tcp
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    server ROUTER_SSH_Server 127.0.0.1:2222 
    server ROUTER_SSH_Server_ipv6 ::1:2222 

# Backend: NAS_SSH_backend ()
backend NAS_SSH_backend
    # health checking is DISABLED
    mode tcp
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    server NAS_server_ipv6 2a02:168:a774::1000:80 
    server NAS_SSH_server 192.168.1.118:22 

# Backend: KVM_SSH_backend ()
backend KVM_SSH_backend
    # health checking is DISABLED
    mode tcp
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    server KVM_SSH_server 192.168.1.105:22 
    server KVM_SSH_server_ipv6 2a02:168:a774::3000:22 

# Backend: SERVER_SSH_backend ()
backend SERVER_SSH_backend
    # health checking is DISABLED
    mode tcp
    balance source
    # stickiness
    stick-table type ip size 50k expire 30m  
    stick on src
    # tuning options
    timeout connect 1000s
    timeout server 1000s
    server SERVER_SSH_server 192.168.1.100:22 
    server SERVER_SSH_server_ipv6 2a02:168:a774::2000:22 



OPNsense (c) 2014-2022 Deciso B.V.

Mapfile

#public access subdomains
flood WEBSERVER_backend
kvm KVM_backend
nas WEBSERVER_backend
grafana WEBSERVER_backend
phpmyadmin WEBSERVER_backend
speedtestserver WEBERSERVER_backend
cloud NAS_backend
dav NAS_backend
stefan NAS_backend
mopidy MOPIDY_backend
git WEBSERVER_backend
chat MATRIX_backend
admin WEBSERVER_backend
sync SYNC_backend
sshnas NAS_SSH_backend
sshserver SERVER_SSH_backend
ssh ROUTER_SSH_backend
sshkvm KVM_SSH_backend

Why is everthing pointed to the r0uter_SSH_backend?

SSH_frontend points to ROUTER_SSH_backend, there is no other relevant configuration in that frontend that would select a different backend.

Can you elaborate what you expect to happen?

In case you want to route to different backends based on the hostname: there is no such thing in SSH. In HTTP you can do that based on the Host header in the HTTP request, in TLS/HTTPS you can do that based on the SNI value in the client_hello. There is no such thing in SSH.