MEDIUM: ssl: add bind-option "strict-sni"

This new option ensures that there is no possible fallback to a default
certificate if the client does not provide an SNI which is explicitly
handled by a certificate.
This commit is contained in:
Emmanuel Hocdet 2013-01-24 17:17:15 +01:00 committed by Willy Tarreau
parent cb2699a152
commit 656233715e
3 changed files with 33 additions and 7 deletions

View File

@ -7241,6 +7241,12 @@ ssl
appear in clear text, so that ACLs and HTTP processing will only have access appear in clear text, so that ACLs and HTTP processing will only have access
to deciphered contents. to deciphered contents.
strict-sni
This setting is only available when support for OpenSSL was built in. The
SSL/TLS negotiation is allow only if the client provided an SNI which match
a certificate. The default certificate is not used.
See the "crt" option for more information.
tfo tfo
Is an optional keyword which is supported only on Linux kernels >= 3.6. It Is an optional keyword which is supported only on Linux kernels >= 3.6. It
enables TCP Fast Open on the listening socket, which means that clients which enables TCP Fast Open on the listening socket, which means that clients which

View File

@ -127,6 +127,7 @@ struct bind_conf {
SSL_CTX *default_ctx; /* SSL context of first/default certificate */ SSL_CTX *default_ctx; /* SSL context of first/default certificate */
char *npn_str; /* NPN protocol string */ char *npn_str; /* NPN protocol string */
int npn_len; /* NPN protocol string length */ int npn_len; /* NPN protocol string length */
int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */ struct eb_root sni_ctx; /* sni_ctx tree of all known certs full-names sorted by name */
struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */ struct eb_root sni_w_ctx; /* sni_ctx tree of all known certs wildcards sorted by name */
#endif #endif

View File

@ -178,8 +178,12 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
(void)al; /* shut gcc stupid warning */ (void)al; /* shut gcc stupid warning */
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (!servername) if (!servername) {
return SSL_TLSEXT_ERR_NOACK; if (s->strict_sni)
return SSL_TLSEXT_ERR_ALERT_FATAL;
else
return SSL_TLSEXT_ERR_NOACK;
}
for (i = 0; i < trash.size; i++) { for (i = 0; i < trash.size; i++) {
if (!servername[i]) if (!servername[i])
@ -193,13 +197,20 @@ static int ssl_sock_switchctx_cbk(SSL *ssl, int *al, struct bind_conf *s)
/* lookup in full qualified names */ /* lookup in full qualified names */
node = ebst_lookup(&s->sni_ctx, trash.str); node = ebst_lookup(&s->sni_ctx, trash.str);
if (!node) { if (!node) {
if (!wildp) if (!wildp) {
return SSL_TLSEXT_ERR_ALERT_WARNING; if (s->strict_sni)
return SSL_TLSEXT_ERR_ALERT_FATAL;
else
return SSL_TLSEXT_ERR_ALERT_WARNING;
}
/* lookup in full wildcards names */ /* lookup in full wildcards names */
node = ebst_lookup(&s->sni_w_ctx, wildp); node = ebst_lookup(&s->sni_w_ctx, wildp);
if (!node) if (!node) {
return SSL_TLSEXT_ERR_ALERT_WARNING; if (s->strict_sni)
return SSL_TLSEXT_ERR_ALERT_FATAL;
else
return SSL_TLSEXT_ERR_ALERT_WARNING;
}
} }
/* switch ctx */ /* switch ctx */
@ -2569,6 +2580,13 @@ static int bind_parse_ssl(char **args, int cur_arg, struct proxy *px, struct bin
return 0; return 0;
} }
/* parse the "strict-sni" bind keyword */
static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
conf->strict_sni = 1;
return 0;
}
/* parse the "verify" bind keyword */ /* parse the "verify" bind keyword */
static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err) static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{ {
@ -2888,6 +2906,7 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
{ "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */ { "no-tlsv12", bind_parse_no_tlsv12, 0 }, /* disable TLSv12 */
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */ { "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */ { "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
{ "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
{ "verify", bind_parse_verify, 1 }, /* set SSL verify method */ { "verify", bind_parse_verify, 1 }, /* set SSL verify method */
{ "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */ { "npn", bind_parse_npn, 1 }, /* set NPN supported protocols */
{ NULL, NULL, 0 }, { NULL, NULL, 0 },