unbound icon indicating copy to clipboard operation
unbound copied to clipboard

DNSoverQUIC

Open wcawijngaards opened this issue 1 year ago • 19 comments

Implementation of DoQ for Unbound, DNS over QUIC transport. This implements doq for downstream, clients that query unbound server, RFC9250.

Compile this with the ngtcp2 library. And with openssl+quic. Like this:

git clone --depth 1 -b OpenSSL_1_1_1o+quic https://github.com/quictls/openssl openssl+quic
cd openssl+quic
./config enable-tls1_3 no-shared threads --prefix=/path/to/openssl+quic_install
make
make install
cd ..
git clone https://github.com/ngtcp2/ngtcp2 ngtcp2
cd ngtcp2
autoreconf -i
./configure PKG_CONFIG_PATH=$PWD/../openssl+quic_install/lib/pkgconfig LDFLAGS="-Wl,-rpath,$PWD/../openssl+quic_install/lib" --prefix=/path/to/ngtcp2_install
make
make install
cd ..
git clone -b dnsoverquic https://github.com/NLnetLabs/unbound unbound_dnsoverquic
cd unbound_dnsoverquic
./configure <other flags> --with-ssl=/path/to/openssl+quic_install --with-libngtcp2=/path/to/ngtcp2_install LDFLAGS="-Wl,-rpath -Wl,/path/to/ngtcp2_install/lib" --prefix=/path/to/unbound_install
make

With the compile, it can be turned on. This is governed by the config option in unbound.conf, quic-port: 853. When an interface is on that port number, the UDP socket receives DoQ queries.

With this unbound.conf:

interface: 127.0.0.1@2853
quic-port: 2853

Then unbound serves quic queries to localhost on the 2853 port number. Also other interfaces work, like ::1@2853. Unbound can be started attached to the console for debug, with ./unbound -d -c theconfig.conf. With -dd it prints logs to the terminal as well. Ctrl-C can exit, or send a term signal.

With make doqclient the test tool can be created to send a query. Send a query with ./doqclient -s 127.0.0.1 -p 2853 www.example.com A IN. With -v it prints more diagnostics, also unbound logs more diagnostics, also from the internals of libngtcp2, when verbosity is 4 or more. An example of output from doqclient is:

./doqclient -s 127.0.0.1 -p 2853 www.example.com A IN
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 0
;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 
;; QUESTION SECTION:
www.example.com.	IN	A

;; ANSWER SECTION:
www.example.com.	86400	IN	A	93.184.216.34
www.example.com.	86400	IN	RRSIG	A 8 3 86400 20230420234414 20230330221500 17695 example.com. DcGGeVQlXf2W91/d5SReEjVlwgJ1W67axWGLBQ6hNgsn5s0gT1pQdOE96YfDb3VP3UKUMyFwR9O7SWs7Cfue3RAs0j3S1b8rIS1CNUt4SGMAjKut3krBS/8nfpQsb8WpCII3Qv1VsCyGuIQmGCQ8wxaFIQ931uyQyloR+oVLK3M= ;{id = 17695}

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:
; EDNS: version: 0; flags: do ; udp: 1232
;; MSG SIZE  rcvd: 231
;; SERVER: 127.0.0.1 2853

It is possible to have the TCP port on the same interface as DoQ server DoT or DoH, dnsovertls or dnsoverhttp, or also serve over TCP.

The resource consumption can be configured with quic-size: 8m. More queries are turned away. The number of quic queries is output in num.query.quic in the statistics. The mem.quic statistic outputs memory used.

wcawijngaards avatar Apr 04 '23 12:04 wcawijngaards

I followed your tutorial and reported an error in ./configure of unbound_dnsoverquic. The error message is as follows. How can I solve this problem? configure: error: No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2

venus1234 avatar Aug 23 '23 14:08 venus1234

The error message is that the openssl library found by configure does not have quic support, the one in https://github.com/quictls/openssl has it.

wcawijngaards avatar Aug 23 '23 14:08 wcawijngaards

The error message is that the openssl library found by configure does not have quic support, the one in https://github.com/quictls/openssl has it.

I use this openssl. openssl-3.0.10+quic

venus1234 avatar Aug 23 '23 15:08 venus1234

Which version of ngtcp2 did you use during the implementation? I'm currently compiling unbound with the latest version of ngtcp2 and reporting some errors like this: In file included from services/mesh.c:65: ./services/listen_dnsport.h:587:39: error: field 'last_error' has incomplete type 587 | struct ngtcp2_connection_close_error last_error; | ^~~~~~~~~~

zhangyuanayuan avatar Aug 24 '23 04:08 zhangyuanayuan

Which version of ngtcp2 did you use during the implementation? I'm currently compiling unbound with the latest version of ngtcp2 and reporting some errors like this: In file included from services/mesh.c:65: ./services/listen_dnsport.h:587:39: error: field 'last_error' has incomplete type 587 | struct ngtcp2_connection_close_error last_error; | ^~~~~~~~~~

Now configure will run without an error, but make will run without an error. In file included from services/mesh.c:65: ./services/listen_dnsport.h:587:39: error: field 'last_error' has incomplete type 587 | struct ngtcp2_connection_close_error last_error; | ^~~~~~~~~~

zhangyuanayuan avatar Aug 24 '23 13:08 zhangyuanayuan

There are still some problems compiling with your modified version. The specific error message is as follows: checking for ngtcp2/ngtcp2_crypto_openssl.h... no checking for ngtcp2/ngtcp2_crypto_quictls.h... yes checking whether ngtcp2_conn_server_new is declared... yes checking whether ngtcp2_crypto_encrypt_cb is declared... yes checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_openssl... no checking for ngtcp2_crypto_encrypt_cb in -lngtcp2_crypto_quictls... yes checking for ngtcp2_crypto_encrypt_cb... yes checking for ngtcp2_ccerr_default... yes checking for SSL_is_quic... no configure: error: No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.

venus1234 avatar Aug 24 '23 14:08 venus1234

The fixes updates the code branch from a libngtcp2 version of slightly after 0.5 from its code repository, to a version of slightly after 0.18 from its code repository. The unit test works with the new version. That should fix the initial configure stage error and the incomplete type errors.

Also this compiles with openssl-3.0.10+quic and this works here. The SSL_is_quic test does not fail here, something must be wrong; perhaps try again with the extra code fixes, or look in the output of config.log - the part that is pertinent for the SSL_is_quic test, search in there for it, and the compile command line of the test and the error output of the compiler could give more information.

wcawijngaards avatar Aug 25 '23 07:08 wcawijngaards

How do I get a certificate that can be used for testing? I try to generate a certificate with openssl in OpenSSL-3.0.10 +quic, but I always get the following error:

[root@localhost unbound_dnsoverquic_my]# ./unbound -dd [1692538673] unbound[36447:0] info: is quic called, ::1 2853 2853 [1692538673] unbound[36447:0] info: is quic called, 127.0.0.1 2853 2853 [1692538673] unbound[36447:0] notice: init module 0: validator [1692538673] unbound[36447:0] notice: init module 1: iterator [1692538673] unbound[36447:0] error: doq: error for cert file: /root/key/quic_certificate.pem [1692538673] unbound[36447:0] error: doq: error in SSL_CTX_use_certificate_chain_file crypto error:80000002:system library::No such file or directory [1692538673] unbound[36447:0] error: and additionally crypto error:10080002:BIO routines::system lib [1692538673] unbound[36447:0] error: and additionally crypto error:0A080002:SSL routines::system lib [1692538673] unbound[36447:0] error: doq: error for cert file: /root/key/quic_certificate.pem [1692538673] unbound[36447:0] error: doq: error in SSL_CTX_use_certificate_chain_file crypto error:80000002:system library::No such file or directory [1692538673] unbound[36447:0] error: and additionally crypto error:10080002:BIO routines::system lib [1692538673] unbound[36447:0] error: and additionally crypto error:0A080002:SSL routines::system lib [1692538673] unbound[36447:0] info: start of service (unbound 1.17.2). ^C[1692538679] unbound[36447:0] info: service stopped (unbound 1.17.2). [1692538679] unbound[36447:0] info: server stats for thread 0: 0 queries, 0 answers from cache, 0 recursions, 0 prefetch, 0 rejected by ip ratelimiting [1692538679] unbound[36447:0] info: server stats for thread 0: requestlist max 0 avg 0 exceeded 0 jostled 0

RangerDuan avatar Aug 26 '23 08:08 RangerDuan

The log output contains a debug message, the commit removes it. It also explains that the file does not exist.

Perhaps chroot: somedir is enabled, it is enabled by default, and this modifies the paths unbound uses. Put the file inside the chroot, perhaps.

wcawijngaards avatar Aug 28 '23 08:08 wcawijngaards

The log output contains a debug message, the commit removes it. It also explains that the file does not exist.

Perhaps chroot: somedir is enabled, it is enabled by default, and this modifies the paths unbound uses. Put the file inside the chroot, perhaps.

Your inference is correct. I disabled chroot by modifying the conf file and now it works. Thks :)

RangerDuan avatar Aug 29 '23 06:08 RangerDuan

ssl.h: No such file or directory 95 | #include <ngtcp2/ngtcp2_crypto_openssl.h> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ compilation terminated. make: *** [Makefile:323: listen_dnsport.lo] Error 1

This is because the latest version removes openssl specific libs, I think git checkout 1d0cad6697992cf71661e69a6cccb347f63e4aaa should work for ngtcp2.

Tomatcree01 avatar Sep 25 '23 00:09 Tomatcree01

With ngtcp2-0.19.1, available from the releases and tags, together with openssl+quic, the code works with this API. That uses nghttp3-0.15.0 for the examples in ngtcp2, by the way. Since the configure script detects a number of changes, it could also work for some other, intermediate, versions.

wcawijngaards avatar Oct 16 '23 07:10 wcawijngaards

@gthess any update on this?

sanderdewit avatar Dec 23 '23 22:12 sanderdewit

This is pending review from my part to then go into the next feature release. Due to other developments, I will refocus on this on January.

gthess avatar Dec 27 '23 20:12 gthess

Hello, I'm in a similar situation to venus1234, where I get an error that QUIC isn't supported.

configure: error: No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.

Below is the log related to SSL_is_quic.

configure:21910: checking for SSL_is_quic configure:21910: gcc -o conftest -g -O2 -D_GNU_SOURCE -flto -I/usr/local/include -I/path/to/ngtcp2_install/include -Wl,-rpath -Wl,/path/to/ngtcp2_install/lib -L/usr/local/lib -L/path/to/ngtcp2_install/lib conftest.c -lcrypto -lngtcp2 >&5 /usr/bin/ld: /tmp/cc6EkE5f.ltrans0.ltrans.o: in function main': /home/nekoy/unbound_dnsoverquic/conftest.c:193: undefined reference to SSL_is_quic' collect2: error: ld returned 1 exit status configure:21910: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "unbound" | #define PACKAGE_TARNAME "unbound" | #define PACKAGE_VERSION "1.19.4" | #define PACKAGE_STRING "unbound 1.19.4" | #define PACKAGE_BUGREPORT "[email protected] or https://github.com/NLnetLabs/unbound/issues"
| #define PACKAGE_URL "" | #define CONFCMDLINE "--with-libngtcp2=/path/to/ngtcp2_install LDFLAGS=-Wl,-rpath -Wl,/path/to/ngtcp2_install/lib --prefix=/path/to/unbound_install" | #define HAVE_STDIO_H 1 | #define HAVE_STDLIB_H 1 | #define HAVE_STRING_H 1 ... | #if defined __stub_SSL_is_quic || defined __stub___SSL_is_quic | choke me | #endif | | int | main (void) | { | return SSL_is_quic (); | ; | return 0; | } configure:21910: result: no configure:21917: error: No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2. ... ac_cv_func_SSL_is_quic=no

nekoy3 avatar Jul 04 '24 08:07 nekoy3

The check indicates that the openssl+quic version is not detected. That has the function that is looked for. If the openssl+quic version is in use, the error makes it seem like '--disable-flto' could fix the issue, if the lto optimization is causing it.

So, using the system default openssl version is not likely to work, as that does not have the quic functionality.

wcawijngaards avatar Jul 04 '24 08:07 wcawijngaards

I tried the --disable-flto option immediately, but got the same result.

Also, I found out that the default OpenSSL doesn't support QUIC, so I installed the QUIC-compatible version yesterday, but it didn't improve anything.

$ openssl version OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

below is the log again. configure:21910: checking for SSL_is_quic configure:21910: gcc -o conftest -g -O2 -D_GNU_SOURCE -I/path/to/openssl+quic_install/include -I/path/to/ngtcp2_install/include -Wl,-rpath -Wl,/path/to/ngtcp2_install/lib -L/path/to/openssl+quic_install/lib -L/path/to/ngtcp2_install/lib conftest.c -lcrypto -lngtcp2 >&5 /usr/bin/ld: /tmp/cclsRvi8.o: in function main': /home/nekoy/unbound_dnsoverquic/conftest.c:188: undefined reference to SSL_is_quic' collect2: error: ld returned 1 exit status

nekoy3 avatar Jul 05 '24 09:07 nekoy3

Is that the openssl that is just a version increase, where openssl has more quic support. But what the code needs is the openssl version from the branch of code, linked at the top post, that has the quic functions that are used by libngtcp2. That prints a version line like OpenSSL <version>+quic. If this is an install of that line of versions, then there is a failure in the configure detection logic possibly, but I think, since the version line is wrong, it is likely the openssl version.

wcawijngaards avatar Jul 05 '24 09:07 wcawijngaards

I'm sorry for all the fuss. I seem to have forgotten to change the /path/to... I was able to set it up successfully. Thank you.

nekoy3 avatar Jul 05 '24 10:07 nekoy3