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:

        log local0
        log local1 notice
        # log local0
        user haproxy
        group haproxy
        maxconn 20000

        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 check inter 1s
        server web02 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.


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.

  • Actually terminating decrypted HTTP on 443 has its merits, because Apache and/or the application can treat requests accordingly. If you route everything to Port 80, it may be difficult to discern whether the original request had used SSL at all. Note that some applications (e.g. rails) accept special headers to mark just such requests, which haproxy can do for you. – Felix Frank May 23 '14 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.