diff --git a/bin/named/config.c b/bin/named/config.c index 72094f8302..123e277349 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -94,6 +94,7 @@ options {\n\ # pid-file \"" NAMED_LOCALSTATEDIR "/run/named/named.pid\"; \n\ port 53;\n\ tls-port 853;\n\ + https-port 443;\n\ prefetch 2 9;\n\ recursing-file \"named.recursing\";\n\ recursive-clients 1000;\n\ diff --git a/bin/named/include/named/globals.h b/bin/named/include/named/globals.h index 501bedaea4..3671211bb9 100644 --- a/bin/named/include/named/globals.h +++ b/bin/named/include/named/globals.h @@ -73,6 +73,7 @@ EXTERN const char *named_g_configargs INIT(PACKAGE_CONFIGARGS); EXTERN const char *named_g_builder INIT(PACKAGE_BUILDER); EXTERN in_port_t named_g_port INIT(0); EXTERN in_port_t named_g_tlsport INIT(0); +EXTERN in_port_t named_g_http_secure_port INIT(0); EXTERN isc_dscp_t named_g_dscp INIT(-1); EXTERN named_server_t *named_g_server INIT(NULL); diff --git a/bin/named/main.c b/bin/named/main.c index eacb18cc81..c803934859 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -705,7 +705,7 @@ parse_T_opt(char *option) { static void parse_port(char *arg) { - enum { DNSPORT, TLSPORT } ptype = DNSPORT; + enum { DNSPORT, TLSPORT, HTTP_SECURE_PORT } ptype = DNSPORT; char *value = arg; int port; @@ -714,6 +714,9 @@ parse_port(char *arg) { } else if (strncmp(arg, "tls=", 4) == 0) { value = arg + 4; ptype = TLSPORT; + } else if (strncmp(arg, "https=", 6) == 0) { + value = arg + 6; + ptype = HTTP_SECURE_PORT; } port = parse_int(value, "port"); @@ -728,6 +731,9 @@ parse_port(char *arg) { case TLSPORT: named_g_tlsport = port; break; + case HTTP_SECURE_PORT: + named_g_http_secure_port = port; + break; default: INSIST(0); ISC_UNREACHABLE(); diff --git a/bin/named/named.conf.rst b/bin/named/named.conf.rst index 722c514dbc..2ba2f2f6bc 100644 --- a/bin/named/named.conf.rst +++ b/bin/named/named.conf.rst @@ -264,6 +264,12 @@ OPTIONS glue-cache boolean;// deprecated heartbeat-interval integer; hostname ( quoted_string | none ); + https-endpoint quoted_string https-server string; + https-port integer; + https-server string [ port integer ] tls string { ( + quoted_string [ port integer ] [ dscp integer ] | + ipv4_address [ port integer ] [ dscp integer ] | + ipv6_address [ port integer ] [ dscp integer ] ); ... }; inline-signing boolean; interface-interval duration; ipv4only-contact string; @@ -652,6 +658,7 @@ VIEW forwarders [ port integer ] [ dscp integer ] { ( ipv4_address | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; glue-cache boolean;// deprecated + https-endpoint quoted_string https-server string; inline-signing boolean; ipv4only-contact string; ipv4only-enable boolean; diff --git a/bin/named/named.rst b/bin/named/named.rst index 9b039cdbf0..c2b19f6dd6 100644 --- a/bin/named/named.rst +++ b/bin/named/named.rst @@ -115,7 +115,9 @@ Options ``portnum``; if not not specified, the default is port 53. If ``value`` is of the form ``tls=``, the server will listen for TLS queries on ``portnum``; the default is 853. - + If ``value`` is of the form ``https=``, the server will + listen for HTTPS queries on ``portnum``; the default is 443. + ``-s`` This option writes memory usage statistics to ``stdout`` on exit. diff --git a/bin/tests/system/checkconf/good-doh-global.conf b/bin/tests/system/checkconf/good-doh-global.conf new file mode 100644 index 0000000000..83711d6329 --- /dev/null +++ b/bin/tests/system/checkconf/good-doh-global.conf @@ -0,0 +1,21 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +tls local-tls { + key-file "key.pem"; + cert-file "cert.pem"; +}; + +options { + listen-on { 10.53.0.1; }; + https-server local-server port 443 tls local-tls { 10.53.0.1; }; + https-endpoint "/dns-query" https-server local-server; +}; diff --git a/bin/tests/system/checkconf/good-doh-view.conf b/bin/tests/system/checkconf/good-doh-view.conf new file mode 100644 index 0000000000..cdbce79741 --- /dev/null +++ b/bin/tests/system/checkconf/good-doh-view.conf @@ -0,0 +1,24 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +tls local-tls { + key-file "key.pem"; + cert-file "cert.pem"; +}; + +options { + listen-on { 10.53.0.1; }; + https-server local-server port 443 tls local-tls { 10.53.0.1; }; +}; + +view one { + https-endpoint "/dns-query" https-server local-server; +}; diff --git a/bin/tests/system/checkconf/good-dot-global.conf b/bin/tests/system/checkconf/good-dot-global.conf new file mode 100644 index 0000000000..2a1729752d --- /dev/null +++ b/bin/tests/system/checkconf/good-dot-global.conf @@ -0,0 +1,19 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +tls local-tls { + key-file "key.pem"; + cert-file "cert.pem"; +}; + +options { + listen-on port 853 tls local-tls { 10.53.0.1; }; +}; diff --git a/bin/tests/system/conf.sh.common b/bin/tests/system/conf.sh.common index de998c050e..df88dd1d10 100644 --- a/bin/tests/system/conf.sh.common +++ b/bin/tests/system/conf.sh.common @@ -668,6 +668,7 @@ copy_setports() { atsign="@" sed -e "s/${atsign}PORT${atsign}/${PORT}/g" \ -e "s/${atsign}TLSPORT${atsign}/${TLSPORT}/g" \ + -e "s/${atsign}HTTPSPORT${atsign}/${HTTPSPORT}/g" \ -e "s/${atsign}EXTRAPORT1${atsign}/${EXTRAPORT1}/g" \ -e "s/${atsign}EXTRAPORT2${atsign}/${EXTRAPORT2}/g" \ -e "s/${atsign}EXTRAPORT3${atsign}/${EXTRAPORT3}/g" \ diff --git a/bin/tests/system/get_ports.sh b/bin/tests/system/get_ports.sh index eac854d65c..f63ba47253 100755 --- a/bin/tests/system/get_ports.sh +++ b/bin/tests/system/get_ports.sh @@ -82,6 +82,7 @@ done echo "export PORT=$(get_port "$baseport")" echo "export TLSPORT=$(get_port)" +echo "export HTTPSPORT=$(get_port)" echo "export EXTRAPORT1=$(get_port)" echo "export EXTRAPORT2=$(get_port)" echo "export EXTRAPORT3=$(get_port)" diff --git a/bin/tests/system/run.sh.in b/bin/tests/system/run.sh.in index e802332c8c..3802181762 100644 --- a/bin/tests/system/run.sh.in +++ b/bin/tests/system/run.sh.in @@ -149,7 +149,7 @@ stop_servers() { echostart "S:$systest:$(date_with_args)" echoinfo "T:$systest:1:A" echoinfo "A:$systest:System test $systest" -echoinfo "I:$systest:PORTS:${PORT},${TLSPORT},${EXTRAPORT1},${EXTRAPORT2},${EXTRAPORT3},${EXTRAPORT4},${EXTRAPORT5},${EXTRAPORT6},${EXTRAPORT7},${EXTRAPORT8},${CONTROLPORT}" +echoinfo "I:$systest:PORTS:${PORT},${TLSPORT},${HTTPSPORT},${EXTRAPORT1},${EXTRAPORT2},${EXTRAPORT3},${EXTRAPORT4},${EXTRAPORT5},${EXTRAPORT6},${EXTRAPORT7},${EXTRAPORT8},${CONTROLPORT}" $PERL ${srcdir}/testsock.pl -p "$PORT" || { echowarn "I:$systest:Network interface aliases not set up. Skipping test." diff --git a/doc/arm/reference.rst b/doc/arm/reference.rst index f3599be319..b699da9171 100644 --- a/doc/arm/reference.rst +++ b/doc/arm/reference.rst @@ -1078,6 +1078,14 @@ default is used. the default is the ``named`` working directory. See :ref:`acl` for details about ``geoip`` ACLs. +.. _https_endpoint: + +``https-endpoint`` + This configures an DNS-over-HTTPS service endpoint. It takes a string + which specifies the endpoint URL path, and an ``https-server`` + parameter specifying the server name of an HTTPS listener. (See + :ref:`Link title `.) + ``key-directory`` This is the directory where the public and private DNSSEC key files should be found when performing a dynamic update of secure zones, if different @@ -2436,6 +2444,8 @@ Interfaces The interfaces and ports that the server answers queries from may be specified using the ``listen-on`` and ``listen-on-v6`` options. +specified using the ``listen-on`` and ``listen-on-v6`` options, as +well as the ``https-server`` option for HTTPS queries. ``listen-on`` takes an optional port, an optional TLS configuration identifier, and an ``address_match_list`` of IPv4 addresses. (IPv6 @@ -2488,6 +2498,15 @@ To instruct the server not to listen on any IPv6 addresses, use: listen-on-v6 { none; }; +.. _https_server: + +``https-server`` takes a server name, an optional port, a TLS +configuration identifier, and an ``address_match_list`` of both IPv4 and +IPv6 addresses. This sets up an HTTPS responder using the key and +certificate specified in the referenced ``tls`` statement. The endpoint +for incoming HTTPS queries must be specified using the ``https-endpoint`` +option (see :ref:`Link title `). + .. _query_address: Query Address diff --git a/doc/man/named.8in b/doc/man/named.8in index db3ddd4176..f758454cde 100644 --- a/doc/man/named.8in +++ b/doc/man/named.8in @@ -115,6 +115,8 @@ for queries. If \fBvalue\fP is of the form \fB\fP or \fBportnum\fP; if not not specified, the default is port 53. If \fBvalue\fP is of the form \fBtls=\fP, the server will listen for TLS queries on \fBportnum\fP; the default is 853. +If \fBvalue\fP is of the form \fBhttps=\fP, the server will +listen for HTTPS queries on \fBportnum\fP; the default is 443. .TP .B \fB\-s\fP This option writes memory usage statistics to \fBstdout\fP on exit. diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index 7884fd5f28..ac9d03ded3 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -327,6 +327,12 @@ options { glue\-cache boolean;// deprecated heartbeat\-interval integer; hostname ( quoted_string | none ); + https\-endpoint quoted_string https\-server string; + https\-port integer; + https\-server string [ port integer ] tls string { ( + quoted_string [ port integer ] [ dscp integer ] | + ipv4_address [ port integer ] [ dscp integer ] | + ipv6_address [ port integer ] [ dscp integer ] ); ... }; inline\-signing boolean; interface\-interval duration; ipv4only\-contact string; @@ -747,6 +753,7 @@ view string [ class ] { forwarders [ port integer ] [ dscp integer ] { ( ipv4_address | ipv6_address ) [ port integer ] [ dscp integer ]; ... }; glue\-cache boolean;// deprecated + https\-endpoint quoted_string https\-server string; inline\-signing boolean; ipv4only\-contact string; ipv4only\-enable boolean; diff --git a/doc/misc/options b/doc/misc/options index 1e5bedec9c..c1fd824808 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -193,6 +193,12 @@ options { glue-cache ; // deprecated heartbeat-interval ; hostname ( | none ); + https-endpoint https-server ; + https-port ; + https-server [ port ] tls { ( + [ port ] [ dscp ] | + [ port ] [ dscp ] | + [ port ] [ dscp ] ); ... }; inline-signing ; interface-interval ; ipv4only-contact ; @@ -541,6 +547,7 @@ view [ ] { forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; glue-cache ; // deprecated + https-endpoint https-server ; inline-signing ; ipv4only-contact ; ipv4only-enable ; diff --git a/doc/misc/options.active b/doc/misc/options.active index 0e007d6855..2bafa0664e 100644 --- a/doc/misc/options.active +++ b/doc/misc/options.active @@ -192,6 +192,12 @@ options { glue-cache ; // deprecated heartbeat-interval ; hostname ( | none ); + https-endpoint https-server ; + https-port ; + https-server [ port ] tls { ( + [ port ] [ dscp ] | + [ port ] [ dscp ] | + [ port ] [ dscp ] ); ... }; inline-signing ; interface-interval ; ipv4only-contact ; @@ -538,6 +544,7 @@ view [ ] { forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; glue-cache ; // deprecated + https-endpoint https-server ; inline-signing ; ipv4only-contact ; ipv4only-enable ; diff --git a/doc/misc/options.grammar.rst b/doc/misc/options.grammar.rst index 30aee7b7c9..5e8d8d04f5 100644 --- a/doc/misc/options.grammar.rst +++ b/doc/misc/options.grammar.rst @@ -119,6 +119,12 @@ glue-cache ; // deprecated heartbeat-interval ; hostname ( | none ); + https-endpoint https-server ; + https-port ; + https-server [ port ] tls { ( + [ port ] [ dscp ] | + [ port ] [ dscp ] | + [ port ] [ dscp ] ); ... }; inline-signing ; interface-interval ; ipv4only-contact ; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index c18196ea5b..75e81cd297 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -91,6 +91,8 @@ static cfg_type_t cfg_type_dnstap; static cfg_type_t cfg_type_dnstapoutput; static cfg_type_t cfg_type_dyndb; static cfg_type_t cfg_type_plugin; +static cfg_type_t cfg_type_http_secure_endpoint; +static cfg_type_t cfg_type_http_secure_server; static cfg_type_t cfg_type_ixfrdifftype; static cfg_type_t cfg_type_ixfrratio; static cfg_type_t cfg_type_key; @@ -1205,6 +1207,7 @@ static cfg_clausedef_t options_clauses[] = { { "host-statistics", NULL, CFG_CLAUSEFLAG_ANCIENT }, { "host-statistics-max", NULL, CFG_CLAUSEFLAG_ANCIENT }, { "hostname", &cfg_type_qstringornone, 0 }, + { "https-server", &cfg_type_http_secure_server, 0 }, { "interface-interval", &cfg_type_duration, 0 }, { "keep-response-order", &cfg_type_bracketed_aml, 0 }, { "listen-on", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI }, @@ -1221,6 +1224,7 @@ static cfg_clausedef_t options_clauses[] = { { "pid-file", &cfg_type_qstringornone, 0 }, { "port", &cfg_type_uint32, 0 }, { "tls-port", &cfg_type_uint32, 0 }, + { "https-port", &cfg_type_uint32, 0 }, { "querylog", &cfg_type_boolean, 0 }, { "random-device", &cfg_type_qstringornone, 0 }, { "recursing-file", &cfg_type_qstring, 0 }, @@ -1988,6 +1992,7 @@ static cfg_clausedef_t view_clauses[] = { { "filter-aaaa-on-v4", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT }, { "filter-aaaa-on-v6", &cfg_type_boolean, CFG_CLAUSEFLAG_ANCIENT }, { "glue-cache", &cfg_type_boolean, CFG_CLAUSEFLAG_DEPRECATED }, + { "https-endpoint", &cfg_type_http_secure_endpoint, 0 }, { "ipv4only-enable", &cfg_type_boolean, 0 }, { "ipv4only-contact", &cfg_type_astring, 0 }, { "ipv4only-server", &cfg_type_astring, 0 }, @@ -3853,3 +3858,35 @@ 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 }; + +static keyword_type_t servername_kw = { "https-server", &cfg_type_astring }; +static cfg_type_t cfg_type_servername = { "servername", parse_keyvalue, + print_keyvalue, doc_keyvalue, + &cfg_rep_string, &servername_kw }; + +/* http-endpoint */ +static cfg_tuplefielddef_t endpoint_fields[] = { + { "path", &cfg_type_qstring, 0 }, + { "servername", &cfg_type_servername, 0 }, + { NULL, NULL, 0 } +}; +static cfg_type_t cfg_type_http_secure_endpoint = { + "endpoint", cfg_parse_tuple, cfg_print_tuple, + cfg_doc_tuple, &cfg_rep_tuple, endpoint_fields +}; + +/* http-server */ +static cfg_tuplefielddef_t server_fields[] = { + { "name", &cfg_type_astring, 0 }, + { "port", &cfg_type_optional_port, 0 }, + { "tls", &cfg_type_tls, 0 }, + { "addresses", &cfg_type_bracketed_sockaddrnameportlist, 0 }, + { NULL, NULL, 0 } +}; +static cfg_type_t cfg_type_http_secure_server = { + "server", cfg_parse_tuple, cfg_print_tuple, + cfg_doc_tuple, &cfg_rep_tuple, server_fields +};