ssl - How to do server fixation with HAProxy through HTTPS

06
2014-04
  • hydrarulz

    I previously created a loadbalancer for web servers in HAProxy, but that one was HTTP, not HTTPS.

    This is he config I previously used.

    listen appname 0.0.0.0:80
        mode http
        stats enable
        stats uri /haproxy?stats
        stats realm Strictly\ Private
        stats auth admin:XXXXXXXX
        balance roundrobin
        option http-server-close
        timeout http-keep-alive 3000
        option forwardfor
        cookie SRVNAME insert
        server lamp1 10.128.24.97:80 cookie S1 check
        server lamp2 10.128.24.98:80 cookie S2 check
    

    I don't know how to rewrite this config to make the requests to port 443 available to the servers behind HAProxy. I copied the previous one and changed the port to 443. However I get a lot of errors. How can I translate the config to be valid for a HTTPS / SSL connection?

    listen httpsapp 0.0.0.0:443
        mode tcp
        stats enable
        stats uri /haproxy?stats
        stats realm Strictly\ Private
        stats auth admin:XXXXXXXXXXX
        balance roundrobin
        option http-server-close
        timeout http-keep-alive 3000
        option forwardfor
        cookie SRVNAME insert
        server lamp1 10.128.24.97:443 cookie S1 check
        server lamp2 10.128.24.98:443 cookie S2 check
    

    I get the warnings when I restart HAProxy

    [WARNING] 007/090716 (2409) : config : cookie will be ignored for proxy 'httpsapp' (needs 'mode http').
    [WARNING] 007/090716 (2409) : config : 'option httplog' not usable with proxy 'httpsapp' (needs 'mode http'). Falling back to 'option tcplog'.
    [WARNING] 007/090716 (2409) : config : 'stats' statement ignored for proxy 'httpsapp' as it requires HTTP mode.
    [WARNING] 007/090716 (2409) : config : 'option forwardfor' ignored for proxy 'httpsapp' as it requires HTTP mode.
    [WARNING] 007/090716 (2409) : config : 'option http-server-close' ignored for proxy 'httpsapp' as it requires HTTP mode.
    [WARNING] 007/090716 (2409) : config : proxy 'httpsapp' : ignoring cookie for server 'lamp1' as HTTP mode is disabled.
    [WARNING] 007/090716 (2409) : config : proxy 'httpsapp' : ignoring cookie for server 'lamp2' as HTTP mode is disabled.
    
  • Answers
  • walkeran

    When you create an HTTPS proxy (depending on what version of HAProxy you are using, and if it has SSL support compiled in), you have 2 different ways of handling the traffic.

    One is the route you took with this config -- Make it a straight TCP proxy, and pass the traffic right through to the backend server without doing any Layer7 processing.

    mode tcp
    

    When in tcp mode, you won't be able to use any options that are specifically for http proxies -- in your case, you'd lose the stats endpoint, the cookie processing, the insertion of the 'X-Forwarded-For' header, etc. The warnings are in place to just let you know that this proxy will still function, but it probably won't operate as you are expecting, since you use options that are specific only to http proxies.

    The other route you could take, is to terminate the SSL on the HAProxy server. In this scenario, you have HTTPS traffic between your client and HAProxy, and (typically) unencrypted HTTP traffic between HAProxy and your backend servers. If you were going to do the SSL termination in HAProxy itself, and not with something like pound, then you would need to be running v1.5 with SSL support compiled in. Your resulting proxy config could look something like the following.

    listen appname
      bind 0.0.0.0:80
      bind 0.0.0.0:443 ssl crt /path/to/your/cert.pem ciphers TLSv1+HIGH:!SSLv2:RC4+MEDIUM:!aNULL:!eNULL:!3DES:@STRENGTH
      mode http
      stats enable
      stats uri /haproxy?stats
      stats realm Strictly\ Private
      stats auth admin:XXXXXXXX
      balance roundrobin
      option http-server-close
      timeout http-keep-alive 3000
      option forwardfor
      cookie SRVNAME insert
      server lamp1 10.128.24.97:80 cookie S1 check
      server lamp2 10.128.24.98:80 cookie S2 check
    

    A couple of notes on this. This listen directive is actually lumping both the HTTP and the HTTPS proxies into the same one. It could just as easily be split back up, but unless it's required, I like to keep things a little cleaner like this. Also, the "ciphers" options are configurable to your liking or application -- I'm no SSL expert, but those options are what work for me, so I figured I'd include them.


  • Related Question

    ssl - Daily Dilbert strip served by https
  • crb

    I have a web site which embeds the Daily Dilbert comic strip by parsing it from the RSS feed that dilbert.com publishes, but said website is SSL encrypted, and the image as published is not. This triggers a mixed content warning in Internet Explorer.

    I don't want to have to pull it down once a day and serve it locally if I can help - does anyone have a link to a publicly available daily Dilbert which I can fetch with an SSL (https) URL?

    Edit: I hadn't thought of proxying it myself (thanks splattne!) which solves it neatly:

        RewriteCond %{REQUEST_URI} ^/dilbert-proxy/
        RewriteRule ^/dilbert-proxy/(.*)$ http://dilbert.com/$1 [P]
    

  • Related Answers
  • splattne

    Let's pretend you've got the permission from Scott Adams or whoever owns the rights of the Dilbert strips.

    You could do some reverse proxying, creating a rule for a fictive URL on your site, let's say a request

    https://www.example.com/dilbert/strip.gif
    

    which triggers your reverse proxy mechanism to fetch the image from the dilbert.com site

    http://www.dilbert.com/..../strip.gif
    

    and sending the response from your server with the content fetched from the Dilbert server. This way you can keep the SSL connection, because it's transparent for the user.

    Depending on your platform you'll have to see your options for using a revery proxy mechanism.

  • patjbs

    Unless you have permission from the site owners at Daily Dilbert, I'd suggest doing exactly that - make a local copy and serve it yourself. Serving the image on your page off their servers is bad web manners.