HAproxy + SNI



  • Hallo liebe Community,

    ich habe ein Problem mit haproxy als reverse proxy. Ich möchte gerne 2 verschiedene domains (gleiche externe IP, aber unterschiedliche interne IP) mittels reverse proxy und ssl Verbindung
    aufrufen können. Ich benutze ein Frontend, welches auf den Ports 80 u. 443 abhört und 2 getrennte Backends für die unterschiedlichen domains. Als proxy Typ habe ich SSL/TCP gewählt.
    Das Frontend checkt ob die TSL Erweiterung meine domain enthällt und leitet dann auf die gewünschte Aktion um.

    Ich kann zur Zeit jedoch nur domain1 über http://domain1 aufrufen um dann auf https://domain1 inkl. SSL zukommen. Wenn ich domain2 über http://domain2 aufrufe komme ich zu keiner Seite/Verbindung.
    Rufe ich jedoch die domain2 mittels https://domain2 auf, so komme ich zu meiner gewünschten domain2 inkl. SSL.

    Ich bin schon richtig am Verzweifeln und weiß nicht woran es liegen könnte. Ich habe auch schon versucht auf port 80 von domain2 weiterleiten zulassen und dort einen reforward auf port 443 vorzunehmen.
    Ich wäre sehr dankbar, wenn mir jemand bei der Lösung dieses Problems helfen könnte.

    Liebe Grüße
    Herb



  • Can you share the haproxy.cfg used from the link at the bottom of the config tab? (sorry for the English response..)



  • Hi PiBa,

    big THX for your reply!

    here is my config:

    global
    	stats socket /tmp/haproxy.socket level admin
    	uid			80
    	gid			80
    	nbproc			1
    	chroot			/tmp/haproxy_chroot
    	daemon
    
    frontend WAN
    	bind			WAN_IP:443 name WAN_IP:443   
    	bind			WAN_IP:80   name WAN_IP:80   
    	mode			tcp
    	log			global
    	timeout client		30000
    	tcp-request inspect-delay	5s
    	acl			MAIL	req.ssl_sni -m sub -i domain1.com
    	acl			LAB	req.ssl_sni -m sub -i domain2.com
    	tcp-request content accept if { req.ssl_hello_type 1 }
    
    	use_backend Connect-MAIL_https_ipvANY  if  MAIL 
    	use_backend Connect-LAB_https_ipvANY  if  LAB 
    
    backend Connect-MAIL_https_ipvANY
    	mode			tcp
    	log			global
    	timeout connect		30000
    	timeout server		30000
    	retries			3
    	option			httpchk OPTIONS / 
    	server			Connect-Mail 192.168.0.9:443 check-ssl check inter 1000  verify none 
    
    backend Connect-LAB_https_ipvANY
    	mode			tcp
    	log			global
    	timeout connect		30000
    	timeout server		30000
    	retries			3
    	option			httpchk OPTIONS / 
    	server			Connect-LAB 192.168.0.7:443 check-ssl check inter 1000  verify none
    

    I've installed pfsense again. Now only domain1 can be accessed via https:// domain 2 shows nothing on https:// nor http://



  • Hi Herb,

    The http :80 will be forwarded as-is to backends that expect a ssl connection, also the acl's will not see any SNI information in the plain http request. So this config cannot work..

    If you want to listen for both :443 and :80 on 1 frontend then you 'must' use offloading on the 443 port.
    Otherwise two completely different kinds of traffic HTTP / SSL are forwarded to the (default) backends.

    Since you only want to use https it might be best to configure the :80 on a completely separate frontend where you add a advanced setting for a https redirect.

    redirect scheme https if !{ ssl_fc }
    

    For the https://domain2 the config looks ok, to check that further configure a stats port on the settings tab then check in the stats page that the servers are seen as 'up'. If they are not try changing the method to GET instead of OPTIONS and add a 'version' and hostname.```
    HTTP/1.1\r\nHost:\ www

    
    Once the servers show as 'up' in the stats check that traffic and or connection attempts are send to them.
    
    Regards,
    PiBa-NL


  • Hi PiBa,

    YOU ARE MY HERO!!!
    Everything is now working except the https redirect for domain 1. The backend of the domain points to an IIS server with a roundcube on it. I can get a connection only if I
    browse through https:// to it.

    For the redirection I created a seperate frontend which listem on WAN 80 and than put your code into the advanced passthrough section, the protocol type is http.

    Regards,
    Herb



  • The redirect on :80 should happen for every request that gets there. Also try with a different browser / clear the cache to see if maybe thats somehow affecting what is happening.. Either the redirect should work for any or no domain pointed there. Type http is correct for it. Can you share the config you currently have again?

    Other thought is perhaps you have squid intercepting traffic? While for the other domain there could be a cached or preloaded hsts header?



  • Hi PiBa,

    here is my config agin. I've tryed lots of things, but still no luck. Domain 1 accessible with http:// and https://
    Domain 2 only with https://. The 2443 port is just used, because I thought that maybe it's the fault of winserver 2012, so i installed apache with a basic ssl setup and website on my working machine and had to redirect to port 2443 because of skype allready listening to 443 ;D

    global
    stats socket /tmp/haproxy.socket level admin
    uid 80
    gid 80
    nbproc 1
    chroot /tmp/haproxy_chroot
    daemon
    tune.ssl.default-dh-param 1025

    listen HAProxyLocalStats
    bind 127.0.0.1:2200 name localstats
    mode http
    stats enable
    stats admin if TRUE
    stats uri /haproxy_stats.php?haproxystats=1
    timeout client 5000
    timeout connect 5000
    timeout server 5000

    frontend IN_OFFLOAD
    bind Ext_WAN_IP:443 name Ext_WAN_IP:443 ssl  crt /var/etc/haproxy/IN_OFFLOAD.pem crt /var/etc/haproxy/IN_OFFLOAD 
    mode http
    log global
    option http-keep-alive
    timeout client 30000
    acl check-mail hdr_dir(host) -i domain1.com
    acl check-lab hdr_dir(host) -i domain2.com
    acl aclcrt_IN_OFFLOAD hdr_reg(host) -i ^domain2.com(:([0-9]){1,5})?$
    acl aclcrt_IN_OFFLOAD hdr_reg(host) -i ^www.domain2.com(:([0-9]){1,5})?$
    acl aclcrt_IN_OFFLOAD hdr_reg(host) -i ^domain1.com(:([0-9]){1,5})?$
    acl aclcrt_IN_OFFLOAD hdr_reg(host) -i ^www.domain1.com(:([0-9]){1,5})?$
    use_backend Connect-MAIL_http_ipvANY  if  check-mail aclcrt_IN_OFFLOAD
    use_backend Connect-LAB_http_ipvANY  if  check-lab aclcrt_IN_OFFLOAD

    frontend Redirect
    bind Ext_WAN_IP:80 name Ext_WAN_IP:80 
    mode http
    log global
    option http-keep-alive
    timeout client 30000
    redirect scheme https if !{ ssl_fc }

    backend Connect-MAIL_http_ipvANY
    mode http
    log global
    timeout connect 30000
    timeout server 30000
    retries 3
    option httpchk GET /
    server Connect-Mail 192.168.0.19:2443 ssl check inter 1000  verify none

    backend Connect-LAB_http_ipvANY
    mode http
    log global
    timeout connect 30000
    timeout server 30000
    retries 3
    option httpchk HEAD /
    server Connect-LAB 192.168.0.7:443 ssl check inter 1000  verify none



  • In my opinion the :80 redirect to :443 cannot fail.. Check firebug net screen or network F12 in chrome to check whats happening there..

    As for the :443 frontend i see you have changed it to offloading, that wasn't strictly required but should work.. Anyway if both domains work over https there is no need to change anything there.. (unless if you want to lower cpu usage on pfSense perhaps.. now its decrypting and encrypting the traffic while it passes through)

    Are you sure the domains both resolve to your haproxy-wan-ip? (no split-dns or hosts file overrides?)

    p.s. Skype has a advanced/connection setting to disable listening on 443.. imho its strange they did that by default..



  • Hi PiBa,

    I really want to thank you again for all your help! It's really awesome how the community helps!

    The error was, that I had no rule to allow any wan connection to connect to port 80. I only had that rule for 443 :o OMG so NOOB.
    After that everything worked, but I couldn't access the mailserver(domain1) from lan so I had to switch on pure NAT. But suddently pfsense locked out every wan connection :-[.
    I reinstalled the whole pfsense set everything like before and BOOOOOOOOOM GAME  8)

    Thanks again!
    Herb