]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: checks: Respect the no-check-ssl option
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 27 Mar 2020 17:55:49 +0000 (18:55 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Apr 2020 07:39:37 +0000 (09:39 +0200)
This options is used to force a non-SSL connection to check a SSL server or to
invert a check-ssl option inherited from the default section. The use_ssl field
in the check structure is used to know if a SSL connection must be used
(use_ssl=1) or not (use_ssl=0). The server configuration is used by default.

The problem is that we cannot distinguish the default case (no specific SSL
check option) and the case of an explicit non-SSL check. In both, use_ssl is set
to 0. So the server configuration is always used. For a SSL server, when
no-check-ssl option is set, the check is still performed using a SSL
configuration.

To fix the bug, instead of a boolean value (0=TCP, 1=SSL), we use a ternary value :

  * 0  = use server config
  * 1  = force SSL
  * -1 = force non-SSL

The same is done for the server parameter. It is not really necessary for
now. But it is a good way to know is the server no-ssl option is set.

In addition, the PR_O_TCPCHK_SSL proxy option is no longer used to set use_ssl
to 1 for a check. Instead the flag is directly tested to prepare or destroy the
server SSL context.

This patch should be backported as far as 1.8.

include/types/checks.h
include/types/server.h
src/cfgparse.c
src/checks.c
src/haproxy.c
src/ssl_sock.c

index cbab28f8b9717e456766c342c6964a709fd6f851..e94824b8af39216e35d2149372c80b2cbb124487 100644 (file)
@@ -167,7 +167,7 @@ struct check {
        short status, code;                     /* check result, check code */
        unsigned short port;                    /* the port to use for the health checks */
        char desc[HCHK_DESC_LEN];               /* health check description */
-       int use_ssl;                            /* use SSL for health checks */
+       char use_ssl;                           /* use SSL for health checks (1: on, 0: server mode, -1: off) */
        int send_proxy;                         /* send a PROXY protocol header with checks */
        struct list *tcpcheck_rules;            /* tcp-check send / expect rules */
        struct tcpcheck_rule *current_step;     /* current step when using tcpcheck */
index 48582e6138f95b1a9bd7253c43ba2f0f71e1c9c1..a21411962a167c98fa39bc863981e5a633d6f8d4 100644 (file)
@@ -201,7 +201,7 @@ struct server {
        enum obj_type obj_type;                 /* object type == OBJ_TYPE_SERVER */
        enum srv_state next_state, cur_state;   /* server state among SRV_ST_* */
        enum srv_admin next_admin, cur_admin;   /* server maintenance status : SRV_ADMF_* */
-       unsigned char use_ssl;                  /* ssl enabled  */
+       char use_ssl;                           /* ssl enabled (1: on, 0: disabled, -1 forced off)  */
        unsigned int pp_opts;                   /* proxy protocol options (SRV_PP_*) */
        struct server *next;
        int cklen;                              /* the len of the cookie, to speed up checks */
index 59bdb3bab49e3c7224c7e803ab7bdb1bfc764649..926cd1d66bcee00b54c59758321a0f5a03e93238 100644 (file)
@@ -3252,7 +3252,7 @@ out_uri_auth_compat:
                        }
 
                        /* this will also properly set the transport layer for prod and checks */
-                       if (newsrv->use_ssl || newsrv->check.use_ssl) {
+                       if (newsrv->use_ssl == 1 || newsrv->check.use_ssl == 1 || (newsrv->proxy->options & PR_O_TCPCHK_SSL)) {
                                if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
                                        cfgerr += xprt_get(XPRT_SSL)->prepare_srv(newsrv);
                        }
@@ -4005,7 +4005,7 @@ out_uri_auth_compat:
                                p = curpeers->remote;
                                while (p) {
                                        if (p->srv) {
-                                               if (p->srv->use_ssl && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
+                                               if (p->srv->use_ssl == 1 && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv)
                                                        cfgerr += xprt_get(XPRT_SSL)->prepare_srv(p->srv);
                                        }
                                        p = p->next;
index 22a2c501bccf13b05037a81daff884d3cce9e466..f52647b721721e7737d558b7bcceaf01443d4e9e 100644 (file)
@@ -1371,7 +1371,7 @@ static void __event_srv_chk_r(struct conn_stream *cs)
        default:
                /* good connection is enough for pure TCP check */
                if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) {
-                       if (check->use_ssl)
+                       if (check->use_ssl == 1)
                                set_server_check_status(check, HCHK_STATUS_L6OK, NULL);
                        else
                                set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
@@ -2366,7 +2366,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
                if (check->result == CHK_RES_UNKNOWN) {
                        /* good connection is enough for pure TCP check */
                        if (!(conn->flags & CO_FL_WAIT_XPRT) && !check->type) {
-                               if (check->use_ssl)
+                               if (check->use_ssl == 1)
                                        set_server_check_status(check, HCHK_STATUS_L6OK, NULL);
                                else
                                        set_server_check_status(check, HCHK_STATUS_L4OK, NULL);
@@ -3670,7 +3670,8 @@ int srv_check_healthcheck_port(struct check *chk)
         * default, unless one is specified.
         */
        if (!chk->port && !is_addr(&chk->addr)) {
-               chk->use_ssl |= (srv->use_ssl || (srv->proxy->options & PR_O_TCPCHK_SSL));
+               if (!chk->use_ssl)
+                       chk->use_ssl = srv->use_ssl;
                chk->send_proxy |= (srv->pp_opts);
        }
 
index 4af56fbc55b0575aa95ab959d7eec9d7a812d0e0..a702e7869928743d5321da9f13e576d5eb9f99f6 100644 (file)
@@ -2686,7 +2686,7 @@ void deinit(void)
                        free(s->available_conns);
                        free(s->curr_idle_thr);
 
-                       if (s->use_ssl || s->check.use_ssl) {
+                       if (s->use_ssl == 1 || s->check.use_ssl == 1 || (s->proxy->options & PR_O_TCPCHK_SSL)) {
                                if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
                                        xprt_get(XPRT_SSL)->destroy_srv(s);
                        }
index 12b40123d3da42bfc93654a9d6cc2e91234bed9c..224de28661132516c3bc2df6e9d3592fb4210e98 100644 (file)
@@ -5925,9 +5925,9 @@ int ssl_sock_prepare_srv_ctx(struct server *srv)
                        return cfgerr;
                }
        }
-       if (srv->use_ssl)
+       if (srv->use_ssl == 1)
                srv->xprt = &ssl_sock;
-       if (srv->check.use_ssl)
+       if (srv->check.use_ssl == 1)
                srv->check.xprt = &ssl_sock;
 
        ctx = SSL_CTX_new(SSLv23_client_method());
@@ -9956,7 +9956,7 @@ static int srv_parse_crt(char **args, int *cur_arg, struct proxy *px, struct ser
 /* parse the "no-check-ssl" server keyword */
 static int srv_parse_no_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
-       newsrv->check.use_ssl = 0;
+       newsrv->check.use_ssl = -1;
        free(newsrv->ssl_ctx.ciphers);
        newsrv->ssl_ctx.ciphers = NULL;
        newsrv->ssl_ctx.options &= ~global_ssl.connect_default_ssloptions;
@@ -9983,7 +9983,7 @@ static int srv_parse_no_send_proxy_cn(char **args, int *cur_arg, struct proxy *p
 /* parse the "no-ssl" server keyword */
 static int srv_parse_no_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
 {
-       newsrv->use_ssl = 0;
+       newsrv->use_ssl = -1;
        free(newsrv->ssl_ctx.ciphers);
        newsrv->ssl_ctx.ciphers = NULL;
        return 0;