I needed to proxy Parallels RAS (Remote Application Server) through HAProxy alongside other services, all on port 443 with a single public IP. Sounds simple, right? It wasn't.
Initial symptoms:
- Web portal loaded perfectly on first access
- Clicking to launch an application triggered an infinite loading loop
- Refreshing the page resulted in 503 Service Unavailable errors
- Opening the same URL in a new incognito tab worked again
This intermittent behavior was maddening.
First Attempt: HTTP Mode (The Wrong Approach)
My initial HAProxy configuration treated Parallels RAS like any other web service:
frontend https_frontend
bind *:443 ssl crt /etc/haproxy/certs/
mode http
use_backend home_backend if { hdr(host) -i home.raidho.fr }
backend home_backend
mode http
server ras01 192.168.0.159:443 check ssl verify none
Why this failed:
- HAProxy was terminating SSL and re-encrypting to the backend
- HTTP headers were being added/modified (
X-Forwarded-For
,X-Forwarded-Proto
, etc.) - Parallels RAS uses WebSocket connections and proprietary protocols for application launching
- These protocols are sensitive to header manipulation and SSL re-negotiation
Result: The web portal loaded, but launching applications failed completely.
Second Attempt: TCP Passthrough with SNI Routing
The solution seemed obvious: use TCP mode for transparent passthrough. But with multiple services on port 443, I needed a way to route traffic. Enter SNI (Server Name Indication) inspection:
frontend https_tcp_frontend
bind *:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl host_home req_ssl_sni -i home.raidho.fr
use_backend home_tcp_backend if host_home
default_backend https_ssl_termination
backend home_tcp_backend
mode tcp
server ras01 192.168.0.159:443 check
This worked... sort of. The portal loaded, I could log in, but refreshing the page gave 503 errors.
The Root Cause: Connection Reuse vs. SNI Inspection
Here's what I learned the hard way:
How SNI inspection works:
- Client initiates TLS handshake
- SNI (hostname) is sent during the ClientHello message
- HAProxy inspects SNI and routes to the appropriate backend
- Connection established
The fatal flaw:
- SNI only exists in the initial TLS handshake
- Modern browsers reuse TCP connections (HTTP/1.1 keep-alive, HTTP/2 multiplexing)
- When a user refreshes the page, the browser reuses the existing connection
- No new TLS handshake = no SNI to inspect
- HAProxy can't determine where to route the traffic
- HAProxy sends TCP RST (reset) packet
- Result: 503 Service Unavailable
Why tcpdump revealed the truth:
$ sudo tcpdump -i any -n port 443 and host 192.168.0.159
# First connection - works
07:25:59.622151 ens18 Out IP ... Flags [S], seq ... (SYN)
07:25:59.622221 ens18 Out IP ... Flags [P.], seq 1:1725 (Data with SNI)
# Refresh attempt - fails
07:25:59.785608 ens18 Out IP ... Flags [R.], seq 1 (RST - connection reset!)
HAProxy was actively killing connections because it couldn't route without SNI.

Why Standard Solutions Don't Work
"Just use SSL offload!"
- This brings us back to problem #1
- Terminates SSL, modifies headers, breaks RAS protocols
"Use a second public IP!"
- Requires additional IP allocation
- More complex firewall rules
- Valid solution, but I wanted something simpler
"Keep the SNI routing and live with it!"
- Unacceptable UX: users can't refresh pages
- Applications fail to launch intermittently
- Support nightmare
The Actual Solution: Dedicated Port
After fighting with the architecture, I accepted reality: SNI-based routing on a shared port with TCP passthrough is fundamentally incompatible with connection reuse.
Final configuration:
# Port 443: Regular services with SSL termination
frontend https_frontend
bind *:443 ssl crt /etc/haproxy/certs/
mode http
# ... route to various backends
# Port 8443: Parallels RAS with pure TCP passthrough
frontend ras_frontend
bind *:8443
mode tcp
timeout client 3600s
default_backend home_tcp_backend
backend home_tcp_backend
mode tcp
timeout server 3600s
timeout tunnel 3600s
server gateway01 192.168.0.163:443 check
Why this works:
- No SNI inspection needed - all traffic on 8443 goes to RAS
- Pure TCP passthrough maintains connection integrity
- No header manipulation, no SSL termination
- Connection reuse works perfectly
- Refreshing works, application launching works, everything works
Lessons Learned
- SNI inspection is read-once during TLS handshake - it cannot work with connection reuse
- Not all protocols are HTTP-friendly - some require transparent TCP passthrough
- Sometimes the "simple" solution (shared port) is architecturally impossible - fighting it wastes time
- Port 8443 is standard for alternate HTTPS services - there's a reason enterprises use it
- Protocol limitations beat configuration cleverness - no amount of tuning fixes a fundamental incompatibility
Alternatives That Would Work
If opening port 8443 isn't possible:
- Second public IP address: Bind RAS to a dedicated IP, no SNI routing needed
- Different subdomain on different IP:
ras.domain.com
→ separate IP - HTTP redirect landing page:
domain.com
→domain.com:8443
(transparent to users) - Accept the limitation: Document that users should bookmark the full URL and not refresh

The right architecture matters more than clever configuration. I spent hours trying to make SNI-based routing work on port 443 before accepting that the protocol stack itself made it impossible. Using port 8443 with pure TCP passthrough solved all issues immediately.