Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNSoverQUIC #871

Merged
merged 186 commits into from
Oct 9, 2024
Merged

DNSoverQUIC #871

merged 186 commits into from
Oct 9, 2024

Conversation

wcawijngaards
Copy link
Member

@wcawijngaards wcawijngaards commented Apr 4, 2023

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.

@gthess gthess self-assigned this Jun 26, 2024
@nekoy3
Copy link

nekoy3 commented Jul 4, 2024

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

@wcawijngaards
Copy link
Member Author

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.

@nekoy3
Copy link

nekoy3 commented Jul 5, 2024

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

@wcawijngaards
Copy link
Member Author

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.

@nekoy3
Copy link

nekoy3 commented Jul 5, 2024

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.

@zs311521
Copy link

zs311521 commented Sep 6, 2024

I have OpenSSL version 3.3.2 which natively supports QUIC.

Can I use this version? I have not yet swapped over to the forked version hoping I can use the native OpenSSL.

But the quic-port command isn't recognized

@wcawijngaards
Copy link
Member Author

I believe that only implements the client part, and the branch implements server code, with the other library.

@zs311521
Copy link

zs311521 commented Sep 6, 2024

I believe that only implements the client part, and the branch implements server code, with the other library.

Thank you.

Do you know when this will be available in the next Unbound release? Currently 1.2.1 I believe.

Also, if you are working on Upstream DoQ forwarding as well, similar to DOT?

@wcawijngaards
Copy link
Member Author

No, I do not know. The upstream part is present on plans.

@tamntm03
Copy link

tamntm03 commented Oct 1, 2024

i have a few questions. Does this installation before or after i setup an unbound resolver? because i 've done everything above but i cannot find quic -port in unbound.conf. I have installed unbound resolver before starting this and i try doqclient but it show errors ngtcp2_conn_handle_expriry fail: ERR_IDLE_CLOSE.

Please help. I'm new to unbound. I chose it to setup up DoQ lab and now im so lost.

@wcawijngaards
Copy link
Member Author

The instructions above are for compilation, you would need to compile before running the unbound server. That means using the version of the software that is compiled, and not a version that is installed from a package system. Perhaps ports are firewalled on the computer, and this is dropping all traffic, and thus timeouts, instead of a compilation problem.

@tamntm03
Copy link

tamntm03 commented Oct 1, 2024

The instructions above are for compilation, you would need to compile before running the unbound server. That means using the version of the software that is compiled, and not a version that is installed from a package system. Perhaps ports are firewalled on the computer, and this is dropping all traffic, and thus timeouts, instead of a compilation problem.

I dont think that is the case. My firewall is down and my unbound is built from source. I did restart my unbound server but it did not work (it still can perform normal query with dig but cannot perform DoQ one with /doqclient . Maybe because i built the server first then the instructions. They just dont work together.

unbound-checkconf even gives me error for putting "quic-port" in unbound.conf. So i think it is a compilation problem.

@wcawijngaards
Copy link
Member Author

Yeah the build of the server needs the result from those instructions. So the instructions are earlier, but I cannot tell what the compilation problem is, apart from that in the unbound that is attempted the doq does not seem to be present.

@tamntm03
Copy link

tamntm03 commented Oct 2, 2024

I build the server again. This time when i try to start the server, it fails and log looks like this:

[1727840988] unbound[66391:0] error: doq server socket create: no tls-service-key
[1727840988] unbound[66391:0] error: could not create doq comm_point
[1727840988] unbound[66391:0] error: can't create commpoint
[1727840988] unbound[66391:0] error: could not create listening sockets
[1727840988] unbound[66391:0] fatal error: Could not initialize main thread

Clearly it requires a tls-key. But where can i get one? Do i have to make it myself or its already somewhere in the software? Does it supposed to have tls within quic?

@wcawijngaards
Copy link
Member Author

The dnsoverquic needs tls-server-key and tls-server-pem, just like for TLS service, with the certificate for the server. This is the server public and private key files. But it looks like it is the correct code that starts from the failure.

Copy link
Member

@gthess gthess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good and the flow makes sense!
Only some review comments in two PRs in total.

Quick notes on testing:

  • tested with master merged locally
  • test iterations combining lock/mem tests and debug builds
  • tested with third-party clients which work for the most part; I'll add the results/information to the accompanying blog post when this is released.

gthess and others added 4 commits October 9, 2024 10:11
- lock_protect also for HAVE_NGTCP2_CCERR_DEFAULT
- fix doq logging for inet_ntop failures
- no value returned from msghdr_get_ecn when S_SPLINT_S is defined
@wcawijngaards wcawijngaards merged commit 3d89c26 into master Oct 9, 2024
1 check passed
wcawijngaards added a commit that referenced this pull request Oct 9, 2024
- Merge #871: DNS over QUIC. This adds `quic-port: 853` and
  `quic-size: 8m` that enable dnsoverquic, and the counters
  `num.query.quic` and `mem.quic` in the statistics output.
  The feature needs to be enabled by compiling with libngtcp2,
  with `--with-libngtcp2=path` and libngtcp2 needs openssl+quic,
  pass that with `--with-ssl=path` to compile unbound as well.
jedisct1 added a commit to jedisct1/unbound that referenced this pull request Oct 25, 2024
* nlnet/master: (24 commits)
  Add changelog entry for tag for 1.22.0rc1.
  - Tag for 1.22.0 release. This did not contain the 1154 fix   from 16 oct. The code repository continues with   version 1.22.1 in development.
  - Fix NLnetLabs#1154: Tag Incorrectly Applying for Other Interfaces   Using the Same IP. This fix is not for 1.22.0.
  - Fix for dnstap with dnscrypt and dnstap without dnsoverquic.
  - Fix for dnsoverquic and dnstap to use the correct dnstap   environment.
  - Fix dnsoverquic to extend the number of streams when one is closed.
  - Fix to display warning if quic-port is set but dnsoverquic is not   enabled when compiled.
  - Fix contrib/aaaa-filter-iterator.patch for change in call   signature for cache_fill_missing.
  - Fix harden-unverified-glue for AAAA cache_fill_missing lookups.
  - Fix to disable detection of quic configured ports when quic is   not compiled in.
  - Fix add reallocarray to alloc stats unit test, and disable   override of strdup in unbound-host, and the result of config   get option is freed properly.
  - Fix cookie_file test sporadic fails for time change during   the test.
  - Fix for dnstap compile of doqclient with doq disabled.
  Changelog entry and unit test for fix of NSEC TTL and prefetch ttl. - Fix to limit NSEC TTL for messages from cachedb. Fix to limit the   prefetch ttl for messages after a CNAME with short TTL.
  - Fix to limit NSEC TTL for messages from cachedb. Fix to limit the   prefetch ttl for messages after a CNAME with short TTL.
  Changelog note for NLnetLabs#871 - Merge NLnetLabs#871: DNS over QUIC. This adds `quic-port: 853` and   `quic-size: 8m` that enable dnsoverquic, and the counters   `num.query.quic` and `mem.quic` in the statistics output.   The feature needs to be enabled by compiling with libngtcp2,   with `--with-libngtcp2=path` and libngtcp2 needs openssl+quic,   pass that with `--with-ssl=path` to compile unbound as well.
  DNSoverQUIC (NLnetLabs#871)
  - Fix NLnetLabs#1128: Cannot override tcp-upstream and tls-upstream with   forward-tcp-upstream and forward-tls-upstream.
  - Fix NLnetLabs#1149: unbound-control-setup hangs sometimes depending on   the openssl version.
  - The fix for CVE-2024-8508 was part of 1.21.1, a security point release   on 1.21.0. The code repository continues with this fix and the version   number 1.22.0.
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.