}
}
+static void handleOpenSSLSettings(const dnsdist::rust::settings::TlsTuningConfiguration& tlsSettings)
+{
+ for (const auto& engine : tlsSettings.engines) {
+#if defined(HAVE_LIBSSL) && !defined(HAVE_TLS_PROVIDERS)
+ auto [success, error] = libssl_load_engine(std::string(engine.name), !engine.default_string.empty() ? std::optional<std::string>(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)
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) {
});
}
+ 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;
}
setLuaSideEffect();
if (facility.type() == typeid(std::string)) {
- static std::map<std::string, int> 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<std::string>(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<int>(facility));
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;
}
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;
}
general: GeneralConfiguration,
key_value_stores: KeyValueStoresConfiguration,
load_balancing_policies: LoadBalancingPoliciesConfiguration,
+ logging: LoggingConfiguration,
metrics: MetricsConfiguration,
packet_caches: Vec<PacketCacheConfiguration>,
pools: Vec<PoolConfiguration>,
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 {
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<String>,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ engines: Vec<TlsEngineConfiguration>,
}
#[derive(Deserialize, Serialize, Debug, PartialEq)]
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 {
#[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,
#[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<dnsdistsettings::PacketCacheConfiguration>,
}
+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();
}
+// 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();
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(())
}
}
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(())
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()?;
type: "LoadBalancingPoliciesConfiguration"
default: true
description: "Load-balancing policies"
+ - name: "logging"
+ type: "LoggingConfiguration"
+ default: true
+ description: "Logging settings"
- name: "metrics"
type: "MetricsConfiguration"
default: true
- 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"
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:
lua-name: "setOutgoingTLSSessionsCacheMaxTicketsPerBackend"
internal-field-name: "d_tlsSessionCacheMaxSessionsPerBackend"
runtime-configurable: true
+ - name: "providers"
+ type: "Vec<String>"
+ 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<TlsEngineConfiguration>"
+ 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"
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"
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"
- **general**: :ref:`GeneralConfiguration <yaml-settings-GeneralConfiguration>` - General settings
- **key_value_stores**: :ref:`KeyValueStoresConfiguration <yaml-settings-KeyValueStoresConfiguration>` - Key-Value stores
- **load_balancing_policies**: :ref:`LoadBalancingPoliciesConfiguration <yaml-settings-LoadBalancingPoliciesConfiguration>` - Load-balancing policies
+- **logging**: :ref:`LoggingConfiguration <yaml-settings-LoggingConfiguration>` - Logging settings
- **metrics**: :ref:`MetricsConfiguration <yaml-settings-MetricsConfiguration>` - Metrics-related settings
- **packet_caches**: Sequence of :ref:`PacketCacheConfiguration <yaml-settings-PacketCacheConfiguration>` - Packet-cache definitions
- **pools**: Sequence of :ref:`PoolConfiguration <yaml-settings-PoolConfiguration>` - Pools of backends
``eBPF`` and ``XDP`` related settings
-- **ipv4**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv4 maps
-- **ipv6**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv6 maps
-- **cidr_ipv4**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv4 subnets maps
-- **cidr_ipv6**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv6 subnets maps
-- **qnames**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - DNS names maps
+- **ipv4**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv4 map
+- **ipv6**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv6 map
+- **cidr_ipv4**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv4 subnets map
+- **cidr_ipv6**: :ref:`EbpfMapConfiguration <yaml-settings-EbpfMapConfiguration>` - IPv6 subnets map
+- **qnames**: :ref:`EbpfMapConfiguration <yaml-settings-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
- **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 ``("")``
- **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-StructuredLoggingConfiguration>`
+
+
.. _yaml-settings-MetricsConfiguration:
MetricsConfiguration
- **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
- **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
- **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 <yaml-settings-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:
}
}
+std::optional<int> logFacilityFromString(std::string facilityStr)
+{
+ static std::unordered_map<std::string, int> 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())
DNSName getTSIGAlgoName(TSIGHashEnum& algoEnum);
int logFacilityToLOG(unsigned int facility);
+std::optional<int> logFacilityFromString(std::string facilityStr);
template<typename Container>
void