dnsjava is an implementation of DNS in Java. It
-
supports almost all defined record types (including the DNSSEC types), and unknown types.
-
can be used for queries, zone transfers, and dynamic updates.
-
includes a cache which can be used by clients, and an authoritative only server.
-
supports TSIG authenticated messages, DNSSEC verification, and EDNS0.
-
is fully thread safe.
Have a look at the basic examples.
Some settings of dnsjava can be configured via Java system properties:
Property |
Explanation |
||
---|---|---|---|
Type |
Default |
Example |
|
dns[.fallback].server |
DNS server(s) to use for resolving. Comma separated list. Can be IPv4/IPv6 addresses or hostnames (which are resolved using Java’s built in DNS support). |
||
String |
- |
8.8.8.8,[2001:4860:4860::8888]:853,dns.google |
|
dns[.fallback].search |
Comma separated list of DNS search paths. |
||
String |
- |
ds.example.com,example.com |
|
dns[.fallback].ndots |
Sets a threshold for the number of dots which must appear in a name given to resolve before an initial absolute query will be made. |
||
Integer |
1 |
2 |
|
dnsjava.options |
Comma separated key-value pairs, see dnsjava.options pairs. |
||
option list |
- |
BINDTTL,tsigfudge=1 |
|
dnsjava.configprovider.skipinit |
Set to true to disable static ResolverConfig initialization. |
||
Boolean |
false |
true |
|
dnsjava.configprovider.sunjvm.enabled |
Set to true to enable the reflection based DNS server lookup, see Limitations. |
||
Boolean |
false |
true |
|
dnsjava.udp.ephemeral.start |
First ephemeral port for UDP-based DNS queries. |
||
Integer |
49152 (Linux: 32768) |
50000 |
|
dnsjava.udp.ephemeral.end |
Last ephemeral port for UDP-based DNS queries. |
||
Integer |
65535 (Linux: 60999) |
60000 |
|
dnsjava.udp.ephemeral.use_ephemeral_port |
Use an OS-assigned ephemeral port for UDP queries. Enabling this option is insecure! Do NOT use it. |
||
Boolean |
false |
true |
|
dnsjava.lookup.max_iterations |
Maximum number of CNAMEs to follow in a chain. |
||
Integer |
16 |
20 |
|
dnsjava.lookup.use_hosts_file |
Use the system’s hosts file for lookups before resorting to a resolver. |
||
Boolean |
true |
false |
|
dnsjava.nio.selector_timeout |
Set selector timeout in milliseconds. Default/Max 1000, Min 1. |
||
Integer |
1000 |
700 |
|
dnsjava.harden_unknown_additional |
Harden against unknown records in the authority section and additional section. If disabled, such records are copied from the upstream and presented to the client together with the answer. |
||
Boolean |
True |
False |
|
DNSSEC Options |
|||
dnsjava.dnssec.keycache.max_ttl |
Maximum time-to-live (TTL) of entries in the key cache in seconds. |
||
Integer |
900 |
1800 |
|
dnsjava.dnssec.keycache.max_size |
Maximum number of entries in the key cache. |
||
Integer |
1000 |
5000 |
|
org.jitsi.dnssec.nsec3.iterations.N |
Maximum iteration count for the NSEC3 hashing function depending on the key size N. The defaults are from RFC5155. |
||
Integer |
e.g. dnsjava.dnssec.nsec3.iterations.1024=200 |
||
dnsjava.dnssec.trust_anchor_file |
The file from which the trust anchor should be loaded. The file must be formatted like a DNS zone master file. It can only contain DS or DNSKEY records. |
||
String |
- |
/etc/dnssec-root-anchors |
|
dnsjava.dnssec.digest_preference |
Defines the preferred DS record digest algorithm if a zone has registered multiple DS records. The list is comma-separated, the highest preference first. If this property is not specified, the DS record with the highest digest ID is chosen. To stay compliant with the RFCs, the mandatory digest IDs must be listed in this property. The GOST digest requires BouncyCastle on the classpath. |
||
String |
- |
2,1,4 |
|
dnsjava.dnssec.harden_algo_downgrade |
Prevent algorithm downgrade when multiple algorithms are advertised in a zone’s DS records.
If |
||
Boolean |
true |
false |
|
dnsjava.dnssec.max_validate_rrsigs |
Maximum number of RRSig records to validate until the response is considered bogus. This is limited to avoid the 'KeyTrap' vulnerability (CVE-2023-50387). |
||
Integer |
8 |
4 |
|
dnsjava.dnssec.max_ds_match_failures |
Maximum number of DS records to validate until the response is considered bogus. This is limited to avoid the 'KeyTrap' vulnerability (CVE-2023-50387). |
||
Integer |
4 |
2 |
|
dnsjava.dnssec.algorithm_enabled.ID |
Enable or disable a DS/DNSKEY algorithm.
See
RFC8624 for recommended values.
Note that algorithm number 1, |
||
Boolean |
Disable ED448:
|
||
dnsjava.dnssec.algorithm_rsa_min_key_size |
Set the minimum size, in bits, for RSA keys. |
||
Integer |
1024 |
512 |
|
dnsjava.dnssec.digest_enabled.ID |
Enable or disable a DS record digest algorithm. See RFC8624 for recommended values. |
||
Boolean |
Disable SHA.1:
|
The dnsjava.options
configuration options can also be set programmatically through the Options
class.
Please refer to the Javadoc for details.
Key | Type | Default | Explanation |
---|---|---|---|
|
Boolean |
false |
Print TTLs in BIND format |
|
Boolean |
false |
Print records in multiline format |
|
Boolean |
false |
Do not print the class of a record if it is |
|
Integer |
300 |
Sets the default TSIG fudge value (in seconds) |
|
Integer |
300 |
Sets the default SIG(0) validity period (in seconds) |
A Resolver
that uses multiple Resolver
s to send the queries, defaulting to SimpleResolver
s.
Can be configured to query the servers in a round-robin order.
Blacklists a server if it times out.
Proof-of-concept DNS over HTTP resolver, e.g. to use https://dns.google/query.
DNSSEC validating stub resolver.
Originally based on the work of the Unbound Java prototype from 2005/2006.
The Unbound prototype was stripped from all unnecessary parts, heavily modified, complemented with more than 300 unit test and found bugs were fixed.
Before the import into dnsjava, the resolver was developed as an independent library at https://github.com/ibauersachs/dnssecjava.
To migrate from dnssecjava, replace org.jitsi
with org.xbill.DNS
in Java packages and org.jitsi
with dnsjava
in property prefixes.
Validated, secure responses contain the DNS AD
-flag, while responses that failed validation return the SERVFAIL
-RCode.
Insecure responses return the actual return code without the AD
-flag set.
The reason why the validation failed or is insecure is provided as a localized string in the additional section under the record ./65280/TXT (a TXT record for the owner name of the root zone in the private query class ValidatingResolver.VALIDATION_REASON_QCLASS
).
The Extended DNS Errors (EDE, RFC8914) also provides the failure reason, although in less detail.
The examples contain a small demo.
Important
|
Do not use the
A response will need CNAME/DNAME post-processing, and DNS messages can still be manipulated with DNSSEC alone.
Subsequent processing and validation of messages is intricate and best done using the built-in ValidatingResolver standalone.LookupSession (or the legacy Lookup ) class.
|
dnsjava v3 has significant API changes compared to version 2.1.x and is neither source nor binary compatible. The most important changes are:
-
Requires at least Java 8
-
Uses slf4j for logging and thus needs
slf4j-api
on the classpath -
The command line tools were moved to the
org.xbill.DNS.tools
package -
On Windows, JNA should be on the classpath for the search path and proper DNS server finding
-
The
Resolver
API for custom resolvers has changed to useCompletionStage<Message>
for asynchronous resolving. The built-in resolvers are now fully non-blocking and do not start a thread per query anymore. -
Many methods return a
List<T>
instead of an array. Ideally, use a for-each loop. If this is not possible, callsize()
instead of usinglength
:-
Cache#findAnyRecords
-
Cache#findRecords
-
Lookup#getDefaultSearchPath
-
Message#getSectionRRsets
-
SetResponse#answers
-
ResolverConfig
-
-
RRset returns a List<T> instead of an
Iterator
. Ideally, modify your code to use a for-each loop. If this is not possible, create an iterator on the returned list:-
RRset#rrs
-
RRset#sigs
-
-
Methods using
java.util.Date
are deprecated. Use the new versions withjava.time.Instant
orjava.time.Duration
instead -
The type hierarchy of
SMIMEARecord
changed, it now inherits fromTLSARecord
and constants are shared -
Record
s are no longer marked asSerializable
after 3.0. While 3.5 reintroducedSerializable
, it is preferred to use the RFC defined serialization formats directly:-
toString()
,rrToString()
↔fromString()
-
toWire()
↔fromWire()
,newRecord()
-
-
Message
andHeader
properly supportclone()
Java versions from 1.4 to 8 can load DNS service providers at runtime. To load the dnsjava service provider, build dnsjava on JDK 8 and set the system property:
sun.net.spi.nameservice.provider.1=dns,dnsjava
This instructs the JVM to use the dnsjava service provide for DNS at the highest priority.
The functionality to load a DNS SPI was removed in JDK 9 and a replacement API was requested.
JEP 418: Internet-Address Resolution SPI reintroduces a DNS SPI. See #245 for the support status in dnsjava.
dnsjava uses Maven as the build system.
Run mvn package
from the toplevel directory to build dnsjava.
JDK 8 or higher is required.
Matt Rutherford contributed a number of unit tests, which are in the tests subdirectory.
The hierarchy under tests mirrors the org.xbill.DNS
classes.
To run the unit tests, execute mvn test
.
There is no standard way to determine what the local nameserver or DNS search path is at runtime from within the JVM. dnsjava attempts several methods until one succeeds.
-
The properties
dns.server
anddns.search
(comma delimited lists) are checked. The servers can either be IP addresses or hostnames (which are resolved using Java’s built in DNS support). -
On Unix/Solaris,
/etc/resolv.conf
is parsed. -
On Windows, if JNA is available on the classpath, the
GetAdaptersAddresses
API is used. -
On Android the
ConnectivityManager
is used (requires initialization usingorg.xbill.DNS.config.AndroidResolverConfigProvider.setContext
). -
The
sun.net.dns.ResolverConfiguration
class is queried if enabled. As of Java 16 the JVM flag--add-opens java.base/sun.net.dns=ALL-UNNAMED
(classpath) or--add-opens java.base/sun.net.dns=org.dnsjava
(modules) is also required. -
If available and no servers have been found yet, JNDI-DNS is used.
-
If still no servers have been found yet, use the fallback properties. This can be used to query e.g. a well-known public DNS server instead of localhost.
-
As a last resort,
localhost
is used as the nameserver, and the search path is empty.
Javadoc documentation can be built with mvn javadoc:javadoc
or viewed online at javadoc.io.
See the examples for some basic usage information.
dnsjava is placed under the BSD-3-Clause license.
dnsjava was started as an excuse to learn Java. It was useful for testing new features in BIND without rewriting the C resolver. It was then cleaned up and extended in order to be used as a testing framework for DNS interoperability testing. The high level API and caching resolver were added to make it useful to a wider audience. The authoritative only server was added as proof of concept.
This repository has been a mirror of the dnsjava project at Sourceforge since 2014 to maintain the Maven build for publishing to Maven Central. As of 2019-05-15, GitHub is officially the new home of dnsjava. The dnsjava-users mailing list (archive) still exists but is mostly inactive.
Please use the GitHub issue tracker and send - well tested - pull requests.
-
Brian Wellington (@bwelling), March 12, 2004
-
Various contributors, see the Changelog
-
Ingo Bauersachs (@ibauersachs), current maintainer