From: Remi Gacogne Date: Thu, 13 Feb 2025 12:17:02 +0000 (+0100) Subject: dnsdist: Disable Lua configuration directives in YAML mode X-Git-Tag: dnsdist-2.0.0-alpha1~36^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a9195c3e1ec5ed9d62e35f3380889c374f20c104;p=thirdparty%2Fpdns.git dnsdist: Disable Lua configuration directives in YAML mode This commit restricts the Lua directives available to a Lua script loaded alongside with a YAML configuration, disabling all Lua configuration directives. This prevents a mess when settings are set to different values in YAML and Lua, and make it clear that the when a YAML configuration is used, any Lua file should only be used to provide functions to the YAML configuration. This behaviour can be reverted via the `enableLuaConfiguration` directive if really needed. --- diff --git a/pdns/dnsdistdist/dnsdist-console.cc b/pdns/dnsdistdist/dnsdist-console.cc index b5581ac762..94ea4d2194 100644 --- a/pdns/dnsdistdist/dnsdist-console.cc +++ b/pdns/dnsdistdist/dnsdist-console.cc @@ -529,6 +529,7 @@ static const std::vector s_consoleKeywords{ {"dynBlockRulesGroup", true, "", "return a new DynBlockRulesGroup object"}, {"EDNSVersionRule", true, "version", "matches queries with the specified EDNS version"}, {"EDNSOptionRule", true, "optcode", "matches queries with the specified EDNS0 option present"}, + {"enableLuaConfiguration", true, "", "Enable using Lua configuration directives along with a YAML configuration file. It is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML"}, {"ERCodeAction", true, "ercode", "Reply immediately by turning the query into a response with the specified EDNS extended rcode"}, {"ERCodeRule", true, "rcode", "matches responses with the specified extended rcode (EDNS0)"}, {"exceedNXDOMAINs", true, "rate, seconds", "get set of addresses that exceed `rate` NXDOMAIN/s over `seconds` seconds"}, diff --git a/pdns/dnsdistdist/dnsdist-lua.cc b/pdns/dnsdistdist/dnsdist-lua.cc index 464f019225..810fa4aba8 100644 --- a/pdns/dnsdistdist/dnsdist-lua.cc +++ b/pdns/dnsdistdist/dnsdist-lua.cc @@ -411,14 +411,6 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) { dnsdist::lua::setupConfigurationItems(luaCtx); - luaCtx.writeFunction("inClientStartup", [client]() { - return client && !dnsdist::configuration::isImmutableConfigurationDone(); - }); - - luaCtx.writeFunction("inConfigCheck", [configCheck]() { - return configCheck; - }); - luaCtx.writeFunction("newServer", [client, configCheck](boost::variant pvars, boost::optional qps) { setLuaSideEffect(); @@ -3165,10 +3157,20 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) namespace dnsdist::lua { -void setupLua(LuaContext& luaCtx, bool client, bool configCheck) +void setupLuaBindingsOnly(LuaContext& luaCtx, bool client, bool configCheck) { - setupLuaActions(luaCtx); - setupLuaConfig(luaCtx, client, configCheck); + luaCtx.writeFunction("inClientStartup", [client]() { + return client && !dnsdist::configuration::isImmutableConfigurationDone(); + }); + + luaCtx.writeFunction("inConfigCheck", [configCheck]() { + return configCheck; + }); + + luaCtx.writeFunction("enableLuaConfiguration", [&luaCtx, client, configCheck]() { + setupLuaConfigurationOptions(luaCtx, client, configCheck); + }); + setupLuaBindings(luaCtx, client, configCheck); setupLuaBindingsDNSCrypt(luaCtx, client); setupLuaBindingsDNSParser(luaCtx); @@ -3179,9 +3181,7 @@ void setupLua(LuaContext& luaCtx, bool client, bool configCheck) setupLuaBindingsPacketCache(luaCtx, client); setupLuaBindingsProtoBuf(luaCtx, client, configCheck); setupLuaBindingsRings(luaCtx, client); - dnsdist::lua::hooks::setupLuaHooks(luaCtx); setupLuaInspection(luaCtx); - setupLuaRules(luaCtx); setupLuaVars(luaCtx); setupLuaWeb(luaCtx); @@ -3189,6 +3189,25 @@ void setupLua(LuaContext& luaCtx, bool client, bool configCheck) luaCtx.executeCode(getLuaFFIWrappers()); #endif } + +void setupLuaConfigurationOptions(LuaContext& luaCtx, bool client, bool configCheck) +{ + static std::atomic s_initialized{false}; + if (s_initialized.exchange(true)) { + return; + } + + setupLuaConfig(luaCtx, client, configCheck); + setupLuaActions(luaCtx); + setupLuaRules(luaCtx); + dnsdist::lua::hooks::setupLuaHooks(luaCtx); +} + +void setupLua(LuaContext& luaCtx, bool client, bool configCheck) +{ + setupLuaBindingsOnly(luaCtx, client, configCheck); + setupLuaConfigurationOptions(luaCtx, client, configCheck); +} } namespace dnsdist::configuration::lua diff --git a/pdns/dnsdistdist/dnsdist-lua.hh b/pdns/dnsdistdist/dnsdist-lua.hh index 09d18a643b..fc70190d72 100644 --- a/pdns/dnsdistdist/dnsdist-lua.hh +++ b/pdns/dnsdistdist/dnsdist-lua.hh @@ -65,6 +65,8 @@ void setupLuaLoadBalancingContext(LuaContext& luaCtx); namespace dnsdist::lua { void setupLua(LuaContext& luaCtx, bool client, bool configCheck); +void setupLuaBindingsOnly(LuaContext& luaCtx, bool client, bool configCheck); +void setupLuaConfigurationOptions(LuaContext& luaCtx, bool client, bool configCheck); void setupConfigurationItems(LuaContext& luaCtx); template diff --git a/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-settings-documentation-generator.py b/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-settings-documentation-generator.py index 4eef23a3b2..c6c220375d 100644 --- a/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-settings-documentation-generator.py +++ b/pdns/dnsdistdist/dnsdist-rust-lib/dnsdist-settings-documentation-generator.py @@ -138,6 +138,8 @@ Since 2.0.0, :program:`dnsdist` supports the YAML configuration format in additi If the configuration file passed to :program:`dnsdist` via the ``-C`` command-line switch ends in ``.yml``, it is assumed to be in the new YAML format, and an attempt to load a Lua configuration file with the same name but the ``.lua`` will be done before loading the YAML configuration. If the names ends in ``.lua``, there will also be an attempt to find a file with the same name but ending in ``.yml``. Otherwise the existing Lua configuration format is assumed. +By default, when a YAML configuration file is used, any Lua configuration file used along the YAML configuration should only contain functions, and ideally even those should be defined either inline in the YAML file or in separate files included from the YAML configuration, for clarity. It is however possible to change this behaviour using the :func:`enableLuaConfiguration` directive to enable Lua configuration directives, but it is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML but to not mix them. + A YAML configuration file contains several sections, that are described below. .. code-block:: yaml\n diff --git a/pdns/dnsdistdist/dnsdist.cc b/pdns/dnsdistdist/dnsdist.cc index 4482fba142..b09bb0a734 100644 --- a/pdns/dnsdistdist/dnsdist.cc +++ b/pdns/dnsdistdist/dnsdist.cc @@ -3289,11 +3289,20 @@ static bool loadConfigurationFromFile(const std::string& configurationFile, bool if (boost::ends_with(configurationFile, ".yml")) { if (auto tentativeLuaConfFile = lookForTentativeConfigurationFileWithExtension(configurationFile, "lua")) { vinfolog("Loading configuration from auto-discovered Lua file %s", *tentativeLuaConfFile); + dnsdist::lua::setupLuaBindingsOnly(*(g_lua.lock()), isClient, configCheck); dnsdist::configuration::lua::loadLuaConfigurationFile(*(g_lua.lock()), *tentativeLuaConfFile, configCheck); } vinfolog("Loading configuration from YAML file %s", configurationFile); - return dnsdist::configuration::yaml::loadConfigurationFromFile(configurationFile, isClient, configCheck); + if (!dnsdist::configuration::yaml::loadConfigurationFromFile(configurationFile, isClient, configCheck)) { + return false; + } + if (!isClient && !configCheck) { + dnsdist::lua::setupLuaConfigurationOptions(*(g_lua.lock()), false, false); + } + return true; } + + dnsdist::lua::setupLua(*(g_lua.lock()), isClient, configCheck); if (boost::ends_with(configurationFile, ".lua")) { vinfolog("Loading configuration from Lua file %s", configurationFile); dnsdist::configuration::lua::loadLuaConfigurationFile(*(g_lua.lock()), configurationFile, configCheck); @@ -3358,7 +3367,6 @@ int main(int argc, char** argv) }); if (cmdLine.beClient || !cmdLine.command.empty()) { - dnsdist::lua::setupLua(*(g_lua.lock()), true, false); if (!loadConfigurationFromFile(cmdLine.config, true, false)) { #ifdef COVERAGE exit(EXIT_FAILURE); @@ -3395,7 +3403,6 @@ int main(int argc, char** argv) dnsdist::webserver::registerBuiltInWebHandlers(); if (cmdLine.checkConfig) { - dnsdist::lua::setupLua(*(g_lua.lock()), false, true); if (!loadConfigurationFromFile(cmdLine.config, false, true)) { #ifdef COVERAGE exit(EXIT_FAILURE); @@ -3420,7 +3427,6 @@ int main(int argc, char** argv) /* create the default pool no matter what */ createPoolIfNotExists(""); - dnsdist::lua::setupLua(*(g_lua.lock()), false, false); if (!loadConfigurationFromFile(cmdLine.config, false, false)) { #ifdef COVERAGE exit(EXIT_FAILURE); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 11521e1be4..4855fd87bb 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -46,6 +46,13 @@ Global configuration Note that this does not grant the capabilities to the process, doing so might be done by running it as root which we don't advise, or by adding capabilities via the systemd unit file, for example. Please also be aware that switching to a different user via ``--uid`` will still drop all capabilities. +.. function:: enableLuaConfiguration() + + .. versionadded:: 2.0.0 + + Enable using Lua configuration directives along with a YAML configuration file. By default, when a YAML configuration file is used, any Lua configuration file used along the YAML configuration should only contain functions, and ideally even those should be defined either inline in the YAML file or in separate files included from the YAML configuration, for clarity. + It is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML but to not mix them. + .. function:: includeDirectory(path) Include configuration files from ``path``. diff --git a/pdns/dnsdistdist/docs/reference/yaml-settings.rst b/pdns/dnsdistdist/docs/reference/yaml-settings.rst index ccdf76da8f..f02d2d29f9 100644 --- a/pdns/dnsdistdist/docs/reference/yaml-settings.rst +++ b/pdns/dnsdistdist/docs/reference/yaml-settings.rst @@ -11,6 +11,8 @@ Since 2.0.0, :program:`dnsdist` supports the YAML configuration format in additi If the configuration file passed to :program:`dnsdist` via the ``-C`` command-line switch ends in ``.yml``, it is assumed to be in the new YAML format, and an attempt to load a Lua configuration file with the same name but the ``.lua`` will be done before loading the YAML configuration. If the names ends in ``.lua``, there will also be an attempt to find a file with the same name but ending in ``.yml``. Otherwise the existing Lua configuration format is assumed. +By default, when a YAML configuration file is used, any Lua configuration file used along the YAML configuration should only contain functions, and ideally even those should be defined either inline in the YAML file or in separate files included from the YAML configuration, for clarity. It is however possible to change this behaviour using the :func:`enableLuaConfiguration` directive to enable Lua configuration directives, but it is strongly advised not to use this directive unless absolutely necessary, and to prefer doing all the configuration in either Lua or YAML but to not mix them. + A YAML configuration file contains several sections, that are described below. .. code-block:: yaml