through TCP request content inspection. Please see the "tcp-request content"
keyword for more detailed information on the subject.
+is_ssl
+ Returns true when the incoming connection was made via an SSL/TLS data layer
+ and is locally deciphered. This means it has matched a socket declared with
+ a "bind" line having the "ssl" option.
+
rep_ssl_hello_type <integer>
Returns true when data in the response buffer looks like a complete SSL (v3
or superior) hello message and handshake type is equal to <integer>.
This test was designed to be used with TCP response content inspection: a
- SSL session ID may be fetched.
+ SSL session ID may be fetched. Note that this only applies to raw contents
+ found in the request buffer and not to contents deciphered via an SSL data
+ layer, so this will not work with "bind" lines having the "ssl" option.
req_len <integer>
Returns true when the length of the data in the request buffer matches the
Returns true when data in the request buffer looks like a complete SSL (v3
or superior) hello message and handshake type is equal to <integer>.
This test was designed to be used with TCP request content inspection: an
- SSL session ID may be fetched.
+ SSL session ID may be fetched. Note that this only applies to raw contents
+ found in the request buffer and not to contents deciphered via an SSL data
+ layer, so this will not work with "bind" lines having the "ssl" option.
req_ssl_sni <string>
Returns true when data in the request buffer looks like a complete SSL (v3
or denying access to certain hosts when SSL/TLS is used by the client. This
test was designed to be used with TCP request content inspection. If content
switching is needed, it is recommended to first wait for a complete client
- hello (type 1), like in the example below.
+ hello (type 1), like in the example below. Note that this only applies to raw
+ contents found in the request buffer and not to contents deciphered via an
+ SSL data layer, so this will not work with "bind" lines having the "ssl"
+ option. See also "ssl_sni" below.
Examples :
# Wait for a client hello for at most 5 seconds
easily fooled. In particular, it waits for as many bytes as announced in the
message header if this header looks valid (bound to the buffer size). Note
that TLSv1 is announced as SSL version 3.1. This test was designed to be used
- with TCP request content inspection.
+ with TCP request content inspection. Note that this only applies to raw
+ contents found in the request buffer and not to contents deciphered via an
+ SSL data layer, so this will not work with "bind" lines having the "ssl"
+ option.
+
+ssl_sni <string>
+ Returns true when the incoming connection was made over an SSL/TLS data layer
+ which deciphered it and found a Server Name Indication TLS extension sent by
+ the client, matching the specified string. In HTTPS, the SNI field (when
+ present) is equal to the requested host name. This match is different from
+ req_ssl_sni above in that it applies to the connection being deciphered by
+ haproxy and not to SSL contents being blindly forwarded. This requires that
+ the SSL library is build with support for TLS extensions (check haproxy -vv).
+
+ssl_has_sni
+ This is used to check for presence of a Server Name Indication TLS extension
+ in an incoming connection was made over an SSL/TLS data layer. Returns true
+ when the incoming connection presents a TLS SNI field. This requires that
+ the SSL library is build with support for TLS extensions (check haproxy -vv).
+
+ssl_sni <string>
+ Returns true when the incoming connection was made over an SSL/TLS data layer
+ which deciphered it and found a Server Name Indication TLS extension sent by
+ the client, matching the specified string. In HTTPS, the SNI field (when
+ present) is equal to the requested host name. This match is different from
+ req_ssl_sni above in that it applies to the connection being deciphered by
+ haproxy and not to SSL contents being blindly forwarded. See also ssl_sni_end
+ and ssl_sni_req below. This requires that the SSL library is build with
+ support for TLS extensions (check haproxy -vv).
+
+ssl_sni_end <string>
+ Returns true when the incoming connection was made over an SSL/TLS data layer
+ which deciphered it and found a Server Name Indication TLS extension sent by
+ the client, ending like the specified string. In HTTPS, the SNI field (when
+ present) is equal to the requested host name. This match is different from
+ req_ssl_sni above in that it applies to the connection being deciphered by
+ haproxy and not to SSL contents being blindly forwarded. This requires that
+ the SSL library is build with support for TLS extensions (check haproxy -vv).
+
+ssl_sni_req <regex>
+ Returns true when the incoming connection was made over an SSL/TLS data layer
+ which deciphered it and found a Server Name Indication TLS extension sent by
+ the client, matching the specified regex. In HTTPS, the SNI field (when
+ present) is equal to the requested host name. This match is different from
+ req_ssl_sni above in that it applies to the connection being deciphered by
+ haproxy and not to SSL contents being blindly forwarded. This requires that
+ the SSL library is build with support for TLS extensions (check haproxy -vv).
wait_end
Waits for the end of the analysis period to return true. This may be used in
last one. A typical use is with the X-Forwarded-For header once
converted to IP, associated with an IP stick-table.
+ is_ssl This checks the data layer used by incoming connection, and
+ returns 1 if the connection was made via an SSL/TLS data layer,
+ otherwise zero.
+
path This extracts the request's URL path (without the host part). A
typical use is with prefetch-capable caches, and with portals
which need to aggregate multiple information from databases and
that this function will be useful but it's available at no cost.
It is of type integer and only works with such tables.
+ ssl_has_sni This checks the data layer used by incoming connection, and
+ returns 1 if the connection was made via an SSL/TLS data layer
+ and the client sent a Server Name Indication TLS extension,
+ otherwise zero. This requires that the SSL library is build with
+ support for TLS extensions (check haproxy -vv).
+
+ ssl_sni This extracts the Server Name Indication field from an incoming
+ connection made via an SSL/TLS data layer and locally deciphered
+ by haproxy. The result typically is a string matching the HTTPS
+ host name (253 chars or less). The SSL library must have been
+ built with support for TLS extensions (check haproxy -vv).
+
url This extracts the request's URL as presented in the request. A
typical use is with prefetch-capable caches, and with portals
which need to aggregate multiple information from databases and
#include <types/global.h>
#include <types/ssl_sock.h>
+#include <proto/acl.h>
+#include <proto/arg.h>
#include <proto/connection.h>
#include <proto/fd.h>
#include <proto/freq_ctr.h>
SSL_set_shutdown(conn->data_ctx, SSL_SENT_SHUTDOWN);
}
+/***** Below are some sample fetching functions for ACL/patterns *****/
+
+/* boolean, returns true if data layer is SSL */
+static int
+smp_fetch_is_ssl(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+ const struct arg *args, struct sample *smp)
+{
+ smp->type = SMP_T_BOOL;
+ smp->data.uint = (l4->si[0].conn.data == &ssl_sock);
+ return 1;
+}
+
+/* boolean, returns true if data layer is SSL */
+static int
+smp_fetch_has_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+ const struct arg *args, struct sample *smp)
+{
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+ smp->type = SMP_T_BOOL;
+ smp->data.uint = (l4->si[0].conn.data == &ssl_sock) &&
+ SSL_get_servername(l4->si[0].conn.data_ctx, TLSEXT_NAMETYPE_host_name) != NULL;
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+static int
+smp_fetch_ssl_sni(struct proxy *px, struct session *l4, void *l7, unsigned int opt,
+ const struct arg *args, struct sample *smp)
+{
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+ smp->flags = 0;
+ smp->type = SMP_T_CSTR;
+
+ if (!l4 || l4->si[0].conn.data != &ssl_sock)
+ return 0;
+
+ /* data points to cookie value */
+ smp->data.str.str = (char *)SSL_get_servername(l4->si[0].conn.data_ctx, TLSEXT_NAMETYPE_host_name);
+ smp->data.str.len = strlen(smp->data.str.str);
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+/* Note: must not be declared <const> as its list will be overwritten.
+ * Please take care of keeping this list alphabetically sorted.
+ */
+static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
+ { "is_ssl", smp_fetch_is_ssl, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
+ { "ssl_has_sni", smp_fetch_has_sni, 0, NULL, SMP_T_BOOL, SMP_CAP_REQ|SMP_CAP_RES },
+ { "ssl_sni", smp_fetch_ssl_sni, 0, NULL, SMP_T_CSTR, SMP_CAP_REQ|SMP_CAP_RES },
+ { NULL, NULL, 0, 0, 0 },
+}};
+
+/* Note: must not be declared <const> as its list will be overwritten.
+ * Please take care of keeping this list alphabetically sorted.
+ */
+static struct acl_kw_list acl_kws = {{ },{
+ { "is_ssl", acl_parse_int, smp_fetch_is_ssl, acl_match_nothing, ACL_USE_L6REQ_PERMANENT, 0 },
+ { "ssl_has_sni", acl_parse_int, smp_fetch_has_sni, acl_match_nothing, ACL_USE_L6REQ_PERMANENT, 0 },
+ { "ssl_sni", acl_parse_str, smp_fetch_ssl_sni, acl_match_str, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
+ { "ssl_sni_end", acl_parse_str, smp_fetch_ssl_sni, acl_match_end, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
+ { "ssl_sni_reg", acl_parse_str, smp_fetch_ssl_sni, acl_match_reg, ACL_USE_L6REQ_PERMANENT|ACL_MAY_LOOKUP, 0 },
+ { NULL, NULL, NULL, NULL },
+}};
+
/* data-layer operations for SSL sockets */
struct data_ops ssl_sock = {
SSL_library_init();
cm = SSL_COMP_get_compression_methods();
sk_SSL_COMP_zero(cm);
+ sample_register_fetches(&sample_fetch_keywords);
+ acl_register_keywords(&acl_kws);
}
/*