MINOR: ssl: add statements 'verify', 'ca-file' and 'crl-file' on servers.
It now becomes possible to verify the server's certificate using the "verify" directive. This one only supports "none" and "required", as it does not make much sense to also support "optional" here.
This commit is contained in:
parent
f9c5c4701c
commit
ef42d9219d
@ -7048,6 +7048,13 @@ backup
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
ca-file <cafile>
|
||||
This setting is only available when support for OpenSSL was built in. It
|
||||
designates a PEM file from which to load CA certificates used to verify
|
||||
server's certificate.
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
check
|
||||
This option enables health checks on the server. By default, a server is
|
||||
always considered available. If "check" is set, the server is available when
|
||||
@ -7110,6 +7117,13 @@ cookie <value>
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
crl-file <crlfile>
|
||||
This setting is only available when support for OpenSSL was built in. It
|
||||
designates a PEM file from which to load certificate revocation list used
|
||||
to verify server's certificate.
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
disabled
|
||||
The "disabled" keyword starts the server in the "disabled" state. That means
|
||||
that it is marked down in maintenance mode, and no connection other than the
|
||||
@ -7456,6 +7470,15 @@ track [<proxy>/]<server>
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
verify [none|required]
|
||||
This setting is only available when support for OpenSSL was built in. If set
|
||||
to 'none', server certificate is not verified. This is the default. In the
|
||||
other case, The certificate provided by the server is verified using CAs from
|
||||
'ca-file' and optional CRLs from 'crl-file'. On verify failure the handshake
|
||||
is aborted.
|
||||
|
||||
Supported in default-server: No
|
||||
|
||||
weight <weight>
|
||||
The "weight" parameter is used to adjust the server's weight relative to
|
||||
other servers. All servers will receive a load proportional to their weight
|
||||
|
@ -197,6 +197,9 @@ struct server {
|
||||
SSL_SESSION *reused_sess;
|
||||
char *ciphers; /* cipher suite to use if non-null */
|
||||
int options; /* ssl options */
|
||||
int verify; /* verify method (set of SSL_VERIFY_* flags) */
|
||||
char *ca_file; /* CAfile to use on verify */
|
||||
char *crl_file; /* CRLfile to use on verify */
|
||||
} ssl_ctx;
|
||||
#endif
|
||||
struct {
|
||||
|
118
src/ssl_sock.c
118
src/ssl_sock.c
@ -628,7 +628,34 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy)
|
||||
|
||||
SSL_CTX_set_options(srv->ssl_ctx.ctx, options);
|
||||
SSL_CTX_set_mode(srv->ssl_ctx.ctx, mode);
|
||||
SSL_CTX_set_verify(srv->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL);
|
||||
SSL_CTX_set_verify(srv->ssl_ctx.ctx, srv->ssl_ctx.verify ? srv->ssl_ctx.verify : SSL_VERIFY_NONE, NULL);
|
||||
if (srv->ssl_ctx.verify & SSL_VERIFY_PEER) {
|
||||
if (srv->ssl_ctx.ca_file) {
|
||||
/* load CAfile to verify */
|
||||
if (!SSL_CTX_load_verify_locations(srv->ssl_ctx.ctx, srv->ssl_ctx.ca_file, NULL)) {
|
||||
Alert("Proxy '%s', server '%s' |%s:%d] unable to load CA file '%s'.\n",
|
||||
curproxy->id, srv->id,
|
||||
srv->conf.file, srv->conf.line, srv->ssl_ctx.ca_file);
|
||||
cfgerr++;
|
||||
}
|
||||
}
|
||||
#ifdef X509_V_FLAG_CRL_CHECK
|
||||
if (srv->ssl_ctx.crl_file) {
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(srv->ssl_ctx.ctx);
|
||||
|
||||
if (!store || !X509_STORE_load_locations(store, srv->ssl_ctx.crl_file, NULL)) {
|
||||
Alert("Proxy '%s', server '%s' |%s:%d] unable to configure CRL file '%s'.\n",
|
||||
curproxy->id, srv->id,
|
||||
srv->conf.file, srv->conf.line, srv->ssl_ctx.crl_file);
|
||||
cfgerr++;
|
||||
}
|
||||
else {
|
||||
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SSL_CTX_set_session_cache_mode(srv->ssl_ctx.ctx, SSL_SESS_CACHE_OFF);
|
||||
if (srv->ssl_ctx.ciphers &&
|
||||
!SSL_CTX_set_cipher_list(srv->ssl_ctx.ctx, srv->ssl_ctx.ciphers)) {
|
||||
@ -1189,14 +1216,11 @@ static int bind_parse_ca_file(char **args, int cur_arg, struct proxy *px, struct
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if ((*args[cur_arg + 1] != '/') && global.ca_base) {
|
||||
conf->ca_file = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1);
|
||||
if (conf->ca_file)
|
||||
sprintf(conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
|
||||
return 0;
|
||||
}
|
||||
if ((*args[cur_arg + 1] != '/') && global.ca_base)
|
||||
memprintf(&conf->ca_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
|
||||
else
|
||||
memprintf(&conf->ca_file, "%s", args[cur_arg + 1]);
|
||||
|
||||
conf->ca_file = strdup(args[cur_arg + 1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1254,14 +1278,11 @@ static int bind_parse_crl_file(char **args, int cur_arg, struct proxy *px, struc
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if ((*args[cur_arg + 1] != '/') && global.ca_base) {
|
||||
conf->crl_file = malloc(strlen(global.ca_base) + 1 + strlen(args[cur_arg + 1]) + 1);
|
||||
if (conf->crl_file)
|
||||
sprintf(conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
|
||||
return 0;
|
||||
}
|
||||
if ((*args[cur_arg + 1] != '/') && global.ca_base)
|
||||
memprintf(&conf->crl_file, "%s/%s", global.ca_base, args[cur_arg + 1]);
|
||||
else
|
||||
memprintf(&conf->crl_file, "%s", args[cur_arg + 1]);
|
||||
|
||||
conf->crl_file = strdup(args[cur_arg + 1]);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@ -1448,6 +1469,23 @@ static int bind_parse_verify(char **args, int cur_arg, struct proxy *px, struct
|
||||
|
||||
/************** "server" keywords ****************/
|
||||
|
||||
/* parse the "ca-file" server keyword */
|
||||
static int srv_parse_ca_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
|
||||
{
|
||||
if (!*args[*cur_arg + 1]) {
|
||||
if (err)
|
||||
memprintf(err, "'%s' : missing CAfile path", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if ((*args[*cur_arg + 1] != '/') && global.ca_base)
|
||||
memprintf(&newsrv->ssl_ctx.ca_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
|
||||
else
|
||||
memprintf(&newsrv->ssl_ctx.ca_file, "%s", args[*cur_arg + 1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse the "check-ssl" server keyword */
|
||||
static int srv_parse_check_ssl(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
|
||||
{
|
||||
@ -1470,6 +1508,30 @@ static int srv_parse_ciphers(char **args, int *cur_arg, struct proxy *px, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse the "crl-file" server keyword */
|
||||
static int srv_parse_crl_file(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
|
||||
{
|
||||
#ifndef X509_V_FLAG_CRL_CHECK
|
||||
if (err)
|
||||
memprintf(err, "'%s' : library does not support CRL verify", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
#else
|
||||
if (!*args[*cur_arg + 1]) {
|
||||
if (err)
|
||||
memprintf(err, "'%s' : missing CRLfile path", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if ((*args[*cur_arg + 1] != '/') && global.ca_base)
|
||||
memprintf(&newsrv->ssl_ctx.crl_file, "%s/%s", global.ca_base, args[*cur_arg + 1]);
|
||||
else
|
||||
memprintf(&newsrv->ssl_ctx.crl_file, "%s", args[*cur_arg + 1]);
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* parse the "force-sslv3" server keyword */
|
||||
static int srv_parse_force_sslv3(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
|
||||
{
|
||||
@ -1554,6 +1616,29 @@ static int srv_parse_ssl(char **args, int *cur_arg, struct proxy *px, struct ser
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse the "verify" server keyword */
|
||||
static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
|
||||
{
|
||||
if (!*args[*cur_arg + 1]) {
|
||||
if (err)
|
||||
memprintf(err, "'%s' : missing verify method", args[*cur_arg]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
if (strcmp(args[*cur_arg + 1], "none") == 0)
|
||||
newsrv->ssl_ctx.verify = SSL_VERIFY_NONE;
|
||||
else if (strcmp(args[*cur_arg + 1], "required") == 0)
|
||||
newsrv->ssl_ctx.verify = SSL_VERIFY_PEER;
|
||||
else {
|
||||
if (err)
|
||||
memprintf(err, "'%s' : unknown verify method '%s', only 'none' and 'required' are supported\n",
|
||||
args[*cur_arg], args[*cur_arg + 1]);
|
||||
return ERR_ALERT | ERR_FATAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
@ -1623,8 +1708,10 @@ static struct bind_kw_list bind_kws = { "SSL", { }, {
|
||||
* not enabled.
|
||||
*/
|
||||
static struct srv_kw_list srv_kws = { "SSL", { }, {
|
||||
{ "ca-file", srv_parse_ca_file, 1, 0 }, /* set CAfile to process verify server cert */
|
||||
{ "check-ssl", srv_parse_check_ssl, 0, 0 }, /* enable SSL for health checks */
|
||||
{ "ciphers", srv_parse_ciphers, 1, 0 }, /* select the cipher suite */
|
||||
{ "crl-file", srv_parse_crl_file, 1, 0 }, /* set certificate revocation list file use on server cert verify */
|
||||
{ "force-sslv3", srv_parse_force_sslv3, 0, 0 }, /* force SSLv3 */
|
||||
{ "force-tlsv10", srv_parse_force_tlsv10, 0, 0 }, /* force TLSv10 */
|
||||
{ "force-tlsv11", srv_parse_force_tlsv11, 0, 0 }, /* force TLSv11 */
|
||||
@ -1635,6 +1722,7 @@ static struct srv_kw_list srv_kws = { "SSL", { }, {
|
||||
{ "no-tlsv12", srv_parse_no_tlsv12, 0, 0 }, /* disable TLSv12 */
|
||||
{ "no-tls-tickets", srv_parse_no_tls_tickets, 0, 0 }, /* disable session resumption tickets */
|
||||
{ "ssl", srv_parse_ssl, 0, 0 }, /* enable SSL processing */
|
||||
{ "verify", srv_parse_verify, 1, 0 }, /* set SSL verify method */
|
||||
{ NULL, NULL, 0, 0 },
|
||||
}};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user