Hello all,
I am trying to configure SNI routing using OPNSense HAProxy plugin (based on HAProxy 2.8).
After configuration in the GUI, it gives me this configuration:
#
# 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
nbthread 1
hard-stop-after 60s
no strict-limits
tune.ssl.default-dh-param 2048
spread-checks 2
tune.bufsize 16384
tune.lua.maxmem 0
log /var/run/log local0 debug
lua-prepend-path /tmp/haproxy/lua/?.lua
defaults
log global
option redispatch -1
timeout client 30s
timeout connect 30s
timeout server 30s
retries 3
default-server init-addr last,libc
# autogenerated entries for ACLs
# autogenerated entries for config in backends/frontends
# autogenerated entries for stats
# Frontend: public_https (HTTPS Port)
frontend public_https
bind 0.0.0.0:443 name 0.0.0.0:443
mode tcp
default_backend backend_https
# logging options
option tcplog
# Frontend: public_http (HTTP Port)
frontend public_http
bind 0.0.0.0:80 name 0.0.0.0:80
mode http
option http-keep-alive
default_backend backend_http
# logging options
option httplog
# Backend: backend_https (Backend HTTPS)
backend backend_https
# health checking is DISABLED
mode tcp
balance source
# stickiness
stick-table type ip size 50k expire 30m
stick on src
# ACL: iot_myserver_org_condition_sni
acl acl_65a84ebeebab75.87915974 req.ssl_sni -m sub -i iot.myserver.org
# ACL: server_myserver_org_condition_sni
acl acl_65a84ed2d27713.21832231 req.ssl_sni -m sub -i server.myserver.org
# ACTION: iot_myserver_org_https_sni_rules
use-server iot_myserver_org_server_https if acl_65a84ebeebab75.87915974
# ACTION: server_myserver_org_https_sni_rules
use-server server_myserver_org_server_https if acl_65a84ed2d27713.21832231
server iot_myserver_org_server_https 192.168.9.5:443
server server_myserver_org_server_https 192.168.9.10:443
# Backend: backend_http (Backend HTTP)
backend backend_http
# health checking is DISABLED
mode http
balance source
# stickiness
stick-table type ip size 50k expire 30m
stick on src
# ACL: iot_myserver_org_condition_host
acl acl_65a851411fc3d3.35763680 hdr_sub(host) -i iot.myserver.org
# ACL: server_myserver_org_condition_host
acl acl_65a85167495161.41598361 hdr_sub(host) -i server.myserver.org
# ACTION: iot_myserver_org_http_host_rules
use-server iot_myserver_org_server_http if acl_65a851411fc3d3.35763680
# ACTION: server_myserver_org_http_host_rules
use-server server_myserver_org_server_http if acl_65a85167495161.41598361
http-reuse safe
server iot_myserver_org_server_http 192.168.9.5:80
server server_myserver_org_server_http 192.168.9.10:80
listen local_statistics
bind 127.0.0.1:8822
mode http
stats uri /haproxy?stats
stats realm HAProxy\ statistics
stats admin if TRUE
# remote statistics are DISABLED
When I am trying to access both servers, it always redirect me to the same server (yesterday it actually always redirect me to server.myserver.org
while today is iot.myserver.org
even I have not changed anything in the conf). I would suspect my ACL rule are not working and it is just doing load balancing.
Both servers are running nginx. I enabled debug
logging on both. I can confirm the SNI is sent through the TLS connections.
Example from this morning, I am trying to access curl https://server.myserver.org
and on iot.myserver.org
nginx logs:
2024/01/18 08:53:27 [debug] 4317#4317: epoll: fd:6 ev:0001 d:00007FB850AF2100
2024/01/18 08:53:27 [debug] 4317#4317: accept on 0.0.0.0:443, ready: 0
2024/01/18 08:53:27 [debug] 4317#4317: posix_memalign: 000055678966F830:512 @16
2024/01/18 08:53:27 [debug] 4317#4317: *2 accept: 192.168.9.254:26612 fd:15
2024/01/18 08:53:27 [debug] 4317#4317: *2 event timer add: 15: 60000:126347578
2024/01/18 08:53:27 [debug] 4317#4317: *2 reusable connection: 1
2024/01/18 08:53:27 [debug] 4317#4317: *2 epoll add event: fd:15 op:1 ev:80002001
2024/01/18 08:53:27 [debug] 4317#4317: epoll del event: fd:6 op:2 ev:00000000
2024/01/18 08:53:27 [debug] 4317#4317: epoll add event: fd:6 op:1 ev:10000001
2024/01/18 08:53:27 [debug] 4317#4317: timer delta: 314684
2024/01/18 08:53:27 [debug] 4317#4317: worker cycle
2024/01/18 08:53:27 [debug] 4317#4317: epoll timer: 60000
2024/01/18 08:53:27 [debug] 4317#4317: epoll: fd:15 ev:0001 d:00007FB850AF24C0
2024/01/18 08:53:27 [debug] 4317#4317: *2 http check ssl handshake
2024/01/18 08:53:27 [debug] 4317#4317: *2 http recv(): 1
2024/01/18 08:53:27 [debug] 4317#4317: *2 https ssl handshake: 0x16
2024/01/18 08:53:27 [debug] 4317#4317: *2 tcp_nodelay
2024/01/18 08:53:27 [debug] 4317#4317: *2 reusable connection: 0
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL server name: "server.myserver.org"
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL ALPN supported by client: h2
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL ALPN supported by client: http/1.1
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL ALPN selected: http/1.1
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL_do_handshake: -1
2024/01/18 08:53:27 [debug] 4317#4317: *2 SSL_get_error: 2
(...)
So the SNI seems to be correct (SSL server name: "server.myserver.org"
)
The corresponding log entry in HAProxy is:
2024-01-18T08:53:27 Informational haproxy 82.207.235.198:7748 [18/Jan/2024:08:53:27.851] public_https backend_https/iot_codeur_org_server_https 1/0/115 4302 -- 1/1/0/0/0 0/0
It would be nice to have a setting in HAProxy where the ACL rule can be debugged (for instance for each frontend/backend get the result of the rule). At the moment the debug
seems to only for custom Lua code
: Observability | Logging | Setting Log Levels | HAProxy Enterprise 2.8r1
… And if someone has an idea what is my issue.