]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Document how Lua functions can be called from YAML
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 24 Mar 2025 16:22:00 +0000 (17:22 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 24 Mar 2025 16:22:00 +0000 (17:22 +0100)
pdns/dnsdistdist/docs/advanced/luaaction.rst

index 0655f513e34433731e1f2aac9d854affc7cc12f7..b35dbe567db74a19a56debd419ec6b88312a058c 100644 (file)
@@ -1,20 +1,92 @@
 Lua actions in rules
 ====================
 
-While we can pass every packet through the :func:`blockFilter` functions, it is also possible to configure :program:`dnsdist` to only hand off some packets for Lua inspection. 
-If you think Lua is too slow for your query load, or if you are doing heavy processing in Lua, this may make sense.
+:program:`dnsdist` comes with a lot of built-in :doc:`selectors<../reference/selectors>` and :doc:`actions<../reference/actions>`, but it is also
+possible to write custom selectors and actions in Lua. Note that Lua is usually slower than built-in options written in C++, although the FFI
+and per-thread FFI options can be quite competitive, as explained in :doc:`tuning guide<tuning>`.
 
-To select specific packets for Lua attention, use :func:`addAction` with :func:`LuaAction`, or :func:`addResponseAction` with :func:`LuaResponseAction`.
+To write a custom selector in Lua, one can do:
 
-A sample configuration could look like this::
+.. code-block:: lua
 
-  function luarule(dq)
-    if(dq.qtype==35) -- NAPTR
-    then
-      return DNSAction.Pool, "abuse" -- send to abuse pool
-    else
-      return DNSAction.None, ""      -- no action
-    end
+  function luaselector(dq)
+    return dq.qtype == DNSQType.A
   end
+  addAction(LuaRule(luaselector), DropAction())
 
-  addAction(AllRule(), LuaAction(luarule))
+
+And for a custom action:
+
+.. code-block:: lua
+
+  function luapoolaction(dq)
+    return DNSAction.Pool, "abuse" -- send to abuse pool
+  end
+  addAction(AllRule(), LuaAction(luapoolaction))
+
+If the YAML configuration is used, there are three different ways of calling a Lua function. The first option is to declare the Lua function in
+a global Lua file that will loaded before the YAML configuration is parsed. This is done by creating a Lua file with the exact same name as
+the YAML configuration one, but with a ``.lua`` extension. See :doc:`../reference/yaml-settings` for more information. For example, creating
+a file named ``/etc/dnsdist/dnsdist.lua`` containing:
+
+.. code-block:: lua
+
+  function luapoolaction(dq)
+    return DNSAction.Pool, "abuse" -- send to abuse pool
+  end
+
+it is now possible to call this function from the YAML configuration at ``/etc/dnsdist/dnsdist.yml``
+
+.. code-block:: yaml
+
+  query_rules:
+    - name: "route powerdns.com to the abuse pool"
+      selector:
+        type: "QNameSet"
+        qnames:
+          - "powerdns.com."
+      action:
+        type: "Lua"
+        function_name: "luapoolaction"
+
+
+A second option is to declare the Lua code inline in the YAML configuration file, which requires returning a Lua function, which does not have to be named:
+
+.. code-block:: yaml
+
+  query_rules:
+    - name: "route powerdns.com to the abuse pool"
+      selector:
+        type: "QNameSet"
+        qnames:
+          - "powerdns.com."
+      action:
+        type: "Lua"
+        function_code: |
+          return function(dq)
+            return DNSAction.Pool, "abuse" -- send to abuse pool
+          end
+
+
+Finally the third option is to declare the Lua code in a separate file which is referenced from the YAML configuration. The separate file has to return a Lua function, as in the previous case:
+
+.. code-block:: yaml
+
+  query_rules:
+    - name: "route powerdns.com to the abuse pool"
+      selector:
+        type: "QNameSet"
+        qnames:
+          - "powerdns.com."
+      action:
+        type: "Lua"
+        function_file: "/etc/dnsdist/lua-to-pool-abuse.lua"
+
+
+where the ``/etc/dnsdist/lua-to-pool-abuse.lua`` file contains:
+
+.. code-block:: lua
+
+  return function(dq)
+    return DNSAction.Pool, "abuse" -- send to abuse pool
+  end