Net::D...Unbound(3pm)

πŸ’– Net::D...Unbound(3pm) β€” bestie edition πŸ’–

okay so this page is literally from the User Contributed Perl Documentation and it's filed under Net::D...Unbound(3pm). yes the name is truncated, no we don't know why, moving on. this is a whole page about Net::DNS::Resolver::Unbound and it's genuinely so good. grab a boba, we're doing DNSSEC. πŸ§‹βœ¨


🌸 NAME 🌸

Net::DNS::Resolver::Unbound β€” a Net::DNS resolver based on libunbound. slay.


✨ SYNOPSIS ✨

        use Net::DNS;
        use Net::DNS::Resolver::Unbound;
        my $resolver = Net::DNS::Resolver::Unbound->new(...);
        my $response = $resolver->send(...);

see how chill that is? three lines and you're resolving. πŸ‘‘


πŸ¦‹ DESCRIPTION πŸ¦‹

so Net::DNS::Resolver::Unbound is built as an extension to an existing Net::DNS installation, and what it does is help you out with two big things: DNS name resolution and DNSSEC validation, all using the libunbound library that the lovely people at NLnet Labs made. 🫢

specifically, it comes for the jobs of send() and bgsend() in the Net::DNS::Resolver::Base implementation β€” like, it takes those over. main character energy fr.

but β€” and I need you to hear me on this β€” as of this writing the implementation has some significant limitations. not little ones. significant ones:

  • Selection of transport protocol and associated parameters is almost entirely at the discretion of Unbound. you're not driving, Unbound is. πŸš—
  • There is no provision for specifying DNS header flags or EDNS options in outbound packets. nope, none. don't ask.
  • It is not possible to send a pre-constructed packet to a nameserver. instead a best-effort attempt is made using (qname,qtype,qclass) extracted from the presented packet.
  • Result packet is synthesised in libunbound and not the "real thing". and in particular?? the queryID returned by Unbound is always zero. always. zero. iconic in a cursed way πŸ’€

πŸŽ€ Replacing Net::DNS::Resolver Base Class πŸŽ€

so if you drop -register into the Net::DNS::Resolver::Unbound import list, it will register itself with Net::DNS as the resolver base class. like it's volunteering. confident queen.

        use Net::DNS;
        use Net::DNS::Resolver::Unbound -register;
        my $resolver = Net::DNS::Resolver->new(...);
        my $response = $resolver->send(...);
⚠️ heads up bestie: -register is a global setting that applies to the entire program. it cannot be applied only for certain callers, it cannot be removed, and it cannot be limited by lexical scope. it's forever. it's giving commitment issues in reverse.

πŸ’… METHODS πŸ’…

new

        # Use the default configuration
        my $resolver = Net::DNS::Resolver::Unbound->new();

        # Set options in the constructor
        my $resolver = Net::DNS::Resolver::Unbound->new(
                debug_level => 2,
                defnames    => 1,
                dnsrch,     => 1,
                domain      => 'domain',
                nameservers => [ '2001:DB8::1', ... ],
                ndots       => 1,
                searchlist  => ['domain' ... ]
                );

Returns a new Net::DNS::Resolver::Unbound resolver object. and if you supply no arguments at all, new() hands you an object with the default configuration. low effort, high reward.

On Unix and Linux systems, the default values are read from the following files, in the order indicated:

    /etc/resolv.conf, $HOME/.resolv.conf, ./.resolv.conf

The following keywords are recognised in resolver configuration files:

  • nameserver β€” IP address of a name server that the resolver should query.
  • domain β€” The domain suffix to be appended to a short non-absolute name.
  • search β€” A space-separated list of domains in the desired search path.

Except for /etc/resolv.conf, files will only be read if owned by the effective userid running the program. so like, ownership check, don't get cute with it.

πŸ“Œ note note note: the domain and searchlist keywords are mutually exclusive. If both are present, the resulting behaviour is unspecified. and if neither is present, the domain is determined from the local hostname. pick a lane bestie.

nameservers

        my $DNSSEC_resolver = Net::DNS::Resolver::Unbound->new(
                nameservers => [],      # override /etc/resolv.conf
                add_ta_file => '/var/lib/unbound/root.key'
                );

        my $DNSSEC_stub = Net::DNS::Resolver::Unbound->new(
                nameservers => ['8.8.8.8', '1.1.1.1'],
                add_ta_file => '/var/lib/unbound/root.key'
                );

        my $DoT_resolver = Net::DNS::Resolver::Unbound->new(
                nameserver => '2606:4700:4700::1111@853#cloudflare-dns.com',
                nameserver => '1.1.1.1@853#cloudflare-dns.com',
                nameserver => '2001:4860:4860::8888@853#dns.google',
                nameserver => '8.8.8.8@853#dns.google',
                add_ta_file => '/var/lib/unbound/root.key',
                option  => ['tls-cert-bundle' => '/etc/ssl/cert.pem'],
                set_tls => 1
                );

        $resolver->nameservers( '::1', '127.0.0.1', ... );
        @nameservers = $resolver->nameservers;

By default, DNS queries are sent to the IP addresses listed in /etc/resolv.conf or similar platform-specific sources. that's the vibe out of the box. ✨

search, query, send, bgsend, bgbusy, bgread

See Net::DNS::Resolver. (go read that one, it's the prequel 🎬)

option

        $resolver->option( 'tls-cert-bundle' => '/etc/ssl/cert.pem' );

Set Unbound resolver (name,value) context option. that's the whole bit.

config

        $resolver->config( 'Unbound.cfg' );

This is a power-users interface that lets you specify all sorts of Unbound configuration options. all sorts!! go wild, but like, responsibly.

set_fwd

        $resolver->set_fwd( 'IP address' );

Set IPv4 or IPv6 address to which DNS queries are to be directed. The destination machine is expected to run a recursive resolver. If the proxy is not DNSSEC-capable, validation may fail. 😭 Can be called several times β€” in that case the addresses are used as backup servers. stacking them like friendship bracelets.

set_tls

        $resolver->set_tls( 0 );
        $resolver->set_tls( 1 );

Use DNS over TLS for queries to nameservers specified using set_fwd(). secure girlie behaviour. πŸ”’

set_stub

        $resolver->set_stub( 'zone', '10.1.2.3', 0 );

Add a stub zone, with given address to send to. This is for custom root hints or pointing to a local authoritative DNS server. For DNS resolvers and the 'DHCP DNS' IP address, use set_fwd(). different tool, different job, don't mix them up. 🎯

resolv_conf

        $resolver->resolv_conf( 'filename' );

Extract nameserver list from resolv.conf(5) format configuration file. Any domain, searchlist, ndots or other settings are ignored. nameservers only. that's it, that's the deal.

πŸ“Œ Note that Net::DNS builds its own nameserver list using /etc/resolv.conf or other platform-specific sources.

hosts

        $resolver->hosts( 'filename' );

Read list of hosts from the filename given, usually /etc/hosts. heads up though: these addresses are not flagged as DNSSEC secure when queried. so, you know. noted. πŸ™ˆ

add_ta

        $resolver->add_ta( 'trust anchor' );

Add a trust anchor which is a string that holds a valid DNSKEY or DS RR in RFC1035 zonefile format. yes you read that right, RFC1035.

add_ta_file

        $resolver->add_ta_file( '/var/lib/unbound/root.key' );

Pass the name of a file containing DS and DNSKEY records (as from dig or drill). πŸ“

add_ta_autr

        $resolver->add_ta_autr( 'filename' );

Add trust anchor to the given context that is tracked with RFC5011 automated trust anchor maintenance. The file is written when the trust anchor is changed. it maintains itself, we love a self-sufficient anchor. πŸ’…

trusted_keys

        $resolver->trusted_keys( 'filename' );

Pass the name of a BIND-style config file containing trusted-keys{}.

debug_out

        $resolver->debug_out( out );

Send debug output (and error output) to the specified stream. Pass a null argument to disable. The default is stderr.

debug_level

        $resolver->debug_level(0);

Set verbosity of the debug output directed to stderr. The default level 0 is off, 1 minimal, 2 detailed, 3 lots, and 4 lots more. like, it just keeps going. 4 is for the brave. πŸ”₯

async_thread

        $resolver->async_thread(1);

Set the context behaviour for asynchronous actions. Enable a call to resolve_async() to create a thread to handle work in the background. If false (by default), a process is forked to perform the work. thread or fork, choose your fighter. πŸ₯Š

        $resolver->print;
        print $resolver->string;

Prints the resolver state on the standard output. pretty. 🌈


Copyright (c)2022,2024 Dick Franks

All Rights Reserved


πŸŽ€ LICENSE πŸŽ€

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the original copyright notices appear in all copies and that both copyright notice and this permission notice appear in supporting documentation, and that the name of the author not be used in advertising or publicity pertaining to distribution of the software without specific prior written permission.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


πŸ’œ SEE ALSO πŸ’œ


and that's the whole page bestie, no cap. πŸ’–βœ¨ this one shipped with perl v5.42.3, dated 2026-08-19, and it's filed under Net::D...Unbound(3pm). go forth and resolve responsibly. πŸ¦‹πŸŒΈπŸ’…

πŸ“¦ where this page comes from