]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Set up default logging for SSLKEYLOGFILE
authorMichał Kępień <michal@isc.org>
Wed, 22 Dec 2021 17:17:26 +0000 (18:17 +0100)
committerMichał Kępień <michal@isc.org>
Wed, 22 Dec 2021 17:17:26 +0000 (18:17 +0100)
A customary method of exporting TLS pre-master secrets used by a piece
of software (for debugging purposes, e.g. to examine decrypted traffic
in a packet sniffer) is to set the SSLKEYLOGFILE environment variable to
the path to the file in which this data should be logged.

In order to enable writing any data to a file using the logging
framework provided by libisc, a logging channel needs to be defined and
the relevant logging category needs to be associated with it.  Since the
SSLKEYLOGFILE variable is only expected to contain a path, some defaults
for the logging channel need to be assumed.  Add a new function,
named_log_setdefaultsslkeylogfile(), for setting up those implicit
defaults, which are equivalent to the following logging configuration:

    channel default_sslkeylogfile {
        file "${SSLKEYLOGFILE}" versions 10 size 100m suffix timestamp;
    };

    category sslkeylog {
     default_sslkeylogfile;
    };

This ensures TLS pre-master secrets do not use up more than about 1 GB
of disk space, which should be enough to hold debugging data for the
most recent 1 million TLS connections.

As these values are arguably not universally appropriate for all
deployment environments, a way for overriding them needs to exist.
Suppress creation of the default logging channel for TLS pre-master
secrets when the SSLKEYLOGFILE variable is set to the string "config".
This enables providing custom logging configuration for the relevant
category via the "logging" stanza.  (Note that it would have been
simpler to only skip setting up the default logging channel for TLS
pre-master secrets if the SSLKEYLOGFILE environment variable is not set
at all.  However, libisc only logs pre-master secrets if that variable
is set.  Detecting a "magic" string enables the SSLKEYLOGFILE
environment variable to serve as a single control for both enabling TLS
pre-master secret collection and potentially also indicating where and
how they should be exported.)

bin/named/include/named/log.h
bin/named/log.c
bin/named/logconf.c
bin/named/server.c

index 3b1767c5067737b491dc5ae9b885d99fe62f7fb1..a696f9d4563a7feea283a5ae6f70ac53581b7489 100644 (file)
@@ -58,6 +58,14 @@ named_log_setsafechannels(isc_logconfig_t *lcfg);
  * Like named_log_setdefaultchannels(), but omits any logging to files.
  */
 
+void
+named_log_setdefaultsslkeylogfile(isc_logconfig_t *lcfg);
+/*%
+ * If the SSLKEYLOGFILE environment variable is set, sets up a default
+ * logging channel for writing TLS pre-master secrets to the path stored
+ * in that environment variable (for debugging purposes).
+ */
+
 isc_result_t
 named_log_setdefaultcategory(isc_logconfig_t *lcfg);
 /*%
index 2ae9282f96017a1ec5f186d14a63d01d186d8f12..39ae21117c64337e08a1555cbcfe883b02e64af7 100644 (file)
 
 /*! \file */
 
+#include <stdlib.h>
+
 #include <isc/result.h>
+#include <isc/util.h>
 
 #include <dns/log.h>
 
@@ -78,6 +81,8 @@ named_log_init(bool safe) {
                goto cleanup;
        }
 
+       named_log_setdefaultsslkeylogfile(lcfg);
+
        return (ISC_R_SUCCESS);
 
 cleanup:
@@ -167,6 +172,41 @@ named_log_setsafechannels(isc_logconfig_t *lcfg) {
 #endif /* if ISC_FACILITY != LOG_DAEMON */
 }
 
+/*
+ * If the SSLKEYLOGFILE environment variable is set, TLS pre-master secrets are
+ * logged (for debugging purposes) to the file whose path is provided in that
+ * variable.  Set up a default logging channel which maintains up to 10 files
+ * containing TLS pre-master secrets, each up to 100 MB in size.  If the
+ * SSLKEYLOGFILE environment variable is set to the string "config", suppress
+ * creation of the default channel, allowing custom logging channel
+ * configuration for TLS pre-master secrets to be provided via the "logging"
+ * stanza in the configuration file.
+ */
+void
+named_log_setdefaultsslkeylogfile(isc_logconfig_t *lcfg) {
+       const char *sslkeylogfile_path = getenv("SSLKEYLOGFILE");
+       isc_logdestination_t destination = {
+               .file = {
+                       .name = sslkeylogfile_path,
+                       .versions = 10,
+                       .suffix = isc_log_rollsuffix_timestamp,
+                       .maximum_size = 100 * 1024 * 1024,
+               },
+       };
+       isc_result_t result;
+
+       if (sslkeylogfile_path == NULL ||
+           strcmp(sslkeylogfile_path, "config") == 0) {
+               return;
+       }
+
+       isc_log_createchannel(lcfg, "default_sslkeylogfile", ISC_LOG_TOFILE,
+                             ISC_LOG_INFO, &destination, 0);
+       result = isc_log_usechannel(lcfg, "default_sslkeylogfile",
+                                   ISC_LOGCATEGORY_SSLKEYLOG, NULL);
+       RUNTIME_CHECK(result == ISC_R_SUCCESS);
+}
+
 isc_result_t
 named_log_setdefaultcategory(isc_logconfig_t *lcfg) {
        isc_result_t result = ISC_R_SUCCESS;
index 68dd83773e355798c5df9ceb9e6c444299a91ede..960385834a476e242cf7c0bc3eeb73458e32bff7 100644 (file)
@@ -326,6 +326,7 @@ named_logconfig(isc_logconfig_t *logconfig, const cfg_obj_t *logstmt) {
 
        if (logconfig != NULL) {
                named_log_setdefaultchannels(logconfig);
+               named_log_setdefaultsslkeylogfile(logconfig);
        }
 
        (void)cfg_map_get(logstmt, "channel", &channels);
index 8943ce7e17d4899edaff4703fd0cc51090c11b09..1467efa1916495b6b4f489868310f431ca526e59 100644 (file)
@@ -9321,6 +9321,7 @@ load_configuration(const char *filename, named_server_t *server,
                               "configuring logging");
                } else {
                        named_log_setdefaultchannels(logc);
+                       named_log_setdefaultsslkeylogfile(logc);
                        CHECKM(named_log_setunmatchedcategory(logc),
                               "setting up default 'category unmatched'");
                        CHECKM(named_log_setdefaultcategory(logc),