"tune.ssl.ocsp-update.maxdelay". See option "ocsp-update" for more
information about the auto update mechanism.
+tune.ssl.ocsp-update.mode [ on | off ]
+ Sets the default ocsp-update mode for all certificates used in the
+ configuration. This global option can be superseded by the crt-list
+ "ocsp-update" option but an error will be raised if a given certificate has
+ two distinct configurations simultaneously. This option is set to "off" by
+ default.
+ See option "ocsp-update" for more information about the auto update
+ mechanism.
+
tune.stick-counters <number>
Sets the number of stick-counters that may be tracked at the same time by a
connection or a request via "track-sc*" actions in "tcp-request" or
Its value defaults to 'off'.
Please note that for now, this option can only be used in a crt-list line, it
cannot be used directly on a bind line. It lies in this "Bind options"
- section because it is still a frontend option. This limitation was set so
- that the option applies to only one certificate at a time.
+ section because it is still a frontend option. For now, the only way to
+ enable OCSP auto update on a bind line certificate is via the global option
+ "tune.ocsp-update.mode".
If a given certificate is used in multiple crt-lists with different values of
- the 'ocsp-update' set, an error will be raised. Here is an example
- configuration enabling it:
+ the 'ocsp-update' set, an error will be raised. Likewise, if a certificate
+ inherits from the global option on a bind line and has an incompatible
+ explicit 'ocsp-update' option set in a crt-list, the same error will be
+ raised.
+ Here is an example configuration enabling it:
haproxy.cfg:
frontend fe
hour limit. A minimum update interval of 5 minutes will still exist in order
to avoid updating too often responses that have a really short expire time or
even no 'Next Update' at all. Because of this hard limit, please note that
- when auto update is set to 'on' or 'auto', any OCSP response loaded during
- init will not be updated until at least 5 minutes, even if its expire time
- ends before now+5m. This should not be too much of a hassle since an OCSP
- response must be valid when it gets loaded during init (its expire time must
- be in the future) so it is unlikely that this response expires in such a
- short time after init.
+ when auto update is set to 'on', any OCSP response loaded during init will
+ not be updated until at least 5 minutes, even if its expire time ends before
+ now+5m. This should not be too much of a hassle since an OCSP response must
+ be valid when it gets loaded during init (its expire time must be in the
+ future) so it is unlikely that this response expires in such a short time
+ after init.
On the other hand, if a certificate has an OCSP uri specified and no OCSP
response, setting this option to 'on' for the given certificate will ensure
that the OCSP response gets fetched automatically right after init.
struct {
unsigned int delay_max;
unsigned int delay_min;
+ int mode; /* default mode used for ocsp auto-update (off, on) */
} ocsp_update;
#endif
};
return 0;
}
+static int ssl_parse_global_ocsp_update_mode(char **args, int section_type, struct proxy *curpx,
+ const struct proxy *defpx, const char *file, int line,
+ char **err)
+{
+ int ret = 0;
+
+ if (!*args[1]) {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ if (strcmp(args[1], "on") == 0)
+ global_ssl.ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_ON;
+ else if (strcmp(args[1], "off") == 0)
+ global_ssl.ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_OFF;
+ else {
+ memprintf(err, "'%s' : expecting <on|off>", args[0]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ if (global_ssl.ocsp_update.mode != SSL_SOCK_OCSP_UPDATE_OFF) {
+ /* We might need to create the main ocsp update task */
+ ret = ssl_create_ocsp_update_task(err);
+ }
+
+ return ret;
+}
+
+
/* Note: must not be declared <const> as its list will be overwritten.
#ifndef OPENSSL_NO_OCSP
{ CFG_GLOBAL, "tune.ssl.ocsp-update.maxdelay", ssl_parse_global_ocsp_maxdelay },
{ CFG_GLOBAL, "tune.ssl.ocsp-update.mindelay", ssl_parse_global_ocsp_mindelay },
+ { CFG_GLOBAL, "tune.ssl.ocsp-update.mode", ssl_parse_global_ocsp_update_mode },
#endif
{ 0, NULL, NULL },
}};
goto end;
}
+ data->ocsp_update_mode = global_ssl.ocsp_update.mode;
+
/* remove the ".crt" extension */
if (global_ssl.extra_files_noext) {
char *ext;
entry->crtlist = newlist;
if (entry->ssl_conf)
ckchs->data->ocsp_update_mode = entry->ssl_conf->ocsp_update;
+ if (ckchs->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT)
+ ckchs->data->ocsp_update_mode = global_ssl.ocsp_update.mode;
ebpt_insert(&newlist->entries, &entry->node);
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
if (entry->ssl_conf)
ckchs->data->ocsp_update_mode = entry->ssl_conf->ocsp_update;
+ if (ckchs->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT)
+ ckchs->data->ocsp_update_mode = global_ssl.ocsp_update.mode;
ebpt_insert(&newlist->entries, &entry_dup->node);
LIST_APPEND(&newlist->ord_entries, &entry_dup->by_crtlist);
LIST_APPEND(&ckchs->crtlist_entry, &entry_dup->by_ckch_store);
if (entry->ssl_conf)
ckchs->data->ocsp_update_mode = entry->ssl_conf->ocsp_update;
+ if (ckchs->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT)
+ ckchs->data->ocsp_update_mode = global_ssl.ocsp_update.mode;
ebpt_insert(&newlist->entries, &entry->node);
LIST_APPEND(&newlist->ord_entries, &entry->by_crtlist);
LIST_APPEND(&ckchs->crtlist_entry, &entry->by_ckch_store);
if (entry->ssl_conf)
store->data->ocsp_update_mode = entry->ssl_conf->ocsp_update;
+ if (store->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT)
+ store->data->ocsp_update_mode = global_ssl.ocsp_update.mode;
/* check if it's possible to insert this new crtlist_entry */
entry->node.key = store;
ssl_sock_free_ocsp_instance(ctx->ocsp);
}
-/* Check if the ckch_store and the entry does have the same configuration */
+/* Check if the ckch_store and the entry do have the same configuration. Also
+ * ensure that those options are compatible with the global ocsp-update mode. */
int ocsp_update_check_cfg_consistency(struct ckch_store *store, struct crtlist_entry *entry, char *crt_path, char **err)
{
int err_code = ERR_NONE;
+ int incompat_found = 0;
- if (store->data->ocsp_update_mode != SSL_SOCK_OCSP_UPDATE_DFLT || entry->ssl_conf) {
- if ((!entry->ssl_conf && store->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON)
- || (entry->ssl_conf && entry->ssl_conf->ocsp_update != SSL_SOCK_OCSP_UPDATE_OFF &&
- store->data->ocsp_update_mode != entry->ssl_conf->ocsp_update)) {
- memprintf(err, "%sIncompatibilities found in OCSP update mode for certificate %s\n", err && *err ? *err : "", crt_path);
- err_code |= ERR_ALERT | ERR_FATAL;
- }
+ switch(store->data->ocsp_update_mode) {
+ case SSL_SOCK_OCSP_UPDATE_DFLT:
+ if (entry && entry->ssl_conf && entry->ssl_conf->ocsp_update == SSL_SOCK_OCSP_UPDATE_ON &&
+ global_ssl.ocsp_update.mode != SSL_SOCK_OCSP_UPDATE_ON)
+ incompat_found = 1;
+ break;
+ case SSL_SOCK_OCSP_UPDATE_OFF:
+ if ((entry && entry->ssl_conf && entry->ssl_conf->ocsp_update == SSL_SOCK_OCSP_UPDATE_ON) ||
+ ((!entry || !entry->ssl_conf) && global_ssl.ocsp_update.mode == SSL_SOCK_OCSP_UPDATE_ON))
+ incompat_found = 1;
+ break;
+ case SSL_SOCK_OCSP_UPDATE_ON:
+ if ((entry && entry->ssl_conf && entry->ssl_conf->ocsp_update != SSL_SOCK_OCSP_UPDATE_ON) ||
+ ((!entry || !entry->ssl_conf) && global_ssl.ocsp_update.mode != SSL_SOCK_OCSP_UPDATE_ON))
+ incompat_found = 1;
+ break;
}
+
+ if (incompat_found) {
+ memprintf(err, "%sIncompatibilities found in OCSP update mode for certificate %s\n", err && *err ? *err : "", crt_path);
+ err_code |= ERR_ALERT | ERR_FATAL;
+ }
+
return err_code;
}
#ifndef OPENSSL_NO_OCSP
.ocsp_update.delay_max = SSL_OCSP_UPDATE_DELAY_MAX,
.ocsp_update.delay_min = SSL_OCSP_UPDATE_DELAY_MIN,
+ .ocsp_update.mode = SSL_SOCK_OCSP_UPDATE_DFLT,
#endif
};
char *err = NULL;
size_t path_len;
int inc_refcount_store = 0;
+ int enable_auto_update = (data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON ||
+ (data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_DFLT &&
+ global_ssl.ocsp_update.mode == SSL_SOCK_OCSP_UPDATE_ON));
x = data->cert;
if (!x)
goto out;
ssl_ocsp_get_uri_from_cert(x, ocsp_uri, &err);
- /* We should have an "OCSP URI" field in order for auto update to work. */
- if (data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON && b_data(ocsp_uri) == 0)
- goto out;
-
- /* In case of ocsp update mode set to 'on', this function might be
- * called with no known ocsp response. If no ocsp uri can be found in
- * the certificate, nothing needs to be done here. */
if (!data->ocsp_response && !data->ocsp_cid) {
- if (data->ocsp_update_mode != SSL_SOCK_OCSP_UPDATE_ON || b_data(ocsp_uri) == 0) {
+ /* In case of ocsp update mode set to 'on', this function might
+ * be called with no known ocsp response. If no ocsp uri can be
+ * found in the certificate, nothing needs to be done here. */
+ if (!enable_auto_update || b_data(ocsp_uri) == 0) {
ret = 0;
goto out;
}
+ } else {
+ /* If we have an OCSP response provided and the ocsp auto update
+ * enabled, we must raise an error if no OCSP URI was found. */
+ if (data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON && b_data(ocsp_uri) == 0)
+ goto out;
}
issuer = data->ocsp_issuer;
*/
memcpy(iocsp->path, path, path_len + 1);
- if (data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) {
+ if (enable_auto_update) {
ssl_ocsp_update_insert(iocsp);
/* If we are during init the update task is not
* scheduled yet so a wakeup won't do anything.
if (ocsp_update_task)
task_wakeup(ocsp_update_task, TASK_WOKEN_MSG);
}
- } else if (iocsp->uri && data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) {
+ } else if (iocsp->uri && enable_auto_update) {
/* This unlikely case can happen if a series of "del ssl
* crt-list" / "add ssl crt-list" commands are made on the CLI.
* In such a case, the OCSP response tree entry will be created
/* we found the ckchs in the tree, we can use it directly */
cfgerr |= ssl_sock_load_ckchs(path, ckchs, bind_conf, NULL, NULL, 0, is_default, &ckch_inst, err);
- /* This certificate has an 'ocsp-update' already set in a
- * previous crt-list so we must raise an error. */
- if (ckchs->data->ocsp_update_mode == SSL_SOCK_OCSP_UPDATE_ON) {
- memprintf(err, "%sIncompatibilities found in OCSP update mode for certificate %s\n", err && *err ? *err: "", path);
- cfgerr |= ERR_ALERT | ERR_FATAL;
- }
+ /* The ckch_store might have been created through a crt-list
+ * line so we must check that the ocsp-update modes are still
+ * compatible between the global mode and the explicit one from
+ * the crt-list. */
+ cfgerr |= ocsp_update_check_cfg_consistency(ckchs, NULL, path, err);
found++;
} else if (stat(path, &buf) == 0) {