Commit Graph

345 Commits

Author SHA1 Message Date
Emmanuel Hocdet
d294aea605 MEDIUM: ssl: support SNI filters with multicerts
SNI filters used to be ignored with multicerts (eg: those providing
ECDSA and RSA at the same time). This patch makes them work like
other certs.

Note: most of the changes in this patch are due to an extra level of
      indent, read it with "git show -b".
2016-06-20 17:15:17 +02:00
Roberto Guimaraes
0ea4c23ca7 BUG/MINOR: ssl: fix potential memory leak in ssl_sock_load_dh_params()
Valgrind reports that the memory allocated in ssl_get_dh_1024() was leaking. Upon further inspection of openssl code, it seems that SSL_CTX_set_tmp_dh makes a copy of the data, so calling DH_free afterwards makes sense.
2016-06-12 13:12:32 +02:00
Willy Tarreau
bb137a8af7 BUG/MEDIUM: ssl: rewind the BIO when reading certificates
Emeric found that some certificate files that were valid with the old method
(the one with the explicit name involving SSL_CTX_use_PrivateKey_file()) do
not work anymore with the new one (the one trying to load multiple cert types
using PEM_read_bio_PrivateKey()). With the last one, the private key couldn't
be loaded.

The difference was related to the ordering in the PEM file was different. The
old method would always work. The new method only works if the private key is
at the top, or if it appears as an "EC" private key. The cause in fact is that
we never rewind the BIO between the various calls. So this patch moves the
loading of the private key as the first step, then it rewinds the BIO, and
then it loads the cert and the chain. With this everything works.

No backport is needed, this issue came with the recent addition of the
multi-cert support.
2016-04-06 19:02:38 +02:00
Vincent Bernat
02779b6263 CLEANUP: uniformize last argument of malloc/calloc
Instead of repeating the type of the LHS argument (sizeof(struct ...))
in calls to malloc/calloc, we directly use the pointer
name (sizeof(*...)). The following Coccinelle patch was used:

@@
type T;
T *x;
@@

  x = malloc(
- sizeof(T)
+ sizeof(*x)
  )

@@
type T;
T *x;
@@

  x = calloc(1,
- sizeof(T)
+ sizeof(*x)
  )

When the LHS is not just a variable name, no change is made. Moreover,
the following patch was used to ensure that "1" is consistently used as
a first argument of calloc, not the last one:

@@
@@

  calloc(
+ 1,
  ...
- ,1
  )
2016-04-03 14:17:42 +02:00
Vincent Bernat
3c2f2f207f CLEANUP: remove unneeded casts
In C89, "void *" is automatically promoted to any pointer type. Casting
the result of malloc/calloc to the type of the LHS variable is therefore
unneeded.

Most of this patch was built using this Coccinelle patch:

@@
type T;
@@

- (T *)
  (\(lua_touserdata\|malloc\|calloc\|SSL_get_app_data\|hlua_checkudata\|lua_newuserdata\)(...))

@@
type T;
T *x;
void *data;
@@

  x =
- (T *)
  data

@@
type T;
T *x;
T *data;
@@

  x =
- (T *)
  data

Unfortunately, either Coccinelle or I is too limited to detect situation
where a complex RHS expression is of type "void *" and therefore casting
is not needed. Those cases were manually examined and corrected.
2016-04-03 14:17:42 +02:00
Nenad Merdanovic
1789115a52 BUG/MEDIUM: Fix RFC5077 resumption when more than TLS_TICKETS_NO are present
Olivier Doucet reported the issue on the ML and tested that when using
more than TLS_TICKETS_NO keys in the file, the CPU usage is much higeher
than expected.

Lukas Tribus then provided a test case which showed that resumption doesn't
work at all in that case.

This fix needs to be backported to 1.6.

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2016-03-29 16:03:37 +02:00
Willy Tarreau
e237fe1172 BUG/MINOR: ssl: fix usage of the various sample fetch functions
Technically speaking, many SSL sample fetch functions act on the
connection and depend on USE_L5CLI on the client side, which means
they're usable as soon as a handshake is completed on a connection.
This means that the test consisting in refusing to call them when
the stream is NULL will prevent them from working when we implement
the tcp-request session ruleset. Better fix this now. The fix consists
in using smp->sess->origin when they're called for the front connection,
and smp->strm->si[1].end when called for the back connection.

There is currently no known side effect for this issue, though it would
better be backported into 1.6 so that the code base remains consistend.
2016-03-10 17:28:05 +01:00
Willy Tarreau
be508f1580 BUG/MAJOR: samples: check smp->strm before using it
Since commit 6879ad3 ("MEDIUM: sample: fill the struct sample with the
session, proxy and stream pointers") merged in 1.6-dev2, the sample
contains the pointer to the stream and sample fetch functions as well
as converters use it heavily.

The problem is that earlier commit 87b0966 ("REORG/MAJOR: session:
rename the "session" entity to "stream"") had split the session and
stream resulting in the possibility for smp->strm to be NULL before
the stream was initialized. This is what happens in tcp-request
connection rulesets, as discovered by Baptiste.

The sample fetch functions must now check that smp->strm is valid
before using it. An alternative could consist in using a dummy stream
with nothing in it to avoid some checks but it would only result in
deferring them to the next step anyway, and making it harder to detect
that a stream is valid or the dummy one.

There is still an issue with variables which requires a complete
independant fix. They use strm->sess to find the session with strm
possibly NULL and passed as an argument. All call places indirectly
use smp->strm to build strm. So the problem is there but the API needs
to be changed to remove this duplicate argument that makes it much
harder to know what pointer to use.

This fix must be backported to 1.6, as well as the next one fixing
variables.
2016-03-10 16:42:58 +01:00
Cyril Bonté
23d19d669b BUG/MEDIUM: cfgparse: wrong argument offset after parsing server "sni" keyword
Owen Marshall reported an issue depending on the server keywords order in the
configuration.

Working line :
  server dev1 <ip>:<port> check inter 5000 ssl verify none sni req.hdr(Host)

Non working line :
  server dev1 <ip>:<port> check inter 5000 ssl sni req.hdr(Host) verify none

Indeed, both parse_server() and srv_parse_sni() modified the current argument
offset at the same time. To fix the issue, srv_parse_sni() can work on a local
copy ot the offset, leaving parse_server() responsible of the actual value.

This fix must be backported to 1.6.
2016-03-07 23:47:05 +01:00
Willy Tarreau
3724da1261 BUG/MEDIUM: ssl: fix off-by-one in NPN list allocation
After seeing previous ALPN fix, I suspected that NPN code was wrong
as well, and indeed it was since ALPN was copied from it. This fix
must be backported into 1.6 and 1.5.
2016-02-12 17:11:12 +01:00
Marcoen Hirschberg
bef6091cff BUG/MEDIUM: ssl: fix off-by-one in ALPN list allocation
The first time I tried it (1.6.3) I got a segmentation fault :(

After some investigation with gdb and valgrind I found the
problem. memcpy() copies past an allocated buffer in
"bind_parse_alpn". This patch fixes it.

[wt: this fix must be backported into 1.6 and 1.5]
2016-02-12 17:10:52 +01:00
Christopher Faulet
635c0adec2 BUG/MINOR: ssl: Be sure to use unique serial for regenerated certificates
The serial number for a generated certificate was computed using the requested
servername, without any variable/random part. It is not a problem from the
moment it is not regenerated.

But if the cache is disabled or when the certificate is evicted from the cache,
we may need to regenerate it. It is important to not reuse the same serial
number for the new certificate. Else clients (especially browsers) trigger a
warning because 2 certificates issued by the same CA have the same serial
number.

So now, the serial is a static variable initialized with now_ms (internal date
in milliseconds) and incremented at each new certificate generation.

(Ref MPS-2031)
2016-02-09 09:04:53 +01:00
Willy Tarreau
30da7ad809 BUILD: ssl: set SSL_SOCK_NUM_KEYTYPES with openssl < 1.0.2
Last patch unfortunately broke build with openssl older than 1.0.2.
Let's just define a single key type in this case.
2015-12-14 11:28:33 +01:00
yanbzhu
be2774dd35 MEDIUM: ssl: Added support for Multi-Cert OCSP Stapling
Enabled loading of OCSP staple responses (.ocsp files) when processing a
bundled certificate with multiple keytypes.
2015-12-14 11:22:29 +01:00
yanbzhu
63ea846399 MEDIUM: ssl: Added multi cert support for loading crt directories
Loading of multiple certs into shared contexts is now supported if a user
specifies a directory instead of a cert file.
2015-12-14 11:22:29 +01:00
yanbzhu
1b04e5b0e0 MINOR: ssl: Added multi cert support for crt-list config keyword
Added support for loading mutiple certs into shared contexts when they
are specified in a crt-list

Note that it's not practical to support SNI filters with multicerts, so
any SNI filters that's provided to the crt-list is ignored if a
multi-cert opertion is used.
2015-12-14 11:22:29 +01:00
yanbzhu
08ce6ab0c9 MEDIUM: ssl: Added support for creating SSL_CTX with multiple certs
Added ability for users to specify multiple certificates that all relate
a single server. Users do this by specifying certificate "cert_name.pem"
but having "cert_name.pem.rsa", "cert_name.pem.dsa" and/or
"cert_name.pem.ecdsa" in the directory.

HAProxy will now intelligently search for those 3 files and try combine
them into as few SSL_CTX's as possible based on CN/SAN. This will allow
HAProxy to support multiple ciphersuite key algorithms off a single
SSL_CTX.

This change integrates into the existing architecture of SNI lookup and
multiple SNI's can point to the same SSL_CTX, which can support multiple
key_types.
2015-12-14 11:22:29 +01:00
yanbzhu
488a4d2e75 MINOR: ssl: Added cert_key_and_chain struct
Added cert_key_and_chain struct to ssl. This struct will store the
contents of a crt path (from the config file) into memory. This will
allow us to use the data stored in memory instead of reading the file
multiple times.

This will be used to support a later commit to load multiple pkeys/certs
into a single SSL_CTX
2015-12-14 11:22:29 +01:00
Daniel Jakots
54ffb918cb BUILD: check for libressl to be able to build against it
[wt: might be worth backporting it to 1.6]
2015-11-08 07:28:02 +01:00
Christopher Faulet
e7db21693f BUILD: ssl: fix build error introduced in commit 7969a3 with OpenSSL < 1.0.0
The function 'EVP_PKEY_get_default_digest_nid()' was introduced in OpenSSL
1.0.0. So for older version of OpenSSL, compiled with the SNI support, the
HAProxy compilation fails with the following error:

src/ssl_sock.c: In function 'ssl_sock_do_create_cert':
src/ssl_sock.c:1096:7: warning: implicit declaration of function 'EVP_PKEY_get_default_digest_nid'
   if (EVP_PKEY_get_default_digest_nid(capkey, &nid) <= 0)
[...]
src/ssl_sock.c:1096: undefined reference to `EVP_PKEY_get_default_digest_nid'
collect2: error: ld returned 1 exit status
Makefile:760: recipe for target 'haproxy' failed
make: *** [haproxy] Error 1

So we must add a #ifdef to check the OpenSSL version (>= 1.0.0) to use this
function. It is used to get default signature digest associated to the private
key used to sign generated X509 certificates. It is called when the private key
differs than EVP_PKEY_RSA, EVP_PKEY_DSA and EVP_PKEY_EC. It should be enough for
most of cases.
2015-10-22 13:32:34 +02:00
Willy Tarreau
2f63ef4d1c BUG/MAJOR: ssl: free the generated SSL_CTX if the LRU cache is disabled
Kim Seri reported that haproxy 1.6.0 crashes after a few requests
when a bind line has SSL enabled with more than one certificate. This
was caused by an insufficient condition to free generated certs during
ssl_sock_close() which can also catch other certs.

Christopher Faulet analysed the situation like this :

-------
First the LRU tree is only initialized when the SSL certs generation is
configured on a bind line. So, in the most of cases, it is NULL (it is
not the same thing than empty).
When the SSL certs generation is used, if the cache is not NULL, a such
certificate is pushed in the cache and there is no need to release it
when the connection is closed.
But it can be disabled in the configuration. So in that case, we must
free the generated certificate when the connection is closed.

Then here, we have really a bug. Here is the buggy part:

3125)      if (conn->xprt_ctx) {
3126) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
3127)              if (!ssl_ctx_lru_tree && objt_listener(conn->target)) {
3128)                      SSL_CTX *ctx = SSL_get_SSL_CTX(conn->xprt_ctx);
3129)                      if (ctx != 3130)
 SSL_CTX_free(ctx);
3131)              }
3133)              SSL_free(conn->xprt_ctx);
3134)              conn->xprt_ctx = NULL;
3135)              sslconns--;
3136)      }

The check on the line 3127 is not enough to determine if this is a
generated certificate or not. Because ssl_ctx_lru_tree is NULL,
generated certificates, if any, must be freed. But here ctx should also
be compared to all SNI certificates and not only to default_ctx. Because
of this bug, when a SNI certificate is used for a connection, it is
erroneously freed when this connection is closed.
-------

Christopher provided this reliable reproducer :

----------
global
    tune.ssl.default-dh-param   2048
    daemon

listen ssl_server
    mode tcp
    bind 127.0.0.1:4443 ssl crt srv1.test.com.pem crt srv2.test.com.pem

    timeout connect 5000
    timeout client  30000
    timeout server  30000

    server srv A.B.C.D:80

You just need to generate 2 SSL certificates with 2 CN (here
srv1.test.com and srv2.test.com).

Then, by doing SSL requests with the first CN, there is no problem. But
with the second CN, it should segfault on the 2nd request.

openssl s_client -connect 127.0.0.1:4443 -servername srv1.test.com // OK
openssl s_client -connect 127.0.0.1:4443 -servername srv1.test.com // OK

But,

openssl s_client -connect 127.0.0.1:4443 -servername srv2.test.com // OK
openssl s_client -connect 127.0.0.1:4443 -servername srv2.test.com // KO
-----------

A long discussion led to the following proposal which this patch implements :

- the cert is generated. It gets a refcount = 1.
- we assign it to the SSL. Its refcount becomes two.
- we try to insert it into the tree. The tree will handle its freeing
  using SSL_CTX_free() during eviction.
- if we can't insert into the tree because the tree is disabled, then
  we have to call SSL_CTX_free() ourselves, then we'd rather do it
  immediately. It will more closely mimmick the case where the cert
  is added to the tree and immediately evicted by concurrent activity
  on the cache.
- we never have to call SSL_CTX_free() during ssl_sock_close() because
  the SSL session only relies on openssl doing the right thing based on
  the refcount only.
- thus we never need to know how the cert was created since the
  SSL_CTX_free() is either guaranteed or already done for generated
  certs, and this protects other ones against any accidental call to
  SSL_CTX_free() without having to track where the cert comes from.

This patch also reduces the inter-dependence between the LRU tree and
the SSL stack, so it should cause less sweating to migrate to threads
later.

This bug is specific to 1.6.0, as it was introduced after dev7 by
this fix :

   d2cab92 ("BUG/MINOR: ssl: fix management of the cache where forged certificates are stored")

Thus a backport to 1.6 is required, but not to 1.5.
2015-10-20 15:29:01 +02:00
Christopher Faulet
85b5a1a781 MINOR: ssl: Add callbacks to set DH/ECDH params for generated certificates
Now, A callback is defined for generated certificates to set DH parameters for
ephemeral key exchange when required.
In same way, when possible, we also defined Elliptic Curve DH (ECDH) parameters.
2015-10-09 12:13:17 +02:00
Christopher Faulet
7969a33a01 MINOR: ssl: Add support for EC for the CA used to sign generated certificates
This is done by adding EVP_PKEY_EC type in supported types for the CA private
key when we get the message digest used to sign a generated X509 certificate.
So now, we support DSA, RSA and EC private keys.

And to be sure, when the type of the private key is not directly supported, we
get its default message digest using the function
'EVP_PKEY_get_default_digest_nid'.

We also use the key of the default certificate instead of generated it. So we
are sure to use the same key type instead of always using a RSA key.
2015-10-09 12:13:12 +02:00
Christopher Faulet
c6f02fb929 MINOR: ssl: Read the file used to generate certificates in any order
the file specified by the SSL option 'ca-sign-file' can now contain the CA
certificate used to dynamically generate certificates and its private key in any
order.
2015-10-09 12:13:08 +02:00
Willy Tarreau
a84c267522 BUILD: ssl: fix build error introduced by recent commit
Commit d2cab92 ("BUG/MINOR: ssl: fix management of the cache where forged
certificates are stored") removed some needed #ifdefs resulting in ssl not
building on older openssl versions where SSL_CTRL_SET_TLSEXT_HOSTNAME is
not defined :

src/ssl_sock.c: In function 'ssl_sock_load_ca':
src/ssl_sock.c:2504: error: 'ssl_ctx_lru_tree' undeclared (first use in this function)
src/ssl_sock.c:2504: error: (Each undeclared identifier is reported only once
src/ssl_sock.c:2504: error: for each function it appears in.)
src/ssl_sock.c:2505: error: 'ssl_ctx_lru_seed' undeclared (first use in this function)
src/ssl_sock.c: In function 'ssl_sock_close':
src/ssl_sock.c:3095: error: 'ssl_ctx_lru_tree' undeclared (first use in this function)
src/ssl_sock.c: In function '__ssl_sock_deinit':
src/ssl_sock.c:5367: error: 'ssl_ctx_lru_tree' undeclared (first use in this function)
make: *** [src/ssl_sock.o] Error 1

Reintroduce the ifdefs around the faulty areas.
2015-10-09 12:13:07 +02:00
Christopher Faulet
77fe80c0b4 MINOR: ssl: Release Servers SSL context when HAProxy is shut down
[wt: could be backported to 1.5 as well]
2015-10-09 10:33:00 +02:00
Christopher Faulet
d2cab92e75 BUG/MINOR: ssl: fix management of the cache where forged certificates are stored
First, the LRU cache must be initialized after the configuration parsing to
correctly set its size.
Next, the function 'ssl_sock_set_generated_cert' returns -1 when an error occurs
(0 if success). In that case, the caller is responsible to free the memory
allocated for the certificate.
Finally, when a SSL certificate is generated by HAProxy but cannot be inserted
in the cache, it must be freed when the SSL connection is closed. This happens
when 'tune.ssl.ssl-ctx-cache-size' is set to 0.
2015-10-09 10:20:53 +02:00
Thierry FOURNIER
bc965348d7 DOC: ssl: missing LF
An error message miss LF
2015-08-27 11:24:23 +02:00
Thierry FOURNIER
136f9d34a9 MINOR: samples: rename union from "data" to "u"
The union name "data" is a little bit heavy while we read the source
code because we can read "data.data.sint". The rename from "data" to "u"
makes the read easiest like "data.u.sint".
2015-08-20 17:13:46 +02:00
Thierry FOURNIER
8c542cac07 MEDIUM: samples: Use the "struct sample_data" in the "struct sample"
This patch remove the struct information stored both in the struct
sample_data and in the striuct sample. Now, only thestruct sample_data
contains data, and the struct sample use the struct sample_data for storing
his own data.
2015-08-20 17:13:46 +02:00
Pradeep Jindal
cc79b003cb BUG/MINOR: ssl: TLS Ticket Key rotation broken via socket command
It seems haproxy was doing wrong pointer arithmetic to update the ticket
ring correctly.
2015-08-20 16:23:22 +02:00
Jérémie Courrèges-Anglas
17c3f6284c BUILD: ssl: Allow building against libssl without SSLv3.
If SSLv3 is explicitely requested but not available, warn the user and
bail out.
2015-07-26 08:11:57 +02:00
Thierry FOURNIER
bf65cd4d77 MAJOR: arg: converts uint and sint in sint
This patch removes the 32 bits unsigned integer and the 32 bit signed
integer. It replaces these types by a unique type 64 bit signed.
2015-07-22 00:48:23 +02:00
Thierry FOURNIER
07ee64ef4d MAJOR: sample: converts uint and sint in 64 bits signed integer
This patch removes the 32 bits unsigned integer and the 32 bit signed
integer. It replaces these types by a unique type 64 bit signed.

This makes easy the usage of integer and clarify signed and unsigned use.
With the previous version, signed and unsigned are used ones in place of
others, and sometimes the converter loose the sign. For example, divisions
are processed with "unsigned", if one entry is negative, the result is
wrong.

Note that the integer pattern matching and dotted version pattern matching
are already working with signed 64 bits integer values.

There is one user-visible change : the "uint()" and "sint()" sample fetch
functions which used to return a constant integer have been replaced with
a new more natural, unified "int()" function. These functions were only
introduced in the latest 1.6-dev2 so there's no impact on regular
deployments.
2015-07-22 00:48:23 +02:00
Willy Tarreau
732eac41f4 MEDIUM: ssl: add sni support on the server lines
The new "sni" server directive takes a sample fetch expression and
uses its return value as a hostname sent as the TLS SNI extension.
A typical use case consists in forwarding the front connection's SNI
value to the server in a bridged HTTPS forwarder :

   sni ssl_fc_sni
2015-07-10 11:43:15 +02:00
Willy Tarreau
630764188b MINOR: ssl: provide ia function to set the SNI extension on a connection
ssl_sock_set_servername() is used to set the SNI hostname on an
outgoing connection. This function comes from code originally
provided by Christopher Faulet of Qualys.
2015-07-10 11:37:29 +02:00
Willy Tarreau
fc017fec48 CLEANUP: ssl: make ssl_sock_generate_certificate() use ssl_sock_generated_cert_serial()
It saves from open-coding the hashing method. Instead all serial
generation is done in a single function.
2015-07-07 18:09:34 +02:00
Willy Tarreau
646b864fe5 CLEANUP: ssl: make ssl_sock_generated_cert_serial() take a const
It doesn't modify the input.
2015-07-07 18:09:15 +02:00
Willy Tarreau
f67214554c MINOR: ssl: make self-generated certs also work with raw IPv6 addresses
The current method of retrieving the incoming connection's destination
address to hash it is not compatible with IPv6 nor the proxy protocol
because it directly tries to get an IPv4 address from the socket. Instead
we must ask the connection. This is only used when no SNI is provided.
2015-07-07 18:04:38 +02:00
Willy Tarreau
745d412758 BUG/MINOR: ssl: fix smp_fetch_ssl_fc_session_id
Dmitry Sivachenko reported the following build warning using Clang
which is a real bug :

src/ssl_sock.c:4104:44: warning: address of 'smp->data.str.len' will always
      evaluate to 'true' [-Wpointer-bool-conversion]
        if (!smp->data.str.str || !&smp->data.str.len)

The impact is very low however, it will return an empty session_id
instead of no session id when none is found.

The fix should be backported to 1.5.
2015-06-17 19:46:14 +02:00
Willy Tarreau
c8ad3beded BUILD: ssl: fix recent build breakage on older SSL libs
Commit 31af49d ("MEDIUM: ssl: Add options to forge SSL certificates")
introduced some dependencies on SSL_CTRL_SET_TLSEXT_HOSTNAME for which
a few checks were missing, breaking the build on openssl 0.9.8.
2015-06-17 15:50:40 +02:00
Christopher Faulet
3054880e09 MINOR: ssl: Export functions to manipulate generated certificates
Following functions are now available in the SSL public API:

  * ssl_sock_create_cert
  * ssl_sock_get_generated_cert
  * ssl_sock_set_generated_cert
  * ssl_sock_generated_cert_serial

These functions could be used to create a certificate by hand, set it in the
cache used to store generated certificates and retrieve it. Here is an example
(pseudo code):

  X509        *cacert     = ...;
  EVP_PKEY    *capkey     = ...;
  char        *servername = ...;
  unsigned int serial;

  serial = ssl_sock_generated_cert_serial(servername, strlen(servername));
  if (!ssl_sock_get_generated_cert(serial, cacert)) {
      SSL_CTX *ctx = ssl_sock_create_cert(servername, serial, cacert, capkey);
      ssl_sock_set_generated_cert(ctx, serial, cacert);
  }
2015-06-12 18:06:59 +02:00
Christopher Faulet
31af49d62b MEDIUM: ssl: Add options to forge SSL certificates
With this patch, it is possible to configure HAProxy to forge the SSL
certificate sent to a client using the SNI servername. We do it in the SNI
callback.

To enable this feature, you must pass following BIND options:

 * ca-sign-file <FILE> : This is the PEM file containing the CA certitifacte and
   the CA private key to create and sign server's certificates.

 * (optionally) ca-sign-pass <PASS>: This is the CA private key passphrase, if
   any.

 * generate-certificates: Enable the dynamic generation of certificates for a
   listener.

Because generating certificates is expensive, there is a LRU cache to store
them. Its size can be customized by setting the global parameter
'tune.ssl.ssl-ctx-cache-size'.
2015-06-12 18:06:59 +02:00
Remi Gacogne
d3a341a96f MEDIUM: ssl: replace standards DH groups with custom ones
It is likely that powerful adversaries have been pre-computing the
standardized DH groups, because being widely used have made them
valuable targets. While users are advised to generate their own
DH parameters, replace the ones we ship by values been randomly
generated for this product only.

[wt: replaced dh1024_p, dh2048_p, and dh4096_p with locally-generated
 ones as recommended by Rémi]
2015-05-31 22:41:28 +02:00
Remi Gacogne
47783ef05b MEDIUM: ssl: add the possibility to use a global DH parameters file
This patch adds the ssl-dh-param-file global setting. It sets the
default DH parameters that will be used during the SSL/TLS handshake when
ephemeral Diffie-Hellman (DHE) key exchange is used, for all "bind" lines
which do not explicitely define theirs.
2015-05-31 22:02:00 +02:00
Remi Gacogne
d3a23c3eb8 MINOR: ssl: add a destructor to free allocated SSL ressources
Using valgrind or another memory leak tracking tool is easier
when the memory internally allocated by OpenSSL is cleanly released
at shutdown.
2015-05-28 18:03:29 +02:00
Remi Gacogne
4f902b8832 BUG/MEDIUM: ssl: fix tune.ssl.default-dh-param value being overwritten
Hervé Commowick reported that the logic used to avoid complaining about
ssl-default-dh-param not being set when static DH params are present
in the certificate file was clearly wrong when more than one sni_ctx
is used.
This patch stores whether static DH params are being used for each
SSL_CTX individually, and does not overwrite the value of
tune.ssl.default-dh-param.
2015-05-28 18:03:27 +02:00
Nenad Merdanovic
26ea822190 MINOR: Add sample fetch which identifies if the SSL session has been resumed
Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-18 07:07:53 +02:00
Nenad Merdanovic
200b0facde MEDIUM: Add support for updating TLS ticket keys via socket
Until now, HAproxy needed to be restarted to change the TLS ticket
keys. With this patch, the TLS keys can be updated on a per-file
basis using the admin socket. Two new socket commands have been
introduced: "show tls-keys" and "set ssl tls-keys".

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-16 11:28:04 +02:00
Nenad Merdanovic
146defaff4 MINOR: Add TLS ticket keys reference and use it in the listener struct
Within the listener struct we need to use a reference to the TLS
ticket keys which binds the actual keys with the filename. This will
make it possible to update the keys through the socket

Signed-off-by: Nenad Merdanovic <nmerdan@anine.io>
2015-05-16 11:28:04 +02:00
Willy Tarreau
e26bf05115 BUILD/MINOR: ssl: fix build failure introduced by recent patch
Baptiste reported that commit 0a9a2b8 ("MEDIUM: sample change the
prototype of sample-fetches and converters functions") broke the
build of ssl_sock.c when using openssl-1.0.2 because one missed
replacement of sess with smp->sess. No backport is needed.
2015-05-12 10:30:12 +02:00
Thierry FOURNIER
0786d05a04 MEDIUM: sample: change the prototype of sample-fetches functions
This patch removes the "opt" entry from the prototype of the
sample-fetches fucntions. This permits to remove some weight
in the prototype call.
2015-05-11 20:03:08 +02:00
Thierry FOURNIER
0a9a2b8cec MEDIUM: sample change the prototype of sample-fetches and converters functions
This patch removes the structs "session", "stream" and "proxy" from
the sample-fetches and converters function prototypes.

This permits to remove some weight in the prototype call.
2015-05-11 20:01:42 +02:00
Alexander Rigbo
fc65af0c61 BUG/MINOR: ssl: Display correct filename in error message
This patch should be backported to 1.5.
2015-04-11 10:28:59 +02:00
Willy Tarreau
192252e2d8 MAJOR: sample: pass a pointer to the session to each sample fetch function
Many such function need a session, and till now they used to dereference
the stream. Once we remove the stream from the embryonic session, this
will not be possible anymore.

So as of now, sample fetch functions will be called with this :

   - sess = NULL,  strm = NULL                     : never
   - sess = valid, strm = NULL                     : tcp-req connection
   - sess = valid, strm = valid, strm->txn = NULL  : tcp-req content
   - sess = valid, strm = valid, strm->txn = valid : http-req / http-res
2015-04-06 11:37:25 +02:00
Willy Tarreau
15e91e1b36 MAJOR: sample: don't pass l7 anymore to sample fetch functions
All of them can now retrieve the HTTP transaction *if it exists* from
the stream and be sure to get NULL there when called with an embryonic
session.

The patch is a bit large because many locations were touched (all fetch
functions had to have their prototype adjusted). The opportunity was
taken to also uniformize the call names (the stream is now always "strm"
instead of "l4") and to fix indent where it was broken. This way when
we later introduce the session here there will be less confusion.
2015-04-06 11:35:53 +02:00
Willy Tarreau
53c9b4db41 CLEANUP: sample: remove useless tests in fetch functions for l4 != NULL
The stream may never be null given that all these functions are called
from sample_process(). Let's remove this now confusing test which
sometimes happens after a dereference was already done.
2015-04-06 11:35:52 +02:00
Willy Tarreau
9ad7bd48d2 MEDIUM: session: use the pointer to the origin instead of s->si[0].end
When s->si[0].end was dereferenced as a connection or anything in
order to retrieve information about the originating session, we'll
now use sess->origin instead so that when we have to chain multiple
streams in HTTP/2, we'll keep accessing the same origin.
2015-04-06 11:34:29 +02:00
Willy Tarreau
87b09668be REORG/MAJOR: session: rename the "session" entity to "stream"
With HTTP/2, we'll have to support multiplexed streams. A stream is in
fact the largest part of what we currently call a session, it has buffers,
logs, etc.

In order to catch any error, this commit removes any reference to the
struct session and tries to rename most "session" occurrences in function
names to "stream" and "sess" to "strm" when that's related to a session.

The files stream.{c,h} were added and session.{c,h} removed.

The session will be reintroduced later and a few parts of the stream
will progressively be moved overthere. It will more or less contain
only what we need in an embryonic session.

Sample fetch functions and converters will have to change a bit so
that they'll use an L5 (session) instead of what's currently called
"L4" which is in fact L6 for now.

Once all changes are completed, we should see approximately this :

   L7 - http_txn
   L6 - stream
   L5 - session
   L4 - connection | applet

There will be at most one http_txn per stream, and a same session will
possibly be referenced by multiple streams. A connection will point to
a session and to a stream. The session will hold all the information
we need to keep even when we don't yet have a stream.

Some more cleanup is needed because some code was already far from
being clean. The server queue management still refers to sessions at
many places while comments talk about connections. This will have to
be cleaned up once we have a server-side connection pool manager.
Stream flags "SN_*" still need to be renamed, it doesn't seem like
any of them will need to move to the session.
2015-04-06 11:23:56 +02:00
Willy Tarreau
d85c48589a REORG: connection: move conn_drain() to connection.c and rename it
It's now called conn_sock_drain() to make it clear that it only reads
at the sock layer and not at the data layer. The function was too big
to remain inlined and it's used at a few places where size counts.
2015-03-13 00:42:48 +01:00
Janusz Dziemidowicz
2c701b5f3b MEDIUM: ssl: Certificate Transparency support
Adds ability to include Signed Certificate Timestamp List in TLS
extension. File containing SCTL must be present at the same path of
the certificate file, suffixed with '.sctl'. This requires OpenSSL
1.0.2 or later.
2015-03-11 23:27:05 +01:00
Thierry FOURNIER
f41a809dc9 MINOR: sample: add private argument to the struct sample_fetch
The add of this private argument is to prepare the integration
of the lua fetchs.
2015-02-28 23:12:31 +01:00
Willy Tarreau
622317d5e2 BUILD/CLEANUP: ssl: avoid a warning due to mixed code and declaration
Actually it was caused by some dummy code meant to shut gcc up for
an unused argument!
2015-02-28 23:12:30 +01:00
Nenad Merdanovic
05552d4b98 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 <nmerdan@anine.io>
2015-02-28 23:10:22 +01:00
Willy Tarreau
2a3fb1c8bb MINOR: ssl/server: add the "no-ssl-reuse" server option
This option disables SSL session reuse when SSL is used to communicate with
the server. It will force the server to perform a full handshake for every
new connection. It's probably only useful for benchmarking, troubleshooting,
and for paranoid users.
2015-02-06 18:04:08 +01:00
Cyril Bonté
3180f7b554 MINOR: ssl: load certificates in alphabetical order
As reported by Raphaël Enrici, certificates loaded from a directory are loaded
in a non predictive order. If no certificate was first loaded from a file, it
can result in different behaviours when haproxy is used in cluster.
We can also imagine other cases which weren't met yet.

Instead of using readdir(), we can use scandir() and sort files alphabetically.
This will ensure a predictive behaviour.

This patch should also be backported to 1.5.
2015-01-25 00:48:01 +01:00
Willy Tarreau
d92aa5c44a MINOR: global: report information about the cost of SSL connections
An SSL connection takes some memory when it exists and during handshakes.
We measured up to 16kB for an established endpoint, and up to 76 extra kB
during a handshake. The SSL layer stores these values into the global
struct during initialization. If other SSL libs are used, it's easy to
change these values. Anyway they'll only be used as gross estimates in
order to guess the max number of SSL conns that can be established when
memory is constrained and the limit is not set.
2015-01-15 21:34:39 +01:00
Willy Tarreau
fce03113fa MINOR: global: always export some SSL-specific metrics
We'll need to know the number of SSL connections, their use and their
cost soon. In order to avoid getting tons of ifdefs everywhere, always
export SSL information in the global section. We add two flags to know
whether or not SSL is used in a frontend and in a backend.
2015-01-15 21:32:40 +01:00
Lukas Tribus
e4e30f7d52 BUILD: ssl: use OPENSSL_NO_OCSP to detect OCSP support
Since commit 656c5fa7e8 ("BUILD: ssl: disable OCSP when using
boringssl) the OCSP code is bypassed when OPENSSL_IS_BORINGSSL
is defined. The correct thing to do here is to use OPENSSL_NO_OCSP
instead, which is defined for this exact purpose in
openssl/opensslfeatures.h.

This makes haproxy forward compatible if boringssl ever introduces
full OCSP support with the additional benefit that it links fine
against a OCSP-disabled openssl.

Signed-off-by: Lukas Tribus <luky-37@hotmail.com>
2014-12-09 20:49:22 +01:00
Cyril Bonté
9ce1311ebc BUG/MEDIUM: checks: fix conflicts between agent checks and ssl healthchecks
Lasse Birnbaum Jensen reported an issue when agent checks are used at the same
time as standard healthchecks when SSL is enabled on the server side.

The symptom is that agent checks try to communicate in SSL while it should
manage raw data. This happens because the transport layer is shared between all
kind of checks.

To fix the issue, the transport layer is now stored in each check type,
allowing to use SSL healthchecks when required, while an agent check should
always use the raw_sock implementation.

The fix must be backported to 1.5.
2014-11-16 00:53:12 +01:00
Willy Tarreau
396a186def MEDIUM: ssl: add support for smaller SSL records
There's a very common openssl patch on the net meant to significantly
reduce openssl's memory usage. This patch has been provided for many
versions now, and it makes sense to add support for it given that it
is very simple. It only requires to add an extra SSL_MODE flag. Just
like for other flags, if the flag is unknown, it's unset. About 44kB
of memory may be saved per SSL session with the patch.
2014-11-13 14:08:53 +01:00
Willy Tarreau
fba03cdc5a BUG/MEDIUM: ssl: force a full GC in case of memory shortage
When memory becomes scarce and openssl refuses to allocate a new SSL
session, it is worth freeing the pools and trying again instead of
rejecting all incoming SSL connection. This can happen when some
memory usage limits have been assigned to the haproxy process using
-m or with ulimit -m/-v.

This is mostly an enhancement of previous fix and is worth backporting
to 1.5.
2014-11-13 13:48:58 +01:00
Emeric Brun
5547615cda BUG/MEDIUM: ssl: fix bad ssl context init can cause segfault in case of OOM.
Some SSL context's init functions errors were not handled and
can cause a segfault due to an incomplete SSL context
initialization.

This fix must be backported to 1.5.
2014-11-13 13:44:12 +01:00
Emeric Brun
0bed9945ee BUG/MINOR: ssl: correctly initialize ssl ctx for invalid certificates
Bug reported by John Leach: no-sslv3 does not work using some certificates.

It appears that ssl ctx is not updated with configured options if the
CommonName of the certificate's subject is not found.

It applies only on the first cerificate of a configured bind line.

There is no security impact, because only invalid nameless certficates
are concerned.

This fix must be backported to 1.5
2014-10-30 20:02:33 +01:00
Emeric Brun
2c86cbf753 MINOR: ssl: add statement to force some ssl options in global.
Adds global statements 'ssl-default-server-options' and
'ssl-default-bind-options' to force on 'server' and 'bind' lines
some ssl options.

Currently available options are 'no-sslv3', 'no-tlsv10', 'no-tlsv11',
'no-tlsv12', 'force-sslv3', 'force-tlsv10', 'force-tlsv11',
'force-tlsv12', and 'no-tls-tickets'.

Example:
      global
        ssl-default-server-options no-sslv3
        ssl-default-bind-options no-sslv3
2014-10-30 17:06:29 +01:00
Emeric Brun
43e7958def MINOR: add fetchs 'ssl_c_der' and 'ssl_f_der' to return DER formatted certs
ssl_c_der : binary
  Returns the DER formatted certificate presented by the client when the
  incoming connection was made over an SSL/TLS transport layer. When used for
  an ACL, the value(s) to match against can be passed in hexadecimal form.

ssl_f_der : binary
  Returns the DER formatted certificate presented by the frontend when the
  incoming connection was made over an SSL/TLS transport layer. When used for
  an ACL, the value(s) to match against can be passed in hexadecimal form.
2014-10-29 19:25:24 +01:00
Willy Tarreau
a616ba6f5f BUILD/MINOR: ssl: de-constify "ciphers" to avoid a warning on openssl-0.9.8
When building on openssl-0.9.8, since commit 23d5d37 ("MINOR: ssl: use
SSL_get_ciphers() instead of directly accessing the cipher list.") we get
the following warning :

	src/ssl_sock.c: In function 'ssl_sock_prepare_ctx':
	src/ssl_sock.c:1592: warning: passing argument 1 of 'SSL_CIPHER_description' discards qualifiers from pointer target type

This is because the openssl API has changed between 0.9.8 and 1.0.1 :

	0.9.8: char *SSL_CIPHER_description(SSL_CIPHER *,char *buf,int size);
	1.0.1: char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size);

So let's remove the "const" type qualifier to satisfy both versions.
Note that the fix above was backported to 1.5, so this one should as well.
2014-10-26 06:52:13 +01:00
Remi Gacogne
23d5d378d0 MINOR: ssl: use SSL_get_ciphers() instead of directly accessing the cipher list. 2014-10-20 18:01:06 +02:00
Dave McCowan
328fb58d74 MEDIUM: connection: add new bit in Proxy Protocol V2
There are two sample commands to get information about the presence of a
client certificate.
ssl_fc_has_crt is true if there is a certificate present in the current
connection
ssl_c_used is true if there is a certificate present in the session.
If a session has stopped and resumed, then ssl_c_used could be true, while
ssl_fc_has_crt is false.

In the client byte of the TLS TLV of Proxy Protocol V2, there is only one
bit to indicate whether a certificate is present on the connection.  The
attached patch adds a second bit to indicate the presence for the session.

This maintains backward compatibility.

[wt: this should be backported to 1.5 to help maintain compatibility
 between versions]
2014-08-23 07:35:29 +02:00
Lukas Tribus
90132726c5 MINOR: ssl: don't use boringssl's cipher_list
Google's boringssl has a different cipher_list, we cannot use it as
in OpenSSL. This is due to the "Equal preference cipher groups" feature:

https://boringssl.googlesource.com/boringssl/+/858a88daf27975f67d9f63e18f95645be2886bfb^!/

also see:
https://www.imperialviolet.org/2014/02/27/tlssymmetriccrypto.html

cipher_list is used in haproxy since commit f46cd6e4ec ("MEDIUM: ssl:
Add the option to use standardized DH parameters >= 1024 bits") to
check if DHE ciphers are used.

So, if boringssl is used, the patch just assumes that there is some
DHE cipher enabled. This will lead to false positives, but thats better
than compiler warnings and crashes.

This may be replaced one day by properly implementing the the new style
cipher_list, in the meantime this workaround allows to build and use
boringssl.

Signed-off-by: Lukas Tribus <luky-37@hotmail.com>
2014-08-18 14:33:48 +02:00
Lukas Tribus
4c0d45a861 BUILD: ssl: don't call get_rfc2409_prime when using boringssl
get_rfc2409_prime_1024() and friends are not available in Google's
boringssl, so use the fallback in that case.

Signed-off-by: Lukas Tribus <luky-37@hotmail.com>
2014-08-18 14:33:48 +02:00
Lukas Tribus
656c5fa7e8 BUILD: ssl: disable OCSP when using boringssl
Google's boringssl doesn't currently support OCSP, so
disable it if detected.

OCSP support may be reintroduced as per:
https://code.google.com/p/chromium/issues/detail?id=398677

In that case we can simply revert this commit.

Signed-off-by: Lukas Tribus <luky-37@hotmail.com>
2014-08-18 14:33:48 +02:00
Remi Gacogne
8de5415b85 BUG/MEDIUM: ssl: Fix a memory leak in DHE key exchange
OpenSSL does not free the DH * value returned by the callback specified with SSL_CTX_set_tmp_dh_callback(),
leading to a memory leak for SSL/TLS connections using Diffie Hellman Ephemeral key exchange.
This patch fixes the leak by allocating the DH * structs holding the DH parameters once, at configuration time.

Note: this fix must be backported to 1.5.
2014-07-15 16:07:05 +02:00
Emeric Brun
0abf836ecb BUG/MINOR: ssl: Fix external function in order not to return a pointer on an internal trash buffer.
'ssl_sock_get_common_name' applied to a connection was also renamed
'ssl_sock_get_remote_common_name'. Currently, this function is only used
with protocol PROXYv2 to retrieve the client certificate's common name.
A further usage could be to retrieve the server certificate's common name
on an outgoing connection.
2014-06-24 22:39:16 +02:00
Emeric Brun
1d3865b096 BUG/MINOR: ssl: Fix OCSP resp update fails with the same certificate configured twice. 2014-06-23 12:14:47 +02:00
Emeric Brun
4f3c87a5d9 BUG/MEDIUM: ssl: Fix to not serve expired OCSP responses.
For some browsers (firefox), an expired OCSP Response causes unwanted behavior.

Haproxy stops serving OCSP response if nextupdate date minus
the supported time skew (#define OCSP_MAX_RESPONSE_TIME_SKEW) is
in the past.
2014-06-23 12:14:47 +02:00
Emeric Brun
13a6b48e24 BUG/MINOR: ssl: rejects OCSP response without nextupdate.
To cache an OCSP Response without expiration time is not safe.
2014-06-23 12:14:47 +02:00
Emeric Brun
c8b27b6c68 MEDIUM: ssl: add 300s supported time skew on OCSP response update.
OCSP_MAX_RESPONSE_TIME_SKEW can be set to a different value at
compilation (default is 300 seconds).
2014-06-19 14:37:30 +02:00
Emeric Brun
4147b2ef10 MEDIUM: ssl: basic OCSP stapling support.
The support is all based on static responses. This doesn't add any
request / response logic to HAProxy, but allows a way to update
information through the socket interface.

Currently certificates specified using "crt" or "crt-list" on "bind" lines
are loaded as PEM files.
For each PEM file, haproxy checks for the presence of file at the same path
suffixed by ".ocsp". If such file is found, support for the TLS Certificate
Status Request extension (also known as "OCSP stapling") is automatically
enabled. The content of this file is optional. If not empty, it must contain
a valid OCSP Response in DER format. In order to be valid an OCSP Response
must comply with the following rules: it has to indicate a good status,
it has to be a single response for the certificate of the PEM file, and it
has to be valid at the moment of addition. If these rules are not respected
the OCSP Response is ignored and a warning is emitted. In order to  identify
which certificate an OCSP Response applies to, the issuer's certificate is
necessary. If the issuer's certificate is not found in the PEM file, it will
be loaded from a file at the same path as the PEM file suffixed by ".issuer"
if it exists otherwise it will fail with an error.

It is possible to update an OCSP Response from the unix socket using:

  set ssl ocsp-response <response>

This command is used to update an OCSP Response for a certificate (see "crt"
on "bind" lines). Same controls are performed as during the initial loading of
the response. The <response> must be passed as a base64 encoded string of the
DER encoded response from the OCSP server.

Example:
  openssl ocsp -issuer issuer.pem -cert server.pem \
               -host ocsp.issuer.com:80 -respout resp.der
  echo "set ssl ocsp-response $(base64 -w 10000 resp.der)" | \
               socat stdio /var/run/haproxy.stat

This feature is automatically enabled on openssl 0.9.8h and above.

This work was performed jointly by Dirkjan Bussink of GitHub and
Emeric Brun of HAProxy Technologies.
2014-06-18 18:28:56 +02:00
Emeric Brun
2aab722dc1 MEDIUM: ssl: ignored file names ending as '.issuer' or '.ocsp'.
We don't want to load these files found in directories specified in "crt" or
"crt-list".

These suffixes are reserved for OCSP stapling.
2014-06-18 18:24:55 +02:00
Remi Gacogne
c1eab8c96f MEDIUM: ssl: fix detection of ephemeral diffie-hellman key exchange by using the cipher description.
In OpenSSL, the name of a cipher using ephemeral diffie-hellman for key
 exchange can start with EDH, but also DHE, EXP-EDH or EXP1024-DHE.
We work around this issue by using the cipher's description instead of
the cipher's name.
Hopefully the description is less likely to change in the future.
2014-06-12 20:52:41 +02:00
Remi Gacogne
f46cd6e4ec MEDIUM: ssl: Add the option to use standardized DH parameters >= 1024 bits
When no static DH parameters are specified, this patch makes haproxy
use standardized (rfc 2409 / rfc 3526) DH parameters with prime lenghts
of 1024, 2048, 4096 or 8192 bits for DHE key exchange. The size of the
temporary/ephemeral DH key is computed as the minimum of the RSA/DSA server
key size and the value of a new option named tune.ssl.default-dh-param.
2014-06-12 16:12:23 +02:00
Willy Tarreau
0c9c2720dc MINOR: stats: report SSL key computations per second
It's commonly needed to know how many SSL asymmetric keys are computed
per second on either side (frontend or backend), and to know the SSL
session reuse ratio. Now we compute these values and report them in
"show info".
2014-05-28 12:28:58 +02:00
Remi Gacogne
af5c3da89e MINOR: ssl: SSL_CTX_set_options() and SSL_CTX_set_mode() take a long, not an int
This is a minor fix, but the SSL_CTX_set_options() and
SSL_CTX_set_mode() functions take a long, not an int parameter. As
SSL_OP_ALL is now (since OpenSSL 1.0.0) defined as 0x80000BFFL, I think
it is worth fixing.
2014-05-19 11:20:23 +02:00
David S
afb768340c MEDIUM: connection: Implement and extented PROXY Protocol V2
This commit modifies the PROXY protocol V2 specification to support headers
longer than 255 bytes allowing for optional extensions.  It implements the
PROXY protocol V2 which is a binary representation of V1. This will make
parsing more efficient for clients who will know in advance exactly how
many bytes to read.  Also, it defines and implements some optional PROXY
protocol V2 extensions to send information about downstream SSL/TLS
connections.  Support for PROXY protocol V1 remains unchanged.
2014-05-09 08:25:38 +02:00
Willy Tarreau
5cbe4ef265 BUILD: ssl: SSL_CTX_set_msg_callback() needs openssl >= 0.9.7
1.5-dev24 introduced SSL_CTX_set_msg_callback(), which came with OpenSSL
0.9.7. A build attempt with an older one failed and we're still compatible
with 0.9.6 in 1.5.
2014-05-08 22:46:31 +02:00
Emeric Brun
b73a9b039c MINOR: ssl: convert to binary ssl_fc_unique_id and ssl_bc_unique_id.
Previously ssl_fc_unique_id and ssl_bc_unique_id return a string encoded
in base64 of the RFC 5929 TLS unique identifier. This patch modify those fetches
to return directly the ID in the original binary format. The user can make the
choice to encode in base64 using the converter.

i.e. : ssl_fc_unique_id,base64
2014-04-30 22:31:11 +02:00
Emeric Brun
55f4fa8825 MINOR: ssl: adds ssl_f_sha1 fetch to return frontend's certificate fingerprint
ssl_f_sha1 is a binary binary fetch used to returns the SHA-1 fingerprint of
the certificate presented by the frontend when the incoming connection was
made over an SSL/TLS transport layer. This can be used to know which
certificate was chosen using SNI.
2014-04-30 22:31:11 +02:00
Emeric Brun
ba841a1da1 MINOR: ssl: merge client's and frontend's certificate functions. 2014-04-30 22:31:11 +02:00
Emeric Brun
645ae79b40 MINOR: ssl: adds fetchs and ACLs for ssl back connection.
Adds ssl fetchs and ACLs for outgoinf SSL/Transport layer connection with their
docs:
ssl_bc, ssl_bc_alg_keysize, ssl_bc_cipher, ssl_bc_protocol, ssl_bc_unique_id,
ssl_bc_session_id and ssl_bc_use_keysize.
2014-04-30 22:31:11 +02:00
Emeric Brun
5bd99b4bd6 MINOR: ssl: clean unused ACLs declarations
Now those ACLs are automatically created from pattern fetch declare.
2014-04-30 22:16:39 +02:00
Willy Tarreau
aeed672a6d MINOR: ssl: finally catch the heartbeats missing the padding
Previous patch only focused on parsing the packet right and blocking
it, so it relaxed one test on the packet length. The difference is
not usable for attacking but the logs will not report an attack for
such cases, which is probably bad. Better report all known invalid
packets cases.
2014-04-26 00:03:48 +02:00
Willy Tarreau
3b2fdb6f55 BUG/MINOR: ssl: really block OpenSSL's response to heartbleed attack
Recent commit f51c698 ("MEDIUM: ssl: implement a workaround for the
OpenSSL heartbleed attack") did not always work well, because OpenSSL
is fun enough for not testing errors before sending data... So the
output sometimes contained some data.

The OpenSSL code relies on the max_send_segment value to limit the
packet length. The code ensures that a value of zero will result in
no single byte leaking. So we're forcing this instead and that
definitely fixes the issue. Note that we need to set it the hard
way since the regular API checks for valid values.
2014-04-25 23:48:21 +02:00
Willy Tarreau
84815006a0 BUILD: ssl: avoid a warning about conn not used with OpenSSL < 1.0.1
Building with a version of openssl without heartbeat gives this since
latest 29f037d ("MEDIUM: ssl: explicitly log failed handshakes after a
heartbeat") :

src/ssl_sock.c: In function 'ssl_sock_msgcbk':
src/ssl_sock.c:188: warning: unused variable 'conn'

Simply declare conn inside the ifdef. No backport is needed.
2014-04-25 21:40:27 +02:00
Willy Tarreau
6e774b455f BUG/MEDIUM: Revert "MEDIUM: ssl: Add standardized DH parameters >= 1024 bits"
This reverts commit 9ece05f590.

Sander Klein reported an important performance regression with this
patch applied. It is not yet certain what is exactly the cause but
let's not break other setups now and sort this out after dev24.

The commit was merged into dev23, no need to backport.
2014-04-25 21:35:23 +02:00
Willy Tarreau
f51c6989b0 MEDIUM: ssl: implement a workaround for the OpenSSL heartbleed attack
Using the previous callback, it's trivial to block the heartbeat attack,
first we control the message length, then we emit an SSL error if it is
out of bounds. A special log is emitted, indicating that a heartbleed
attack was stopped so that they are not confused with other failures.

That way, haproxy can protect itself even when running on an unpatched
SSL stack. Tests performed with openssl-1.0.1c indicate a total success.
2014-04-25 20:06:33 +02:00
Emeric Brun
29f037d872 MEDIUM: ssl: explicitly log failed handshakes after a heartbeat
Add a callback to receive the heartbeat notification. There, we add
SSL_SOCK_RECV_HEARTBEAT flag on the ssl session if a heartbeat is seen.

If a handshake fails, we log a different message to mention the fact that
a heartbeat was seen. The test is only performed on the frontend side.
2014-04-25 19:25:33 +02:00
Willy Tarreau
b75d692ca6 BUILD/MINOR: ssl: remove one call to sprintf()
Lukas reported another OpenBSD complaint about this use of sprintf() that
I missed :

src/ssl_sock.o(.text+0x2a79): In function `bind_parse_crt':
src/ssl_sock.c:3015: warning: sprintf() is often misused, please use snprintf()

This one was even easier to handle. Note that some of these calls could
be simplified by checking the snprintf output size instead of doing the
preliminary size computation.
2014-04-14 18:05:41 +02:00
Remi Gacogne
9ece05f590 MEDIUM: ssl: Add standardized DH parameters >= 1024 bits
This patch adds standardized (rfc 2409 / rfc 3526)
DH parameters with prime lengths of 1024, 2048, 3072, 4096, 6144 and
8192 bits, based on the private key size.
2014-04-14 18:00:20 +02:00
Willy Tarreau
073edf3311 BUILD: ssl: previous patch failed
This is a minor error, s/SMP_T_CSTR/SMP_T_STR + SMP_F_CONST.
2014-04-09 15:41:52 +02:00
David S
c1ad52e8f7 MINOR: ssl: add ssl_fc_unique_id to fetch TLS Unique ID
The TLS unique id, or unique channel binding, is a byte string that can be
pulled from a TLS connection and it is unique to that connection. It is
defined in RFC 5929 section 3.  The value is used by various upper layer
protocols as part of an extra layer of security.  For example XMPP
(RFC 6120) and EST (RFC 7030).

Add the ssl_fc_unique_id keyword and corresponding sample fetch method.
Value is retrieved from OpenSSL and base64 encoded as described in RFC
5929 section 3.
2014-04-09 13:48:33 +02:00
Thierry FOURNIER
c5a4e98639 MEDIUM: acl: Change the acl register struct
This patch replace a lot of pointeur by pattern matching identifier. If
the declared ACL use all the predefined pattern matching functions, the
register function gets the functions provided by "pattern.c" and
identified by the PAT_LATCH_*.

In the case of the acl uses his own functions, they can be declared, and
the acl registration doesn't change it.
2014-03-17 18:06:08 +01:00
Thierry FOURNIER
e369ca2e66 MEDIUM: pattern_find_smp: functions find_smp uses the pat_ref_elt to find the element to be removed
The find_smp search the smp using the value of the pat_ref_elt pointer.

The pat_find_smp_* are no longer used. The function pattern_find_smp()
known all pattern indexation, and can be found
2014-03-17 18:06:08 +01:00
Thierry FOURNIER
7acca4b269 MEDIUM: pattern: delete() function uses the pat_ref_elt to find the element to be removed
All the pattern delete function can use her reference to the original
"struct pat_ref_elt" to find the element to be remove. The functions
pat_del_list_str() and pat_del_meth() were deleted because after
applying this modification, they have the same code than pat_del_list_ptr().
2014-03-17 18:06:08 +01:00
Thierry FOURNIER
55d0b10f06 MEDIUM: pattern: add sample lookup function.
Some functions needs to change the sample associated to pattern. This
new pointer permit to return the a pointer to the sample pointer. The
caller can use or change the value.
2014-03-17 18:06:07 +01:00
Thierry FOURNIER
6f7203d673 MEDIUM: pattern: add prune function
This path add specific pointer to each expression to point on prune
function. Now, each pattern expression embed his own prune function.
2014-03-17 18:06:07 +01:00
Thierry FOURNIER
b113650e54 MEDIUM: pattern: add delete functions
This commit adds a delete function for patterns. It looks up all
instances of the pattern to delete and deletes them all. The fetch
keyword declarations have been extended to point to the appropriate
delete function.
2014-03-17 18:06:07 +01:00
Thierry FOURNIER
7654c9ff44 MEDIUM: sample: Remove types SMP_T_CSTR and SMP_T_CBIN, replace it by SMP_F_CONST flags
The operations applied on types SMP_T_CSTR and SMP_T_STR are the same,
but the check code and the declarations are double, because it must
declare action for SMP_T_C* and SMP_T_*. The declared actions and checks
are the same. this complexify the code. Only the "conv" functions can
change from "C*" to "*"

Now, if a function needs to modify input string, it can call the new
function smp_dup(). This one duplicate data in a trash buffer.
2014-03-17 18:06:07 +01:00
Thierry FOURNIER
b9b08460a2 MEDIUM: pattern: add indexation function.
Before this patch, the indexation function check the declared patttern
matching function and index the data according with this function. This
is not useful to add some indexation mode.

This commit adds dedicated indexation function. Each struct pattern is
associated with one indexation function. This function permit to index
data according with the type of pattern and with the type of match.
2014-03-17 18:06:06 +01:00
Willy Tarreau
518ceddebe BUG/MEDIUM: ssl: always send a full buffer after EAGAIN
Igor Chan reported a very interesting bug which was triggered by the
recent dynamic size change in SSL.

The OpenSSL API refuses to send less data than any failed previous
attempt. So what's happening is that if an SSL_write() in streaming
mode sends 5kB of data and the openssl layer cannot send them all,
it returns SSL_ERROR_WANT_WRITE, which haproxy reacts to by enabling
polling on the file descriptor. In the mean time, haproxy may detect
that the buffer was almost full and will disable streaming mode. Upon
write notification, it will try to send again, but less data this
time (limited to tune.ssl_max_record). OpenSSL disagrees with this
and returns a generic error SSL_ERROR_SSL.

The solution which was found consists in adding a flag to the SSL
context to remind that we must not shrink writes after a failed
attempt. Thus, if EAGAIN is encountered, the next send() will not
be limited in order to retry the same size as before.
2014-02-17 16:02:01 +01:00
Dirkjan Bussink
48f1c4e3ad MEDIUM: ssl: Use ALPN support as it will be available in OpenSSL 1.0.2
The current ALPN support is based on custom OpenSSL patches. These are
however not the same as what has landed on OpenSSL:

http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=6f017a8f9db3a79f3a3406cf8d493ccd346db691

This patch change the code so it supports ALPN as it will be part of
OpenSSL.
2014-02-16 19:49:51 +01:00
Willy Tarreau
07ba08b57c BUG/MINOR: ssl: fix syntax in config error message
Some error messages about server lines had a confusing '|' instead
of '[' to delimit the config file name.
2014-02-16 19:22:08 +01:00
Willy Tarreau
610f04bbf6 MINOR: config: add global directives to set default SSL ciphers
The ability to globally override the default client and server cipher
suites has been requested multiple times since the introduction of SSL.
This commit adds two new keywords to the global section for this :
  - ssl-default-bind-ciphers
  - ssl-default-server-ciphers

It is still possible to preset them at build time by setting the macros
LISTEN_DEFAULT_CIPHERS and CONNECT_DEFAULT_CIPHERS.
2014-02-13 11:36:41 +01:00
Willy Tarreau
7bed945be0 OPTIM: ssl: implement dynamic record size adjustment
By having the stream interface pass the CF_STREAMER flag to the
snd_buf() primitive, we're able to tell the send layer whether
we're sending large chunks or small ones.

We use this information in SSL to adjust the max record dynamically.
This results in small chunks respecting tune.ssl.maxrecord at the
beginning of a transfer or for small transfers, with an automatic
switch to full records if the exchanges last long. This allows the
receiver to parse HTML contents on the fly without having to retrieve
16kB of data, which is even more important with small initcwnd since
the receiver does not need to wait for round trips to start fetching
new objects. However, sending large files still produces large chunks.

For example, with tune.ssl.maxrecord = 2859, we see 5 write(2885)
sent in two segments each and 6 write(16421).

This idea was first proposed on the haproxy mailing list by Ilya Grigorik.
2014-02-06 11:37:29 +01:00
Willy Tarreau
1049b1f551 MEDIUM: connection: don't use real send() flags in snd_buf()
This prevents us from passing other useful info and requires the
upper levels to know these flags. Let's use a new flags category
instead : CO_SFL_*. For now, only MSG_MORE has been remapped.
2014-02-06 11:37:29 +01:00
Emeric Brun
d8b2bb5c05 MINOR: ssl: handshake optim for long certificate chains.
Suggested on the mailing list by Ilya Grigorik and greatly inspired
from Nginx code: we try to dynamicaly rise the output buffer size from
4k to 16k during the handshake to reduce the number of round trips.
This is mostly beneficial when initcwnd==10.

Ilya's tests confirm the gain and show a handshake time divided by 3 :

before:
   http://www.webpagetest.org/result/140116_VW_3bd95a5cfb7e667498ef13b59639b9bf/2/details/
after:
   http://www.webpagetest.org/result/140201_2X_03511ec63344f442b81c24d2bf39f59d/3/details/
2014-02-02 09:38:06 +01:00
Emeric Brun
850efd5149 MEDIUM: ssl: Set verify 'required' as global default for servers side.
If no CA file specified on a server line, the config parser will show an error.

Adds an cmdline option '-dV' to re-set verify 'none' as global default on
servers side (previous behavior).

Also adds 'ssl-server-verify' global statement to set global default to
'none' or 'required'.

WARNING: this changes the default verify mode from "none" to "required" on
the server side, and it *will* break insecure setups.
2014-01-29 17:08:15 +01:00
Willy Tarreau
71b734c307 MINOR: cli: add more information to the "show info" output
In addition to previous outputs, we also emit the cumulated number of
connections, the cumulated number of requests, the maximum allowed
SSL connection concurrency, the current number of SSL connections and
the cumulated number of SSL connections. This will help troubleshoot
systems which experience memory shortage due to SSL.
2014-01-28 15:19:44 +01:00
Willy Tarreau
3c72872da1 CLEANUP: connection: use conn_ctrl_ready() instead of checking the flag
It's easier and safer to rely on conn_ctrl_ready() everywhere than to
check the flag itself. It will also simplify adding extra checks later
if needed. Some useless controls for !ctrl have been removed, as the
CTRL_READY flag itself guarantees ctrl is set.
2014-01-26 00:42:31 +01:00
Willy Tarreau
e1f50c4b02 MEDIUM: connection: remove conn_{data,sock}_poll_{recv,send}
We simply remove these functions and replace their calls with the
appropriate ones :

  - if we're in the data phase, we can simply report wait on the FD
  - if we're in the socket phase, we may also have to signal the
    desire to read/write on the socket because it might not be
    active yet.
2014-01-26 00:42:30 +01:00
Willy Tarreau
46be2e5039 MEDIUM: connection: update callers of ctrl->drain() to use conn_drain()
Now we can more safely rely on the connection state to decide how to
drain and what to do when data are drained. Callers don't need to
manipulate the file descriptor's state anymore.

Note that it also removes the need for the fix ea90063 ("BUG/MEDIUM:
stream-int: fix the keep-alive idle connection handler") since conn_drain()
correctly sets the polling flags.
2014-01-20 22:27:17 +01:00
Willy Tarreau
00b0fb9349 BUG/MAJOR: ssl: fix breakage caused by recent fix abf08d9
Recent commit abf08d9 ("BUG/MAJOR: connection: fix mismatch between rcv_buf's
API and usage") accidentely broke SSL by relying on an uninitialized value to
enter the read loop.

Many thanks to Cyril Bonté and Steve Ruiz for reporting this issue.
2014-01-17 11:09:40 +01:00
Willy Tarreau
abf08d9365 BUG/MAJOR: connection: fix mismatch between rcv_buf's API and usage
Steve Ruiz reported some reproducible crashes with HTTP health checks
on a certain page returning a huge length. The traces he provided
clearly showed that the recv() call was performed twice for a total
size exceeding the buffer's length.

Cyril Bonté tracked down the problem to be caused by the full buffer
size being passed to rcv_buf() in event_srv_chk_r() instead of passing
just the remaining amount of space. Indeed, this change happened during
the connection rework in 1.5-dev13 with the following commit :

f150317 MAJOR: checks: completely use the connection transport layer

But one of the problems is also that the comments at the top of the
rcv_buf() functions suggest that the caller only has to ensure the
requested size doesn't overflow the buffer's size.

Also, these functions already have to care about the buffer's size to
handle wrapping free space when there are pending data in the buffer.
So let's change the API instead to more closely match what could be
expected from these functions :

- the caller asks for the maximum amount of bytes it wants to read ;
This means that only the caller is responsible for enforcing the
reserve if it wants to (eg: checks don't).

- the rcv_buf() functions fix their computations to always consider
this size as a max, and always perform validity checks based on
the buffer's free space.

As a result, the code is simplified and reduced, and made more robust
for callers which now just have to care about whether they want the
buffer to be filled or not.

Since the bug was introduced in 1.5-dev13, no backport to stable versions
is needed.
2014-01-15 01:09:48 +01:00
Willy Tarreau
f79c8171b2 MAJOR: connection: add two new flags to indicate readiness of control/transport
Currently the control and transport layers of a connection are supposed
to be initialized when their respective pointers are not NULL. This will
not work anymore when we plan to reuse connections, because there is an
asymmetry between the accept() side and the connect() side :

  - on accept() side, the fd is set first, then the ctrl layer then the
    transport layer ; upon error, they must be undone in the reverse order,
    then the FD must be closed. The FD must not be deleted if the control
    layer was not yet initialized ;

  - on the connect() side, the fd is set last and there is no reliable way
    to know if it has been initialized or not. In practice it's initialized
    to -1 first but this is hackish and supposes that local FDs only will
    be used forever. Also, there are even less solutions for keeping trace
    of the transport layer's state.

Also it is possible to support delayed close() when something (eg: logs)
tracks some information requiring the transport and/or control layers,
making it even more difficult to clean them.

So the proposed solution is to add two flags to the connection :

  - CO_FL_CTRL_READY is set when the control layer is initialized (fd_insert)
    and cleared after it's released (fd_delete).

  - CO_FL_XPRT_READY is set when the control layer is initialized (xprt->init)
    and cleared after it's released (xprt->close).

The functions have been adapted to rely on this and not on the pointers
anymore. conn_xprt_close() was unused and dangerous : it did not close
the control layer (eg: the socket itself) but still marks the transport
layer as closed, preventing any future call to conn_full_close() from
finishing the job.

The problem comes from conn_full_close() in fact. It needs to close the
xprt and ctrl layers independantly. After that we're still having an issue :
we don't know based on ->ctrl alone whether the fd was registered or not.
For this we use the two new flags CO_FL_XPRT_READY and CO_FL_CTRL_READY. We
now rely on this and not on conn->xprt nor conn->ctrl anymore to decide what
remains to be done on the connection.

In order not to miss some flag assignments, we introduce conn_ctrl_init()
to initialize the control layer, register the fd using fd_insert() and set
the flag, and conn_ctrl_close() which unregisters the fd and removes the
flag, but only if the transport layer was closed.

Similarly, at the transport layer, conn_xprt_init() calls ->init and sets
the flag, while conn_xprt_close() checks the flag, calls ->close and clears
the flag, regardless xprt_ctx or xprt_st. This also ensures that the ->init
and the ->close functions are called only once each and in the correct order.
Note that conn_xprt_close() does nothing if the transport layer is still
tracked.

conn_full_close() now simply calls conn_xprt_close() then conn_full_close()
in turn, which do nothing if CO_FL_XPRT_TRACKED is set.

In order to handle the error path, we also provide conn_force_close() which
ignores CO_FL_XPRT_TRACKED and closes the transport and the control layers
in turns. All relevant instances of fd_delete() have been replaced with
conn_force_close(). Now we always know what state the connection is in and
we can expect to split its initialization.
2013-12-09 15:40:23 +01:00
Willy Tarreau
b363a1f469 MAJOR: stream-int: stop using si->conn and use si->end instead
The connection will only remain there as a pre-allocated entity whose
goal is to be placed in ->end when establishing an outgoing connection.
All connection initialization can be made on this connection, but all
information retrieved should be applied to the end point only.

This change is huge because there were many users of si->conn. Now the
only users are those who initialize the new connection. The difficulty
appears in a few places such as backend.c, proto_http.c, peers.c where
si->conn is used to hold the connection's target address before assigning
the connection to the stream interface. This is why we have to keep
si->conn for now. A future improvement might consist in dynamically
allocating the connection when it is needed.
2013-12-09 15:40:22 +01:00
Thierry FOURNIER
a65b343eee MEDIUM: pattern: rename "acl" prefix to "pat"
This patch just renames functions, types and enums. No code was changed.
A significant number of files were touched, especially the ACL arrays,
so it is likely that some external patches will not apply anymore.

One important thing is that we had to split ACL_PAT_* into two groups :
  - ACL_TEST_{PASS|MISS|FAIL}
  - PAT_{MATCH|UNMATCH}

A future patch will enforce enums on all these places to avoid confusion.
2013-12-02 23:31:33 +01:00
Thierry FOURNIER
ed66c297c2 REORG: acl/pattern: extract pattern matching from the acl file and create pattern.c
This patch just moves code without any change.

The ACL are just the association between sample and pattern. The pattern
contains the match method and the parse method. These two things are
different. This patch cleans the code by splitting it.
2013-12-02 23:31:33 +01:00
Simon Horman
6618300e13 MEDIUM: Split up struct server's check element
This is in preparation for associating a agent check
with a server which runs as well as the server's existing check.

The split has been made by:
* Moving elements of struct server's check element that will
  be shared by both checks into a new check_common element
  of struct server.
* Moving the remaining elements to a new struct check and
  making struct server's check element a struct check.
* Adding a server element to struct check, a back-pointer
  to the server element it is a member of.
  - At this time the server could be obtained using
    container_of, however, this will not be so easy
    once a second struct check element is added to struct server
    to accommodate an agent health check.

Signed-off-by: Simon Horman <horms@verge.net.au>
2013-11-19 09:35:48 +01:00
Emeric Brun
369da8565a BUG/MINOR: ssl: verifyhost does not match empty strings on wildcard.
RFC6125 does not specify if wildcard matches empty strings but
classical browsers implementations does.
After the fix foo*bar.exemple.om matches foobar.exemple.com.
2013-10-10 11:33:27 +02:00
Emeric Brun
a848dae3f0 MINOR: ssl: optimization of verifyhost on wildcard certificates.
Optimizes verifyhost on wildcard certificates avoiding travel several times
the same string.
2013-10-10 11:33:21 +02:00
Emeric Brun
9bf3ba28e1 BUG/MINOR: ssl: potential memory leaks using ssl_c_key_alg or ssl_c_sig_alg.
The leak occurs in an error case which practically never happens.
2013-10-10 11:33:14 +02:00
Emeric Brun
a33410cf94 BUILD: ssl: compilation issue with openssl v0.9.6.
Failed to compile with openssl 0.9.6 since the 'verifyhost' feature.
2013-09-17 23:19:41 +02:00
Emeric Brun
4ad50a469d BUG/MEDIUM: ssl: potential memory leak using verifyhost
If server certificate presents dns aliases, a memory leak appears
on health checks when 'verifyhost' statement is used.
2013-09-17 23:19:27 +02:00
Evan Broder
be55431f9f MINOR: ssl: Add statement 'verifyhost' to "server" statements
verifyhost allows you to specify a hostname that the remote server's
SSL certificate must match. Connections that don't match will be
closed with an SSL error.
2013-09-01 07:55:49 +02:00
Willy Tarreau
380110368e MINOR: ssl: use MAXPATHLEN instead of PATH_MAX
Apollon Oikonomopoulos reported a build failure on Hurd where PATH_MAX
is not defined. The only place where it is referenced is ssl_sock.c,
all other places use MAXPATHLEN instead, with a fallback to 128 when
the OS does not define it. So let's switch to MAXPATHLEN as well.
2013-08-13 16:59:39 +02:00
Willy Tarreau
ef38c39287 MEDIUM: sample: systematically pass the keyword pointer to the keyword
We're having a lot of duplicate code just because of minor variants between
fetch functions that could be dealt with if the functions had the pointer to
the original keyword, so let's pass it as the last argument. An earlier
version used to pass a pointer to the sample_fetch element, but this is not
the best solution for two reasons :
  - fetch functions will solely rely on the keyword string
  - some other smp_fetch_* users do not have the pointer to the original
    keyword and were forced to pass NULL.

So finally we're passing a pointer to the keyword as a const char *, which
perfectly fits the original purpose.
2013-08-01 21:17:13 +02:00
Willy Tarreau
dc13c11c1e BUG/MEDIUM: prevent gcc from moving empty keywords lists into BSS
Benoit Dolez reported a failure to start haproxy 1.5-dev19. The
process would immediately report an internal error with missing
fetches from some crap instead of ACL names.

The cause is that some versions of gcc seem to trim static structs
containing a variable array when moving them to BSS, and only keep
the fixed size, which is just a list head for all ACL and sample
fetch keywords. This was confirmed at least with gcc 3.4.6. And we
can't move these structs to const because they contain a list element
which is needed to link all of them together during the parsing.

The bug indeed appeared with 1.5-dev19 because it's the first one
to have some empty ACL keyword lists.

One solution is to impose -fno-zero-initialized-in-bss to everyone
but this is not really nice. Another solution consists in ensuring
the struct is never empty so that it does not move there. The easy
solution consists in having a non-null list head since it's not yet
initialized.

A new "ILH" list head type was thus created for this purpose : create
an Initialized List Head so that gcc cannot move the struct to BSS.
This fixes the issue for this version of gcc and does not create any
burden for the declarations.
2013-06-21 23:29:02 +02:00
Willy Tarreau
6d4e4e8dd2 MEDIUM: acl: remove a lot of useless ACLs that are equivalent to their fetches
The following 116 ACLs were removed because they're redundant with their
fetch function since last commit which allows the fetch function to be
used instead for types BOOL, INT and IP. Most places are now left with
an empty ACL keyword list that was not removed so that it's easier to
add other ACLs later.

always_false, always_true, avg_queue, be_conn, be_id, be_sess_rate, connslots,
nbsrv, queue, srv_conn, srv_id, srv_is_up, srv_sess_rate, res.comp, fe_conn,
fe_id, fe_sess_rate, dst_conn, so_id, wait_end, http_auth, http_first_req,
status, dst, dst_port, src, src_port, sc1_bytes_in_rate, sc1_bytes_out_rate,
sc1_clr_gpc0, sc1_conn_cnt, sc1_conn_cur, sc1_conn_rate, sc1_get_gpc0,
sc1_gpc0_rate, sc1_http_err_cnt, sc1_http_err_rate, sc1_http_req_cnt,
sc1_http_req_rate, sc1_inc_gpc0, sc1_kbytes_in, sc1_kbytes_out, sc1_sess_cnt,
sc1_sess_rate, sc1_tracked, sc1_trackers, sc2_bytes_in_rate,
sc2_bytes_out_rate, sc2_clr_gpc0, sc2_conn_cnt, sc2_conn_cur, sc2_conn_rate,
sc2_get_gpc0, sc2_gpc0_rate, sc2_http_err_cnt, sc2_http_err_rate,
sc2_http_req_cnt, sc2_http_req_rate, sc2_inc_gpc0, sc2_kbytes_in,
sc2_kbytes_out, sc2_sess_cnt, sc2_sess_rate, sc2_tracked, sc2_trackers,
sc3_bytes_in_rate, sc3_bytes_out_rate, sc3_clr_gpc0, sc3_conn_cnt,
sc3_conn_cur, sc3_conn_rate, sc3_get_gpc0, sc3_gpc0_rate, sc3_http_err_cnt,
sc3_http_err_rate, sc3_http_req_cnt, sc3_http_req_rate, sc3_inc_gpc0,
sc3_kbytes_in, sc3_kbytes_out, sc3_sess_cnt, sc3_sess_rate, sc3_tracked,
sc3_trackers, src_bytes_in_rate, src_bytes_out_rate, src_clr_gpc0,
src_conn_cnt, src_conn_cur, src_conn_rate, src_get_gpc0, src_gpc0_rate,
src_http_err_cnt, src_http_err_rate, src_http_req_cnt, src_http_req_rate,
src_inc_gpc0, src_kbytes_in, src_kbytes_out, src_sess_cnt, src_sess_rate,
src_updt_conn_cnt, table_avl, table_cnt, ssl_c_ca_err, ssl_c_ca_err_depth,
ssl_c_err, ssl_c_used, ssl_c_verify, ssl_c_version, ssl_f_version, ssl_fc,
ssl_fc_alg_keysize, ssl_fc_has_crt, ssl_fc_has_sni, ssl_fc_use_keysize,
2013-06-11 21:22:58 +02:00
Willy Tarreau
2b57cb8f30 MEDIUM: protocol: implement a "drain" function in protocol layers
Since commit cfd97c6f was merged into 1.5-dev14 (BUG/MEDIUM: checks:
prevent TIME_WAITs from appearing also on timeouts), some valid health
checks sometimes used to show some TCP resets. For example, this HTTP
health check sent to a local server :

  19:55:15.742818 IP 127.0.0.1.16568 > 127.0.0.1.8000: S 3355859679:3355859679(0) win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
  19:55:15.742841 IP 127.0.0.1.8000 > 127.0.0.1.16568: S 1060952566:1060952566(0) ack 3355859680 win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
  19:55:15.742863 IP 127.0.0.1.16568 > 127.0.0.1.8000: . ack 1 win 257
  19:55:15.745402 IP 127.0.0.1.16568 > 127.0.0.1.8000: P 1:23(22) ack 1 win 257
  19:55:15.745488 IP 127.0.0.1.8000 > 127.0.0.1.16568: FP 1:146(145) ack 23 win 257
  19:55:15.747109 IP 127.0.0.1.16568 > 127.0.0.1.8000: R 23:23(0) ack 147 win 257

After some discussion with Chris Huang-Leaver, it appeared clear that
what we want is to only send the RST when we have no other choice, which
means when the server has not closed. So we still keep SYN/SYN-ACK/RST
for pure TCP checks, but don't want to see an RST emitted as above when
the server has already sent the FIN.

The solution against this consists in implementing a "drain" function at
the protocol layer, which, when defined, causes as much as possible of
the input socket buffer to be flushed to make recv() return zero so that
we know that the server's FIN was received and ACKed. On Linux, we can make
use of MSG_TRUNC on TCP sockets, which has the benefit of draining everything
at once without even copying data. On other platforms, we read up to one
buffer of data before the close. If recv() manages to get the final zero,
we don't disable lingering. Same for hard errors. Otherwise we do.

In practice, on HTTP health checks we generally find that the close was
pending and is returned upon first recv() call. The network trace becomes
cleaner :

  19:55:23.650621 IP 127.0.0.1.16561 > 127.0.0.1.8000: S 3982804816:3982804816(0) win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
  19:55:23.650644 IP 127.0.0.1.8000 > 127.0.0.1.16561: S 4082139313:4082139313(0) ack 3982804817 win 32792 <mss 16396,nop,nop,sackOK,nop,wscale 7>
  19:55:23.650666 IP 127.0.0.1.16561 > 127.0.0.1.8000: . ack 1 win 257
  19:55:23.651615 IP 127.0.0.1.16561 > 127.0.0.1.8000: P 1:23(22) ack 1 win 257
  19:55:23.651696 IP 127.0.0.1.8000 > 127.0.0.1.16561: FP 1:146(145) ack 23 win 257
  19:55:23.652628 IP 127.0.0.1.16561 > 127.0.0.1.8000: F 23:23(0) ack 147 win 257
  19:55:23.652655 IP 127.0.0.1.8000 > 127.0.0.1.16561: . ack 24 win 257

This change should be backported to 1.4 which is where Chris encountered
this issue. The code is different, so probably the tcp_drain() function
will have to be put in the checks only.
2013-06-10 20:33:23 +02:00
Emmanuel Hocdet
79274e2c40 BUG: ssl: fix crt-list for clients not supporting SNI
I left a mistake in my previous patch bringing the crt-list feature,
it breaks clients with no SNI support.

Also remove the useless wildp = NULL as per a previous discussion.
2013-05-31 13:59:35 +02:00