3. Simple HTTP/HTTPS load-balancing with cookie insertion

=========================================================
3. Simple HTTP/HTTPS load-balancing with cookie insertion
=========================================================

This is the same context as in example 1 above, but the web
server uses HTTPS.

                +-------+
                |clients|  clients
                +---+---+
                    |
                   -+-----+--------+----
                          |       _|_db
                       +--+--+   (___)
                       | SSL |   (___)
                       | web |   (___)
                       +-----+
                   192.168.1.1   192.168.1.2


Since haproxy does not handle SSL, this part will have to be extracted from the
servers (freeing even more ressources) and installed on the load-balancer
itself. Install haproxy and apache+mod_ssl on the old box which will spread the
load between the new boxes. Apache will work in SSL reverse-proxy-cache. If the
application is correctly developped, it might even lower its load. However,
since there now is a cache between the clients and haproxy, some security
measures must be taken to ensure that inserted cookies will not be cached.


  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     apache         4 cheap web servers
     mod_ssl
     haproxy


Config on haproxy (LB1) :
-------------------------
      
    listen 127.0.0.1:8000
       mode http
       balance roundrobin
       cookie SERVERID insert indirect nocache
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check
      

Description :
-------------
 - apache on LB1 will receive clients requests on port 443
 - it forwards it to haproxy bound to 127.0.0.1:8000
 - if a request does not contain a cookie, it will be forwarded to a valid
   server
 - in return, a cookie "SERVERID" will be inserted in the response holding the
   server name (eg: "A"), and a "Cache-control: private" header will be added
   so that the apache does not cache any page containing such cookie.
 - when the client comes again with the cookie "SERVERID=A", LB1 will know that
   it must be forwarded to server A. The cookie will be removed so that the
   server does not see it.
 - if server "webA" dies, the requests will be sent to another valid server
   and a cookie will be reassigned.

Notes :
-------
 - if the cookie works in "prefix" mode, there is no need to add the "nocache"
   option because it is an application cookie which will be modified, and the
   application flags will be preserved.
 - if apache 1.3 is used as a front-end before haproxy, it always disables
   HTTP keep-alive on the back-end, so there is no need for the "httpclose"
   option on haproxy.
 - configure apache to set the X-Forwarded-For header itself, and do not do
   it on haproxy if you need the application to know about the client's IP.


Flows :
-------

(apache)                           (haproxy)                         (server A)
  >-- GET /URI1 HTTP/1.0 ------------> |
               ( no cookie, haproxy forwards in load-balancing mode. )
                                       | >-- GET /URI1 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
               ( the proxy now adds the server cookie in return )
  <-- HTTP/1.0 200 OK ---------------< |
      Set-Cookie: SERVERID=A           |
      Cache-Control: private           |
  >-- GET /URI2 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
      ( the proxy sees the cookie. it forwards to server A and deletes it )
                                       | >-- GET /URI2 HTTP/1.0 ---------->
                                       | <-- HTTP/1.0 200 OK -------------<
   ( the proxy does not add the cookie in return because the client knows it )
  <-- HTTP/1.0 200 OK ---------------< |
  >-- GET /URI3 HTTP/1.0 ------------> |
      Cookie: SERVERID=A               |
                                    ( ... )



========================================
3.1. Alternate solution using Stunnel
========================================

When only SSL is required and cache is not needed, stunnel is a cheaper
solution than Apache+mod_ssl. By default, stunnel does not process HTTP and
does not add any X-Forwarded-For header, but there is a patch on the official
haproxy site to provide this feature to recent stunnel versions.

This time, stunnel will only process HTTPS and not HTTP. This means that
haproxy will get all HTTP traffic, so haproxy will have to add the
X-Forwarded-For header for HTTP traffic, but not for HTTPS traffic since
stunnel will already have done it. We will use the "except" keyword to tell
haproxy that connections from local host already have a valid header.


  192.168.1.1    192.168.1.11-192.168.1.14   192.168.1.2
 -------+-----------+-----+-----+-----+--------+----
        |           |     |     |     |       _|_db
     +--+--+      +-+-+ +-+-+ +-+-+ +-+-+    (___)
     | LB1 |      | A | | B | | C | | D |    (___)
     +-----+      +---+ +---+ +---+ +---+    (___)
     stunnel        4 cheap web servers
     haproxy


Config on stunnel (LB1) :
-------------------------

    cert=/etc/stunnel/stunnel.pem
    setuid=stunnel
    setgid=proxy

    socket=l:TCP_NODELAY=1
    socket=r:TCP_NODELAY=1

    [https]
    accept=192.168.1.1:443
    connect=192.168.1.1:80
    xforwardedfor=yes


Config on haproxy (LB1) :
-------------------------
      
    listen 192.168.1.1:80
       mode http
       balance roundrobin
       option forwardfor except 192.168.1.1
       cookie SERVERID insert indirect nocache
       option httpchk HEAD /index.html HTTP/1.0
       server webA 192.168.1.11:80 cookie A check
       server webB 192.168.1.12:80 cookie B check
       server webC 192.168.1.13:80 cookie C check
       server webD 192.168.1.14:80 cookie D check

Description :
-------------
 - stunnel on LB1 will receive clients requests on port 443
 - it forwards them to haproxy bound to port 80
 - haproxy will receive HTTP client requests on port 80 and decrypted SSL
   requests from Stunnel on the same port.
 - stunnel will add the X-Forwarded-For header
 - haproxy will add the X-Forwarded-For header for everyone except the local
   address (stunnel).


========================================
 

你可能感兴趣的:(haproxy,https,simple,cookie,insertion)