HAProxy forwarding to HTTPS sites


#1

I’m pretty newb at certificates, but here is what I have and also what I’m trying to do.

I have domain1.com running Wordpress and domain2.com running Nextcloud. I want both services to work over 80 which has the potential to redirect to port 443 for https connections. Since these services are running on separate servers and the same ports, I have HAProxy set up in front of them as a reverse proxy, and it is currently forwarding http traffic to these sites by ACLs. Looking at some sites, I THINK I know what I’m doing in terms of setting up HAProxy, except how to deal with certs for this whole setup. domain1 and domain2 have their own unique certificate. Since I am just forwarding this traffic to whichever server is specified, how do I give HAProxy the proper certificate for the site? Do I have to copy over the certificate from each domain to HAProxy to use? If so, what file would I use?\

The server is Ubuntu Server 16.04, and I have Wordpress, Nextcloud and HAProxy running in their own LXC containers


#2

Do you actually want HAProxy to deal with SSL and certificates at all? Because HAProxy is capable of inspecting the handshake and you could just use SSL pass-through to forward traffic. Check for example this article - https://scriptthe.net/2015/02/08/pass-through-ssl-with-haproxy/


#3

I don’t want it to handle it, I’m just speaking with a lack of knowledge :stuck_out_tongue: I’m not sure how well I am following that configuration…his configuration deals with one domain name it seems, so I think I am having redirect problems at this point in the http-in section of the config file. Currently I have 2 redirect lines, which I assume is wrong because here is my http-in:

frontend http-in
bind 10.0.0.105:80

    acl is_nextcloud hdr(host) -i domain1   #10.0.0.160
    acl is_wordpress hdr(host) -i domain2      #10.0.0.165

    use_backend nextcloud_cluster if is_nextcloud
    use_backend wordpress_cluster if is_wordpress

    redirect scheme https code 301 if { hdr_end(host) -i domain1 } !{ ssl_fc }
    redirect scheme https code 301 if { hdr_end(host) -i domain2 } !{ ssl_fc }

Currently if I type in domain1, it fails to connect but if I type in domain2 it connects to domain1 with domain2’s name


#4

It seems there is no easy way to have multiple domains inside a single network, especially requiring HTTPS. I have a very simple configuration now that’s different and I can connect to one domain with the proper certificate, but my browser gives a warning saying the connection is not secure. I still can’t connect to my second domain at all


#5

You have to use tcp mode and inspect “req.ssl_sni”.


#6

How does this look:

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    maxconn 4096
    user haproxy
    group haproxy
    daemon
 defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    timeout connect 15s
    timeout client  15s
    timeout server  15s
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http


 frontend localhost
    bind *:80
    bind *:443
    option tcplog
    mode tcp


    acl is_wordpress req.ssl_sni -i domain1.com
    acl is_nextcloud req.ssl_sni -i domain2.com            
    
    use_backend nextcloud_cluster if is_nextcloud
    use_backend wordpress_cluster if is_wordpress


 backend wordpress_cluster
    mode tcp

    option ssl-hello-chk

    server is_wordpress 10.0.0.165:443 check


 backend nextcloud_cluster
    mode tcp

    option ssl-hello-chk

    server is_nextcloud 10.0.0.160:443 check


#7

Add this to the frontend

acl tls req.ssl_hello_type 1

tcp-request inspect-delay 5s
tcp-request content accept if tls

Make a separate frontend for port 80.


#8

Here is my change to my frontends

frontend localhost80
    bind *:80
    mode http
    redirect scheme https if !{ ssl_fc }

frontend localhost443
    bind *:443
    option tcplog
    mode tcp

    acl tls req.ssl_hello_type 1

    tcp-request inspect-delay 5s
    tcp-request content accept if tls

    acl is_wordpress req.ssl_sni -i domain1.com   #10.0.0.165
    acl is_nextcloud req.ssl_sni -i domain2.com                #10.0.0.160

    use_backend nextcloud_cluster if is_nextcloud
    use_backend wordpress_cluster if is_wordpress

I am SO close! I can currently connect to my wordpress site but I cannot connect to Nextcloud.

Wordpress results:
curl domain2.com - good
curl domain2.com:80 - good
curl domain2.com:443 - curl: (52) Empty reply from server

Nextcloud results:
curl domain1.com - good
curl domain1.com:80 - good
curl domain1.com:443 - curl: (52) Empty reply from server


#9

Well, what does the haproxy log say? Is “domain1.com:443” actually a valid argument for curl? curl seems to expect a URL and domain1.com:443 is not a URL.


#10

I can’t seem to get my logs working…it’s empty. Good to know on the curl part that it won’t accept ports.


#11

Can’t get logs working, but so far it appears this configuration is working. Here is my /etc/haproxy/haproxy.cfg.

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    maxconn 4096
    user haproxy
    group haproxy
    daemon


defaults
    log     global
    mode    tcp
    option  tcplog
    option  dontlognull
    timeout connect 15s
    timeout client  15s
    timeout server  15s
    errorfile 400 /etc/haproxy/errors/400.http
    errorfile 403 /etc/haproxy/errors/403.http
    errorfile 408 /etc/haproxy/errors/408.http
    errorfile 500 /etc/haproxy/errors/500.http
    errorfile 502 /etc/haproxy/errors/502.http
    errorfile 503 /etc/haproxy/errors/503.http
    errorfile 504 /etc/haproxy/errors/504.http


frontend localhost80
    bind *:80
    mode http
    redirect scheme https code 301 if !{ ssl_fc }

frontend localhost443
    bind *:443
    option tcplog
    mode tcp

    acl tls req.ssl_hello_type 1

    tcp-request inspect-delay 5s
    tcp-request content accept if tls

    acl is_wordpress req.ssl_sni -i mydomain1.com   #10.0.0.165
    acl is_nextcloud req.ssl_sni -i mydomain2.com                #10.0.0.160

    use_backend nextcloud_cluster if is_nextcloud
    use_backend wordpress_cluster if is_wordpress


backend wordpress_cluster
    mode tcp

    option ssl-hello-chk

    server is_wordpress 10.0.0.165:443 check


backend nextcloud_cluster
    mode tcp

    option ssl-hello-chk

    server is_nextcloud 10.0.0.160:443 check

#12

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.