diff --git a/include/haproxy/server.h b/include/haproxy/server.h index 05446e98f..ba4e6c104 100644 --- a/include/haproxy/server.h +++ b/include/haproxy/server.h @@ -55,6 +55,7 @@ int srv_update_addr(struct server *s, void *ip, int ip_sin_family, struct server 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 srv_configure_auto_sni(struct server *srv, int *err_code, 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); diff --git a/src/cfgparse-ssl.c b/src/cfgparse-ssl.c index 5053cf336..508113668 100644 --- a/src/cfgparse-ssl.c +++ b/src/cfgparse-ssl.c @@ -2743,7 +2743,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, { { "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-sni-auto", srv_parse_no_sni_auto, 0, 1, 1 }, /* 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 */ diff --git a/src/proxy.c b/src/proxy.c index 92550dcd1..dadcff0c6 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -2536,29 +2536,20 @@ int proxy_finalize(struct proxy *px, int *err_code) 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 is not set and we can rely on the host - * header value, fill the sni expression accordingly - */ - if (!newsrv->sni_expr && 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,:)"); - if (!newsrv->sni_expr) { - ha_alert("parsing [%s:%d]: out of memory while generating server auto SNI expression.\n", - newsrv->conf.file, newsrv->conf.line); - cfgerr++; - *err_code |= ERR_ALERT | ERR_ABORT; + /* In HTTP only, if the SNI is not set and we can rely on the + * host header value, fill the sni expression accordingly + */ + if (newsrv->proxy->mode == PR_MODE_HTTP && + (newsrv->use_ssl == 1 || (newsrv->flags & SRV_F_DEFSRV_USE_SSL)) && + !newsrv->sni_expr && !(newsrv->ssl_ctx.options & SRV_SSL_O_NO_AUTO_SNI)) { + if (srv_configure_auto_sni(newsrv, err_code, &err)) { + ha_alert("parsing [%s:%d]: %s.\n", + newsrv->conf.file, newsrv->conf.line, err); + ha_free(&err); + ++cfgerr; + if (*err_code & ERR_ABORT) goto out; - } - - err = NULL; - if (server_parse_exprs(newsrv, px, &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; - } + goto next_srv; } } diff --git a/src/server.c b/src/server.c index 925b0c4af..66e1513d3 100644 --- a/src/server.c +++ b/src/server.c @@ -3377,6 +3377,29 @@ int server_parse_exprs(struct server *srv, struct proxy *px, char **errmsg) return ret; } +/* Fill SNI expression to reuse the host header on outgoing requests. + * + * Returns 0 on success else non-zero. On error, and message + * are both set. + */ +int srv_configure_auto_sni(struct server *srv, int *err_code, char **err) +{ + srv->sni_expr = strdup("req.hdr(host),field(1,:)"); + if (!srv->sni_expr) { + memprintf(err, "out of memory while generating server auto SNI expression"); + *err_code |= ERR_ALERT | ERR_ABORT; + return 1; + } + + if (server_parse_exprs(srv, srv->proxy, err)) { + memprintf(err, "failed to parse auto SNI expression: %s", *err); + *err_code |= ERR_ALERT | ERR_FATAL; + return 1; + } + + return 0; +} + /* Initialize as much as possible servers from server template. * Note that a server template is a special server with * a few different parameters than a server which has @@ -6231,6 +6254,15 @@ static int cli_parse_add_server(char **args, char *payload, struct appctx *appct } } + /* Define default SNI from host header if needed. */ + if (srv->proxy->mode == PR_MODE_HTTP && srv->use_ssl == 1 && + !srv->sni_expr && !(srv->ssl_ctx.options & SRV_SSL_O_NO_AUTO_SNI)) { + if (srv_configure_auto_sni(srv, &errcode, &errmsg)) { + ha_alert("%s.\n", errmsg); + goto out; + } + } + if (srv->trackit) { if (srv_apply_track(srv, be)) goto out;