Machine friendly alternative to nsupdate

Mark Andrews marka at isc.org
Wed Apr 1 13:12:22 UTC 2020



> On 1 Apr 2020, at 20:07, Petr Bena <petr at bena.rocks> wrote:
> 
> Hello,
> 
> Some preamble: Some time ago I created an open source DNS admin web GUI *1 that is basically a wrapper around dig and nsupdate that allows people with "less CLI knowledge" to easily manipulate DNS records. The main reason for this was that in our corporation we have about 400 internal DNS zones hosted on over 100 different BIND master servers, in more than 10 countries around the planet and this tool allowed us to unify the management as it allowed integration with different master servers, allow granular role based access for individual zones (integrated with LDAP groups), including some web API for our automation tools etc.
> 
> Now to the actual problem: as I said, this tool is just a wrapper around nsupdate and dig, I like it that way because it's non-invasive, unlike other similar DNS admin panels, it doesn't require ANY changes on DNS server configuration and it integrates well with other solutions already in place. The problem I have however, is, that nsupdate was created as a tool for humans, rather than machines and parsing its output and even giving it input is very hard. Plus some things don't even seem to be possible in it.
> 
> Is there any alternative to nsupdate, something that can work with XML or JSON payloads or provide output in such machine parseable format? For example, typical problem I am facing right now - is that nsupdate silently ignores things that IMHO shouldn't be ignored - for example when someone try to add a record that already exists, or try to add an A record over CNAME, nsupdate silently ignores this, even in debug output I can't see any difference, in first send the record is created, resulting in NOERROR, in second identical send, update is ignored resulting in NOERROR, so I have no way to tell users of my app that record was not in fact created or changed (because it already exists). For example:

Add a prerequisite that a CNAME RRset does not exist at the name and the nameserver will return the appropriate error code it if does (YXRRSET).

nxrrset petrbena.test.zone CNAME
add petrbena.test.zone. 600 A 0.0.0.0

If you want to add a CNAME regardless of what is already there then you need to clear the existing records as CNAME and other data can’t co-exist, the exceptions are KEY, NSEC and RRSIG records and if you care about them then you
need to do the more complicate update based on the SOA’s value.

del petrbena.test.zone.
add petrbena.test.zone. 600 CNAME this.is.test.

For more complicated conditionals you use the SOA record and do a value dependent prerequisite that it hasn’t
changed since you have determined the state of the zone.

Request the SOA, request the state of the names you care about, request the SOA and if it hasn’t changed compute
the update request with the SOA record as a prerequisite.  If the SOA changes you start the process over.  NXRRSET
would be the error code from the UPDATE request if the SOA doesn’t match.

yxrrset example.com 0 IN SOA …
changes here


> Here is operation where I first add a CNAME record and then try to add same A record (imagine two different users were doing this so user B was unaware that CNAME already exists) you can see in both cases nsupdate respond with same answer, despite record is created only in first case. And on top of that this answer is not easy to machine parse.
> 
> > debug
> > update add petrbena.test.zone. 600 CNAME this.is.test.
> > send
> Sending update to 10.15.12.17#53
> Outgoing update query:
> ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 48433
> ;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
> ;; ZONE SECTION:
> ;test.zone.            IN    SOA
> 
> ;; UPDATE SECTION:
> petrbena.test.zone.    600    IN    CNAME    this.is.test.
> 
> ;; TSIG PSEUDOSECTION:
> server. 0    ANY    TSIG    hmac-md5.sig-alg.reg.int. 1585729680 300 16 xx== 48433 NOERROR 0
> 
> 
> Reply from update query:
> ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 48433
> ;; flags: qr ra; ZONE: 1, PREREQ: 0, UPDATE: 0, ADDITIONAL: 1
> ;; ZONE SECTION:
> ;test.zone.            IN    SOA
> 
> ;; TSIG PSEUDOSECTION:
> server. 0    ANY    TSIG    hmac-md5.sig-alg.reg.int. 1585729680 300 16 xx== 48433 NOERROR 0
> 
> > update add petrbena.test.zone. 600 A 0.0.0.0
> > send
> Sending update to 10.15.12.17#53
> Outgoing update query:
> ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 30709
> ;; flags:; ZONE: 1, PREREQ: 0, UPDATE: 1, ADDITIONAL: 1
> ;; ZONE SECTION:
> ;test.zone.            IN    SOA
> 
> ;; UPDATE SECTION:
> petrbena.test.zone.    600    IN    A    0.0.0.0
> 
> ;; TSIG PSEUDOSECTION:
> 
> server. 0    ANY    TSIG    hmac-md5.sig-alg.reg.int. 1585729721 300 16 xx== 30709 NOERROR 0
> 
> 
> Is there any alternative to nsupdate that can do this? Or some newer version of nsupdate that can acomplish this?
> 
> Thanks
> 
> 
> *1 https://github.com/benapetr/dnsphpadmin
> 
> _______________________________________________
> Please visit https://lists.isc.org/mailman/listinfo/bind-users to unsubscribe from this list
> 
> bind-users mailing list
> bind-users at lists.isc.org
> https://lists.isc.org/mailman/listinfo/bind-users

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742              INTERNET: marka at isc.org



More information about the bind-users mailing list