MXS-1019: Make peer certificate verification configurable
The new `ssl_verify_peer_certificate` parameter controls whether the peer certificate is verified. This allows self-signed certificates to be properly used with MaxScale.
This commit is contained in:
@ -65,6 +65,7 @@ typedef struct ssl_listener
|
|||||||
char *ssl_key; /*< SSL private key */
|
char *ssl_key; /*< SSL private key */
|
||||||
char *ssl_ca_cert; /*< SSL CA certificate */
|
char *ssl_ca_cert; /*< SSL CA certificate */
|
||||||
bool ssl_init_done; /*< If SSL has already been initialized for this service */
|
bool ssl_init_done; /*< If SSL has already been initialized for this service */
|
||||||
|
bool ssl_verify_peer_certificate; /*< Enable peer certificate verification */
|
||||||
struct ssl_listener
|
struct ssl_listener
|
||||||
*next; /*< Next SSL configuration, currently used to store obsolete configurations */
|
*next; /*< Next SSL configuration, currently used to store obsolete configurations */
|
||||||
} SSL_LISTENER;
|
} SSL_LISTENER;
|
||||||
@ -75,5 +76,6 @@ bool ssl_check_data_to_process(struct dcb *dcb);
|
|||||||
bool ssl_required_by_dcb(struct dcb *dcb);
|
bool ssl_required_by_dcb(struct dcb *dcb);
|
||||||
bool ssl_required_but_not_negotiated(struct dcb *dcb);
|
bool ssl_required_but_not_negotiated(struct dcb *dcb);
|
||||||
const char* ssl_method_type_to_string(ssl_method_type_t method_type);
|
const char* ssl_method_type_to_string(ssl_method_type_t method_type);
|
||||||
|
void write_ssl_config(int fd, SSL_LISTENER* ssl);
|
||||||
|
|
||||||
MXS_END_DECLS
|
MXS_END_DECLS
|
||||||
|
@ -154,6 +154,7 @@ static const char *listener_params[] =
|
|||||||
"ssl_key",
|
"ssl_key",
|
||||||
"ssl_version",
|
"ssl_version",
|
||||||
"ssl_cert_verify_depth",
|
"ssl_cert_verify_depth",
|
||||||
|
"ssl_verify_peer_certificate",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -199,6 +200,7 @@ static const char *server_params[] =
|
|||||||
"ssl_key",
|
"ssl_key",
|
||||||
"ssl_version",
|
"ssl_version",
|
||||||
"ssl_cert_verify_depth",
|
"ssl_cert_verify_depth",
|
||||||
|
"ssl_verify_peer_certificate",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1466,8 +1468,11 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e
|
|||||||
ssl_key = config_get_value(obj->parameters, "ssl_key");
|
ssl_key = config_get_value(obj->parameters, "ssl_key");
|
||||||
ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert");
|
ssl_ca_cert = config_get_value(obj->parameters, "ssl_ca_cert");
|
||||||
ssl_version = config_get_value(obj->parameters, "ssl_version");
|
ssl_version = config_get_value(obj->parameters, "ssl_version");
|
||||||
|
char* ssl_verify_peer_certificate = config_get_value(obj->parameters, "ssl_verify_peer_certificate");
|
||||||
ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth");
|
ssl_cert_verify_depth = config_get_value(obj->parameters, "ssl_cert_verify_depth");
|
||||||
new_ssl->ssl_init_done = false;
|
new_ssl->ssl_init_done = false;
|
||||||
|
new_ssl->ssl_cert_verify_depth = 9; // Default of 9 as per Linux man page
|
||||||
|
new_ssl->ssl_verify_peer_certificate = true;
|
||||||
|
|
||||||
if (ssl_version)
|
if (ssl_version)
|
||||||
{
|
{
|
||||||
@ -1490,12 +1495,20 @@ SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *e
|
|||||||
local_errors++;
|
local_errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (ssl_verify_peer_certificate)
|
||||||
{
|
{
|
||||||
/**
|
int rv = config_truth_value(ssl_verify_peer_certificate);
|
||||||
* Default of 9 as per Linux man page
|
if (rv == -1)
|
||||||
*/
|
{
|
||||||
new_ssl->ssl_cert_verify_depth = 9;
|
MXS_ERROR("Invalid parameter value for 'ssl_verify_peer_certificate"
|
||||||
|
" for service '%s': %s", obj->object, ssl_verify_peer_certificate);
|
||||||
|
local_errors++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_ssl->ssl_verify_peer_certificate = rv;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listener_set_certificates(new_ssl, ssl_cert, ssl_key, ssl_ca_cert);
|
listener_set_certificates(new_ssl, ssl_cert, ssl_key, ssl_ca_cert);
|
||||||
|
@ -337,7 +337,7 @@ listener_init_SSL(SSL_LISTENER *ssl_listener)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set to require peer (client) certificate verification */
|
/* Set to require peer (client) certificate verification */
|
||||||
if (ssl_listener->ssl_cert_verify_depth)
|
if (ssl_listener->ssl_verify_peer_certificate)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_verify(ssl_listener->ctx, SSL_VERIFY_PEER, NULL);
|
SSL_CTX_set_verify(ssl_listener->ctx, SSL_VERIFY_PEER, NULL);
|
||||||
}
|
}
|
||||||
@ -430,57 +430,7 @@ static bool create_listener_config(const SERV_LISTENER *listener, const char *fi
|
|||||||
|
|
||||||
if (listener->ssl)
|
if (listener->ssl)
|
||||||
{
|
{
|
||||||
dprintf(file, "ssl=required\n");
|
write_ssl_config(file, listener->ssl);
|
||||||
|
|
||||||
if (listener->ssl->ssl_cert)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_cert=%s\n", listener->ssl->ssl_cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener->ssl->ssl_key)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_key=%s\n", listener->ssl->ssl_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener->ssl->ssl_ca_cert)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_ca_cert=%s\n", listener->ssl->ssl_ca_cert);
|
|
||||||
}
|
|
||||||
if (listener->ssl->ssl_cert_verify_depth)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_cert_verify_depth=%d\n", listener->ssl->ssl_cert_verify_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *version = NULL;
|
|
||||||
|
|
||||||
switch (listener->ssl->ssl_method_type)
|
|
||||||
{
|
|
||||||
#ifndef OPENSSL_1_1
|
|
||||||
case SERVICE_TLS10:
|
|
||||||
version = "TLSV10";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef OPENSSL_1_0
|
|
||||||
case SERVICE_TLS11:
|
|
||||||
version = "TLSV11";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERVICE_TLS12:
|
|
||||||
version = "TLSV12";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case SERVICE_SSL_TLS_MAX:
|
|
||||||
version = "MAX";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_version=%s\n", version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(file);
|
close(file);
|
||||||
|
@ -577,6 +577,7 @@ dprintServer(DCB *dcb, const SERVER *server)
|
|||||||
dcb_printf(dcb, "\tSSL method type: %s\n",
|
dcb_printf(dcb, "\tSSL method type: %s\n",
|
||||||
ssl_method_type_to_string(l->ssl_method_type));
|
ssl_method_type_to_string(l->ssl_method_type));
|
||||||
dcb_printf(dcb, "\tSSL certificate verification depth: %d\n", l->ssl_cert_verify_depth);
|
dcb_printf(dcb, "\tSSL certificate verification depth: %d\n", l->ssl_cert_verify_depth);
|
||||||
|
dcb_printf(dcb, "\tSSL peer verification : %s\n", l->ssl_verify_peer_certificate ? "true" : "false");
|
||||||
dcb_printf(dcb, "\tSSL certificate: %s\n",
|
dcb_printf(dcb, "\tSSL certificate: %s\n",
|
||||||
l->ssl_cert ? l->ssl_cert : "null");
|
l->ssl_cert ? l->ssl_cert : "null");
|
||||||
dcb_printf(dcb, "\tSSL key: %s\n",
|
dcb_printf(dcb, "\tSSL key: %s\n",
|
||||||
@ -1167,57 +1168,7 @@ static bool create_server_config(const SERVER *server, const char *filename)
|
|||||||
|
|
||||||
if (server->server_ssl)
|
if (server->server_ssl)
|
||||||
{
|
{
|
||||||
dprintf(file, "ssl=required\n");
|
write_ssl_config(file, server->server_ssl);
|
||||||
|
|
||||||
if (server->server_ssl->ssl_cert)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_cert=%s\n", server->server_ssl->ssl_cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server->server_ssl->ssl_key)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_key=%s\n", server->server_ssl->ssl_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server->server_ssl->ssl_ca_cert)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_ca_cert=%s\n", server->server_ssl->ssl_ca_cert);
|
|
||||||
}
|
|
||||||
if (server->server_ssl->ssl_cert_verify_depth)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_cert_verify_depth=%d\n", server->server_ssl->ssl_cert_verify_depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *version = NULL;
|
|
||||||
|
|
||||||
switch (server->server_ssl->ssl_method_type)
|
|
||||||
{
|
|
||||||
#ifndef OPENSSL_1_1
|
|
||||||
case SERVICE_TLS10:
|
|
||||||
version = "TLSV10";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef OPENSSL_1_0
|
|
||||||
case SERVICE_TLS11:
|
|
||||||
version = "TLSV11";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERVICE_TLS12:
|
|
||||||
version = "TLSV12";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case SERVICE_SSL_TLS_MAX:
|
|
||||||
version = "MAX";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version)
|
|
||||||
{
|
|
||||||
dprintf(file, "ssl_version=%s\n", version);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close(file);
|
close(file);
|
||||||
|
@ -214,3 +214,64 @@ const char* ssl_method_type_to_string(ssl_method_type_t method_type)
|
|||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void write_ssl_config(int fd, SSL_LISTENER* ssl)
|
||||||
|
{
|
||||||
|
if (ssl)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl=required\n");
|
||||||
|
|
||||||
|
if (ssl->ssl_cert)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl_cert=%s\n", ssl->ssl_cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl->ssl_key)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl_key=%s\n", ssl->ssl_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssl->ssl_ca_cert)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl_ca_cert=%s\n", ssl->ssl_ca_cert);
|
||||||
|
}
|
||||||
|
if (ssl->ssl_cert_verify_depth)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl_cert_verify_depth=%d\n", ssl->ssl_cert_verify_depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(fd, "ssl_verify_peer_certificate=%s\n",
|
||||||
|
ssl->ssl_verify_peer_certificate ? "true" : "false");
|
||||||
|
|
||||||
|
const char *version = NULL;
|
||||||
|
|
||||||
|
switch (ssl->ssl_method_type)
|
||||||
|
{
|
||||||
|
#ifndef OPENSSL_1_1
|
||||||
|
case SERVICE_TLS10:
|
||||||
|
version = "TLSV10";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef OPENSSL_1_0
|
||||||
|
case SERVICE_TLS11:
|
||||||
|
version = "TLSV11";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_TLS12:
|
||||||
|
version = "TLSV12";
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case SERVICE_SSL_TLS_MAX:
|
||||||
|
version = "MAX";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version)
|
||||||
|
{
|
||||||
|
dprintf(fd, "ssl_version=%s\n", version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -712,6 +712,7 @@ createInstance(SERVICE *service, char **options)
|
|||||||
ssl_cfg->ssl_init_done = false;
|
ssl_cfg->ssl_init_done = false;
|
||||||
ssl_cfg->ssl_method_type = SERVICE_SSL_TLS_MAX;
|
ssl_cfg->ssl_method_type = SERVICE_SSL_TLS_MAX;
|
||||||
ssl_cfg->ssl_cert_verify_depth = 9;
|
ssl_cfg->ssl_cert_verify_depth = 9;
|
||||||
|
ssl_cfg->ssl_verify_peer_certificate = true;
|
||||||
|
|
||||||
/** Set SSL pointer in in server struct */
|
/** Set SSL pointer in in server struct */
|
||||||
server->server_ssl = ssl_cfg;
|
server->server_ssl = ssl_cfg;
|
||||||
|
@ -5766,6 +5766,7 @@ blr_set_master_ssl(ROUTER_INSTANCE *router, CHANGE_MASTER_OPTIONS config, char *
|
|||||||
server_ssl->ssl_init_done = false;
|
server_ssl->ssl_init_done = false;
|
||||||
server_ssl->ssl_method_type = SERVICE_SSL_TLS_MAX;
|
server_ssl->ssl_method_type = SERVICE_SSL_TLS_MAX;
|
||||||
server_ssl->ssl_cert_verify_depth = 9;
|
server_ssl->ssl_cert_verify_depth = 9;
|
||||||
|
server_ssl->ssl_verify_peer_certificate = true;
|
||||||
|
|
||||||
/* Set the pointer */
|
/* Set the pointer */
|
||||||
router->service->dbref->server->server_ssl = server_ssl;
|
router->service->dbref->server->server_ssl = server_ssl;
|
||||||
|
Reference in New Issue
Block a user