Skip to content

LUA-AXFR-SCRIPT documentation does not match behaviour in 4.1 #6228

Description

@gryphius
  • Program: Authoritative
  • Issue type: Bug report

Short description

The feature LUA-AXFR-SCRIPT in 4.1 is not consistent with documentation and seems to lack the possibility to actually filter out records.

  • Problem 1: Missing parentheses in the example (easy)
  • Problem 2: Documented returncode 0 does not actually work.
  • Problem 3: Due to problem 2, we can apparently not modify or delete existing records, only append to them.

Environment

  • Operating system: tested on ubuntu and centos
  • Software version: tested 4.1 release on Centos 7, and master (0.0.2059g9859e44) on ubuntu
  • Software source: packages from repo.powerdns.com

Steps to reproduce

  1. create a master zone example.com on a different server and allow axfr to the test system
@ 14400  IN  SOA ns.example.com. hostmaster.example.com 20181337 28800 7200 604800 86400
@   		14400  IN  NS      ns.example.com.
test		3600 IN HINFO Nexus Android

on the test system:

  1. pdnsutil create-slave-zone example.com <master-ip>

  2. create a file /etc/powerdns/test.lua with contents like in https://doc.powerdns.com/md/authoritative/modes-of-operation/

function axfrfilter(remoteip, zone, record)

   -- Replace each HINFO records with this TXT
   if record:qtype() == pdns.HINFO then
      resp = {}
      resp[1] = {
        qname   = record:qname:toString(),
        qtype   = pdns.TXT,
        ttl     = 99,
        content = "Hello Ahu!"
     }
      return 0, resp
   end

   -- Grab each _tstamp TXT record and add a time stamp
   if record:qtype() == pdns.TXT and string.starts(record:qname:toString(), "_tstamp.") then
      resp = {}
      resp[1] = {
        qname   = record:qname():toString(),
        qtype   = record:qtype(),
        ttl     = record:ttl(),
        content = os.date("Ver %Y%m%d-%H:%M")
      }
      return 0, resp
   end

   -- Append A records with this TXT
   if record:qtype() == pdns.A then
      resp = {}
      resp[1] = {
        qname   = record:qname:toString(),
        qtype   = pdns.TXT,
        ttl     = 99,
        content = "Hello Ahu, again!"
      }
      return 1, resp
   end

   resp = {}
   return -1, resp
end

function string.starts(s, start)
   return s.sub(s, 1, s.len(start)) == start
end
  1. ... and activate it:

pdnsutil set-meta example.com LUA-AXFR-SCRIPT /etc/powerdns/my.lua

  1. force a zone transfer to test:
    pdns_control retrieve example.com

Problem 1: missing parentheses in the example

Logs:

Jan 25 19:03:41 ns pdns_server[15102]: Failed to load Lua editing script '/etc/powerdns/my.lua' for incoming AXFR of 'example.com': [string "chunk"]:7: function arguments expected near ':'
  1. To fix this, replace all occurences of record:qname: with record:qname(): in my.lua and try again:

Problem 2: Return code 0 ist not actually allowed

Logs:

Jan 25 19:11:17 ns pdns_server[15102]: Unable to AXFR zone 'example.com' from remote '<munged>' (PDNSException): Cannot understand return code 0 in axfr filter response

pdns/pdns/lua-auth4.cc

Lines 115 to 121 in 4e6b74f

rcode = std::get<0>(ret);
if (rcode < 0)
return false;
else if (rcode == 1)
out.push_back(in);
else
throw PDNSException("Cannot understand return code "+std::to_string(rcode)+" in axfr filter response");
:

  1. Now, lets minimize the lua script and change the returncode to 1:
function axfrfilter(remoteip, zone, record)

   -- Replace each HINFO records with this TXT
   if record:qtype() == pdns.HINFO then
      resp = {}
      resp[1] = {
        qname   = record:qname():toString(),
        qtype   = pdns.TXT,
        ttl     = 99,
        content = "Hello Ahu!"
     }
      return 1, resp
   end

   resp = {}
   return -1, resp
end
  1. yay! The script runs, but...

Problem 3: Records can only be appended to, but not modified/ignored

if we check the database the record has been added, not replaced like we originally intended:

mysql powerdns -e 'select * from records where domain_id=6';
+-----+-----------+------------------+-------+------------------------------------------------------------------------------------+-------+------+-------------+----------+-----------+------+
| id  | domain_id | name             | type  | content                                                                            | ttl   | prio | change_date | disabled | ordername | auth |
+-----+-----------+------------------+-------+------------------------------------------------------------------------------------+-------+------+-------------+----------+-----------+------+
| 141 |         6 | example.com      | SOA   | ns.example.com hostmaster.example.com.example.com 20181337 28800 7200 604800 86400 | 14400 |    0 |        NULL |        0 | NULL      |    1 |
| 142 |         6 | example.com      | NS    | ns.example.com                                                                     | 14400 |    0 |        NULL |        0 | NULL      |    1 |
| 143 |         6 | test.example.com | HINFO | "Nexus" "Android"                                                                  |  3600 |    0 |        NULL |        0 | NULL      |    1 |
| 144 |         6 | test.example.com | TXT   | Hello Ahu!                                                                         |    99 |    0 |        NULL |        0 | NULL      |    1 |
+-----+-----------+------------------+-------+------------------------------------------------------------------------------------+-------+------+-------------+----------+-----------+------+

Long story short:

  • The current documentation does not match the behaviour of LUA-AXFR-SCRIPT
  • unless I'm missing something(*) , axfrfilter can currently not actually filter records, only append

(*) if that turns out to be the case, apologies in advance!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions