Skip to content

Commit

Permalink
dnsdist: Disable Lua configuration directives in YAML mode
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rgacogne committed Feb 13, 2025
1 parent f400ec7 commit a9195c3
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 17 deletions.
1 change: 1 addition & 0 deletions pdns/dnsdistdist/dnsdist-console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ static const std::vector<dnsdist::console::ConsoleKeyword> 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"},
Expand Down
45 changes: 32 additions & 13 deletions pdns/dnsdistdist/dnsdist-lua.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, newserver_t> pvars, boost::optional<int> qps) {
setLuaSideEffect();
Expand Down Expand Up @@ -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);
Expand All @@ -3179,16 +3181,33 @@ 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);

#ifdef LUAJIT_VERSION
luaCtx.executeCode(getLuaFFIWrappers());
#endif
}

void setupLuaConfigurationOptions(LuaContext& luaCtx, bool client, bool configCheck)
{
static std::atomic<bool> 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
Expand Down
2 changes: 2 additions & 0 deletions pdns/dnsdistdist/dnsdist-lua.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class FunctionType>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ def process_settings():
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
Expand Down
14 changes: 10 additions & 4 deletions pdns/dnsdistdist/dnsdist.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions pdns/dnsdistdist/docs/reference/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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``.
Expand Down
2 changes: 2 additions & 0 deletions pdns/dnsdistdist/docs/reference/yaml-settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit a9195c3

Please sign in to comment.