From 01868f1633a49e234698858d4a7ac5e7be4737cd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 16 Jan 2025 14:25:35 +0100 Subject: [PATCH] dnsdist: Add a few missing settings to the YAML configuration --- .../dnsdistdist/dnsdist-configuration-yaml.cc | 71 ++++++++++++ pdns/dnsdistdist/dnsdist-lua.cc | 50 +------- ...dist-configuration-yaml-items-generated.cc | 12 +- .../dnsdist-rust-lib/rust/src/lib.rs | 107 +++++++++++++++++- .../dnsdist-settings-definitions.yml | 107 +++++++++++++++--- .../docs/reference/yaml-settings.rst | 60 ++++++++-- pdns/misc.cc | 56 +++++++++ pdns/misc.hh | 1 + 8 files changed, 383 insertions(+), 81 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc index 19f18bfcde..3719c2dfa9 100644 --- a/pdns/dnsdistdist/dnsdist-configuration-yaml.cc +++ b/pdns/dnsdistdist/dnsdist-configuration-yaml.cc @@ -807,6 +807,73 @@ static void loadCustomPolicies(const ::rust::Vec(engine.default_string) : std::nullopt); + if (!success) { + warnlog("Error while trying to load TLS engine '%s': %s", std::string(engine.name), error); + } +#else + warnlog("Ignoring TLS engine '%s' because OpenSSL engine support is not compiled in", std::string(engine.name)); +#endif /* HAVE_LIBSSL && !HAVE_TLS_PROVIDERS */ + } + + for (const auto& provider : tlsSettings.providers) { +#if defined(HAVE_LIBSSL) && OPENSSL_VERSION_MAJOR >= 3 && defined(HAVE_TLS_PROVIDERS) + auto [success, error] = libssl_load_provider(std::string(provider)); + if (!success) { + warnlog("Error while trying to load TLS provider '%s': %s", std::string(provider), error); + } +#else + warnlog("Ignoring TLS provider '%s' because OpenSSL provider support is not compiled in", std::string(provider)); +#endif /* HAVE_LIBSSL && OPENSSL_VERSION_MAJOR >= 3 && HAVE_TLS_PROVIDERS */ + } +} + +static void handleLoggingConfiguration(const dnsdist::rust::settings::LoggingConfiguration& settings) +{ + if (!settings.verbose_log_destination.empty()) { + auto dest = std::string(settings.verbose_log_destination); + try { + auto stream = std::ofstream(dest.c_str()); + dnsdist::logging::LoggingConfiguration::setVerboseStream(std::move(stream)); + } + catch (const std::exception& e) { + errlog("Error while opening the verbose logging destination file %s: %s", dest, e.what()); + } + } + + if (!settings.syslog_facility.empty()) { + auto facilityLevel = logFacilityFromString(std::string(settings.syslog_facility)); + if (!facilityLevel) { + warnlog("Unknown facility '%s' passed to logging.syslog_facility", std::string(settings.syslog_facility)); + } + else { + setSyslogFacility(*facilityLevel); + } + } + + if (settings.structured.enabled) { + auto levelPrefix = std::string(settings.structured.level_prefix); + auto timeFormat = std::string(settings.structured.time_format); + if (!timeFormat.empty()) { + if (timeFormat == "numeric") { + dnsdist::logging::LoggingConfiguration::setStructuredTimeFormat(dnsdist::logging::LoggingConfiguration::TimeFormat::Numeric); + } + else if (timeFormat == "ISO8601") { + dnsdist::logging::LoggingConfiguration::setStructuredTimeFormat(dnsdist::logging::LoggingConfiguration::TimeFormat::ISO8601); + } + else { + warnlog("Unknown value '%s' to logging.structured.time_format parameter", timeFormat); + } + } + + dnsdist::logging::LoggingConfiguration::setStructuredLogging(true, levelPrefix); + } +} + #endif /* defined(HAVE_YAML_CONFIGURATION) */ bool loadConfigurationFromFile(const std::string& fileName, bool isClient, bool configCheck) @@ -831,6 +898,8 @@ bool loadConfigurationFromFile(const std::string& fileName, bool isClient, bool try { auto globalConfig = dnsdist::rust::settings::from_yaml_string(*data); + handleLoggingConfiguration(globalConfig.logging); + if (!globalConfig.console.listen_address.empty()) { const auto& consoleConf = globalConfig.console; dnsdist::configuration::updateRuntimeConfiguration([consoleConf](dnsdist::configuration::RuntimeConfiguration& config) { @@ -857,6 +926,8 @@ bool loadConfigurationFromFile(const std::string& fileName, bool isClient, bool }); } + handleOpenSSLSettings(globalConfig.tuning.tls); + #if defined(HAVE_EBPF) if (!configCheck && globalConfig.ebpf.ipv4.max_entries > 0 && globalConfig.ebpf.ipv6.max_entries > 0 && globalConfig.ebpf.qnames.max_entries > 0) { BPFFilter::MapFormat format = globalConfig.ebpf.external ? BPFFilter::MapFormat::WithActions : BPFFilter::MapFormat::Legacy; diff --git a/pdns/dnsdistdist/dnsdist-lua.cc b/pdns/dnsdistdist/dnsdist-lua.cc index 067cdd4006..b9119ea496 100644 --- a/pdns/dnsdistdist/dnsdist-lua.cc +++ b/pdns/dnsdistdist/dnsdist-lua.cc @@ -2104,57 +2104,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } setLuaSideEffect(); if (facility.type() == typeid(std::string)) { - static std::map const facilities = { - {"local0", LOG_LOCAL0}, - {"log_local0", LOG_LOCAL0}, - {"local1", LOG_LOCAL1}, - {"log_local1", LOG_LOCAL1}, - {"local2", LOG_LOCAL2}, - {"log_local2", LOG_LOCAL2}, - {"local3", LOG_LOCAL3}, - {"log_local3", LOG_LOCAL3}, - {"local4", LOG_LOCAL4}, - {"log_local4", LOG_LOCAL4}, - {"local5", LOG_LOCAL5}, - {"log_local5", LOG_LOCAL5}, - {"local6", LOG_LOCAL6}, - {"log_local6", LOG_LOCAL6}, - {"local7", LOG_LOCAL7}, - {"log_local7", LOG_LOCAL7}, - /* most of these likely make very little sense - for dnsdist, but why not? */ - {"kern", LOG_KERN}, - {"log_kern", LOG_KERN}, - {"user", LOG_USER}, - {"log_user", LOG_USER}, - {"mail", LOG_MAIL}, - {"log_mail", LOG_MAIL}, - {"daemon", LOG_DAEMON}, - {"log_daemon", LOG_DAEMON}, - {"auth", LOG_AUTH}, - {"log_auth", LOG_AUTH}, - {"syslog", LOG_SYSLOG}, - {"log_syslog", LOG_SYSLOG}, - {"lpr", LOG_LPR}, - {"log_lpr", LOG_LPR}, - {"news", LOG_NEWS}, - {"log_news", LOG_NEWS}, - {"uucp", LOG_UUCP}, - {"log_uucp", LOG_UUCP}, - {"cron", LOG_CRON}, - {"log_cron", LOG_CRON}, - {"authpriv", LOG_AUTHPRIV}, - {"log_authpriv", LOG_AUTHPRIV}, - {"ftp", LOG_FTP}, - {"log_ftp", LOG_FTP}}; auto facilityStr = boost::get(facility); - toLowerInPlace(facilityStr); - auto facilityIt = facilities.find(facilityStr); - if (facilityIt == facilities.end()) { + auto facilityLevel = logFacilityFromString(facilityStr); + if (!facilityLevel) { g_outputBuffer = "Unknown facility '" + facilityStr + "' passed to setSyslogFacility()!\n"; return; } - setSyslogFacility(facilityIt->second); + setSyslogFacility(*facilityLevel); } else { setSyslogFacility(boost::get(facility)); diff --git a/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-configuration-yaml-items-generated.cc b/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-configuration-yaml-items-generated.cc index 020f705c86..fa81278bbd 100644 --- a/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-configuration-yaml-items-generated.cc +++ b/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-configuration-yaml-items-generated.cc @@ -88,6 +88,12 @@ void convertRuntimeFlatSettingsFromRust(const dnsdist::rust::settings::GlobalCon if (config.d_secPollSuffix == "secpoll.powerdns.com.") { config.d_secPollSuffix = std::string(yamlConfig.security_polling.suffix); } + if (config.d_verbose == false) { + config.d_verbose = yamlConfig.logging.verbose; + } + if (config.d_verboseHealthChecks == false) { + config.d_verboseHealthChecks = yamlConfig.logging.verbose_health_checks; + } if (config.d_payloadSizeSelfGenAnswers == 1232) { config.d_payloadSizeSelfGenAnswers = yamlConfig.general.edns_udp_payload_size_self_generated_answers; } @@ -100,12 +106,6 @@ void convertRuntimeFlatSettingsFromRust(const dnsdist::rust::settings::GlobalCon if (config.d_fixupCase == false) { config.d_fixupCase = yamlConfig.general.fixup_case; } - if (config.d_verbose == false) { - config.d_verbose = yamlConfig.general.verbose; - } - if (config.d_verboseHealthChecks == false) { - config.d_verboseHealthChecks = yamlConfig.general.verbose_health_checks; - } if (config.d_allowEmptyResponse == false) { config.d_allowEmptyResponse = yamlConfig.general.allow_empty_responses; } diff --git a/pdns/dnsdistdist/dnsdist-rust-lib/rust/src/lib.rs b/pdns/dnsdistdist/dnsdist-rust-lib/rust/src/lib.rs index b2af8f006e..bf4c00c63e 100644 --- a/pdns/dnsdistdist/dnsdist-rust-lib/rust/src/lib.rs +++ b/pdns/dnsdistdist/dnsdist-rust-lib/rust/src/lib.rs @@ -1140,6 +1140,7 @@ mod dnsdistsettings { general: GeneralConfiguration, key_value_stores: KeyValueStoresConfiguration, load_balancing_policies: LoadBalancingPoliciesConfiguration, + logging: LoggingConfiguration, metrics: MetricsConfiguration, packet_caches: Vec, pools: Vec, @@ -1903,6 +1904,14 @@ mod dnsdistsettings { randomize_ids_to_backend: bool, } + #[derive(Deserialize, Serialize, Debug, PartialEq)] + #[serde(deny_unknown_fields)] + struct TlsEngineConfiguration { + name: String, + #[serde(default, skip_serializing_if = "crate::is_default")] + default_string: String, + } + #[derive(Deserialize, Serialize, Debug, PartialEq)] #[serde(deny_unknown_fields)] struct TlsTuningConfiguration { @@ -1912,6 +1921,10 @@ mod dnsdistsettings { outgoing_tickets_cache_validity: u16, #[serde(default = "crate::U16::<20>::value", skip_serializing_if = "crate::U16::<20>::is_equal")] max_outgoing_tickets_per_backend: u16, + #[serde(default, skip_serializing_if = "crate::is_default")] + providers: Vec, + #[serde(default, skip_serializing_if = "crate::is_default")] + engines: Vec, } #[derive(Deserialize, Serialize, Debug, PartialEq)] @@ -1947,6 +1960,32 @@ mod dnsdistsettings { suffix: String, } + #[derive(Deserialize, Serialize, Debug, PartialEq)] + #[serde(deny_unknown_fields)] + struct StructuredLoggingConfiguration { + #[serde(default, skip_serializing_if = "crate::is_default")] + enabled: bool, + #[serde(default = "crate::default_value_structured_logging_level_prefix", skip_serializing_if = "crate::default_value_equal_structured_logging_level_prefix")] + level_prefix: String, + #[serde(default = "crate::default_value_structured_logging_time_format", skip_serializing_if = "crate::default_value_equal_structured_logging_time_format")] + time_format: String, + } + + #[derive(Deserialize, Serialize, Debug, PartialEq)] + #[serde(deny_unknown_fields)] + struct LoggingConfiguration { + #[serde(default, skip_serializing_if = "crate::is_default")] + verbose: bool, + #[serde(default, skip_serializing_if = "crate::is_default")] + verbose_health_checks: bool, + #[serde(default, skip_serializing_if = "crate::is_default")] + verbose_log_destination: String, + #[serde(default, skip_serializing_if = "crate::is_default")] + syslog_facility: String, + #[serde(default, skip_serializing_if = "crate::is_default")] + structured: StructuredLoggingConfiguration, + } + #[derive(Deserialize, Serialize, Debug, PartialEq)] #[serde(deny_unknown_fields)] struct GeneralConfiguration { @@ -1959,10 +1998,6 @@ mod dnsdistsettings { #[serde(default, skip_serializing_if = "crate::is_default")] fixup_case: bool, #[serde(default, skip_serializing_if = "crate::is_default")] - verbose: bool, - #[serde(default, skip_serializing_if = "crate::is_default")] - verbose_health_checks: bool, - #[serde(default, skip_serializing_if = "crate::is_default")] allow_empty_responses: bool, #[serde(default, skip_serializing_if = "crate::is_default")] drop_empty_queries: bool, @@ -2355,6 +2390,8 @@ impl ResponseRuleConfigurationSerde { #[serde(default, skip_serializing_if = "crate::is_default")] load_balancing_policies: dnsdistsettings::LoadBalancingPoliciesConfiguration, #[serde(default, skip_serializing_if = "crate::is_default")] + logging: dnsdistsettings::LoggingConfiguration, + #[serde(default, skip_serializing_if = "crate::is_default")] metrics: dnsdistsettings::MetricsConfiguration, #[serde(default, skip_serializing_if = "crate::is_default")] packet_caches: Vec, @@ -3042,6 +3079,14 @@ impl Default for dnsdistsettings::UdpTuningConfiguration { } +impl Default for dnsdistsettings::TlsEngineConfiguration { + fn default() -> Self { + let deserialized: dnsdistsettings::TlsEngineConfiguration = serde_yaml::from_str("").unwrap(); + deserialized + } +} + + impl Default for dnsdistsettings::TlsTuningConfiguration { fn default() -> Self { let deserialized: dnsdistsettings::TlsTuningConfiguration = serde_yaml::from_str("").unwrap(); @@ -3083,6 +3128,40 @@ impl Default for dnsdistsettings::SecurityPollingConfiguration { } +// DEFAULT HANDLING for structured_logging_level_prefix +fn default_value_structured_logging_level_prefix() -> String { + String::from("prio") +} +fn default_value_equal_structured_logging_level_prefix(value: &str)-> bool { + value == default_value_structured_logging_level_prefix() +} + + +// DEFAULT HANDLING for structured_logging_time_format +fn default_value_structured_logging_time_format() -> String { + String::from("numeric") +} +fn default_value_equal_structured_logging_time_format(value: &str)-> bool { + value == default_value_structured_logging_time_format() +} + + +impl Default for dnsdistsettings::StructuredLoggingConfiguration { + fn default() -> Self { + let deserialized: dnsdistsettings::StructuredLoggingConfiguration = serde_yaml::from_str("").unwrap(); + deserialized + } +} + + +impl Default for dnsdistsettings::LoggingConfiguration { + fn default() -> Self { + let deserialized: dnsdistsettings::LoggingConfiguration = serde_yaml::from_str("").unwrap(); + deserialized + } +} + + impl Default for dnsdistsettings::GeneralConfiguration { fn default() -> Self { let deserialized: dnsdistsettings::GeneralConfiguration = serde_yaml::from_str("").unwrap(); @@ -3495,8 +3574,16 @@ impl dnsdistsettings::UdpTuningConfiguration { Ok(()) } } +impl dnsdistsettings::TlsEngineConfiguration { + fn validate(&self) -> Result<(), ValidationError> { + Ok(()) + } +} impl dnsdistsettings::TlsTuningConfiguration { fn validate(&self) -> Result<(), ValidationError> { + for sub_type in &self.engines { + sub_type.validate()?; + } Ok(()) } } @@ -3515,6 +3602,17 @@ impl dnsdistsettings::SecurityPollingConfiguration { Ok(()) } } +impl dnsdistsettings::StructuredLoggingConfiguration { + fn validate(&self) -> Result<(), ValidationError> { + Ok(()) + } +} +impl dnsdistsettings::LoggingConfiguration { + fn validate(&self) -> Result<(), ValidationError> { + self.structured.validate()?; + Ok(()) + } +} impl dnsdistsettings::GeneralConfiguration { fn validate(&self) -> Result<(), ValidationError> { Ok(()) @@ -3591,6 +3689,7 @@ impl GlobalConfigurationSerde { self.general.validate()?; self.key_value_stores.validate()?; self.load_balancing_policies.validate()?; + self.logging.validate()?; self.metrics.validate()?; for sub_type in &self.packet_caches { sub_type.validate()?; diff --git a/pdns/dnsdistdist/dnsdist-settings-definitions.yml b/pdns/dnsdistdist/dnsdist-settings-definitions.yml index 879ef731ce..55e53918d6 100644 --- a/pdns/dnsdistdist/dnsdist-settings-definitions.yml +++ b/pdns/dnsdistdist/dnsdist-settings-definitions.yml @@ -65,6 +65,10 @@ global: type: "LoadBalancingPoliciesConfiguration" default: true description: "Load-balancing policies" + - name: "logging" + type: "LoggingConfiguration" + default: true + description: "Logging settings" - name: "metrics" type: "MetricsConfiguration" default: true @@ -490,23 +494,23 @@ ebpf: - name: "ipv4" type: "EbpfMapConfiguration" default: true - description: "IPv4 maps" + description: "IPv4 map" - name: "ipv6" type: "EbpfMapConfiguration" default: true - description: "IPv6 maps" + description: "IPv6 map" - name: "cidr_ipv4" type: "EbpfMapConfiguration" default: true - description: "IPv4 subnets maps" + description: "IPv4 subnets map" - name: "cidr_ipv6" type: "EbpfMapConfiguration" default: true - description: "IPv6 subnets maps" + description: "IPv6 subnets map" - name: "qnames" type: "EbpfMapConfiguration" default: true - description: "DNS names maps" + description: "DNS names map" - name: "external" type: "bool" default: "false" @@ -1546,6 +1550,17 @@ udp_tuning: internal-field-name: "d_randomizeIDsToBackend" runtime-configurable: false +tls_engine: + description: "OpenSSL engine settings" + parameters: + - name: "name" + type: "String" + description: "The engine name" + - name: "default_string" + type: "String" + default: "" + description: "The default string to pass to the engine. The exact value depends on the engine but represents the algorithms to register with the engine, as a list of comma-separated keywords. For example 'RSA,EC,DSA,DH,PKEY,PKEY_CRYPTO,PKEY_ASN1'" + tls_tuning: category: "tuning.tls" parameters: @@ -1567,6 +1582,16 @@ tls_tuning: lua-name: "setOutgoingTLSSessionsCacheMaxTicketsPerBackend" internal-field-name: "d_tlsSessionCacheMaxSessionsPerBackend" runtime-configurable: true + - name: "providers" + type: "Vec" + default: "" + lua-name: "loadTLSProvider" + description: "Load OpenSSL providers. Providers can be used to accelerate cryptographic operations, like for example Intel QAT. At the moment up to a maximum of 32 loaded providers are supported, and that support is experimental. Note that this feature is only available when building against OpenSSL version >= 3.0 and with the ``-–enable-tls-provider`` configure flag on. In other cases, ``engines`` should be used instead. Some providers might actually degrade performance unless the TLS asynchronous mode of OpenSSL is enabled. To enable it see the ``async_mode`` parameter of TLS frontends" + - name: "engines" + type: "Vec" + default: true + lua-name: "loadTLSEngine" + description: "Load OpenSSL engines. Engines can be used to accelerate cryptographic operations, like for example Intel QAT. At the moment up to a maximum of 32 loaded engines are supported, and that support is experimental. Some engines might actually degrade performance unless the TLS asynchronous mode of OpenSSL is enabled. To enable it see the ``async_mode`` parameter of TLS frontends" doh_tuning: category: "tuning.doh" @@ -1632,6 +1657,66 @@ security_polling: internal-field-name: "d_secPollSuffix" runtime-configurable: true +structured_logging: + description: "Structured-like logging settings" + parameters: + - name: "enabled" + type: "bool" + default: "false" + description: | + Set whether log messages should be in a structured-logging-like format. This is turned off by default. + The resulting format looks like this (when timestamps are enabled via ``--log-timestamps`` and with ``level_prefix: prio`` and ``time_format: ISO8601``):: + + ts=\"2023-11-06T12:04:58+0100\" prio=\"Info\" msg=\"Added downstream server 127.0.0.1:53\" + + And with ``level_prefix: level`` and ``time_format: numeric``):: + + ts=\"1699268815.133\" level=\"Info\" msg=\"Added downstream server 127.0.0.1:53\" + + - name: "level_prefix" + type: "String" + default: "prio" + description: "Set the key name for the log level. There is unfortunately no standard name for this key, so in some setups it might be useful to set this value to a different name to have consistency across products" + - name: "time_format" + type: "String" + default: "numeric" + description: "Set the time format" + supported-values: + - "ISO8601" + - "numeric" + +logging: + description: "Logging settings" + parameters: + - name: "verbose" + type: "bool" + default: "false" + lua-name: "setVerbose" + internal-field-name: "d_verbose" + runtime-configurable: true + description: "Set whether log messages issued at the verbose level should be logged" + - name: "verbose_health_checks" + type: "bool" + default: "false" + lua-name: "setVerboseHealthChecks" + internal-field-name: "d_verboseHealthChecks" + runtime-configurable: true + description: "Set whether health check errors should be logged" + - name: "verbose_log_destination" + type: "String" + default: "" + lua-name: "setVerboseLogDestination" + description: "Set a destination file to write the ‘verbose’ log messages to, instead of sending them to syslog and/or the standard output which is the default. Note that these messages will no longer be sent to syslog or the standard output once this option has been set. There is no rotation or file size limit. Only use this feature for debugging under active operator control" + - name: "syslog_facility" + type: "String" + default: "" + lua-name: "setSyslogFacility" + description: "Set the syslog logging facility to the supplied value (values with or without the ``log_`` prefix are supported)" + supported-values: [local0, log_local0, local1, log_local1, local2, log_local2, local3, log_local3, local4, log_local4, local5, log_local5, local6, log_local6, local7, log_local7, kern, log_kern, user, log_user, mail, log_mail, daemon, log_daemon, auth, log_auth, syslog, log_syslog, lpr, log_lpr, news, log_news, uucp, log_uucp, cron, log_cron, authpriv, log_authpriv, ftp, log_ftp] + - name: "structured" + type: "StructuredLoggingConfiguration" + default: true + general: parameters: - name: "edns_udp_payload_size_self_generated_answers" @@ -1658,18 +1743,6 @@ general: lua-name: "fixupCase" internal-field-name: "d_fixupCase" runtime-configurable: true - - name: "verbose" - type: "bool" - default: "false" - lua-name: "setVerbose" - internal-field-name: "d_verbose" - runtime-configurable: true - - name: "verbose_health_checks" - type: "bool" - default: "false" - lua-name: "setVerboseHealthChecks" - internal-field-name: "d_verboseHealthChecks" - runtime-configurable: true - name: "allow_empty_responses" type: "bool" default: "false" diff --git a/pdns/dnsdistdist/docs/reference/yaml-settings.rst b/pdns/dnsdistdist/docs/reference/yaml-settings.rst index 1b6467ae4b..21e2241335 100644 --- a/pdns/dnsdistdist/docs/reference/yaml-settings.rst +++ b/pdns/dnsdistdist/docs/reference/yaml-settings.rst @@ -35,6 +35,7 @@ GlobalConfiguration - **general**: :ref:`GeneralConfiguration ` - General settings - **key_value_stores**: :ref:`KeyValueStoresConfiguration ` - Key-Value stores - **load_balancing_policies**: :ref:`LoadBalancingPoliciesConfiguration ` - Load-balancing policies +- **logging**: :ref:`LoggingConfiguration ` - Logging settings - **metrics**: :ref:`MetricsConfiguration ` - Metrics-related settings - **packet_caches**: Sequence of :ref:`PacketCacheConfiguration ` - Packet-cache definitions - **pools**: Sequence of :ref:`PoolConfiguration ` - Pools of backends @@ -276,11 +277,11 @@ EbpfConfiguration ``eBPF`` and ``XDP`` related settings -- **ipv4**: :ref:`EbpfMapConfiguration ` - IPv4 maps -- **ipv6**: :ref:`EbpfMapConfiguration ` - IPv6 maps -- **cidr_ipv4**: :ref:`EbpfMapConfiguration ` - IPv4 subnets maps -- **cidr_ipv6**: :ref:`EbpfMapConfiguration ` - IPv6 subnets maps -- **qnames**: :ref:`EbpfMapConfiguration ` - DNS names maps +- **ipv4**: :ref:`EbpfMapConfiguration ` - IPv4 map +- **ipv6**: :ref:`EbpfMapConfiguration ` - IPv6 map +- **cidr_ipv4**: :ref:`EbpfMapConfiguration ` - IPv4 subnets map +- **cidr_ipv6**: :ref:`EbpfMapConfiguration ` - IPv6 subnets map +- **qnames**: :ref:`EbpfMapConfiguration ` - DNS names map - **external**: Boolean ``(false)`` - If set to true, :program:`dnsdist` does not load the internal ``eBPF`` program. This is useful for ``AF_XDP`` and ``XDP`` maps @@ -316,8 +317,6 @@ GeneralConfiguration - **add_edns_to_self_generated_answers**: Boolean ``(true)`` - **truncate_tc_answers**: Boolean ``(false)`` - **fixup_case**: Boolean ``(false)`` -- **verbose**: Boolean ``(false)`` -- **verbose_health_checks**: Boolean ``(false)`` - **allow_empty_responses**: Boolean ``(false)`` - **drop_empty_queries**: Boolean ``(false)`` - **capabilities_to_retain**: Sequence of String ``("")`` @@ -621,6 +620,20 @@ LoadBalancingPoliciesConfiguration - **hash_perturbation**: Unsigned integer ``(0)`` +.. _yaml-settings-LoggingConfiguration: + +LoggingConfiguration +-------------------- + +Logging settings + +- **verbose**: Boolean ``(false)`` - Set whether log messages issued at the verbose level should be logged +- **verbose_health_checks**: Boolean ``(false)`` - Set whether health check errors should be logged +- **verbose_log_destination**: String ``("")`` - Set a destination file to write the ‘verbose’ log messages to, instead of sending them to syslog and/or the standard output which is the default. Note that these messages will no longer be sent to syslog or the standard output once this option has been set. There is no rotation or file size limit. Only use this feature for debugging under active operator control +- **syslog_facility**: String ``("")`` - Set the syslog logging facility to the supplied value (values with or without the ``log_`` prefix are supported). Supported values are: local0, log_local0, local1, log_local1, local2, log_local2, local3, log_local3, local4, log_local4, local5, log_local5, local6, log_local6, local7, log_local7, kern, log_kern, user, log_user, mail, log_mail, daemon, log_daemon, auth, log_auth, syslog, log_syslog, lpr, log_lpr, news, log_news, uucp, log_uucp, cron, log_cron, authpriv, log_authpriv, ftp, log_ftp +- **structured**: :ref:`StructuredLoggingConfiguration ` + + .. _yaml-settings-MetricsConfiguration: MetricsConfiguration @@ -850,6 +863,26 @@ SnmpConfiguration - **daemon_socket**: String ``("")`` +.. _yaml-settings-StructuredLoggingConfiguration: + +StructuredLoggingConfiguration +------------------------------ + +Structured-like logging settings + +- **enabled**: Boolean ``(false)`` - Set whether log messages should be in a structured-logging-like format. This is turned off by default. +The resulting format looks like this (when timestamps are enabled via ``--log-timestamps`` and with ``level_prefix: prio`` and ``time_format: ISO8601``):: + + ts=\"2023-11-06T12:04:58+0100\" prio=\"Info\" msg=\"Added downstream server 127.0.0.1:53\" + +And with ``level_prefix: level`` and ``time_format: numeric``):: + + ts=\"1699268815.133\" level=\"Info\" msg=\"Added downstream server 127.0.0.1:53\" + +- **level_prefix**: String ``(prio)`` - Set the key name for the log level. There is unfortunately no standard name for this key, so in some setups it might be useful to set this value to a different name to have consistency across products +- **time_format**: String ``(numeric)`` - Set the time format. Supported values are: ISO8601, numeric + + .. _yaml-settings-TcpTuningConfiguration: TcpTuningConfiguration @@ -869,6 +902,17 @@ TcpTuningConfiguration - **fast_open_key**: String ``("")`` +.. _yaml-settings-TlsEngineConfiguration: + +TlsEngineConfiguration +---------------------- + +OpenSSL engine settings + +- **name**: String - The engine name +- **default_string**: String ``("")`` - The default string to pass to the engine. The exact value depends on the engine but represents the algorithms to register with the engine, as a list of comma-separated keywords. For example 'RSA,EC,DSA,DH,PKEY,PKEY_CRYPTO,PKEY_ASN1' + + .. _yaml-settings-TlsTuningConfiguration: TlsTuningConfiguration @@ -877,6 +921,8 @@ TlsTuningConfiguration - **outgoing_tickets_cache_cleanup_delay**: Unsigned integer ``(60)`` - **outgoing_tickets_cache_validity**: Unsigned integer ``(600)`` - **max_outgoing_tickets_per_backend**: Unsigned integer ``(20)`` +- **providers**: Sequence of String ``("")`` - Load OpenSSL providers. Providers can be used to accelerate cryptographic operations, like for example Intel QAT. At the moment up to a maximum of 32 loaded providers are supported, and that support is experimental. Note that this feature is only available when building against OpenSSL version >= 3.0 and with the ``-–enable-tls-provider`` configure flag on. In other cases, ``engines`` should be used instead. Some providers might actually degrade performance unless the TLS asynchronous mode of OpenSSL is enabled. To enable it see the ``async_mode`` parameter of TLS frontends +- **engines**: Sequence of :ref:`TlsEngineConfiguration ` - Load OpenSSL engines. Engines can be used to accelerate cryptographic operations, like for example Intel QAT. At the moment up to a maximum of 32 loaded engines are supported, and that support is experimental. Some engines might actually degrade performance unless the TLS asynchronous mode of OpenSSL is enabled. To enable it see the ``async_mode`` parameter of TLS frontends .. _yaml-settings-TuningConfiguration: diff --git a/pdns/misc.cc b/pdns/misc.cc index 29adfc51fa..1cc6d5114b 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -729,6 +729,62 @@ int logFacilityToLOG(unsigned int facility) } } +std::optional logFacilityFromString(std::string facilityStr) +{ + static std::unordered_map const s_facilities = { + {"local0", LOG_LOCAL0}, + {"log_local0", LOG_LOCAL0}, + {"local1", LOG_LOCAL1}, + {"log_local1", LOG_LOCAL1}, + {"local2", LOG_LOCAL2}, + {"log_local2", LOG_LOCAL2}, + {"local3", LOG_LOCAL3}, + {"log_local3", LOG_LOCAL3}, + {"local4", LOG_LOCAL4}, + {"log_local4", LOG_LOCAL4}, + {"local5", LOG_LOCAL5}, + {"log_local5", LOG_LOCAL5}, + {"local6", LOG_LOCAL6}, + {"log_local6", LOG_LOCAL6}, + {"local7", LOG_LOCAL7}, + {"log_local7", LOG_LOCAL7}, + /* most of these likely make very little sense + for us, but why not? */ + {"kern", LOG_KERN}, + {"log_kern", LOG_KERN}, + {"user", LOG_USER}, + {"log_user", LOG_USER}, + {"mail", LOG_MAIL}, + {"log_mail", LOG_MAIL}, + {"daemon", LOG_DAEMON}, + {"log_daemon", LOG_DAEMON}, + {"auth", LOG_AUTH}, + {"log_auth", LOG_AUTH}, + {"syslog", LOG_SYSLOG}, + {"log_syslog", LOG_SYSLOG}, + {"lpr", LOG_LPR}, + {"log_lpr", LOG_LPR}, + {"news", LOG_NEWS}, + {"log_news", LOG_NEWS}, + {"uucp", LOG_UUCP}, + {"log_uucp", LOG_UUCP}, + {"cron", LOG_CRON}, + {"log_cron", LOG_CRON}, + {"authpriv", LOG_AUTHPRIV}, + {"log_authpriv", LOG_AUTHPRIV}, + {"ftp", LOG_FTP}, + {"log_ftp", LOG_FTP} + }; + + toLowerInPlace(facilityStr); + auto facilityIt = s_facilities.find(facilityStr); + if (facilityIt == s_facilities.end()) { + return std::nullopt; + } + + return facilityIt->second; +} + string stripDot(const string& dom) { if(dom.empty()) diff --git a/pdns/misc.hh b/pdns/misc.hh index 39fdb6c086..66dd0ccf3e 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -109,6 +109,7 @@ bool getTSIGHashEnum(const DNSName& algoName, TSIGHashEnum& algoEnum); DNSName getTSIGAlgoName(TSIGHashEnum& algoEnum); int logFacilityToLOG(unsigned int facility); +std::optional logFacilityFromString(std::string facilityStr); template void -- 2.47.2