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

https-dns-proxy: init at unstable-20200419 #81365

Merged
merged 1 commit into from Apr 20, 2020

Conversation

peterhoeg
Copy link
Member

Motivation for this change

Some applications support DNS over HTTPS but using the https-dns-proxy, it is
now available to all devices on a network.

This PR was opened on a machine that used a firewall that resolves everything
via https-dns-proxy, so it works.

Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS linux)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Ensured that relevant documentation is up to date
  • Fits CONTRIBUTING.md.

@vcunat
Copy link
Member

vcunat commented Feb 29, 2020

Well, for proxying I'd generally prefer DoT over DoH, but that's certainly nothing against this PR :-)

@pvgoran
Copy link
Contributor

pvgoran commented Mar 1, 2020

Doing random review.

I was able to rebase this branch on nixos-19.09 and run the https-dns-proxy service. However, it did not work out of the box (DNS queries made by, for example, dig @127.0.0.1 -p 5053 github.com timed out).

Turns out this is because I don't have IPv6 connectivity on my machine, and https-dns-proxy only tries to use an IPv6 address for doing upstream queries, unless instructed otherwise.

I think that -4 needs to be added to https-dns-proxy options unless networking.enableIPv6 is true. This can be accomplished by adding https-dns-proxy's own enableIPv6 option which defaults to networking.enableIPv6.

Once I added -4 to extraArgs, DNS resolution worked for me.

@vcunat
Copy link
Member

vcunat commented Mar 1, 2020

Even if networking.enableIPv6 = true (and it is by default), you have no guarantee that IPv6 actually works. For mobile devices that can even change dynamically, and it's my perception that people especially want to encrypt DNS on connections like in a coffee shop, hotel, ... and those in my experience tend not to have IPv6.

@pvgoran
Copy link
Contributor

pvgoran commented Mar 1, 2020

Considering that networking.enableIPv6 is true by default, and it's far more probable to encounter a IPv4-only network rather than IPv6-only network, setting the local enableIPv6 option to false by default makes sense, indeed.

(And maybe it should be called useIPv6, or even connectViaIPv6.)

@vcunat
Copy link
Member

vcunat commented Mar 2, 2020

Yes, unless they implement the recommended approach of trying both protocols in parallel with preference to IPv6.

@peterhoeg
Copy link
Member Author

We now have preferIPv4 which is set to true by default. I haven't tried it yet but will be giving it a go tonight.

@peterhoeg peterhoeg force-pushed the p/https-dns branch 2 times, most recently from f0e3b7a to 6801c08 Compare March 2, 2020 09:35
@pvgoran
Copy link
Contributor

pvgoran commented Mar 2, 2020

I tried the new version. Now it does use -4 by default, but it still doesn't work out of the box. :( However, if I switch provider to "google", it starts working.

Upon further investigation: cloudflare-dns.com has two IPv4 addresses: 104.16.248.249 and 104.16.249.249. 104.16.248.249 one does not work for me:

> curl -H "Host: cloudflare-dns.com" https://104.16.248.249/dns-query -k -v                              ~
*   Trying 104.16.248.249:443...
* TCP_NODELAY set
* connect to 104.16.248.249 port 443 failed: Connection timed out
* Failed to connect to 104.16.248.249 port 443: Connection timed out
* Closing connection 0
curl: (28) Failed to connect to 104.16.248.249 port 443: Connection timed out

Turns out this IP is blocked by the Russian Federation government. :(

For 104.16.249.249, I receive an (empty) response, which is normal, I suppose.

Previously, this PR used Google's 8.8.8.8 for determining DoH provider IP address, and it returns 104.16.249.249 and then 104.16.248.249; so a "good" IP was used. Now, this PR uses Cloudflare's 1.1.1.1 for determining DoH provider's IP address, and it returns 104.16.248.249 and then 104.16.249.249; so a "bad" IP is used.

I don't know what would be a proper solution here. The problem is strictly local, so it could be ignored; on the other hand, it's present for a large territory. Using 8.8.8.8 as a bootstrap DNS server works as a work-around, but it's probably a random effect that shouldn't be relied upon. Defaulting provider to google would make the service work out of the box, but I would rather see cloudflare as a default. The problem would be solved if the https-dns-proxy program somehow tried multiple IPs and used the one that works, but this doesn't look like a trivial enhancement, and is outside the scope of nixpkgs.

@vcunat
Copy link
Member

vcunat commented Mar 2, 2020

Now, this PR uses Cloudflare's 1.1.1.1 for determining DoH provider's IP address, and it returns 104.16.248.249 and then 104.16.249.249; so a "bad" IP is used.

CloudFlare rotates the records randomly on each reply, precisely because some dumb clients always use the first one (even though they shouldn't act that way). We actually discussed this with them.

@pvgoran
Copy link
Contributor

pvgoran commented Mar 2, 2020

CloudFlare rotates the records randomly on each reply, precisely because some dumb clients always use the first one (even though they shouldn't act that way). We actually discussed this with them.

Ok, I tested this, and several consecutive requests to 1.1.1.1 indeed produced results in different order. 8.8.8.8 actually does the same, so I was just lucky the first time, and unlucky the second time.

stdenv.mkDerivation rec {
pname = "https_dns_proxy";
# there are no stable releases (yet?)
version = "git-20200301";
Copy link
Member

Choose a reason for hiding this comment

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

We commonly use this scheme:

Suggested change
version = "git-20200301";
version = "unstable-2020-03-01";

cfg = config.services.https-dns-proxy;

providerCfg =
if cfg.provider == "cloudflare"
Copy link
Member

@Mic92 Mic92 Mar 2, 2020

Choose a reason for hiding this comment

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

I am against hard coding this. Also this limits support to ipv4.
Can we just leave this open? I for example run https://dns.thalheim.io/dns-query.
In an option an example for cloudflare or google could be listed though.
However I would leave it up to to the user to make a choice explicitly.

Copy link
Member Author

Choose a reason for hiding this comment

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

How about a custom option? So cf, google or custom and you then need to provide the servers yourself?

Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of using custom, it's IMHO better to just make provider and (something like) dnsUrl mutually exclusive options.

Copy link
Member

@Mic92 Mic92 Mar 3, 2020

Choose a reason for hiding this comment

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

I would not add any provider option at all. I think users should educate themselves, where they sent all their DNS queries to. I would rather link to https://github.com/curl/curl/wiki/DNS-over-HTTPS#publicly-available-servers in the documentation.

@Mic92
Copy link
Member

Mic92 commented Mar 2, 2020

cc @andir

@peterhoeg
Copy link
Member Author

peterhoeg commented Mar 3, 2020 via email

@Mic92
Copy link
Member

Mic92 commented Mar 11, 2020

I can definitely follow your line of thinking but I will argue that making things accessible beats being "ideologically pure" and that it's better to give people something that works out of the box with relatively sane defaults. I mean, why even provide this considering everybody should be using tor? So what I will do is this: 1. change the PR to allow people to specify the upstream servers 2. expand on the description using the link you provided to inform people about the consequence of their choice of upstream provider If someone just does 'enable = true;' things will work. If somebody such as yourself wants to use a specific upstream, that will work too. Everybody is happy, kittens will sing and free money all around.

ok

@peterhoeg
Copy link
Member Author

This hasn't had a very high priority for me, so I've just changed the PR to only include the packaging. The module will come later.

@peterhoeg peterhoeg changed the title nixos/https-dns-proxy: system level support for DNS over HTTPS https-dns-proxy: init at unstable-20200419 Apr 20, 2020
@peterhoeg
Copy link
Member Author

@GrahamcOfBorg build https-dns-proxy

@peterhoeg peterhoeg merged commit 53c14c4 into NixOS:master Apr 20, 2020
@peterhoeg peterhoeg deleted the p/https-dns branch April 20, 2020 06:06
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

4 participants