Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
gryphius opened this issue Jan 25, 2018 · 2 comments · Fixed by #6370
Closed

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

gryphius opened this issue Jan 25, 2018 · 2 comments · Fixed by #6370
Assignees
Milestone

Comments

@gryphius
Copy link
Contributor

  • 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!

@rgacogne rgacogne added this to the auth-4.1.x milestone Feb 12, 2018
@rgacogne
Copy link
Member

Looks like a regression, possibly introduced in #5250.

@ronnybremer
Copy link

Still present in 4.1.1. Returncode 0 leads to an exception, leaving us unable to filter out records during transfer. For our sub zones this is an issue, cause many queries go to the wrong name servers (which we intent to filter out). Is there any workaround at present or a timeframe for a fix?

Thanks,

Ronny

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

Successfully merging a pull request may close this issue.

4 participants