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

dnsdist: Implement cross-protocol queries #10338

Merged
merged 47 commits into from Aug 27, 2021

Conversation

rgacogne
Copy link
Member

@rgacogne rgacogne commented Apr 28, 2021

Short description

This PR implements cross-protocol queries, allowing passing a query received over a given protocol to a backend over a different protocol. Until now, a query received over UDP was passed over UDP, TCP over TCP, DoT over TCP and DoH over UDP. This PRs implements:

  • support for outgoing DoT (DoT between dnsdist and the backend)
  • fallback to TCP in case of truncation for queries receiver over DoH
  • passing queries received over UDP and DoH to TCP or DoT.

It lacks:

  • documentation
  • tests
  • performance testing
  • TLS session resumption between dnsdist and the backend
  • a good cleanup.

Checklist

I have:

  • read the CONTRIBUTING.md document
  • compiled this code
  • tested this code
  • included documentation (including possible behaviour changes)
  • documented the code
  • added or modified regression test(s)
  • added or modified unit test(s)

@github-actions
Copy link

github-actions bot commented Jun 7, 2021

Misspellings found, please review:

  • Defaut
To accept these changes, run the following commands from this repository on this branch
pushd $(git rev-parse --show-toplevel)
perl -e '
my @expect_files=qw('".github/actions/spell-check/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"autohint dnsparser fastopen fff githubusercontent htm issuecomment proxyprotocol smb "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/expect.txt";
use File::Path qw(make_path);
make_path ".github/actions/spell-check";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"Defaut "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
popd

@github-actions
Copy link

github-actions bot commented Jun 8, 2021

Misspellings found, please review:

  • UDPDo
To accept these changes, run the following commands from this repository on this branch
pushd $(git rev-parse --show-toplevel)
perl -e '
my @expect_files=qw('".github/actions/spell-check/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"autohint dnsparser fastopen fff githubusercontent htm issuecomment proxyprotocol smb "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/expect.txt";
use File::Path qw(make_path);
make_path ".github/actions/spell-check";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"UDPDo "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
popd

@github-actions
Copy link

github-actions bot commented Jun 8, 2021

Misspellings found, please review:

  • UDPDo
To accept these changes, run the following commands from this repository on this branch
pushd $(git rev-parse --show-toplevel)
perl -e '
my @expect_files=qw('".github/actions/spell-check/expect.txt"');
@ARGV=@expect_files;
my @stale=qw('"autohint DNSDistUDPDoT dnsparser fastopen fff githubusercontent htm issuecomment proxyprotocol smb "');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
  if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
  next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spell-check/expect.txt";
use File::Path qw(make_path);
make_path ".github/actions/spell-check";
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"UDPDo "');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a) cmp lc($b)} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;'
popd

@rgacogne rgacogne marked this pull request as ready for review June 24, 2021 07:49
@rgacogne
Copy link
Member Author

Rebased to fix conflicts.

@rgacogne
Copy link
Member Author

rgacogne commented Jul 7, 2021

Rebased to fix conflicts.

@rgacogne
Copy link
Member Author

Rebased on master.

@rgacogne
Copy link
Member Author

Otto, I just requested a review from you but to be clear I don't expect you to look at the dnsdist bits, certainly not in depth. It would be nice if you could have a look at the parts that impact the recursor, like TCPIOHandler, though :)

In TLS 1.3, tickets can be sent at any moment of the TLS session,
and more importantly are not guaranteed to be sent before a few
bytes have been exchanged. In addition, GnuTLS invalidates a session
if the remote closes the connection in a unexpected way (which Python
seems to do, for example) so we can't rely on the ticket being available
at the end of the exchange either.
We now instead use callbacks so we can be notified as soon as a new
ticket arrives, and deal with it. We store inside the TLS connection
object so we can retrieve it at the end of the exchange, when
deciding whether the whole TCP connection can be reused or if we want
to tear it down and store the ticket for later resumption instead.
@rgacogne
Copy link
Member Author

Rebased to fix a conflict.

@rgacogne rgacogne merged commit 43ed01b into PowerDNS:master Aug 27, 2021
@rgacogne rgacogne deleted the ddist-downstream-tls branch August 27, 2021 08:35
@bjornfro
Copy link

Wanted to test support for outgoing DoT (DoT between dnsdist and the backend). However, does that support having a hostname(dns-record) for the DoT server? In my scenario we cannot "hardcode" to an IP-address. If so, how is that configured? I get "Error creating new server with address.....Unable to convert presentation address".

In our case the DNS record of the DoT server has two IP-addresses.

Regards, Bjorn

Trying with:
Version : 1.7.0
Release : 0.alpha0.master.594.gfc905e965.1pdns.el7

@rgacogne
Copy link
Member Author

No, that's not supported and not in target for 1.7.0, but perhaps the workarounds suggested in #10413 might help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants