QubesOS / qubes-issues

The Qubes OS Project issue tracker
https://www.qubes-os.org/doc/issue-tracking/
536 stars 47 forks source link

Firewall should automatically respond to DNS changes, and also filter DNS responses. #3641

Open DemiMarie opened 6 years ago

DemiMarie commented 6 years ago

Qubes OS version:

R4.0

Affected component(s):

FirewallVM


Steps to reproduce the behavior:

Include smtp.gmail.com in the FirewallVM whitelist. Make a DNS query for a non-whitelisted site.

Expected behavior:

When the DNS for smtp.gmail.com changes, the firewall rules should update as well.

Actual behavior:

The firewall rules do not update when the upstream DNS changes, forcing the use of an HTTP filtering proxy. Furthermore, it is possible to make a DNS request for a site that the AppVM should have no access to.

General notes:

This can be implemented by proxying all DNS requests through FirewallVM. FirewallVM will then update its firewall rules whenever it sees the DNS change.

FirewallVM already needs to do DNS queries, so this does not increase attack surface.


Related issues:

ghost commented 6 years ago

You may want to read the second half of this post by @rootkovska. It's old but still relevant.

tl;dr;, dynamic dns resolution for firewall rules is a double-edged sword.

DemiMarie commented 6 years ago

@taradiddles My point of view is that anyone who can MITM DNS can MITM IP. The access required for both (generally, root access on an intermediate router) is identical. Therefore, my thought is that the best answer to that is sixfold:

  1. Only resolve DNS names that the domain is allowed to access.
  2. Only allow traffic via HTTPS or other secure protocol.
  3. Preload HSTS and HPKP rules in each AppVM.
  4. Use 8.8.8.8 (Google public DNS) as the DNS server.
  5. Validate DNSSEC
  6. For domains where we know a priori the ranges where the IP addresses must reside, check that the IP address does resolve to one of those addresses.
  7. Enforce that no public domain name can resolve to a private IP address.

1 enforces that DNS requests to some_random_domain.com will be rejected, so there will be a DNS lookup failure. This can be bypassed by using an IP address directly. But an attacker could already have MITM’d IP.

2 and 3 are the key points: by requiring HTTPS with hostname checking, one ensures that an attacker must forge a TLS certificate for a domain the user has whitelisted. This is a strict improvement over the current situation.

4 ensures that if the attacker does not control IP, they do not control DNS either, because the odds of Google’s DNS being malicious are rather low. 5 ensures that even this risk is eliminated for domains with valid DNSSEC (sadly, not all of them).

6 ensures that, say, google.com is only allowed to resolve to an IP address that is in the range it is supposed to; therefore, any other return value from DNS must be bogus. 7 ensures that an attacker cannot trick a browser into making a request to a private IP address.

ghost commented 6 years ago
  1. Only resolve DNS names that the domain is allowed to access 1 enforces that DNS requests to some_random_domain.com will be rejected, so there will be a DNS lookup failure. This can be bypassed by using an IP address directly. But an attacker could already have MITM’d IP.

That means you'd have to filter DNS in a VM and thus increase the surface attack of this VM (as opposed to have DNS queries "passed" from sys-firewall to sys-net without any processing to your network's DNS servers). If you set up such filtering in sys-firewall and it is compromised, it will affect every VMs connected to sys-firewall.

  1. Only allow traffic via HTTPS or other secure protocol.
  2. Preload HSTS and HPKP rules in each AppVM 2 and 3 are the key points: by requiring HTTPS with hostname checking, one ensures that an attacker must forge a TLS certificate for a domain the user has whitelisted. This is a strict improvement over the current situation.

2: I definitely agree, but firewalls can't be forced upon users, so it's up to them (us) to set up firewall rules that fit their (our) workflow. 3: If HSTS and HPKP don't come by default in the distro they're likely not to be included: Qubes' policy is to keep the VM templates (debian, fedora, ...) as close to the original as possible and if an exception is made to that rule somebody would have to maintain it.

  1. Use 8.8.8.8 (Google public DNS) as the DNS server. 4 ensures that if the attacker does not control IP, they do not control DNS either, because the odds of Google’s DNS being malicious are rather low. 5 ensures that even this risk is eliminated for domains with valid DNSSEC (sadly, not all of them).

4 alone doesn't help - whether it's google's DNS, openDNS' ones or your own secure resolver in the net, they can be MitM'ed. Setting the resolver's ip in a trusted VM (like sys-firewall) and having DNSSEC would be a solution, but except big companies (for which you probably have certificate pinning implemented in your browser) only a few sites have it set up properly.

  1. For domains where we know a priori the ranges where the IP addresses must reside, check that the IP address does resolve to one of those addresses. 6 ensures that, say, google.com is only allowed to resolve to an IP address that is in the range it is supposed to; therefore, any other return value from DNS must be bogus. 7 ensures that an attacker cannot trick a browser into making a request to a private IP address.

The problem here is a priori : how would you know those ips ? They're likely to change at some point so there must be a mecanism to update them, and you're back to square one: secure DNS resolution

I don't want to sound like I'm criticizing your points - I thought about those too some time ago but IMHO they're too complicated to implement on an AppVM basis. A solution may be to set up dns filtering / firewalling / ... in a ProxyVM tailored to your workflow, like for instance performing the following things: