Re: http-request set-map key as fixed string
(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
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
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
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
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
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
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
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
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
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
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
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?