diff --git a/bin/named/named.conf.rst b/bin/named/named.conf.rst index 25ee17cc48..68d1d8eee1 100644 --- a/bin/named/named.conf.rst +++ b/bin/named/named.conf.rst @@ -268,10 +268,10 @@ OPTIONS key-directory quoted_string; lame-ttl duration; listen-on [ port integer ] [ dscp - integer ] { + integer ] [ tls string ] { address_match_element; ... }; listen-on-v6 [ port integer ] [ dscp - integer ] { + integer ] [ tls string ] { address_match_element; ... }; lmdb-mapsize sizeval; lock-file ( quoted_string | none ); @@ -505,6 +505,16 @@ STATISTICS-CHANNELS } ]; }; +TLS +^^^ + +:: + + tls string { + cert-file quoted_string; + key-file quoted_string; + }; + TRUST-ANCHORS ^^^^^^^^^^^^^ diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index 3fac4907a7..47485165fb 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -2417,15 +2417,22 @@ for details on how to specify IP address lists. equal to 300 are treated as seconds and converted to milliseconds before applying the above limits. +.. _interfaces: + Interfaces ^^^^^^^^^^ The interfaces and ports that the server answers queries from may be -specified using the ``listen-on`` option. ``listen-on`` takes an -optional port and an ``address_match_list`` of IPv4 addresses. (IPv6 -addresses are ignored, with a logged warning.) The server listens on -all interfaces allowed by the address match list. If a port is not -specified, port 53 is used. +specified using the ``listen-on`` and ``listen-on-v6`` options. + +``listen-on`` takes an optional port, an optional TLS configuration +identifier, and an ``address_match_list`` of IPv4 addresses. (IPv6 +addresses are ignored, with a logged warning.) The server listens on all +interfaces allowed by the address match list. If a TLS configuration is +specified, ``named`` will listen for DNS-over-TLS (DoT) connections, using +the key and certificate specified in the referenced ``tls`` statement. If a +port number is not specified, the default is 53 for standard DNS and 853 +for DNS-over-TLS. Multiple ``listen-on`` statements are allowed. For example: @@ -2433,18 +2440,20 @@ Multiple ``listen-on`` statements are allowed. For example: listen-on { 5.6.7.8; }; listen-on port 1234 { !1.2.3.4; 1.2/16; }; + listen-on port 8853 tls example-tls { 4.3.2.1; }; -enables the name server on port 53 for the IP address 5.6.7.8, and -on port 1234 of an address on the machine in net 1.2 that is not -1.2.3.4. +enables the name server to listen for standard DNS queries on port 53 of the +IP address 5.6.7.8 and on port 1234 of an address on the machine in net 1.2 +that is not 1.2.3.4, and to listen for DNS-over-TLS connections on port +8853 of the IP address 4.3.2.1. -If no ``listen-on`` is specified, the server listens on port 53 on -all IPv4 interfaces. +If no ``listen-on`` is specified, the server listens for standard DNS +on port 53 of all IPv4 interfaces. -The ``listen-on-v6`` option is used to specify the interfaces and the -ports on which the server listens for incoming queries sent using -IPv6. If not specified, the server listens on port 53 on all IPv6 -interfaces. +The ``listen-on-v6`` option is used to specify the interfaces and the ports +on which the server listens for incoming queries sent using IPv6. If not +specified, the server listens for standard DNS queries on port 53 of all +IPv6 interfaces. Multiple ``listen-on-v6`` options can be used. For example: @@ -2452,11 +2461,12 @@ Multiple ``listen-on-v6`` options can be used. For example: listen-on-v6 { any; }; listen-on-v6 port 1234 { !2001:db8::/32; any; }; + listen-on port 8853 tls example-tls { 2001:db8::100; }; -enables the name server on port 53 for any IPv6 addresses (with a -single wildcard socket), and on port 1234 of IPv6 addresses that are not -in the prefix 2001:db8::/32 (with separate sockets for each matched -address). +enables the name server to listen for standard DNS queries on port 53 of +any IPv6 addresses and on port 1234 of IPv6 addresses that are not in the +prefix 2001:db8::/32, and for DNS-over-TLS connections on port 8853 of +the address 2001:db8::100. To instruct the server not to listen on any IPv6 address, use: diff --git a/doc/man/dig.1in b/doc/man/dig.1in index c4621bd7d5..51b131ec6c 100644 --- a/doc/man/dig.1in +++ b/doc/man/dig.1in @@ -518,14 +518,19 @@ This option sets [or does not set] the TC (TrunCation) bit in the query. The def \fB+notcflag\fP\&. This bit is ignored by the server for QUERY. .TP .B \fB+[no]tcp\fP -This option uses [or does not use] TCP when querying name servers. The default behavior -is to use UDP unless a type \fBany\fP or \fBixfr=N\fP query is requested, -in which case the default is TCP. AXFR queries always use TCP. +This option indicates whether to use TCP when querying name servers. +The default behavior is to use UDP unless a type \fBany\fP or \fBixfr=N\fP +query is requested, in which case the default is TCP. AXFR queries +always use TCP. .TP .B \fB+timeout=T\fP This option sets the timeout for a query to \fBT\fP seconds. The default timeout is 5 seconds. An attempt to set \fBT\fP to less than 1 is silently set to 1. .TP +.B \fB+[no]tls\fP +This option indicates whether to use DNS over TLS (DoT) when querying +name servers. +.TP .B \fB+[no]topdown\fP This feature is related to \fBdig +sigchase\fP, which is obsolete and has been removed. Use \fBdelv\fP instead. diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index cbad85bf4c..1199ac81aa 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -331,10 +331,10 @@ options { key\-directory quoted_string; lame\-ttl duration; listen\-on [ port integer ] [ dscp - integer ] { + integer ] [ tls string ] { address_match_element; ... }; listen\-on\-v6 [ port integer ] [ dscp - integer ] { + integer ] [ tls string ] { address_match_element; ... }; lmdb\-mapsize sizeval; lock\-file ( quoted_string | none ); @@ -587,6 +587,20 @@ statistics\-channels { .fi .UNINDENT .UNINDENT +.SS TLS +.INDENT 0.0 +.INDENT 3.5 +.sp +.nf +.ft C +tls string { + cert\-file quoted_string; + key\-file quoted_string; +}; +.ft P +.fi +.UNINDENT +.UNINDENT .SS TRUST\-ANCHORS .INDENT 0.0 .INDENT 3.5 diff --git a/doc/misc/options b/doc/misc/options index ef4654c84b..1f3daa904a 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -219,10 +219,10 @@ options { key-directory ; lame-ttl ; listen-on [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; // may occur multiple times listen-on-v6 [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; // may occur multiple times lmdb-mapsize ; lock-file ( | none ); @@ -459,6 +459,14 @@ statistics-channels { } ]; // may occur multiple times }; // may occur multiple times +tls { + cert-file ; + ciphers ; // not implemented + dh-param ; // not implemented + key-file ; + protocols ; // not implemented +}; // may occur multiple times + trust-anchors { ( static-key | initial-key | static-ds | initial-ds ) diff --git a/doc/misc/options.active b/doc/misc/options.active index d58a7ff4f1..6da3e4ee7a 100644 --- a/doc/misc/options.active +++ b/doc/misc/options.active @@ -196,10 +196,10 @@ options { key-directory ; lame-ttl ; listen-on [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; // may occur multiple times listen-on-v6 [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; // may occur multiple times lmdb-mapsize ; lock-file ( | none ); @@ -413,6 +413,14 @@ statistics-channels { } ]; // may occur multiple times }; // may occur multiple times +tls { + cert-file ; + ciphers ; // not implemented + dh-param ; // not implemented + key-file ; + protocols ; // not implemented +}; // may occur multiple times + trust-anchors { ( static-key | initial-key | static-ds | initial-ds ) diff --git a/doc/misc/options.grammar.rst b/doc/misc/options.grammar.rst index 5c1ea45f3c..9fef7669d3 100644 --- a/doc/misc/options.grammar.rst +++ b/doc/misc/options.grammar.rst @@ -126,10 +126,10 @@ key-directory ; lame-ttl ; listen-on [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; listen-on-v6 [ port ] [ dscp - ] { + ] [ tls ] { ; ... }; lmdb-mapsize ; lock-file ( | none ); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 87f8aaec68..b4eed89a11 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -111,6 +111,7 @@ static cfg_type_t cfg_type_optional_facility; static cfg_type_t cfg_type_optional_keyref; static cfg_type_t cfg_type_optional_port; static cfg_type_t cfg_type_optional_uint32; +static cfg_type_t cfg_type_optional_tls; static cfg_type_t cfg_type_options; static cfg_type_t cfg_type_portiplist; static cfg_type_t cfg_type_printtime; @@ -127,6 +128,7 @@ static cfg_type_t cfg_type_sizeval; static cfg_type_t cfg_type_sockaddr4wild; static cfg_type_t cfg_type_sockaddr6wild; static cfg_type_t cfg_type_statschannels; +static cfg_type_t cfg_type_tlsconf; static cfg_type_t cfg_type_view; static cfg_type_t cfg_type_viewopts; static cfg_type_t cfg_type_zone; @@ -148,6 +150,7 @@ static cfg_type_t cfg_type_tkey_dhkey = { "tkey-dhkey", cfg_parse_tuple, static cfg_tuplefielddef_t listenon_fields[] = { { "port", &cfg_type_optional_port, 0 }, { "dscp", &cfg_type_optional_dscp, 0 }, + { "tls", &cfg_type_optional_tls, 0 }, { "acl", &cfg_type_bracketed_aml, 0 }, { NULL, NULL, 0 } }; @@ -1073,6 +1076,7 @@ static cfg_clausedef_t namedconf_clauses[] = { { "primaries", &cfg_type_primaries, CFG_CLAUSEFLAG_MULTI }, { "statistics-channels", &cfg_type_statschannels, CFG_CLAUSEFLAG_MULTI }, + { "tls", &cfg_type_tlsconf, CFG_CLAUSEFLAG_MULTI }, { "view", &cfg_type_view, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } }; @@ -1134,7 +1138,7 @@ static cfg_clausedef_t options_clauses[] = { { "dnstap-output", &cfg_type_dnstapoutput, 0 }, { "dnstap-identity", &cfg_type_serverid, 0 }, { "dnstap-version", &cfg_type_qstringornone, 0 }, -#else /* ifdef HAVE_DNSTAP */ +#else /* ifdef HAVE_DNSTAP */ { "dnstap-output", &cfg_type_dnstapoutput, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "dnstap-identity", &cfg_type_serverid, CFG_CLAUSEFLAG_NOTCONFIGURED }, @@ -1154,7 +1158,7 @@ static cfg_clausedef_t options_clauses[] = { { "fstrm-set-output-queue-model", &cfg_type_fstrm_model, 0 }, { "fstrm-set-output-queue-size", &cfg_type_uint32, 0 }, { "fstrm-set-reopen-interval", &cfg_type_duration, 0 }, -#else /* ifdef HAVE_DNSTAP */ +#else /* ifdef HAVE_DNSTAP */ { "fstrm-set-buffer-hint", &cfg_type_uint32, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "fstrm-set-flush-timeout", &cfg_type_uint32, @@ -1172,7 +1176,7 @@ static cfg_clausedef_t options_clauses[] = { #endif /* HAVE_DNSTAP */ #if defined(HAVE_GEOIP2) { "geoip-directory", &cfg_type_qstringornone, 0 }, -#else /* if defined(HAVE_GEOIP2) */ +#else /* if defined(HAVE_GEOIP2) */ { "geoip-directory", &cfg_type_qstringornone, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif /* HAVE_GEOIP2 */ @@ -1745,7 +1749,7 @@ static cfg_tuplefielddef_t rpz_fields[] = { #ifdef USE_DNSRPS { "dnsrps-enable", &cfg_type_boolean, 0 }, { "dnsrps-options", &cfg_type_bracketed_text, 0 }, -#else /* ifdef USE_DNSRPS */ +#else /* ifdef USE_DNSRPS */ { "dnsrps-enable", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "dnsrps-options", &cfg_type_bracketed_text, CFG_CLAUSEFLAG_NOTCONFIGURED }, @@ -1954,7 +1958,7 @@ static cfg_clausedef_t view_clauses[] = { #ifdef USE_DNSRPS { "dnsrps-enable", &cfg_type_boolean, 0 }, { "dnsrps-options", &cfg_type_bracketed_text, 0 }, -#else /* ifdef USE_DNSRPS */ +#else /* ifdef USE_DNSRPS */ { "dnsrps-enable", &cfg_type_boolean, CFG_CLAUSEFLAG_NOTCONFIGURED }, { "dnsrps-options", &cfg_type_bracketed_text, CFG_CLAUSEFLAG_NOTCONFIGURED }, @@ -1968,7 +1972,7 @@ static cfg_clausedef_t view_clauses[] = { { "dnssec-validation", &cfg_type_boolorauto, 0 }, #ifdef HAVE_DNSTAP { "dnstap", &cfg_type_dnstap, 0 }, -#else /* ifdef HAVE_DNSTAP */ +#else /* ifdef HAVE_DNSTAP */ { "dnstap", &cfg_type_dnstap, CFG_CLAUSEFLAG_NOTCONFIGURED }, #endif /* HAVE_DNSTAP */ { "dual-stack-servers", &cfg_type_nameportiplist, 0 }, @@ -1988,7 +1992,7 @@ static cfg_clausedef_t view_clauses[] = { { "lame-ttl", &cfg_type_duration, 0 }, #ifdef HAVE_LMDB { "lmdb-mapsize", &cfg_type_sizeval, 0 }, -#else /* ifdef HAVE_LMDB */ +#else /* ifdef HAVE_LMDB */ { "lmdb-mapsize", &cfg_type_sizeval, CFG_CLAUSEFLAG_NOOP }, #endif /* ifdef HAVE_LMDB */ { "max-acache-size", &cfg_type_sizenodefault, CFG_CLAUSEFLAG_OBSOLETE }, @@ -3808,3 +3812,34 @@ cfg_print_zonegrammar(const unsigned int zonetype, unsigned int flags, pctx.indent--; cfg_print_cstr(&pctx, "};\n"); } + +/*% + * "tls" and related statement syntax. + */ +static cfg_type_t cfg_type_sslprotos = { + "sslprotos", cfg_parse_spacelist, cfg_print_spacelist, + cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring +}; + +static cfg_clausedef_t tls_clauses[] = { + { "key-file", &cfg_type_qstring, 0 }, + { "cert-file", &cfg_type_qstring, 0 }, + { "dh-param", &cfg_type_qstring, CFG_CLAUSEFLAG_NOTIMP }, + { "protocols", &cfg_type_sslprotos, CFG_CLAUSEFLAG_NOTIMP }, + { "ciphers", &cfg_type_astring, CFG_CLAUSEFLAG_NOTIMP }, + { NULL, NULL, 0 } +}; + +static cfg_clausedef_t *tls_clausesets[] = { tls_clauses, NULL }; +static cfg_type_t cfg_type_tlsconf = { "tlsconf", cfg_parse_named_map, + cfg_print_map, cfg_doc_map, + &cfg_rep_map, tls_clausesets }; + +static keyword_type_t tls_kw = { "tls", &cfg_type_astring }; +static cfg_type_t cfg_type_optional_tls = { + "tlsoptional", parse_optional_keyvalue, print_keyvalue, + doc_optional_keyvalue, &cfg_rep_string, &tls_kw +}; +static cfg_type_t cfg_type_tls = { "tls", parse_keyvalue, + print_keyvalue, doc_keyvalue, + &cfg_rep_string, &tls_kw };