Why is nsd service listening on private IPv6 address?

The rationale is that the IP address of the network interface may not be how the box is known on the public network — such as if it is behind a firewall or proxy. Machines on Amazon AWS, for instance, typically have a network interface bound to an AWS-only IP address. The network interface doesn’t know what IP address it appears as on the public internet.

The box needs to know both. The PRIVATE_IP addresses are to identify the network interfaces to bind to. We only use this for nsd though, to prevent it from clashing with the bind9 service on localhost providing local/recursive and secure (i.e. DNSSEC-enabled) DNS. [EDIT: We also use it now in postfix’s configuration so multi-homed machines send outbound mail from the IP address specified in the box’s SPF record, so that there’s no mismatch between the machine’s IP address as visible to the receiver and the IP address in the SPF record.]

The PUBLIC_IP addresses are for what to put in DNS A/AAAA records.

This logic works well for IPv4. My experience with IPv6 is much less so maybe I’m missing something there, but I expect the same sort of rationale would apply. The question is why binding to the interface’s address doesn’t let nsd get connections from the outside.