/* keyword, function, parameters, description */
{ "addACL", true, "netmask", "add to the ACL set who can use this server" },
{ "addAction", true, "DNS rule, DNS action", "add a rule" },
- { "addAnyTCRule", true, "", "generate TC=1 answers to ANY queries received over UDP, moving them to TCP" },
- { "addDelay", true, "domain, n", "delay answers within that domain by n milliseconds" },
- { "addDisableValidationRule", true, "DNS rule", "set the CD flags to 1 for all queries matching the specified domain" },
+ { "addAnyTCRule", true, "", "(deprecated) generate TC=1 answers to ANY queries received over UDP, moving them to TCP" },
+ { "addDelay", true, "domain, n", "(deprecated) delay answers within that domain by n milliseconds" },
+ { "addDisableValidationRule", true, "DNS rule", "(deprecated) set the CD flags to 1 for all queries matching the specified domain" },
{ "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenSize=0, interface=\"\"}", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters" },
- { "addDomainBlock", true, "domain", "block queries within this domain" },
- { "addDomainSpoof", true, "domain, ip[, ip6]", "generate answers for A/AAAA/ANY queries using the ip parameters" },
+ { "addDomainBlock", true, "domain", "(deprecated) block queries within this domain" },
+ { "addDomainSpoof", true, "domain, ip[, ip6]", "(deprecated) generate answers for A/AAAA/ANY queries using the ip parameters" },
{ "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" },
{ "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenSize=0, interface=\"\"}]", "add `addr` to the list of addresses we listen on" },
- { "addLuaAction", true, "x, func", "where 'x' is all the combinations from `addPoolRule`, and func is a function with the parameter `dq`, which returns an action to be taken on this packet. Good for rare packets but where you want to do a lot of processing" },
- { "addLuaResponseAction", true, "x, func", "where 'x' is all the combinations from `addPoolRule`, and func is a function with the parameter `dr`, which returns an action to be taken on this response packet. Good for rare packets but where you want to do a lot of processing" },
- { "addNoRecurseRule", true, "domain", "clear the RD flag for all queries matching the specified domain" },
- { "addPoolRule", true, "domain, pool", "send queries to this domain to that pool" },
- { "addQPSLimit", true, "domain, n", "limit queries within that domain to n per second" },
- { "addQPSPoolRule", true, "x, limit, pool", "like `addPoolRule`, but only select at most 'limit' queries/s for this pool, letting the subsequent rules apply otherwise" },
+ { "addLuaAction", true, "x, func", "where 'x' is all the combinations from `addAction`, and func is a function with the parameter `dq`, which returns an action to be taken on this packet. Good for rare packets but where you want to do a lot of processing" },
+ { "addLuaResponseAction", true, "x, func", "where 'x' is all the combinations from `addAction`, and func is a function with the parameter `dr`, which returns an action to be taken on this response packet. Good for rare packets but where you want to do a lot of processing" },
+ { "addNoRecurseRule", true, "domain", "(deprecated) clear the RD flag for all queries matching the specified domain" },
+ { "addPoolRule", true, "domain, pool", "(deprecated) send queries to this domain to that pool" },
+ { "addQPSLimit", true, "domain, n", "(deprecated) limit queries within that domain to n per second" },
+ { "addQPSPoolRule", true, "x, limit, pool", "(deprecated) like `addPoolRule`, but only select at most 'limit' queries/s for this pool, letting the subsequent rules apply otherwise" },
{ "addCacheHitResponseAction", true, "DNS rule, DNS response action", "add a cache hit response rule" },
{ "addResponseAction", true, "DNS rule, DNS response action", "add a response rule" },
{ "AllowAction", true, "", "let these packets go through" },
g_lua.writeFunction("addAnyTCRule", []() {
setLuaSideEffect();
+ warnlog("addAnyTCRule() is deprecated and will be removed in 1.3.0, please use addAction(AndRule{QTypeRule(dnsdist.ANY), TCPRule(false)}, TCAction()) instead");
+
auto rules=g_rulactions.getCopy();
std::vector<pair<int, shared_ptr<DNSRule> >> v;
v.push_back({1, std::make_shared<QTypeRule>(0xff)});
g_lua.writeFunction("addDomainBlock", [](const std::string& domain) {
setLuaSideEffect();
+ warnlog("addDomainBlock() is deprecated and will be removed in 1.3.0, please use addAction(\"%s\", DropAction()) instead", domain);
SuffixMatchNode smn;
smn.add(DNSName(domain));
g_rulactions.modify([smn](decltype(g_rulactions)::value_type& rulactions) {
g_lua.writeFunction("addDomainSpoof", [](const std::string& domain, boost::variant<string,vector<pair<int, string>>> inp, boost::optional<string> b) {
setLuaSideEffect();
+ warnlog("addDomainSpoof() is deprecated and will be removed in 1.3.0, please use addAction(\"%s\", SpoofAction(...)) instead", domain);
+
SuffixMatchNode smn;
vector<ComboAddress> outp;
try
g_lua.writeFunction("addDomainCNAMESpoof", [](const std::string& domain, const std::string& cname) {
setLuaSideEffect();
+ warnlog("addDomainCNAMESpoof() is deprecated and will be removed in 1.3.0, please use addAction(\"%s\", SpoofCNAMEAction(\"%s\")) instead", domain, cname);
+
SuffixMatchNode smn;
try
{
g_lua.writeFunction("addPoolRule", [](luadnsrule_t var, string pool) {
setLuaSideEffect();
+ warnlog("addPoolRule() is deprecated and will be removed in 1.3.0, please use addAction(..., PoolAction(\"%s\")) instead", pool);
+
auto rule=makeRule(var);
g_rulactions.modify([rule, pool](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({
g_lua.writeFunction("addNoRecurseRule", [](luadnsrule_t var) {
setLuaSideEffect();
+ warnlog("addNoRecurseRule() is deprecated and will be removed in 1.3.0, please use addAction(..., NoRecurseAction()) instead");
+
auto rule=makeRule(var);
g_rulactions.modify([rule](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({
g_lua.writeFunction("addDisableValidationRule", [](luadnsrule_t var) {
setLuaSideEffect();
+ warnlog("addDisableValidationRule() is deprecated and will be removed in 1.3.0, please use addAction(..., DisableValidationAction()) instead");
+
auto rule=makeRule(var);
g_rulactions.modify([rule](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({
g_lua.writeFunction("addQPSPoolRule", [](luadnsrule_t var, int limit, string pool) {
setLuaSideEffect();
+ warnlog("addQPSPoolRule() is deprecated and will be removed in 1.3.0, please use addAction(..., QPSPoolAction(%d, \"%s\")) instead", limit, pool);
+
auto rule = makeRule(var);
g_rulactions.modify([rule, pool,limit](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({
g_lua.writeFunction("setDNSSECPool", [](const std::string& pool) {
setLuaSideEffect();
+ warnlog("setDNSSECPool() is deprecated and will be removed in 1.3.0, please use addAction(DNSSECRule(), PoolAction(\"%s\")) instead", pool);
+
g_rulactions.modify([pool](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({std::make_shared<DNSSECRule>(),
std::make_shared<PoolAction>(pool)});
g_lua.writeFunction("addQPSLimit", [](luadnsrule_t var, int lim) {
setLuaSideEffect();
+ warnlog("addQPSLimit() is deprecated and will be removed in 1.3.0, please use addAction(..., QPSAction(%d)) instead", lim);
+
auto rule = makeRule(var);
g_rulactions.modify([lim,rule](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({rule,
std::make_shared<QPSAction>(lim)});
});
});
-
+
g_lua.writeFunction("addDelay", [](luadnsrule_t var, int msec) {
setLuaSideEffect();
+ warnlog("addDelay() is deprecated and will be removed in 1.3.0, please use addAction(..., DelayAction(%d)) instead", msec);
+
auto rule = makeRule(var);
g_rulactions.modify([msec,rule](decltype(g_rulactions)::value_type& rulactions) {
rulactions.push_back({rule,
-- send the queries for selected domain suffixes to the server
-- in the 'abuse' pool
-addPoolRule({"ezdns.it.", "xxx."}, "abuse")
+addAction({"ezdns.it.", "xxx."}, PoolAction("abuse"))
-- send the queries from a selected subnet to the
-- abuse pool
-addPoolRule("192.168.1.0/24", "abuse")
+addAction("192.168.1.0/24", PoolAction("abuse"))
-- send the queries for the "com" suffix to the "abuse"
-- pool, but only up to 100 qps
-addQPSPoolRule("com.", 100, "abuse")
+addAction("com.", QPSPoolRule(100, "abuse"))
-- declare a Lua action function, routing NAPTR queries
-- to the abuse pool
topRule()
-- drop queries for the following suffixes:
-addDomainBlock("powerdns.org.")
-addDomainBlock("spectre.")
--- this is equivalent to addAction("isis.", DropAction())
-addDomainBlock("isis.")
+addAction("powerdns.org.", DropAction())
+addAction("spectre.", DropAction())
-- called before we distribute a question
block=newDNSName("powerdns.org.")
newServer({address="2001:888:2000:1d::2", pool={"auth", "dnssec"}})
newServer({address="2a01:4f8:110:4389::2", pool={"auth", "dnssec"}})
---setDNSSECPool("dnssec")
+--addAction(DNSSECRule(), PoolAction("dnssec"))
--topRule()
-- split queries between the 'auth' pool and the regular one,
-- addAction(AllRule(), DropAction())
-- clear the RD flag in queries for powerdns.com.
--- addNoRecurseRule("powerdns.com.")
--- another way to do the exact same thing:
-- addAction("powerdns.com.", NoRecurseAction())
-- set the CD flag in queries for powerdns.com.
--- addDisableValidationRule("powerdns.com.")
--- or:
-- addAction("powerdns.com.", DisableValidationAction())
-- delay all responses for 1000ms
-- addAction(AllRule(), DelayAction(1000))
-- truncate ANY queries over UDP only
--- addAnyTCRule()
+-- addAction(AndRule{QTypeRule(dnsdist.ANY), TCPRule(false)}, TCAction())
-- truncate ANY queries over TCP only
-- addAction(AndRule({QTypeRule(dnsdist.ANY), TCPRule(true)}), TCAction())
-- spoof responses for A, AAAA and ANY for spoof.powerdns.com.
-- A queries will get 192.0.2.1, AAAA 2001:DB8::1 and ANY both
--- addDomainSpoof("spoof.powerdns.com.", "192.0.2.1", "2001:DB8::1")
+-- addAction("spoof.powerdns.com.", SpoofAction({"192.0.2.1", "2001:DB8::1"}))
-- spoof responses will multiple records
-- A will get 192.0.2.1 and 192.0.2.2, AAAA 20B8::1 and 2001:DB8::2
-- ANY all of that
--- addDomainSpoof("spoof.powerdns.com", {"192.0.2.1", "192.0.2.2", "20B8::1", "2001:DB8::2"})
+-- addAction("spoof.powerdns.com", SpoofAction({"192.0.2.1", "192.0.2.2", "20B8::1", "2001:DB8::2"}))
-- spoof responses with a CNAME
--- addDomainCNAMESpoof("cnamespoof.powerdns.com.", "cname.powerdns.com.")
+-- addAction("cnamespoof.powerdns.com.", SpoofCNAMEAction("cname.powerdns.com."))
-- spoof responses in Lua
--[[
.. code-block:: lua
- addDelay(MaxQPSIPRule(5, 32, 48), 100)
+ addAction(MaxQPSIPRule(5, 32, 48), DelayAction(100))
This measures traffic per IPv4 address and per /48 of IPv6, and if traffic for such an address (range) exceeds 5 :term:`qps`, it gets delayed by 100ms.
Most of the query processing is done in C++ for maximum performance, but some operations are executed in Lua for maximum flexibility:
- * The :func:`blockfilter` function
* Rules added by :func:`addLuaAction`
* Server selection policies defined via :func:`setServerPolicyLua` or :func:`newServerPolicy`
While Lua is fast, its use should be restricted to the strict necessary in order to achieve maximum performance, it might be worth considering using LuaJIT instead of Lua.
-When Lua inspection is needed, the best course of action is to restrict the queries sent to Lua inspection by using :func:`addLuaAction` instead of inspecting all queries in the :func:`blockfilter` function.
+When Lua inspection is needed, the best course of action is to restrict the queries sent to Lua inspection by using :func:`addLuaAction` with a selector.
:program:`dnsdist` design choices mean that the processing of UDP queries is done by only one thread per local bind.
This is great to keep lock contention to a low level, but might not be optimal for setups using a lot of processing power, caused for example by a large number of complicated rules.
.. code-block:: lua
- addPoolRule({"192.168.12.0/24", "192.168.13.14"}, "abuse")
+ addAction({"192.168.12.0/24", "192.168.13.14"}, PoolAction("abuse"))
To define a pool that should receive only a :term:`QPS`-limited amount of traffic, do:
.. code-block:: lua
- addQPSPoolRule("com.", 10000, "gtld-cluster")
+ addAction("com.", QPSPoolAction(10000, "gtld-cluster"))
Traffic exceeding the :term:`QPS` limit will not match that rule, and subsequent rules will apply normally.
-Both :func:`addDomainBlock` and addPoolRule end up the list of Rules and Actions (for which see below).
-
:class:`Servers <Server>` can be added to or removed from pools with the :func:`Server:addPool` and :func:`Server:rmPool` functions respectively:
.. code-block:: lua
For example::
- addDelay(MaxQPSIPRule(5, 32, 48), 100)
+ addAction(MaxQPSIPRule(5, 32, 48), DelayAction(100))
This measures traffic per IPv4 address and per /48 of IPv6, and if traffic for such an address (range) exceeds 5 qps, it gets delayed by 100ms.
.. function:: addAnyTCRule()
+ .. deprecated:: 1.2.0
+
Set the TC-bit (truncate) on ANY queries received over UDP.
Forcing a retry over TCP.
This is equivalent to doing::
.. function:: addDelay(DNSrule, delay)
+ .. deprecated:: 1.2.0
+
Delay the query for ``delay`` milliseconds before sending to a backend.
+ This function is deprecated as of 1.2.0, please use instead:
+
+ addAction(DNSRule, DelayAction(delay))
:param DNSRule: The DNSRule to match traffic
:param int delay: The delay time in milliseconds.
.. function:: addDisableValidationRule(DNSrule)
+ .. deprecated:: 1.2.0
+
Set the CD (Checking Disabled) flag to 1 for all queries matching the DNSRule.
- Using this function is equal to using the :func:`DisableValidationAction`.
+ Using this function is equal to using the :func:`DisableValidationAction` action.
.. function:: addDomainBlock(domain)
+ .. deprecated:: 1.2.0
+
Drop all queries for ``domain`` and all names below it.
+ Deprecated as of 1.2.0, please use instead:
+
+ addAction(domain, DropAction())
:param string domain: The domain name to block
.. function:: addDomainSpoof(domain, IPv4[, IPv6])
addDomainSpoof(domain, {IP[,...]})
+ .. deprecated:: 1.2.0
+
Generate answers for A/AAAA/ANY queries.
+ This function is deprecated as of 1.2.0, please use:
+
+ addAction(domain, SpoofAction({IP[,...]}))
+
+ or:
+
+ addAction(domain, SpoofAction(IPv4[, IPv6]))
:param string domain: Domain name to spoof for
:param string IPv4: IPv4 address to spoof in the reply
.. function:: addDomainCNAMESpoof(domain, cname)
- Generate CNAME answers for queries.
+ .. deprecated:: 1.2.0
+
+ Generate CNAME answers for queries. This function is deprecated as of 1.2.0 in favor of using:
+
+ addAction(domain, SpoofCNAMEAction(cname))
:param string domain: Domain name to spoof for
:param string cname: Domain name to add CNAME to
.. function:: addNoRecurseRule(DNSrule)
+ .. deprecated:: 1.2.0
+
Clear the RD flag for all queries matching the rule.
+ This function is deprecated as of 1.2.0, please use:
+
+ addAction(DNSRule, NoRecurseAction())
:param DNSRule: match queries based on this rule
.. function:: addPoolRule(DNSRule, pool)
+ .. deprecated:: 1.2.0
+
Send queries matching the first argument to the pool ``pool``.
e.g.::
addPoolRule("example.com", "myPool")
- This is equivalent to::
+ This function is deprecated as of 1.2.0, this is equivalent to::
addAction("example.com", PoolAction("myPool"))
.. function:: addQPSLimit(DNSrule, limit)
+ .. deprecated:: 1.2.0
+
Limit queries matching the DNSRule to ``limit`` queries per second.
All queries over the limit are dropped.
+ This function is deprecated as of 1.2.0, please use:
+
+ addAction(DNSRule, QPSLimitAction(limit))
:param DNSRule: match queries based on this rule
:param int limit: QPS limit for this rule
.. function:: addQPSPoolRule(DNSRule, limit, pool)
+ .. deprecated:: 1.2.0
+
Send at most ``limit`` queries/s for this pool, letting the subsequent rules apply otherwise.
- This is a convience function for the following syntax::
+ This function is deprecated as of 1.2.0, as it is only a convience function for the following syntax::
addAction("192.0.2.0/24", QPSPoolAction(15, "myPool")
Active Rules can be shown with :func:`showRules` and removed with :func:`rmRule`::
- > addQPSLimit("h4xorbooter.xyz.", 10)
- > addQPSLimit({"130.161.0.0/16", "145.14.0.0/16"} , 20)
- > addQPSLimit({"nl.", "be."}, 1)
+ > addAction("h4xorbooter.xyz.", QPSLimitAction(10))
+ > addAction({"130.161.0.0/16", "145.14.0.0/16"} , QPSLimitAction(20))
+ > addAction({"nl.", "be."}, QPSLimitAction(1))
> showRules()
# Matches Rule Action
0 0 h4xorbooter.xyz. qps limit to 10
_config_template = """
newServer{address="127.0.0.1:%s"}
truncateTC(true)
- addAnyTCRule()
+ addAction(AndRule{QTypeRule(dnsdist.ANY), TCPRule(false)}, TCAction())
addAction(RegexRule("evil[0-9]{4,}\\\\.regex\\\\.tests\\\\.powerdns\\\\.com$"), RCodeAction(dnsdist.REFUSED))
mySMN = newSuffixMatchNode()
mySMN:add(newDNSName("nameAndQtype.tests.powerdns.com."))
configTemplate = """
newServer{address="127.0.0.1:53"}
truncateTC(true)
- addAnyTCRule()
+ addAction(AndRule{QTypeRule(dnsdist.ANY), TCPRule(false)}, TCAction())
addAction(RegexRule("evil[0-9]{4,}\\\\.regex\\\\.tests\\\\.powerdns\\\\.com$"), RCodeAction(dnsdist.REFUSED))
mySMN = newSuffixMatchNode()
mySMN:add(newDNSName("nameAndQtype.tests.powerdns.com."))