MEDIUM: ssl: add ssl-min-ver and ssl-max-ver parameters for bind and server
'ssl-min-ver' and 'ssl-max-ver' with argument SSLv3, TLSv1.0, TLSv1.1, TLSv1.2
or TLSv1.3 limit the SSL negotiation version to a continuous range. ssl-min-ver
and ssl-max-ver should be used in replacement of no-tls* and no-sslv3. Warning
and documentation are set accordingly.
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 4486a1c..7f77f4f 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -880,7 +880,7 @@
Example:
global
- ssl-default-bind-options no-sslv3 no-tls-tickets
+ ssl-default-bind-options ssl-min-ver TLSv1.0 no-tls-tickets
ssl-default-server-ciphers <ciphers>
This setting is only available when support for OpenSSL was built in. It
@@ -10417,27 +10417,27 @@
This option enforces use of SSLv3 only on SSL connections instantiated from
this listener. SSLv3 is generally less expensive than the TLS counterparts
for high connection rates. This option is also available on global statement
- "ssl-default-bind-options". See also "no-tlsv*" and "no-sslv3".
+ "ssl-default-bind-options". See also "ssl-min-ver" and "ssl-max-ver".
force-tlsv10
This option enforces use of TLSv1.0 only on SSL connections instantiated from
this listener. This option is also available on global statement
- "ssl-default-bind-options". See also "no-tlsv*" and "no-sslv3".
+ "ssl-default-bind-options". See also "ssl-min-ver" and "ssl-max-ver".
force-tlsv11
This option enforces use of TLSv1.1 only on SSL connections instantiated from
this listener. This option is also available on global statement
- "ssl-default-bind-options". See also "no-tlsv*", and "no-sslv3".
+ "ssl-default-bind-options". See also "ssl-min-ver" and "ssl-max-ver".
force-tlsv12
This option enforces use of TLSv1.2 only on SSL connections instantiated from
this listener. This option is also available on global statement
- "ssl-default-bind-options". See also "no-tlsv*", and "no-sslv3".
+ "ssl-default-bind-options". See also "ssl-min-ver" and "ssl-max-ver".
force-tlsv13
This option enforces use of TLSv1.3 only on SSL connections instantiated from
this listener. This option is also available on global statement
- "ssl-default-bind-options". See also "no-tlsv*", and "no-sslv3".
+ "ssl-default-bind-options". See also "ssl-min-ver" and "ssl-max-ver".
generate-certificates
This setting is only available when support for OpenSSL was built in. It
@@ -10555,8 +10555,8 @@
disables support for SSLv3 on any sockets instantiated from the listener when
SSL is supported. Note that SSLv2 is forced disabled in the code and cannot
be enabled using any configuration option. This option is also available on
- global statement "ssl-default-bind-options". See also "force-tls*",
- and "force-sslv3".
+ global statement "ssl-default-bind-options". Use "ssl-min-ver" and
+ "ssl-max-ver" instead.
no-tls-tickets
This setting is only available when support for OpenSSL was built in. It
@@ -10570,32 +10570,32 @@
disables support for TLSv1.0 on any sockets instantiated from the listener
when SSL is supported. Note that SSLv2 is forced disabled in the code and
cannot be enabled using any configuration option. This option is also
- available on global statement "ssl-default-bind-options". See also
- "force-tlsv*", and "force-sslv3".
+ available on global statement "ssl-default-bind-options". Use "ssl-min-ver"
+ and "ssl-max-ver" instead.
no-tlsv11
This setting is only available when support for OpenSSL was built in. It
disables support for TLSv1.1 on any sockets instantiated from the listener
when SSL is supported. Note that SSLv2 is forced disabled in the code and
cannot be enabled using any configuration option. This option is also
- available on global statement "ssl-default-bind-options". See also
- "force-tlsv*", and "force-sslv3".
+ available on global statement "ssl-default-bind-options". Use "ssl-min-ver"
+ and "ssl-max-ver" instead.
no-tlsv12
This setting is only available when support for OpenSSL was built in. It
disables support for TLSv1.2 on any sockets instantiated from the listener
when SSL is supported. Note that SSLv2 is forced disabled in the code and
cannot be enabled using any configuration option. This option is also
- available on global statement "ssl-default-bind-options". See also
- "force-tlsv*", and "force-sslv3".
+ available on global statement "ssl-default-bind-options". Use "ssl-min-ver"
+ and "ssl-max-ver" instead.
no-tlsv13
This setting is only available when support for OpenSSL was built in. It
disables support for TLSv1.3 on any sockets instantiated from the listener
when SSL is supported. Note that SSLv2 is forced disabled in the code and
cannot be enabled using any configuration option. This option is also
- available on global statement "ssl-default-bind-options". See also
- "force-tlsv*", and "force-sslv3".
+ available on global statement "ssl-default-bind-options". Use "ssl-min-ver"
+ and "ssl-max-ver" instead.
npn <protocols>
This enables the NPN TLS extension and advertises the specified protocol list
@@ -10633,6 +10633,16 @@
appear in clear text, so that ACLs and HTTP processing will only have access
to deciphered contents.
+ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
+ This option enforces use of <version> or lower on SSL connections instantiated
+ from this listener. This option is also available on global statement
+ "ssl-default-bind-options". See also "ssl-min-ver".
+
+ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
+ This option enforces use of <version> or upper on SSL connections instantiated
+ from this listener. This option is also available on global statement
+ "ssl-default-bind-options". See also "ssl-max-ver".
+
strict-sni
This setting is only available when support for OpenSSL was built in. The
SSL/TLS negotiation is allow only if the client provided an SNI which match
@@ -10962,37 +10972,27 @@
This option enforces use of SSLv3 only when SSL is used to communicate with
the server. SSLv3 is generally less expensive than the TLS counterparts for
high connection rates. This option is also available on global statement
- "ssl-default-server-options". See also "no-tlsv*", "no-sslv3".
-
- Supported in default-server: No
+ "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver".
force-tlsv10
This option enforces use of TLSv1.0 only when SSL is used to communicate with
the server. This option is also available on global statement
- "ssl-default-server-options". See also "no-tlsv*", "no-sslv3".
-
- Supported in default-server: No
+ "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver".
force-tlsv11
This option enforces use of TLSv1.1 only when SSL is used to communicate with
the server. This option is also available on global statement
- "ssl-default-server-options". See also "no-tlsv*", "no-sslv3".
-
- Supported in default-server: No
+ "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver".
force-tlsv12
This option enforces use of TLSv1.2 only when SSL is used to communicate with
the server. This option is also available on global statement
- "ssl-default-server-options". See also "no-tlsv*", "no-sslv3".
-
- Supported in default-server: No
+ "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver".
force-tlsv13
This option enforces use of TLSv1.3 only when SSL is used to communicate with
the server. This option is also available on global statement
- "ssl-default-server-options". See also "no-tlsv*", "no-sslv3".
-
- Supported in default-server: No
+ "ssl-default-server-options". See also "ssl-min-ver" and ssl-max-ver".
id <value>
Set a persistent ID for the server. This ID must be positive and unique for
@@ -11163,7 +11163,7 @@
no-sslv3
This option disables support for SSLv3 when SSL is used to communicate with
the server. Note that SSLv2 is disabled in the code and cannot be enabled
- using any configuration option. See also "force-sslv3", "force-tlsv*".
+ using any configuration option. Use "ssl-min-ver" and "ssl-max-ver" instead.
Supported in default-server: No
@@ -11181,7 +11181,7 @@
using any configuration option. TLSv1 is more expensive than SSLv3 so it
often makes sense to disable it when communicating with local servers. This
option is also available on global statement "ssl-default-server-options".
- See also "force-sslv3", "force-tlsv*".
+ Use "ssl-min-ver" and "ssl-max-ver" instead.
Supported in default-server: No
@@ -11191,7 +11191,7 @@
using any configuration option. TLSv1 is more expensive than SSLv3 so it
often makes sense to disable it when communicating with local servers. This
option is also available on global statement "ssl-default-server-options".
- See also "force-sslv3", "force-tlsv*".
+ Use "ssl-min-ver" and "ssl-max-ver" instead.
Supported in default-server: No
@@ -11201,7 +11201,7 @@
using any configuration option. TLSv1 is more expensive than SSLv3 so it
often makes sense to disable it when communicating with local servers. This
option is also available on global statement "ssl-default-server-options".
- See also "force-sslv3", "force-tlsv*".
+ Use "ssl-min-ver" and "ssl-max-ver" instead.
Supported in default-server: No
@@ -11211,7 +11211,7 @@
using any configuration option. TLSv1 is more expensive than SSLv3 so it
often makes sense to disable it when communicating with local servers. This
option is also available on global statement "ssl-default-server-options".
- See also "force-sslv3", "force-tlsv*".
+ Use "ssl-min-ver" and "ssl-max-ver" instead.
Supported in default-server: No
@@ -11453,6 +11453,16 @@
See the "no-ssl" to disable "ssl" option and "check-ssl" option to force
SSL health checks.
+ssl-max-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
+ This option enforces use of <version> or lower when SSL is used to communicate
+ with the server. This option is also available on global statement
+ "ssl-default-server-options". See also "ssl-min-ver".
+
+ssl-min-ver [ SSLv3 | TLSv1.0 | TLSv1.1 | TLSv1.2 | TLSv1.3 ]
+ This option enforces use of <version> or upper when SSL is used to communicate
+ with the server. This option is also available on global statement
+ "ssl-default-server-options". See also "ssl-max-ver".
+
ssl-reuse
This option may be used as "server" setting to reset any "no-ssl-reuse"
setting which would have been inherited from "default-server" directive as
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 5014e70..e30236a 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -3305,7 +3305,7 @@
if (min) {
if (hole) {
Warning("Proxy '%s': SSL/TLS versions range not contiguous for bind '%s' at [%s:%d]. "
- "Hole find for %s. Use only 'min-tlsvX' and 'max-tlsvY' to fix.\n",
+ "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
bind_conf->frontend->id, bind_conf->arg, bind_conf->file, bind_conf->line,
methodVersions[hole].name);
hole = 0;
@@ -3740,7 +3740,7 @@
if (min) {
if (hole) {
Warning("config : %s '%s': SSL/TLS versions range not contiguous for server '%s'. "
- "Hole find for %s. Use only 'min-tlsvX' and 'max-tlsvY' to fix.\n",
+ "Hole find for %s. Use only 'ssl-min-ver' and 'ssl-max-ver' to fix.\n",
proxy_type_str(curproxy), curproxy->id, srv->id,
methodVersions[hole].name);
hole = 0;
@@ -6227,14 +6227,14 @@
return 0;
}
-/* parse tls_method_options */
-static int parse_tls_method_options(char *arg, struct tls_version_filter *methods)
+/* parse tls_method_options "no-xxx" and "force-xxx" */
+static int parse_tls_method_options(char *arg, struct tls_version_filter *methods, char **err)
{
+ uint16_t v;
char *p;
- int v;
p = strchr(arg, '-');
if (!p)
- return 1;
+ goto fail;
p++;
if (!strcmp(p, "sslv3"))
v = CONF_SSLV3;
@@ -6247,36 +6247,70 @@
else if (!strcmp(p, "tlsv13"))
v = CONF_TLSV13;
else
- return 1;
+ goto fail;
if (!strncmp(arg, "no-", 3))
methods->flags |= methodVersions[v].flag;
else if (!strncmp(arg, "force-", 6))
methods->min = methods->max = v;
else
- return 1;
+ goto fail;
return 0;
+ fail:
+ if (err)
+ memprintf(err, "'%s' : option not implemented", arg);
+ return ERR_ALERT | ERR_FATAL;
}
static int bind_parse_tls_method_options(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
- if (parse_tls_method_options(args[cur_arg], &conf->ssl_methods)) {
- if (err)
- memprintf(err, "'%s' : option not implemented", args[cur_arg]);
- return ERR_ALERT | ERR_FATAL;
- }
- return 0;
+ return parse_tls_method_options(args[cur_arg], &conf->ssl_methods, err);
}
static int srv_parse_tls_method_options(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
{
+ return parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods, err);
+}
+
+/* parse tls_method min/max: "ssl-min-ver" and "ssl-max-ver" */
+static int parse_tls_method_minmax(char **args, int cur_arg, struct tls_version_filter *methods, char **err)
+{
- if (parse_tls_method_options(args[*cur_arg], &newsrv->ssl_ctx.methods)) {
+ uint16_t i, v = 0;
+ char *argv = args[cur_arg + 1];
+ if (!*argv) {
+ if (err)
+ memprintf(err, "'%s' : missing the ssl/tls version", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+ for (i = CONF_TLSV_MIN; i <= CONF_TLSV_MAX; i++)
+ if (!strcmp(argv, methodVersions[i].name))
+ v = i;
+ if (!v) {
if (err)
- memprintf(err, "'%s' : option not implemented", args[*cur_arg]);
+ memprintf(err, "'%s' : unknown ssl/tls version", args[cur_arg + 1]);
return ERR_ALERT | ERR_FATAL;
}
+ if (!strcmp("ssl-min-ver", args[cur_arg]))
+ methods->min = v;
+ else if (!strcmp("ssl-max-ver", args[cur_arg]))
+ methods->max = v;
+ else {
+ if (err)
+ memprintf(err, "'%s' : option not implemented", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
return 0;
}
+static int bind_parse_tls_method_minmax(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ return parse_tls_method_minmax(args, cur_arg, &conf->ssl_methods, err);
+}
+
+static int srv_parse_tls_method_minmax(char **args, int *cur_arg, struct proxy *px, struct server *newsrv, char **err)
+{
+ return parse_tls_method_minmax(args, *cur_arg, &newsrv->ssl_ctx.methods, err);
+}
+
/* parse the "no-tls-tickets" bind keyword */
static int bind_parse_no_tls_tickets(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
{
@@ -6796,7 +6830,15 @@
global_ssl.listen_default_ssloptions |= BC_SSL_O_NO_TLS_TICKETS;
else if (!strcmp(args[i], "prefer-client-ciphers"))
global_ssl.listen_default_ssloptions |= BC_SSL_O_PREF_CLIE_CIPH;
- else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods)) {
+ else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
+ if (!parse_tls_method_minmax(args, i, &global_ssl.listen_default_sslmethods, err))
+ i++;
+ else {
+ memprintf(err, "%s on global statement '%s'.", *err, args[0]);
+ return -1;
+ }
+ }
+ else if (parse_tls_method_options(args[i], &global_ssl.listen_default_sslmethods, err)) {
memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
return -1;
}
@@ -6818,7 +6860,15 @@
while (*(args[i])) {
if (!strcmp(args[i], "no-tls-tickets"))
global_ssl.connect_default_ssloptions |= SRV_SSL_O_NO_TLS_TICKETS;
- else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods)) {
+ else if (!strcmp(args[i], "ssl-min-ver") || !strcmp(args[i], "ssl-max-ver")) {
+ if (!parse_tls_method_minmax(args, i, &global_ssl.connect_default_sslmethods, err))
+ i++;
+ else {
+ memprintf(err, "%s on global statement '%s'.", *err, args[0]);
+ return -1;
+ }
+ }
+ else if (parse_tls_method_options(args[i], &global_ssl.connect_default_sslmethods, err)) {
memprintf(err, "unknown option '%s' on global statement '%s'.", args[i], args[0]);
return -1;
}
@@ -7401,6 +7451,8 @@
{ "no-tlsv13", bind_parse_tls_method_options, 0 }, /* disable TLSv13 */
{ "no-tls-tickets", bind_parse_no_tls_tickets, 0 }, /* disable session resumption tickets */
{ "ssl", bind_parse_ssl, 0 }, /* enable SSL processing */
+ { "ssl-min-ver", bind_parse_tls_method_minmax, 1 }, /* minimum version */
+ { "ssl-max-ver", bind_parse_tls_method_minmax, 1 }, /* maximum version */
{ "strict-sni", bind_parse_strict_sni, 0 }, /* refuse negotiation if sni doesn't match a certificate */
{ "tls-ticket-keys", bind_parse_tls_ticket_keys, 1 }, /* set file to load TLS ticket keys from */
{ "verify", bind_parse_verify, 1 }, /* set SSL verify method */
@@ -7417,35 +7469,37 @@
* not enabled.
*/
static struct srv_kw_list srv_kws = { "SSL", { }, {
- { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
- { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
- { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
- { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
- { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
- { "force-sslv3", srv_parse_tls_method_options,0, 1 }, /* force SSLv3 */
- { "force-tlsv10", srv_parse_tls_method_options,0, 1 }, /* force TLSv10 */
- { "force-tlsv11", srv_parse_tls_method_options,0, 1 }, /* force TLSv11 */
- { "force-tlsv12", srv_parse_tls_method_options,0, 1 }, /* force TLSv12 */
- { "force-tlsv13", srv_parse_tls_method_options,0, 1 }, /* force TLSv13 */
- { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
- { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
- { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
- { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
- { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
- { "no-sslv3", srv_parse_tls_method_options,0, 0 }, /* disable SSLv3 */
- { "no-tlsv10", srv_parse_tls_method_options,0, 0 }, /* disable TLSv10 */
- { "no-tlsv11", srv_parse_tls_method_options,0, 0 }, /* disable TLSv11 */
- { "no-tlsv12", srv_parse_tls_method_options,0, 0 }, /* disable TLSv12 */
- { "no-tlsv13", srv_parse_tls_method_options,0, 0 }, /* disable TLSv13 */
- { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
- { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
- { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
- { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
- { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
- { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
- { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
- { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
- { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
+ { "ca-file", srv_parse_ca_file, 1, 1 }, /* set CAfile to process verify server cert */
+ { "check-ssl", srv_parse_check_ssl, 0, 1 }, /* enable SSL for health checks */
+ { "ciphers", srv_parse_ciphers, 1, 1 }, /* select the cipher suite */
+ { "crl-file", srv_parse_crl_file, 1, 1 }, /* set certificate revocation list file use on server cert verify */
+ { "crt", srv_parse_crt, 1, 1 }, /* set client certificate */
+ { "force-sslv3", srv_parse_tls_method_options, 0, 1 }, /* force SSLv3 */
+ { "force-tlsv10", srv_parse_tls_method_options, 0, 1 }, /* force TLSv10 */
+ { "force-tlsv11", srv_parse_tls_method_options, 0, 1 }, /* force TLSv11 */
+ { "force-tlsv12", srv_parse_tls_method_options, 0, 1 }, /* force TLSv12 */
+ { "force-tlsv13", srv_parse_tls_method_options, 0, 1 }, /* force TLSv13 */
+ { "no-check-ssl", srv_parse_no_check_ssl, 0, 1 }, /* disable SSL for health checks */
+ { "no-send-proxy-v2-ssl", srv_parse_no_send_proxy_ssl, 0, 1 }, /* do not send PROXY protocol header v2 with SSL info */
+ { "no-send-proxy-v2-ssl-cn", srv_parse_no_send_proxy_cn, 0, 1 }, /* do not send PROXY protocol header v2 with CN */
+ { "no-ssl", srv_parse_no_ssl, 0, 1 }, /* disable SSL processing */
+ { "no-ssl-reuse", srv_parse_no_ssl_reuse, 0, 1 }, /* disable session reuse */
+ { "no-sslv3", srv_parse_tls_method_options, 0, 0 }, /* disable SSLv3 */
+ { "no-tlsv10", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv10 */
+ { "no-tlsv11", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv11 */
+ { "no-tlsv12", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv12 */
+ { "no-tlsv13", srv_parse_tls_method_options, 0, 0 }, /* disable TLSv13 */
+ { "no-tls-tickets", srv_parse_no_tls_tickets, 0, 1 }, /* disable session resumption tickets */
+ { "send-proxy-v2-ssl", srv_parse_send_proxy_ssl, 0, 1 }, /* send PROXY protocol header v2 with SSL info */
+ { "send-proxy-v2-ssl-cn", srv_parse_send_proxy_cn, 0, 1 }, /* send PROXY protocol header v2 with CN */
+ { "sni", srv_parse_sni, 1, 1 }, /* send SNI extension */
+ { "ssl", srv_parse_ssl, 0, 1 }, /* enable SSL processing */
+ { "ssl-min-ver", srv_parse_tls_method_minmax, 1, 1 }, /* minimum version */
+ { "ssl-max-ver", srv_parse_tls_method_minmax, 1, 1 }, /* maximum version */
+ { "ssl-reuse", srv_parse_ssl_reuse, 0, 1 }, /* enable session reuse */
+ { "tls-tickets", srv_parse_tls_tickets, 0, 1 }, /* enable session resumption tickets */
+ { "verify", srv_parse_verify, 1, 1 }, /* set SSL verify method */
+ { "verifyhost", srv_parse_verifyhost, 1, 1 }, /* require that SSL cert verifies for hostname */
{ NULL, NULL, 0, 0 },
}};