NLnetLabs / nsd

The NLnet Labs Name Server Daemon (NSD) is an authoritative, RFC compliant DNS nameserver.

Home Page:https://nlnetlabs.nl/nsd

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dynamically Generate PTR When Queried ("On the Fly")

BrunoBlanes opened this issue · comments

As per RFC 8501, I think the best-case scenario for IPv6 PTR records would be to generate them on the fly.

It is virtually impossible to generate all PTR records for a common /32 IPv6 prefix and although generating them on the fly might add some complexity if using DNSSEC, it is better than not having it.

Hi @BrunoBlanes! I guess it can be implemented, but it'll involve some work implementing this in NSD as the database is only indexed by name, so generating them on the fly when a request comes in would involve traversing all domains in memory, which can be quite a lot. The answer seems therefore to generate them during zone loading, but in that case the reverse zone may be loaded after zones that include A records that point to an IP address in that zone, so we'd need to make sure we take note of all reverse zones on startup, but as zones may be added dynamically, that doesn't cover all cases. In the latter case, we'd again have to traverse all zones, but this is something that can be documented and that'd be expected behavior. However, in both scenario's the names in multiple zones may point to a specific address, and in that case NSD would have no way to determine where the PTR should point to. For NSD, it seems most convenient to just generate the zone file with the correct PTR records as the operator/developer can include knowledge of the setup in his scripting?

All that being said, other developers may have more insight or hold a different opinion(?) @wtoorop, @wcawijngaards, any thoughts on this?

Generating the PTR record during zone loading would not work, as it could take too much memory. Also as the issue creator suggests, DNSSEC is an issue, and dynamically created data then needs a DNSSEC signature, and for that DNSSEC signing would be needed for the dynamically created record that NSD has made. Including a DNSSEC signer has made us pass up this type of functionality.

What if we define dynamic zones in configuration so whenever a request from said zone comes NSD doesn't have to go through its entire memory, it can assume it won't find it there and just generate it on the fly.
And could we maybe try it first without DNSSEC, as a beta kind of thing, and then see how much overall latency this would add to the request?

Suppose something like this:

nsd.conf

dynamic-ptr: yes
# dynamic-ptr-ttl: 86400
# ptr-domain: "example.com"
[...]

zone:
    name: "example.com"
    zonefile: "example.com.zone"

    name: "0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa"
    zonefile: "0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa.zone"
    ptr-domain: "example.com"
    dynamic-ptr-ttl: 86400
    [...]

static-ptr-zone:
    name: "9.8.7.6.5.e.f.f.f.4.3.2.1.0.0.0.0.0.0.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa"
    zonefile: "9.8.7.6.5.e.f.f.f.4.3.2.1.0.0.0.0.0.0.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa.zone"
    [...]

There'd be a setting for enabling dynamic PTR in the configuration file. When enabled, all PTR records would be dynamically generated without needing to lookup the database, unless the address matches one of the static PTR zones specified.

9.8.7.6.5.e.f.f.f.4.3.2.1.0.0.0.0.0.0.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa.zone

$ORIGIN 9.8.7.6.5.e.f.f.f.4.3.2.1.0.0.0.0.0.0.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa.
$TTL 86400

9.8.7.6.5.e.f.f.f.4.3.2.1.0.0.0.0.0.0.0.0.f.0.8.b.d.0.1.0.0.2.ip6.arpa.  IN  SOA  [...] (
        2023091101
        86400
        7200
        3600000
        86400
)

; Authoritative name servers for this zone
                                        IN      NS      ns1.example.com.
                                        IN      NS      ns2.example.com.

0                                       IN      PTR     0.example.com.
1                                       IN      PTR     1.example.com.
[...]
f                                       IN      PTR     f.example.com.

Static PTR zones would be used whenever you don't want dynamic generated ones, making it, at most, 255 PTR records long for IPv4 or sixteen for IPv6, which is much more manageable.

A few things to keep in mind:

  • When generating records, at least two methods should be available, the hexadecimal representation of the address and the hyphen-separated one which seems to be the most used.

  • There should be a ptr-domain option to specify the domain name for dynamic record generation globally or per zone file.

  • There should be a check in place to ensure that all domains specified for PTR generation are of authority of the same server that is generating the records. This is to ensure compliance with RFC 1912:

    Also, PTR records must point back to a valid A record, not an alias defined by a CNAME.

    This also means that for every dynamic generated PTR record, an A or AAAA corresponding record should also be generated. I don't think this is a problem since it wouldn't add to the latency given that it can be done in parallel to the reply for the PTR record being sent.

  • Whenever a new record is created it should be cached, so there would also need to be a dynamic-ptr-ttl variable or assume some server default. this can also be defined globally or per zone file.

  • Whenever a new static PTR zone is created the cache corresponding to that zone should be flushed to prevent old dynamic generated records from being sent instead.

  • After the TTL of a dynamic record has expired, do nothing, and keep it valid to minimize zone rewrites and DNSSEC bottleneck.

  • It would be nice to be able to have partial zone files, and it might help with this implementation. The use case would be to have the generated records be on a separate file compiled together at run time. This could also be used to better organize zones.

I'm sure this doesn't at all sum up how complex of a task this is, but I hope it serves to help you consider the feature as it would be much appreciated.

@BrunoBlanes, we value your input, but at this point in time we're not willing to implement or include this functionality. While time is a factor, the fact that it cannot be used with DNSSEC signed zones (without online signing) is the biggest. To dynamically generate PTR records, your best bet is to write a script that generates the reverse zone for you. I imagine something that queries the respective domain and generate the zone from that. If you want to make it really fancy, perhaps listening for NOTIFY is an option to make it event-based? If having these records generated by the name server is a requirement, I believe there's implementations that support it, though I haven't used it myself (maybe other readers have suggestions?). You can probably still run NSD as a secondary in that case(?) I'm sorry if my answer isn't the most helpful.