HTTP to HTTPS Using TCP Mode - Exchange 13'

Hello All!

I currently have a test environment with an exchange 2013 configuration being load balanced by an HAProxy virtual machine. All is working moderately well, mail routes with no problem and there are no major issues. However, I have noticed two (2) oddities that I have been unable to remedy…

The first is that, I am able to get to the OWA portal just fine using https (https://mail.domain.com). Yet, when I attempt to use http to resolve the page, it returns nothing. Exchange 2013 is configured to redirect any http connection to https but when you attempt to resolve http://mail.domain.com, the browsers just spins. I believe that this is because i’m using layer 4 (TCP) load balancing instead of http load balancing.

Is there a way to forward any incoming request on port 80 to 443 on the back end using “TCP Mode”? Or is there an alternate configuration using “http mode” available that does NOT require loading an ssl certificate into HAProxy (All encryption/decryption will be handled by the CAS server… HAProxy simply forwards the incoming connections to said servers)?

The second issue I have is that, periodically, my test outlook account will display “connection to server lost”. It only does this for a few moments and then immediately reconnects and everything is fine. I have increased the timeouts in the defaults section but this did not seem to have any effect. Also, there are a large amount of “Client connection resets during transfers” in the HAProxy status page.

Configuration can be found below. Any insight/assistance is greatly appreciated!

Thank you!

global
user haproxy
group haproxy
log /dev/log local0
chroot /var/lib/haproxy#
maxconn 10000
daemon

defaults
mode tcp
balance leastconn
option redispatch
maxconn 10000
contimeout 5000
clitimeout 50000
srvtimeout 50000
default-server inter 3s rise 2s fall 3

timeout http-keep-alive 1s
timeout http-request 15s
timeout queue 30s
timeout tarpit 1m
backlog 10000

listen OWA 1.2.2.45:443
option httpchk GET /owa/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

listen EAC 1.2.2.45:443
option ssl-hello-chk GET /eas/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31:443 check
server SERVER2 1.2.2.32:443 check

listen EWS 1.2.2.45:443
option httpchk GET /ews/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

listen OAB 1.2.2.45:443
option httpchk GET /oab/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

listen EAS 1.2.2.45:443
option httpchk GET /Microsoft-Server-ActiveSync/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

listen Autodiscover 1.2.2.45:443
option httpchk GET /Autodiscover/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

listen OA 1.2.2.45:443
option httpchk GET /rpc/healthcheck.htm
http-check expect status 200
server SERVER1 1.2.2.31 check port 80
server SERVER2 1.2.2.32 check port 80

Hi,

First, could you confirm that you miss the "ssl crt " statements in the configuration you copy/pasted, cause currently, this configuration simply can’t work!

To get HTTP to HTTPs redirection working, you must create a listen section for this purpose:

listen OWA
  bind 1.2.2.45:80
  option httpchk GET /owa/healthcheck.htm
  http-check expect status 200
  server SERVER1 1.2.2.31 check port 80
  server SERVER2 1.2.2.32 check port 80

Or better, you can configure HAProxy to perform the redirection itself:

frontend owa-http
  bind 1.2.2.45:80
  mode http
  http-redirect location https://%[req.hdr(Host)]/owa/

By the way, your configuration is broken by design. Each of your listen section binds the same IP address and port. Which means for new incoming connections, your kernel is going to pick up any of the TCP socket to forward it the connection. Imagine, you want to use OWA and the kernel affect you to the Autodiscover bind socket…
I mean, it currently “works” by luck because all the exchange servers can deliver all the services and in 2013, no persistence is required at all.

An other point:

listen Autodiscover 1.2.2.45:443

is forbidden and should be written:

listen Autodiscover
  bind 1.2.2.45:443 ssl crt <pemfile>

For your last problem, we need to see the log lines to further troubleshoot.

You may want to have a look at this HAProxy/Exchange 2013 deployment guide:
http://haproxy.com/doc/aloha/7.5/deployment_guides/microsoft_exchange_2013.html

Thank you for the reply!

I will read through the guide fully as soon as I am able; I expect that my second problem is directly related to the issues you outlined above.

As for the “ssl crt” statements, I do not have any in the configuration. Aside from the statistics section, that is the entire config. I skimmed through the guide and I would say that (at least in theory/thought process) I am trying to setup HAProxy as a raw TCP transparent proxy… As such, would I need to specify an ssl cert (.pem) for use if HAProxy isn’t actually looking at any of the contents of the packets?

I appreciate your time and feedback!

So you must forward traffic to server’s port 443. You should enable check-ssl on the server line to force the HTTP check request to be sent over TLS.

I ran into this exact same issue. The HAProxy is used for internal load balancing and I wanted users to be redirected to HTTPS. The below configuration does the trick:

frontend ft_exchange_tcp
bind x.x.x.x:443 name https
maxconn 10000
default_backend bk_exchange_tcp
mode tcp

frontend ft_exchange_tcp_http
bind x.x.x.x:80
mode http
redirect scheme https if !{ ssl_fc }

backend bk_exchange_tcp
server server1 x.x.x.x:443 maxconn 10000 check
server server2 x.x.x.x:443 maxconn 10000 check
mode tcp