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

resolved: Don't use domain-limited DNS servers for other queries #3421

Closed
1 of 2 tasks
martinpitt opened this issue Jun 2, 2016 · 1 comment
Closed
1 of 2 tasks
Assignees
Labels
bug 🐛 Programming errors, that need preferential fixing resolve

Comments

@martinpitt
Copy link
Contributor

Submission type

  • Bug report
  • Request for enhancement (RFE)

NOTE: Do not submit anything other than bug reports or RFEs via the issue tracker!

systemd version the issue has been seen with

230

Used distribution

Debian unstable

This is closely related to issue #3420. If you have a .network unit with domain-limited DNS servers, then that DNS server also gets queries which do not match the Domains= ~... list, even if ~. is not in the list. This is at least a privacy violation, but might also cause lookup loops and is generally not expected to work anyway -- after all, you specifically configured it to not apply to every domain. This can be demonstrated in an nspawn container with --private-network (it's not container specific at all, but this avoids having to hack up your actual system):

  • Let's first create a device which acts as your "normal" internet connection:

    # mkdir -p /run/systemd/network/
    # cat <<EOF > /run/systemd/network/global.netdev 
    [NetDev]
    Name=dummy0
    Kind=dummy
    MACAddress=12:34:56:78:9a:bc
    EOF
    
    # cat <<EOF > /run/systemd/network/global.network 
    [Match]
    Name=dummy0
    [Network]
    Address=192.168.1.1
    DNS=192.168.1.1
    EOF
    
  • Now create a device which acts your "company VPN":

    # cat <<EOF > /run/systemd/network/myvpn.netdev  
    [NetDev]
    Name=dummy1
    Kind=dummy
    MACAddress=12:34:56:78:9a:bd
    EOF
    
    # cat <<EOF > /run/systemd/network/myvpn.network 
    [Match]
    Name=dummy1
    [Network]
    Address=10.0.1.20
    DNS=10.0.1.1
    Domains= ~company
    EOF
    
  • Create the devices: # systemctl restart systemd-networkd

  • This also reproduces issue domain-limited DNS servers should not appear as global nameservers in resolved's resolv.conf #3420: /run/systemd/resolve/resolv.conf now has nameserver 192.168.1.1 (correct), and also nameserver 10.0.1.1 (that's wrong).

  • Launch

     strace -vvs1024 -e connect,sendto -p `pgrep -f systemd-resolved`
    

    to see which servers resolved is talking to.

  • for a "company" address, the behaviour is correct and it only uses the 10.0.1.1 server:

    # systemd-resolve foo.company
    connect(17, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.0.1.1")}, 16) = 0
    
  • However, for an unrelated address, both the global and the ~company name server are contacted:

    # systemd-resolve google.com
    connect(18, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("10.0.1.1")}, 16) = 0
    connect(17, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.1.1")}, 16) = 0
    

(The operations will time out of course as these are bogus servers, but that's not the point here).

@martinpitt martinpitt self-assigned this Jun 28, 2016
@martinpitt martinpitt added the bug 🐛 Programming errors, that need preferential fixing label Jun 28, 2016
martinpitt added a commit to martinpitt/systemd that referenced this issue Jun 28, 2016
DNS servers which have route-only domains without "~." should only be used for
the specified domains. Routing queries about other domains there is a privacy
violation, prone to fail (as that DNS server was not meant to be used for other
domains), and puts unnecessary load onto that server. As documented, adding
"~." to Domains= is the way to describe "use that server for all domains",
i.  e. make it a global name server.

Introduce a new helper function dns_server_limited_domains() that checks if the
DNS server should only be used for some selected domains, i. e. has some
route-only domains without "~.". Use that when determining whether to query it
in the scope, and when writing resolv.conf.

Extend the test_route_only_dns() case to ensure that the DNS server limited to
~company does not appear in resolv.conf. Add test_route_only_dns_all_domains()
to ensure that a server that also has ~. does appear in resolv.conf as global
name server.

Fixes systemd#3420
Fixes systemd#3421
martinpitt added a commit to martinpitt/systemd that referenced this issue Jun 30, 2016
DNS servers which have route-only domains without "~." should only be used for
the specified domains. Routing queries about other domains there is a privacy
violation, prone to fail (as that DNS server was not meant to be used for other
domains), and puts unnecessary load onto that server. As documented, adding
"~." to Domains= is the way to describe "use that server for all domains",
i.  e. make it a global name server.

Introduce a new helper function dns_server_limited_domains() that checks if the
DNS server should only be used for some selected domains, i. e. has some
route-only domains without "~.". Use that when determining whether to query it
in the scope, and when writing resolv.conf.

Extend the test_route_only_dns() case to ensure that the DNS server limited to
~company does not appear in resolv.conf. Add test_route_only_dns_all_domains()
to ensure that a server that also has ~. does appear in resolv.conf as global
name server.

Fixes systemd#3420
Fixes systemd#3421
martinpitt added a commit to martinpitt/systemd that referenced this issue Jun 30, 2016
DNS servers which have route-only domains without "~." should only be used for
the specified domains. Routing queries about other domains there is a privacy
violation, prone to fail (as that DNS server was not meant to be used for other
domains), and puts unnecessary load onto that server. As documented, adding
"~." to Domains= is the way to describe "use that server for all domains",
i.  e. make it a global name server.

Introduce a new helper function dns_server_limited_domains() that checks if the
DNS server should only be used for some selected domains, i. e. has some
route-only domains without "~.". Use that when determining whether to query it
in the scope, and when writing resolv.conf.

Extend the test_route_only_dns() case to ensure that the DNS server limited to
~company does not appear in resolv.conf. Add test_route_only_dns_all_domains()
to ensure that a server that also has ~. does appear in resolv.conf as global
name server.

Fixes systemd#3420
Fixes systemd#3421
@martinpitt
Copy link
Contributor Author

martinpitt commented Sep 23, 2016

I created a test harness/case for this: https://gist.github.com/martinpitt/71990ad79ba03d46a4766cc39a3fd92b

This makes it much easier to play around with this, as this provides full control and access to the involved DNS servers and logs.

It isn't factorized yet, but that can happen once we extend it to other scenarios.

martinpitt added a commit to martinpitt/systemd that referenced this issue Sep 26, 2016
DNS servers which have route-only domains should only be used for
the specified domains. Routing queries about other domains there is a privacy
violation, prone to fail (as that DNS server was not meant to be used for other
domains), and puts unnecessary load onto that server.

Introduce a new helper function dns_server_limited_domains() that checks if the
DNS server should only be used for some selected domains, i. e. has some
route-only domains without "~.". Use that when determining whether to query it
in the scope, and when writing resolv.conf.

Extend the test_route_only_dns() case to ensure that the DNS server limited to
~company does not appear in resolv.conf. Add test_route_only_dns_all_domains()
to ensure that a server that also has ~. does appear in resolv.conf as global
name server. These reproduce systemd#3420.

Add a new test_resolved_domain_restricted_dns() test case that verifies that
domain-limited DNS servers are only being used for those domains. This
reproduces systemd#3421.

Clarify what a "routing domain" is in the manpage.

Fixes systemd#3420
Fixes systemd#3421
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 Programming errors, that need preferential fixing resolve
Development

No branches or pull requests

2 participants