Re: http-request set-map key as fixed string

2015-02-27 Thread Vivek Malik
(Sorry for pressing send too early)

Hi,

I am trying to use http-request set-map with fixed strings which are
defined in config file. Example lines

http-request set-map(motion.map) monday %[date()] if acl_1
http-request set-map(motion.map) tuesday %[date()] if acl_2

Note that monday and tuesday are literal string and not log-format
variables. However, when I look into the map using

echo show map motion.map | socat stdio /var/run/socket-haproxy
0x13c1b90  1425089705

As you can see, the key is missing from the map. monday is getting
replaced by space  

However, if I switch the format to
http-request set-map(motion.map) %[date()] monday if acl_1

such that the literal string monday is a value instead of key, the
set-map works fine.

echo show map motion.map | socat stdio /var/run/socket-haproxy
0x13c1b90 1425089710 monday


Please suggest if I have stumbled across a bug or I am missing
something in my configuration.

Regards,
Vivek

On Fri, Feb 27, 2015 at 8:20 PM, Vivek Malik vivek.ma...@gmail.com wrote:
 Hi,

 I am trying to use http-request set-map with fixed strings which are
 defined in config file. Example lines

 http-request set-map(motion.map) monday %[date()] if acl_1
 http-request set-map(motion.map) tuesday %[date()] if acl_2

 Note that monday and tuesday are literal string and not log-format
 variables. However, when I look into the map using

 echo show map motion.map | socat stdio /var/run/socket-haproxy
 0x13c1b90  1425089705

 As you can see, the key is missing from the map. monday is getting
 replaced by space  

 However, if I switch the format to



Re: Balancing requests and backup servers

2015-02-27 Thread Baptiste
On Fri, Feb 27, 2015 at 12:04 PM, Dmitry Sivachenko trtrmi...@gmail.com wrote:

 On 27 февр. 2015 г., at 11:52, Baptiste bed...@gmail.com wrote:

 On Fri, Feb 27, 2015 at 9:02 AM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:

 On 27 февр. 2015 г., at 2:56, Baptiste bed...@gmail.com wrote:

 On Thu, Feb 26, 2015 at 3:58 PM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:
 Hello!

 Given the following configuration

 backend BC
 option allbackups
 server s1 maxconn 30 check
 server s2 maxconn 30 check
 server s3 maxconn 30 check
 server b1 maxconn 30 check backup
 server b2 maxconn 30 check backup

 imagine that s1, s2 and s3 have 30 active sessions and (tcp) checks 
 succeed.


 Hi Dmitry.

 Let me answer inline:

 1) subsequent requests will be balanced between b1 and b2 because s1, s2 
 and s3 reached it's maxconn

 nope, they'll be queued on the backend until one of the server has a free 
 slot
 b1 and b2 will be used when ALL s1, s2 and s3 will be operationnaly DOWN.


 Okay, then how can I achieve the described setup?
 I want to balance requests between s1, s2, s3 until they have less than N 
 active sessions and route extra requests to b1 and b2.


 Two solutions:

 - use balance first load-balancing algorithm and remove the backup keyword
 - create 2 backends, one with 3 servers, one with two, use the 'queue'
 fetch to get the number of queued request on backend1 and route to
 backend 2 if the number is greater than 0.



 BTW what if I have maxqueue 1 in default-server?
 If queue is full for all servers will that backend use backup servers?

Hi,

no, backup servers will be used only when all active servers are DOWN.

Baptiste



Re: http-request set-map key as fixed string

2015-02-27 Thread Vivek Malik
Hi Baptise,

Using set-map on the stats socket gives the expected result (except
that I can't use functions there). set map motion.map monday 12345 did
set the map with key monday and value as 12345.

I found that http-request set-map(motion.map) monday %[date] doesn't
work, but http-request set-map(motion.map) %t does work. Using %T,
%TL, %t works as expected but %[date] doesn't.

Moreover, I am getting crazy results when I try to use http-request
set-map(motion.map) monday %[src]. Using this makes both key and
value as src.

BTW, I am using

HA-Proxy version 1.5.11 2015/01/31
Copyright 2000-2015 Willy Tarreau w...@1wt.eu

Build options :
  TARGET  = linux2628
  CPU = generic
  CC  = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing
  OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_STATIC_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
Running on OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.31 2012-07-06
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT
IPV6_TRANSPARENT IP_FREEBIND

Available polling systems :
  epoll : pref=300,  test result OK
   poll : pref=200,  test result OK
 select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

On Sat, Feb 28, 2015 at 1:26 AM, Baptiste bed...@gmail.com wrote:
 On Sat, Feb 28, 2015 at 3:22 AM, Vivek Malik vivek.ma...@gmail.com wrote:
 (Sorry for pressing send too early)

 Hi,

 I am trying to use http-request set-map with fixed strings which are
 defined in config file. Example lines

 http-request set-map(motion.map) monday %[date()] if acl_1
 http-request set-map(motion.map) tuesday %[date()] if acl_2

 Note that monday and tuesday are literal string and not log-format
 variables. However, when I look into the map using

 echo show map motion.map | socat stdio /var/run/socket-haproxy
 0x13c1b90  1425089705

 As you can see, the key is missing from the map. monday is getting
 replaced by space  

 However, if I switch the format to
 http-request set-map(motion.map) %[date()] monday if acl_1

 such that the literal string monday is a value instead of key, the
 set-map works fine.

 echo show map motion.map | socat stdio /var/run/socket-haproxy
 0x13c1b90 1425089710 monday


 Please suggest if I have stumbled across a bug or I am missing
 something in my configuration.



 Hi Vivek,

 could you try the 'set-map' on the stats socket directly and report if
 you have the same result or not?

 Baptiste



http-request set-map key as fixed string

2015-02-27 Thread Vivek Malik
Hi,

I am trying to use http-request set-map with fixed strings which are
defined in config file. Example lines

http-request set-map(motion.map) monday %[date()] if acl_1
http-request set-map(motion.map) tuesday %[date()] if acl_2

Note that monday and tuesday are literal string and not log-format
variables. However, when I look into the map using

echo show map motion.map | socat stdio /var/run/socket-haproxy
0x13c1b90  1425089705

As you can see, the key is missing from the map. monday is getting
replaced by space  

However, if I switch the format to



Re: How to track 503's

2015-02-27 Thread Baptiste
On Fri, Feb 27, 2015 at 8:23 PM, Daniel Dubovik ddubo...@godaddy.com wrote:
 Hello all!

 I am wanting to use HAProxy to detect if I receive a certain status code
 from a backend web server (say, a 503 error or some such) while processing a
 request.  If I do receive it, track the request, so subsequent requests to
 the domain will behave differently (specifically, go to a different backend
 that has a different load balancing method, or different servers that can
 handle their load.

 Is there a way I can do this in HAProxy?  Stick-tables don't let me track
 requests based on the response, only on the request information, so that
 doesn't seem like it would work, but seems like the only place that it would
 fit?

 Thanks!
 Dan



Hi Daniel,

Something not clear in your request is that do you want to route ALL
traffic after an error, or only the traffic from a single user?

You may use the 'stick store-response' when an error is returned by
the server and track it when traffic comes in with the in_table fetch.
This may require you to switch to HAProxy 1.6-dev.

Baptiste



[PATCH 1/2] MEDIUM: Add support for configurable TLS ticket keys

2015-02-27 Thread Nenad Merdanovic
Until now, the TLS ticket keys couldn't have been configured and
shared between multiple instances or multiple servers running HAproxy.
The result was that if a request got a TLS ticket from one instance/server
and it hits another one afterwards, it will have to go through the full
SSL handshake and negotation.

This patch enables adding a ticket file to the bind line, which will be
used for all SSL contexts created from that bind line. We can use the
same file on all instances or servers to mitigate this issue and have
consistent TLS tickets assigned. Clients will no longer have to negotiate
every time they change the handling process.

Signed-off-by: Nenad Merdanovic nmer...@anine.io
---
 include/common/defaults.h |   5 ++
 include/types/listener.h  |   2 +
 include/types/ssl_sock.h  |   6 ++
 src/cfgparse.c|   1 +
 src/ssl_sock.c| 163 +++---
 5 files changed, 155 insertions(+), 22 deletions(-)

diff --git a/include/common/defaults.h b/include/common/defaults.h
index 0e37dac..3b31849 100644
--- a/include/common/defaults.h
+++ b/include/common/defaults.h
@@ -290,4 +290,9 @@
 #ifndef OCSP_MAX_RESPONSE_TIME_SKEW
 #define OCSP_MAX_RESPONSE_TIME_SKEW 300
 #endif
+
+/* Number of TLS tickets to check, used for rotation */
+#ifndef TLS_TICKETS_NO
+#define TLS_TICKETS_NO 3
+#endif
 #endif /* _COMMON_DEFAULTS_H */
diff --git a/include/types/listener.h b/include/types/listener.h
index 6dcaacc..2f5d566 100644
--- a/include/types/listener.h
+++ b/include/types/listener.h
@@ -132,6 +132,8 @@ struct bind_conf {
int strict_sni;/* refuse negotiation if sni doesn't match a 
certificate */
struct eb_root sni_ctx;/* sni_ctx tree of all known certs 
full-names sorted by name */
struct eb_root sni_w_ctx;  /* sni_ctx tree of all known certs wildcards 
sorted by name */
+   struct tls_sess_key *tls_ticket_keys; /* TLS ticket keys */
+   int tls_ticket_enc_index;  /* array index of the key to use for 
encryption */
 #endif
int is_ssl;/* SSL is required for these listeners */
unsigned long bind_proc;   /* bitmask of processes allowed to use these 
listeners */
diff --git a/include/types/ssl_sock.h b/include/types/ssl_sock.h
index a0b2d79..d769acd 100644
--- a/include/types/ssl_sock.h
+++ b/include/types/ssl_sock.h
@@ -32,4 +32,10 @@ struct sni_ctx {
struct ebmb_node name;/* node holding the servername value */
 };
 
+struct tls_sess_key {
+   unsigned char name[16];
+   unsigned char aes_key[16];
+   unsigned char hmac_key[16];
+} __attribute__((packed));
+
 #endif /* _TYPES_SSL_SOCK_H */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ba07794..f2dc839 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -7740,6 +7740,7 @@ out_uri_auth_compat:
free(bind_conf-ciphers);
free(bind_conf-ecdhe);
free(bind_conf-crl_file);
+   free(bind_conf-tls_ticket_keys);
 #endif /* USE_OPENSSL */
}
 
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 8739e8b..bcf70c9 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -57,6 +57,7 @@
 #include common/ticks.h
 #include common/time.h
 #include common/cfgparse.h
+#include common/base64.h
 
 #include ebsttree.h
 
@@ -95,6 +96,13 @@
 #define SSL_SOCK_ST_TO_CAEDEPTH(s) ((s  (6+16))  15)
 #define SSL_SOCK_ST_TO_CRTERROR(s) ((s  (4+6+16))  63)
 
+/* Supported hash function for TLS tickets */
+#ifdef OPENSSL_NO_SHA256
+#define HASH_FUNCT EVP_sha1
+#else
+#define HASH_FUNCT EVP_sha256
+#endif /* OPENSSL_NO_SHA256 */
+
 /* server and bind verify method, it uses a global value as default */
 enum {
SSL_SOCK_VERIFY_DEFAULT  = 0,
@@ -388,6 +396,47 @@ end:
return ret;
 }
 
+#if (defined SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB  TLS_TICKETS_NO  0)
+static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], 
unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc)
+{
+   struct tls_sess_key *keys;
+   struct connection *conn;
+   int head;
+   int i;
+
+   conn = (struct connection *)SSL_get_app_data(s);
+   keys = objt_listener(conn-target)-bind_conf-tls_ticket_keys;
+   head = objt_listener(conn-target)-bind_conf-tls_ticket_enc_index;
+
+   if (enc) {
+   memcpy(key_name, keys[head].name, 16);
+
+   if(!RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH))
+   return -1;
+
+   if(!EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), NULL, 
keys[head].aes_key, iv))
+   return -1;
+
+   HMAC_Init_ex(hctx, keys[head].hmac_key, 16, HASH_FUNCT(), NULL);
+
+   return 1;
+   } else {
+   for (i = 0; i  TLS_TICKETS_NO; i++) {
+   if (!memcmp(key_name, keys[(head + i) % 
TLS_TICKETS_NO].name, 16))
+   goto found;
+   }
+   

[PATCH 2/2] DOC: Document the new tls-ticket-keys bind keyword

2015-02-27 Thread Nenad Merdanovic
Signed-off-by: Nenad Merdanovic nmer...@anine.io
---
 doc/configuration.txt | 12 
 1 file changed, 12 insertions(+)

diff --git a/doc/configuration.txt b/doc/configuration.txt
index bb7d567..0aac7e9 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -8969,6 +8969,18 @@ tfo
   need to build HAProxy with USE_TFO=1 if your libc doesn't define
   TCP_FASTOPEN.
 
+tls-ticket-keys keyfile
+  Sets the TLS ticket keys file to load the keys from. The keys need to be 48
+  bytes long, encoded with base64 (ex. openssl rand -base64 48). Number of keys
+  is specified by the TLS_TICKETS_NO build option (default 3) and at least as
+  many keys need to be present in the file. Last TLS_TICKETS_NO keys will be
+  used for decryption and the penultimate one for encryption. This enables easy
+  key rotation by just appending new key to the file and reloading the process.
+  Keys must be periodically rotated (ex. every 12h) or Perfect Forward Secrecy
+  is compromised. It is also a good idea to keep the keys off any permanent
+  storage such as hard drives (hint: use tmpfs and don't swap those files).
+  Lifetime hint can be changed using tune.ssl.timeout.
+
 transparent
   Is an optional keyword which is supported only on certain Linux kernels. It
   indicates that the addresses will be bound even if they do not belong to the
-- 
2.1.4




[PATCH 0/2] Add support for TLS ticket keys configuration

2015-02-27 Thread Nenad Merdanovic
This patchset adds support to configure TLS ticket keys used for
encryption and decryption of TLS tickets.

This is the 2nd version of the patchset that has been updated based on 
suggestions from Willy TaRreau, Emeric Brun, Lukas Tribus and Remi Gacogne.

Nenad Merdanovic (2):
  MEDIUM: Add support for configurable TLS ticket keys
  DOC: Document the new tls-ticket-keys bind keyword

 doc/configuration.txt |  12 
 include/common/defaults.h |   5 ++
 include/types/listener.h  |   2 +
 include/types/ssl_sock.h  |   6 ++
 src/cfgparse.c|   1 +
 src/ssl_sock.c| 163 +++---
 6 files changed, 167 insertions(+), 22 deletions(-)

-- 
2.1.4




How to track 503's

2015-02-27 Thread Daniel Dubovik
Hello all!

I am wanting to use HAProxy to detect if I receive a certain status code from a 
backend web server (say, a 503 error or some such) while processing a request.  
If I do receive it, track the request, so subsequent requests to the domain 
will behave differently (specifically, go to a different backend that has a 
different load balancing method, or different servers that can handle their 
load.

Is there a way I can do this in HAProxy?  Stick-tables don’t let me track 
requests based on the response, only on the request information, so that 
doesn’t seem like it would work, but seems like the only place that it would 
fit?

Thanks!
Dan



Re: Balancing requests and backup servers

2015-02-27 Thread Dmitry Sivachenko

 On 27 февр. 2015 г., at 2:56, Baptiste bed...@gmail.com wrote:
 
 On Thu, Feb 26, 2015 at 3:58 PM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:
 Hello!
 
 Given the following configuration
 
 backend BC
 option allbackups
 server s1 maxconn 30 check
 server s2 maxconn 30 check
 server s3 maxconn 30 check
 server b1 maxconn 30 check backup
 server b2 maxconn 30 check backup
 
 imagine that s1, s2 and s3 have 30 active sessions and (tcp) checks succeed.
 
 
 Hi Dmitry.
 
 Let me answer inline:
 
 1) subsequent requests will be balanced between b1 and b2 because s1, s2 and 
 s3 reached it's maxconn
 
 nope, they'll be queued on the backend until one of the server has a free slot
 b1 and b2 will be used when ALL s1, s2 and s3 will be operationnaly DOWN.


Okay, then how can I achieve the described setup?
I want to balance requests between s1, s2, s3 until they have less than N 
active sessions and route extra requests to b1 and b2.



 
 2) nbsrv(BC) will be still equal to 3 because checks for s1, s2 and s3 still 
 succeed
 
 nope, nbsrv is 5, since b1 and b2 should be counted as well.
 

In fact backup server does NOT count in nbsrv(), I am not sure if it is a bug 
or a feature.




Re: Balancing requests and backup servers

2015-02-27 Thread Baptiste
On Fri, Feb 27, 2015 at 9:02 AM, Dmitry Sivachenko trtrmi...@gmail.com wrote:

 On 27 февр. 2015 г., at 2:56, Baptiste bed...@gmail.com wrote:

 On Thu, Feb 26, 2015 at 3:58 PM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:
 Hello!

 Given the following configuration

 backend BC
 option allbackups
 server s1 maxconn 30 check
 server s2 maxconn 30 check
 server s3 maxconn 30 check
 server b1 maxconn 30 check backup
 server b2 maxconn 30 check backup

 imagine that s1, s2 and s3 have 30 active sessions and (tcp) checks succeed.


 Hi Dmitry.

 Let me answer inline:

 1) subsequent requests will be balanced between b1 and b2 because s1, s2 
 and s3 reached it's maxconn

 nope, they'll be queued on the backend until one of the server has a free 
 slot
 b1 and b2 will be used when ALL s1, s2 and s3 will be operationnaly DOWN.


 Okay, then how can I achieve the described setup?
 I want to balance requests between s1, s2, s3 until they have less than N 
 active sessions and route extra requests to b1 and b2.


Two solutions:

- use balance first load-balancing algorithm and remove the backup keyword
- create 2 backends, one with 3 servers, one with two, use the 'queue'
fetch to get the number of queued request on backend1 and route to
backend 2 if the number is greater than 0.





 2) nbsrv(BC) will be still equal to 3 because checks for s1, s2 and s3 
 still succeed

 nope, nbsrv is 5, since b1 and b2 should be counted as well.


 In fact backup server does NOT count in nbsrv(), I am not sure if it is a bug 
 or a feature.


My bad :)
This must be by design

Baptiste



Re: Balancing requests and backup servers

2015-02-27 Thread Dmitry Sivachenko

 On 27 февр. 2015 г., at 11:52, Baptiste bed...@gmail.com wrote:
 
 On Fri, Feb 27, 2015 at 9:02 AM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:
 
 On 27 февр. 2015 г., at 2:56, Baptiste bed...@gmail.com wrote:
 
 On Thu, Feb 26, 2015 at 3:58 PM, Dmitry Sivachenko trtrmi...@gmail.com 
 wrote:
 Hello!
 
 Given the following configuration
 
 backend BC
 option allbackups
 server s1 maxconn 30 check
 server s2 maxconn 30 check
 server s3 maxconn 30 check
 server b1 maxconn 30 check backup
 server b2 maxconn 30 check backup
 
 imagine that s1, s2 and s3 have 30 active sessions and (tcp) checks 
 succeed.
 
 
 Hi Dmitry.
 
 Let me answer inline:
 
 1) subsequent requests will be balanced between b1 and b2 because s1, s2 
 and s3 reached it's maxconn
 
 nope, they'll be queued on the backend until one of the server has a free 
 slot
 b1 and b2 will be used when ALL s1, s2 and s3 will be operationnaly DOWN.
 
 
 Okay, then how can I achieve the described setup?
 I want to balance requests between s1, s2, s3 until they have less than N 
 active sessions and route extra requests to b1 and b2.
 
 
 Two solutions:
 
 - use balance first load-balancing algorithm and remove the backup keyword
 - create 2 backends, one with 3 servers, one with two, use the 'queue'
 fetch to get the number of queued request on backend1 and route to
 backend 2 if the number is greater than 0.
 


BTW what if I have maxqueue 1 in default-server?
If queue is full for all servers will that backend use backup servers?