HOWTO SSL native in HAProxy

IMPORTANT NOTE: this article has been outdated since HAProxy-1.5-dev12 has been released (10th of September). For more information about SSL inside HAProxy. please read:


How to get SSL with HAProxy getting rid of stunnel, stud, nginx or pound

Synopsis

Since yesterday night (FR time), HAProxy can support SSL offloading. It can even crypt traffic to a downstream server.
We’ll see later all the fun we could have with these nice features and the goodness it could bring in term of architecture. Today, I’ll just focus on how to install and configure HAProxy to offload SSL processing from your servers.

It’s important to notice that in order to be able to manage SSL connections, a huge rework of connection management has been done in HAProxy. Despite the long time spent on testing, there might still remain some bugs.
So we ask anybody who tests the procedure below to report bugs to HAProxy mailing list.

Note as well that the job was done by Exceliance engineers, who already improved stunnel and stud.

SSL offloading diagram

This is pretty simple, as shown on the picture below. The client will get connected on HAProxy using SSL, HAProxy will process SSL and get connected in clear to the server:
ssl offloading diagram

HAproxy installation

cd /usr/src
wget http://haproxy.1wt.eu/download/1.5/src/snapshot/haproxy-ss-20120905.tar.gz
tar xzf haproxy-ss-20120905.tar.gz
cd haproxy-ss-20120905/
make TARGET=linux2628 USE_STATIC_PCRE=1 USE_OPENSSL=1
sudo make PREFIX=/opt/haproxy-ssl install

HAProxy configuration for SSL offloading


First of all, you have to generate a key and a certificate using openssl and concatenate them in a file, the certificate first, then the key.
Here is mine, just copy/paste it in a file for your tests:

-----BEGIN CERTIFICATE-----
MIIBrzCCARgCCQCfMsCGwq31yzANBgkqhkiG9w0BAQUFADAcMRowGAYDVQQDExF3
d3cuZXhjZWxpYW5jZS5mcjAeFw0xMjA5MDQwODU3MzNaFw0xMzA5MDQwODU3MzNa
MBwxGjAYBgNVBAMTEXd3dy5leGNlbGlhbmNlLmZyMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDFxSTUwX5RD4AL2Ya5t5PAaNjcwPa3Km40uaPKSHlU8AMydxC1
wB4L0k3Ms9uh98R+kIJS+TxdfDaYxk/GdDYI1CMm4TM+BLHGAVA2DeNf2hBhBRKb
TAgxCxXwORJQSB/B+1r0/ZiQ2ig5Jzr8xGHz+tBsHYZ+t+RmjZPQFjnlewIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBABqVuloGWHReSGLY1yAs20uhJ3j/9SvtoueyFBag
z5jX4BNO/4yhpKEpCGmzYtjr7us3v/s0mKoIVvAgah778rCZW3kF1Y6xR6TYqZna
1ryKB50/MJg9PC4LNL+sAu+WSslOf6+6Ru5N3JjhIZST8edJsGDi6/5HTKoqyvkp
wOMn
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDFxSTUwX5RD4AL2Ya5t5PAaNjcwPa3Km40uaPKSHlU8AMydxC1
wB4L0k3Ms9uh98R+kIJS+TxdfDaYxk/GdDYI1CMm4TM+BLHGAVA2DeNf2hBhBRKb
TAgxCxXwORJQSB/B+1r0/ZiQ2ig5Jzr8xGHz+tBsHYZ+t+RmjZPQFjnlewIDAQAB
AoGBALUeVhuuVLOB4X94qGSe1eZpXunUol2esy0AMhtIAi4iXJsz5Y69sgabg/qL
YQJVOZO7Xk8EyB7JaerB+z9BIFWbZwS9HirqR/sKjjbhu/rAQDgjVWw2Y9sjPhEr
CEAvqmQskT4mY+RW4qz2k8pe4HKq8NAFwbe8iNP7AySP3K4BAkEA4ZPBagtlJzrU
7Tw4BvQJhBmvNYEFviMScipHBlpwzfW+79xvZhTxtsSBHAM9KLbqO33VmJ3C/L/t
xukW8SO6ewJBAOBxU0TfS0EzcRQJ4sn78G6hTjjLwJM2q4xuSwLQDVaWwtXDI6HE
jb7HePaGBGnOrlXxEOFQZCVdDaLhX0zcEQECQQDHcvc+phioGRKPOAFp1HhdfsA2
FIBZX3U90DfAXFMFKFXMiyFMJxSZPyHQ/OQkjaaJN3eWW1c+Vw0MJKgOSkLlAkEA
h8xpqoFEgkXCxHIa00VpuzZEIt89PJVWhJhzMFd7yolbh4UTeRx4+xasHNUHtJFG
MF+0a+99OJIt3wBn7hQ1AQJACScT3p6zJ4llm59xTPeOYpSXyllR4GMilsGIRNzT
RGYxcvqR775RkAgE+5DHmAkswX7TBaxcO6+C1+LJEwFRxw==
-----END RSA PRIVATE KEY-----

Now, HAProxy configuration, very basic, for test purpose, and just to let you know which lines are very important:

frontend ft_test
  mode http
  bind 0.0.0.0:8443 ssl crt ./haproxy.pem  # basic conf require only 1 keyword
  # other (self described) options are: [ciphers <suite>] [nosslv3] [notlsv1]
  default_backend bk_test

backend bk_test
  mode http
  server srv1 127.0.0.1:80

Running HAProxy


First, just test the configuration is valid:

/opt/haproxy-ssl/sbin/haproxy -c -f ./ha.cfg 
[WARNING] 247/110924 (6497) : config : missing timeouts for frontend 'ft_test'.
   | While not properly invalid, you will certainly encounter various problems
   | with such a configuration. To fix this, please ensure that all following
   | timeouts are set to a non-zero value: 'client', 'connect', 'server'.
[WARNING] 247/110924 (6497) : config : missing timeouts for backend 'bk_test'.
   | While not properly invalid, you will certainly encounter various problems
   | with such a configuration. To fix this, please ensure that all following
   | timeouts are set to a non-zero value: 'client', 'connect', 'server'.
Configuration file is valid

Don’t worry about warnings, I purposely wrote a very basic configuration.

Now, you can run HAProxy:

/opt/haproxy-ssl/sbin/haproxy  -f ./ha.cfg

Testing SSL provided by HAProxy


Use curl, with “–insecure” option if your certificate is self-signed, like mine:

curl --noproxy \* -D - --insecure https://127.0.0.1:8443/index.html
HTTP/1.1 200 OK
Date: Tue, 04 Sep 2012 09:13:55 GMT
Server: Apache/2.2.16 (Debian)
Last-Modified: Tue, 04 Sep 2012 09:10:01 GMT
ETag: "a35d1-e-4c8dc9f7d6c40"
Accept-Ranges: bytes
Content-Length: 14
Vary: Accept-Encoding
Content-Type: text/html

Welcome page.

Check SSL parameters with openssl in client mode:

openssl s_client -connect 127.0.0.1:8443
CONNECTED(00000003)
depth=0 /CN=www.exceliance.fr
verify error:num=18:self signed certificate
verify return:1
depth=0 /CN=www.exceliance.fr
verify return:1
---
Certificate chain
 0 s:/CN=www.exceliance.fr
   i:/CN=www.exceliance.fr
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIBrzCCARgCCQCfMsCGwq31yzANBgkqhkiG9w0BAQUFADAcMRowGAYDVQQDExF3
d3cuZXhjZWxpYW5jZS5mcjAeFw0xMjA5MDQwODU3MzNaFw0xMzA5MDQwODU3MzNa
MBwxGjAYBgNVBAMTEXd3dy5leGNlbGlhbmNlLmZyMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDFxSTUwX5RD4AL2Ya5t5PAaNjcwPa3Km40uaPKSHlU8AMydxC1
wB4L0k3Ms9uh98R+kIJS+TxdfDaYxk/GdDYI1CMm4TM+BLHGAVA2DeNf2hBhBRKb
TAgxCxXwORJQSB/B+1r0/ZiQ2ig5Jzr8xGHz+tBsHYZ+t+RmjZPQFjnlewIDAQAB
MA0GCSqGSIb3DQEBBQUAA4GBABqVuloGWHReSGLY1yAs20uhJ3j/9SvtoueyFBag
z5jX4BNO/4yhpKEpCGmzYtjr7us3v/s0mKoIVvAgah778rCZW3kF1Y6xR6TYqZna
1ryKB50/MJg9PC4LNL+sAu+WSslOf6+6Ru5N3JjhIZST8edJsGDi6/5HTKoqyvkp
wOMn
-----END CERTIFICATE-----
subject=/CN=www.exceliance.fr
issuer=/CN=www.exceliance.fr
---
No client certificate CA names sent
---
SSL handshake has read 604 bytes and written 319 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: CF9B7BFF64DE0B332CE9A76896EC1C59C941340D6913612286113FA1F7E09E88
    Session-ID-ctx: 
    Master-Key: C6893078E49626DAF329C61774BA5A35E0264818E0D76542F25BB958584B835154402E02F9B722DD94C56B14EBB14D46
    Key-Arg   : None
    Start Time: 1346750742
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
GET / HTTP/1.0

HTTP/1.1 200 OK
Date: Tue, 04 Sep 2012 09:26:44 GMT
Server: Apache/2.2.16 (Debian)
Last-Modified: Tue, 04 Sep 2012 09:10:01 GMT
ETag: "a35d1-e-4c8dc9f7d6c40"
Accept-Ranges: bytes
Content-Length: 14
Vary: Accept-Encoding
Connection: close
Content-Type: text/html

Welcome page.
closed

Related articles

Links

About these ads

About Baptiste Assmann

Aloha Product Manager
This entry was posted in HAProxy, layer7, ssl and tagged , , , , , , . Bookmark the permalink.

23 Responses to HOWTO SSL native in HAProxy

  1. Thanks for the how-to Baptiste!

    Do you know how well this scales in terms of CPU utilization for SSL processing – can it take advantage of multiple cores?

  2. Pingback: Haproxy SSL support » Mind End | Mind End

  3. Nick Huanca says:

    First I’d like to say, AWESOME! Finally this is a great feature addition!

    Secondly I would like to note I am looking on the haproxy website and this release is still not in the stable release state (http://haproxy.1wt.eu/git?p=haproxy.git;a=commit;h=ee2e3a4027e3a35c43790667a8d61865d93f7ec3). v1.5-development

    FYI for people just copy and pasting the setup instructions :)

    • wtarreau says:

      Nick, as indicated on the mailing list post, 1.5 is still in development and this is a preview of the next development release. Basically it’s a merge in the master tree of several months of hard work, that’s why it was posted. We’re trying to fix as many issues as we can before the -dev12 version so that users can safely try it without bothering with build issues for instance.

  4. wtarreau says:

    Baptiste, could you please update your link to point to 20120905, we fixed a number of build issues so it will save some unpleasant experience to new visitors.

  5. wtarreau says:

    @Kyle: yes that’s how we did it, 4 processes (nbproc 4) on the machine. There are indeed issues with health checks and stats with that number of processes, but it was just for experimentation. We want to work further to dedicate processes to SSL offloading, where this will not be much a problem. Also it’s quite possible to replace stunnel with an haproxy running with nbproc 2 for instance. You won’t get less stats nor health checks :-) If we find time, we’ll merge Emeric’s multi-node SSL synchronization code, which is awesome and allows many hosts to share the same SSL sessions. That way you can build farms out of multiple multi-core machines :-)

  6. Pingback: Enhanced SSL load-balancing with Server Name Indication (SNI) TLS extension | Exceliance – Aloha Load Balancer

  7. Pingback: Scaling out SSL | Exceliance – Aloha Load Balancer

  8. Pingback: Benchmarking SSL performance | Exceliance – Aloha Load Balancer

  9. Pingback: Sysadmin Sunday 96 - Server Density Blog

  10. Pingback: How to get SSL with HAProxy getting rid of stunnel, stud, nginx or pound | Exceliance – Aloha Load Balancer

  11. Pingback: SSL Client certificate management at application level | Exceliance – Aloha Load Balancer

  12. Pingback: » Load Balancing with HAProxy 1.4 thejimmahknows

  13. Бронислав Швец says:

    Have a problem: My configuration is:
    frontend ft_test

    mode http
    bind 0.0.0.0:443 ssl /etc/ssl/output.pem # basic conf require only 1 keyword
    # other (self described) options are: [ciphers ] [nosslv3] [notlsv1]
    default_backend bk_test
    backend bk_test
    mode http
    server srv1 0.0.0.0:8888

    when i use (haproxy -f /etc/haproxy/haproxy.cfg -c) or try restart haproxy? System give me error like this:
    [ALERT] 332/074210 (31836) : parsing [/etc/haproxy/haproxy.cfg:42] : ‘bind’ only supports the ‘transparent’, ‘defer-accept’, ‘name’, ‘id’, ‘mss’ and ‘interface’ options.
    [ALERT] 332/074210 (31836) : Error(s) found in configuration file : /etc/haproxy/haproxy.cfg
    [ALERT] 332/074210 (31836) : Fatal errors found in configuration.

    Where my problem? I can’t find it :-(

  14. Michael says:

    Hi Baptiste,
    I’ve tested in my project. Says the server is “http://192.168.0.1:80″ and the frontend is “https://192.168.0.2:8443″, when i connect it from chrome with url “https://192.168.0.2:8443/login.jsp”, it go well(successfully open the page of http://192.168.0.1:80/login.jsp). But then when the server try to redirect to the main page “http://192.168.0.1:80/main.jsp”, the frontend(my chrome) actually try to connect “http://192.168.0.2:8443/main.jsp”, of course it failed. How can i fix it?

    Thx

  15. lordlinus says:

    Hey I have followed all the step as above but when I am running the command

    /opt/haproxy-ssl/sbin/haproxy -f ./ha.cfg:

    I am gettting the error :

    [ALERT] 332/074210 (31836) : parsing [/etc/haproxy/haproxy.cfg:42] : ‘bind’ only supports the ‘transparent’, ‘defer-accept’, ‘name’, ‘id’, ‘mss’ and ‘interface’ options.

    I have compile using USE_OPENSSL=1 too. but getting the same problem, whats my problem ?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s