It may also be used as "default-server" setting to reset any previous
"default-server" "send-proxy-v2-ssl-cn" setting.
+no-sni-auto
+ May be used in the following contexts: tcp, http, log, peers, ring
+
+ This option may be used as "server" setting to disable the automatic SNI
+ selection which is enabled by default.
+
no-ssl
May be used in the following contexts: tcp, http, log, peers, ring
By default, the SNI is assigned to the connection name for "http-reuse",
unless overridden by the "pool-conn-name" server keyword.
+sni-auto
+ May be used in the following contexts: tcp, http, log, peers, ring
+
+ The "sni-auto" parameter enables the automatic SNI selection, if no value was
+ already set. It is enabled by default but this parameter may be used as
+ "server" setting to reset any "no-sni-auto" setting which would have been
+ inherited from "default-server" directive as default value. It may also be
+ used as "default-server" setting to reset any previous "default-server"
+ "no-sni-auto" setting.
+
+ For HTTPS connections, the selected SNI is based on the request host header
+ value, if found. Otherwise it remains unset. For other protocols, the option
+ is ignored.
+
+ If the automatic selection of the SNI is used, the value is assigned to the
+ connection name for "http-reuse", unless overridden by the "pool-conn-name"
+ server keyword.
+
source <addr>[:<pl>[-<ph>]] [usesrc { <addr2>[:<port2>] | client | clientip } ]
source <addr>[:<port>] [usesrc { <addr2>[:<port2>] | hdr_ip(<hdr>[,<occ>]) } ]
source <addr>[:<pl>[-<ph>]] [interface <name>] ...
/* server ssl options */
#define SRV_SSL_O_NONE 0x0000
+#define SRV_SSL_O_NO_AUTO_SNI 0x0001 /* disable automatic SNI */
#define SRV_SSL_O_NO_TLS_TICKETS 0x0100 /* disable session resumption tickets */
#define SRV_SSL_O_NO_REUSE 0x200 /* disable session reuse */
#define SRV_SSL_O_EARLY_DATA 0x400 /* Allow using early data */
int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server_inetaddr_updater updater);
struct sample_expr *_parse_srv_expr(char *expr, struct arg_list *args_px,
const char *file, int linenum, char **err);
+int server_parse_exprs(struct server *srv, struct proxy *px, char **err);
int server_set_inetaddr(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater, struct buffer *msg);
int server_set_inetaddr_warn(struct server *s, const struct server_inetaddr *inetaddr, struct server_inetaddr_updater updater);
void server_get_inetaddr(struct server *s, struct server_inetaddr *inetaddr);
bind "fd@${clearlst}"
# dummy bind used to test a change when the same crt is used as server and bind
bind "fd@${foobarlst}" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none
- server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none
+ server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify none no-sni-auto
listen clear-verified-lst
bind "fd@${clearverifiedlst}"
- server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify required
+ server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA1.crt verify required no-sni-auto
listen ssl-lst
# crt: certificate of the server
listen clear-lst
bind "fd@${clearlst}"
- server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt crl-file ${testdir}/interCA2_crl_empty.pem verify required
+ server s1 "${tmpdir}/ssl.sock" ssl crt ${testdir}/set_cafile_client.pem ca-file ${testdir}/set_cafile_interCA2.crt crl-file ${testdir}/interCA2_crl_empty.pem verify required no-sni-auto
listen ssl-lst
# crt: certificate of the server
#endif
}
+/* parse the "sni-auto" server keyword */
+static int srv_parse_sni_auto(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+ newsrv->ssl_ctx.options &= ~SRV_SSL_O_NO_AUTO_SNI;
+ return 0;
+}
+
+/* parse the "no-sni-auto" server keyword */
+static int srv_parse_no_sni_auto(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+ newsrv->ssl_ctx.options |= SRV_SSL_O_NO_AUTO_SNI;
+ return 0;
+}
+
/* parse the "ssl" server keyword */
static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
{ "no-renegotiate", srv_parse_renegotiate, 0, 1, 1 }, /* Disable renegotiation */
{ "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1, 0 }, /* do not send PROXY protocol header v2 with SSL info */
{ "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1, 0 }, /* do not send PROXY protocol header v2 with CN */
+ { "no-sni-auto", srv_parse_no_sni_auto, 0, 1, 0 }, /* disable automatic SNI selection */
{ "no-ssl", srv_parse_no_ssl, 0, 1, 0 }, /* disable SSL processing */
{ "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1, 1 }, /* disable session reuse */
{ "no-sslv3", srv_parse_tls_method_options, 0, 0, 1 }, /* disable SSLv3 */
{ "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1, 1 }, /* send PROXY protocol header v2 with CN */
{ "sigalgs", srv_parse_sigalgs, 1, 1, 1 }, /* signature algorithms */
{ "sni", srv_parse_sni, 1, 1, 1 }, /* send SNI extension */
+ { "sni-auto", srv_parse_sni_auto, 0, 1, 0 }, /* enable automatic SNI selection */
{ "ssl", srv_parse_ssl, 0, 1, 1 }, /* enable SSL processing */
{ "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1, 1 }, /* minimum version */
{ "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1, 1 }, /* maximum version */
cfgerr += xprt_get(XPRT_QUIC)->prepare_srv(newsrv);
}
+ if (newsrv->use_ssl == 1 || ((newsrv->flags & SRV_F_DEFSRV_USE_SSL) && newsrv->use_ssl != 1)) {
+ /* In HTTP only, if the SNI not set and we can realy on the host
+ * header value, fill the sni expression accordingly
+ */
+ if (newsrv->proxy->mode == PR_MODE_HTTP && !(newsrv->ssl_ctx.options & SRV_SSL_O_NO_AUTO_SNI)) {
+ newsrv->sni_expr = strdup("req.hdr(host),field(1,:)");
+
+ err = NULL;
+ if (server_parse_exprs(newsrv, curproxy, &err)) {
+ ha_alert("parsing [%s:%d]: failed to parse auto SNI expression: %s\n",
+ newsrv->conf.file, newsrv->conf.line, err);
+ free(err);
+ ++cfgerr;
+ goto next_srv;
+ }
+ }
+ }
+
+
if ((newsrv->flags & SRV_F_FASTOPEN) &&
((curproxy->retry_type & (PR_RE_DISCONNECTED | PR_RE_TIMEOUT)) !=
(PR_RE_DISCONNECTED | PR_RE_TIMEOUT)))
#include <haproxy/xxhash.h>
#include <haproxy/event_hdl.h>
-static inline int _srv_parse_exprs(struct server *srv, struct proxy *px, char **errmsg);
static void srv_update_status(struct server *s, int type, int cause);
static int srv_apply_lastaddr(struct server *srv, int *err_code);
static void srv_cleanup_connections(struct server *srv);
s->use_ssl = use_ssl;
if (s->use_ssl) {
- if (_srv_parse_exprs(s, s->proxy, NULL))
+ if (server_parse_exprs(s, s->proxy, NULL))
return -1;
s->xprt = xprt_get(XPRT_SSL);
}
/* Parse the sni and pool-conn-name expressions. Returns 0 on success and non-zero on
* error. */
-static inline int _srv_parse_exprs(struct server *srv, struct proxy *px, char **errmsg)
+int server_parse_exprs(struct server *srv, struct proxy *px, char **errmsg)
{
int ret = 0;
srv_settings_cpy(newsrv, srv, 1);
srv_prepare_for_resolution(newsrv, srv->hostname);
- if (_srv_parse_exprs(newsrv, px, NULL))
+ if (server_parse_exprs(newsrv, px, NULL))
goto err;
/* append to list of servers available to receive an hostname */
return ERR_ALERT | ERR_FATAL;
}
- if ((ret = _srv_parse_exprs(srv, px, &errmsg))) {
+ if ((ret = server_parse_exprs(srv, px, &errmsg))) {
if (errmsg) {
ha_alert("error detected while parsing sni or pool-conn-name expressions : %s.\n", errmsg);
free(errmsg);