global statement "ssl-default-bind-options". Use "ssl-min-ver" and
"ssl-max-ver" instead.
+no-strict-sni
+ This setting is only available when support for OpenSSL was built in. It
+ disables strict-sni enforcement from a previous "strict-sni" directive. It
+ may be needed in order to selectively disable strict-sni usage on a "bind"
+ line when it was already globally enforced via "ssl-default-bind-options".
+ See also the "strict-sni" bind option.
+
no-tls-tickets
This setting is only available when support for OpenSSL was built in. It
disables the stateless session resumption (RFC 5077 TLS Ticket
SSL/TLS negotiation is allowed only if the client provided an SNI that matches
a certificate. The default certificate is not used. This option also allows
starting without any certificate on a bind line, so an empty directory could
- be used and filled later from the stats socket.
- See the "crt" option for more information. See "add ssl crt-list" command in
- the management guide.
+ be used and filled later from the stats socket. This option is also available
+ on global statement "ssl-default-bind-options", and may be selectively
+ disabled on a "bind" line using "no-strict-sni". See the "crt" option for
+ more information. See "add ssl crt-list" command in the management guide.
tcp-ut <delay>
Sets the TCP User Timeout for all incoming connections instantiated from this
#define BC_SSL_O_NONE 0x0000
#define BC_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
#define BC_SSL_O_PREF_CLIE_CIPH 0x0200 /* prefer client ciphers */
+#define BC_SSL_O_STRICT_SNI 0x0400 /* refuse negotiation if sni doesn't match a certificate */
#endif
struct tls_version_filter {
unsigned long long ca_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth > 0 */
unsigned long long crt_ignerr_bitfield[IGNERR_BF_SIZE]; /* ignored verify errors in handshake if depth == 0 */
void *initial_ctx; /* SSL context for initial negotiation */
- int strict_sni; /* refuse negotiation if sni doesn't match a certificate */
int ssl_options; /* ssl options */
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 */
tune.ssl.capture-buffer-size 1
crt-base ${testdir}
stats socket "${tmpdir}/h1/stats" level admin
+ ssl-default-bind-options strict-sni
defaults
mode http
server s3 "${tmpdir}/first-ssl.sock" ssl verify none sni str(record2.bug940.domain.tld)
listen first-ssl-fe
+ # note: strict-sni is enforced from ssl-default-bind-options above
mode http
- bind "${tmpdir}/first-ssl.sock" ssl strict-sni crt-list ${testdir}/simple.crt-list
+ bind "${tmpdir}/first-ssl.sock" ssl crt-list ${testdir}/simple.crt-list
server s1 ${s1_addr}:${s1_port}
listen second-ssl-fe
mode http
- bind "${tmpdir}/second-ssl.sock" ssl crt-list ${testdir}/localhost.crt-list
+ bind "${tmpdir}/second-ssl.sock" ssl no-strict-sni crt-list ${testdir}/localhost.crt-list
server s1 ${s1_addr}:${s1_port}
} -start
return 0;
}
-/* parse the "strict-sni" bind keyword */
+/* parse the "strict-sni" and "no-strict-sni" bind keywords */
static int bind_parse_strict_sni(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
- conf->strict_sni = 1;
+ if (strncmp(args[cur_arg], "no-", 3) != 0)
+ conf->ssl_options |= BC_SSL_O_STRICT_SNI;
+ else
+ conf->ssl_options &= ~BC_SSL_O_STRICT_SNI;
return 0;
}
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
else if (strcmp(args[i], "prefer-client-ciphers") == 0)
global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
+ else if (strcmp(args[i], "strict-sni") == 0)
+ global_ssl.listen_default_ssloptions |= BC_SSL_O_STRICT_SNI;
+ else if (strcmp(args[i], "no-strict-sni") == 0)
+ global_ssl.listen_default_ssloptions &= ~BC_SSL_O_STRICT_SNI;
else if (strcmp(args[i], "ssl-min-ver") == 0 || strcmp(args[i], "ssl-max-ver") == 0) {
if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
i++;
{ "no-alpn", bind_parse_no_alpn, 0 }, /* disable sending ALPN */
{ "no-ca-names", bind_parse_no_ca_names, 0 }, /* do not send ca names to clients (ca_file related) */
{ "no-sslv3", bind_parse_tls_method_options, 0 }, /* disable SSLv3 */
+ { "no-strict-sni", bind_parse_strict_sni, 0 }, /* do not refuse negotiation if sni doesn't match a certificate */
{ "no-tlsv10", bind_parse_tls_method_options, 0 }, /* disable TLSv10 */
{ "no-tlsv11", bind_parse_tls_method_options, 0 }, /* disable TLSv11 */
{ "no-tlsv12", bind_parse_tls_method_options, 0 }, /* disable TLSv12 */
#endif
/* no servername field is not compatible with strict-sni */
- if (s->strict_sni) {
+ if (s->ssl_options & BC_SSL_O_STRICT_SNI) {
TRACE_ERROR("No server_name provided and 'strict-sni' enabled", SSL_EV_CONN_SWITCHCTX_CB|SSL_EV_CONN_ERR, conn);
goto abort;
}
}
#endif
- if (!s->strict_sni && !default_lookup) {
+ if (!(s->ssl_options & BC_SSL_O_STRICT_SNI) && !default_lookup) {
/* we didn't find a SNI, and we didn't look for a default
* look again to find a matching default cert */
servername = "";
return SSL_TLSEXT_ERR_OK;
}
#endif
- if (s->strict_sni) {
+ if (s->ssl_options & BC_SSL_O_STRICT_SNI) {
TRACE_ERROR("No server_name provided and 'strict-sni' enabled", SSL_EV_CONN_SWITCHCTX_CB|SSL_EV_CONN_ERR);
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
#endif
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
- if (!s->strict_sni && !default_lookup) {
+ if (!(s->ssl_options & BC_SSL_O_STRICT_SNI) && !default_lookup) {
/* we didn't find a SNI, and we didn't look for a default
* look again to find a matching default cert */
servername = "";
servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
if (!servername) {
- if (s->strict_sni)
+ if (s->ssl_options & BC_SSL_O_STRICT_SNI)
goto abort;
/* without servername extension, look for the defaults which is
}
HA_RWLOCK_RDUNLOCK(SNI_LOCK, &s->sni_lock);
- if (!s->strict_sni && !default_lookup) {
+ if (!(s->ssl_options & BC_SSL_O_STRICT_SNI) && !default_lookup) {
/* we didn't find a SNI, and we didn't look for a default
* look again to find a matching default cert */
servername = "";
/* Iterate over all the instances in order to see if any of them is a
* default instance. If this is the case, the entry won't be suppressed. */
list_for_each_entry_safe(inst, inst_s, &entry->ckch_inst, by_crtlist_entry) {
- if (inst->is_default && !inst->bind_conf->strict_sni) {
+ if (inst->is_default && !(inst->bind_conf->ssl_options & BC_SSL_O_STRICT_SNI)) {
if (!error_message_dumped) {
memprintf(&err, "certificate '%s' cannot be deleted, it is used as default certificate by the following frontends:\n", cert_path);
error_message_dumped = 1;
/* check if we have certificates */
if (eb_is_empty(&bind_conf->sni_ctx) && eb_is_empty(&bind_conf->sni_w_ctx)) {
- if (bind_conf->strict_sni && !(bind_conf->options & BC_O_GENERATE_CERTS)) {
+ if ((bind_conf->ssl_options & BC_SSL_O_STRICT_SNI) && !(bind_conf->options & BC_O_GENERATE_CERTS)) {
ha_warning("Proxy '%s': no SSL certificate specified for bind '%s' at [%s:%d], ssl connections will fail (use 'crt').\n",
px->id, bind_conf->arg, bind_conf->file, bind_conf->line);
}