I'm building a highly available site using a multiple HAProxy load balancers, Nginx web serves, and MySQL servers. The site needs to be able to survive load balancer or web servers nodes going offline without any interruption of service to visitors. Currently, I have two boxes running HAProxy sharing a virtual IP using keepalived, which forward to two web servers running Nginx, which then tie into two MySQL boxes using MySQL replication and sharing a virtual IP using heartbeat. Everything is working correctly except for SSL traffic over HAProxy. I'm running version 1.5 dev12 with openssl support compiled in. When I try to navigate to the virtual IP for haproxy over https, I get the message: The plain HTTP request was sent to HTTPS port. Here's my haproxy.cfg so far, which was mainly assembled from other posts:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
# log 127.0.0.1 local0
user haproxy
group haproxy
daemon
maxconn 20000
defaults
log global
option dontlognull
balance leastconn
clitimeout 60000
srvtimeout 60000
contimeout 5000
retries 3
option redispatch
listen front
bind :80
bind :443 ssl crt /etc/pki/tls/certs/cert.pem
mode http
option http-server-close
option forwardfor
reqadd X-Forwarded-Proto:\ https if { is_ssl }
reqadd X-Proto:\ SSL if { is_ssl }
server web01 192.168.25.34 check inter 1s
server web02 192.168.25.32 check inter 1s
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth admin:*********
Any idea why SSL traffic isn't being passed correctly? Also, any other changes you would recommend? I still need to configure logging, so don't worry about that section. Thanks in advance your help.
Best Answer
With ssl, you have to use frontend/backend, not listen. The reason is that with listen, a connection coming in to haproxy on one port goes to the server behind on that same port. So an SSL request on 443 gets decrypted by haproxy, but then sent on to the web server on port 443, which is expecting an SSL connection. (And that is how you get that error.) With frontend/backend, you get to tell haproxy to accept connections on one port on the frontend, but to complete the connection to a different port in the backend.
Alternatively, you could reconfigure your web server to accept http requests (not https requests) on port 443. Personally, I would don't that because that is pretty non-standard, whereas you would expect a load balancer doing SSL offload to accept a connection on 443 and complete it on port 80.