QubesOS / qubes-issues

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

Allow users to choose a SOCKS5 proxy instead of firewall rules. #5032

Open DemiMarie opened 5 years ago

DemiMarie commented 5 years ago

The problem you're addressing (if any) Many websites do not have stable IP addresses, and rely on dynamic DNS instead. Furthermore, multiple sites can share an IP address. Google is an extreme case ― any of Google’s sites can be at any of Google’s IP addresses. This makes L3 firewalling essentially useless.

While the QubesOS docs do provide a way to use an HTTP proxy, it has several disadvantages:

Describe the solution you'd like One solution is to use a filtering SOCKS5 proxy instead. SOCKS5 has several advantages:

For this to be of maximal use, there would need to be tight integration with QubesOS. That is, users must be able to select and configure it via the firewall GUI.

Where is the value to a user, and who might that user be? This allows users to whitelist based on domain name, rather than on IP address. This allows far more specific filtering than would otherwise be possible, especially for sites hosted by large companies such as Google.

Describe alternatives you've considered I previously considerd combining dynamically-updating firewall rules with DNS filtering (#3641). However, those have disadvantages:

Additional context I ran into this problem for months when I was first using QubesOS, and resorted to custom code to work around it.

Relevant documentation you've consulted https://www.qubes-os.org/docs/firewall

Related, non-duplicate issues

3641

maertsen commented 4 years ago

This could also enable wildcard whitelisting of subdomains (e.g. *.domain.tld), which is not currently possible.

marmarek commented 4 years ago
* Not all programs support HTTP proxies.  Thunderbird and OpenSSH are notable examples.

I don't think those are good examples. Thunderd definitely supports both HTTP proxy and SOCKS. And OpenSSH doesn't support directly either (you can provide ProxyCommand though). Generally, my experience is significantly more applications support HTTP proxy than SOCKS. And regarding "tight integration with QubesOS", both approaches requires configuring every single application to actually use that proxy. In case of http(s), there are de facto standard http_proxy and https_proxy environment variables. But it solves only part of the problem.

Otherwise, I agree with all the other points about SOCKS being superior over HTTP.

As for the implementation, I see multiple options:

  1. Run SOCKS over TCP, then use standard firewall to allow only SOCKS. Store filtering rules in a (generated) file on SOCKS server side.
  2. Run SOCKS over qrexec. Store filtering rules in a (generated) file on SOCKS server side.
  3. Run SOCKS over qrexec, with connection parameters in service argument and filtering rules are qrexec policy (requires client side to extract those parameters before making the call and server side to assemble them again)

I think point 3 is most elegant (avoids direct access to the whole IP layer), but also least performant, because qrexec connection setup currently takes about 200ms. We're working on improving it (for example https://github.com/QubesOS/qubes-core-qrexec/pull/6, but your @DemiMarie https://github.com/QubesOS/qubes-core-qrexec/pull/3 is also important step here). But until it's significantly improved, I think those options are blocked.

DemiMarie commented 4 years ago

What about multiplexing several SOCKS connections over a single qrexec connection? That’s what OpenSSH does (though with SSH instead of qrexec).

marmarek commented 4 years ago

@DemiMarie Do you have any recommendation for specific software to use for SOCKS5/HTTP proxy that is also capable of filtering, but also isn't an easy attack target (memory-safe language preferred)? But also - I see a major usability issue with this approach: application(s) need to be specifically configured to use the proxy. It may work for a carefully crafted own custom configuration, but not so much for a system default that should "just work". For HTTP proxy, many applications respects http(s)_proxy environment variable, but last time I've checked, SOCKS support was very inconsistent between applications (some supports addresses like socks:// in env variable, some expect a different env variable or syntax, and many doesn't support SOCKS at all).

DemiMarie commented 4 years ago

@marmarek I only know of Squid and tinyproxy (both written in C) and a SOCKS5 proxy written in Nim. This would be best served by a new proxy. SOCKS5 is extremely simple, though, and Go’s standard library provides an HTTP package that should be up to the task.

Writing a SOCKS5 proxy is ~400 lines or less of Rust, so it isn’t that hard.

tlaurion commented 2 years ago

@DemiMarie @marmarek what PRs are associated with the resolution of this issue?

DemiMarie commented 2 years ago

@tlaurion none so far

3hhh commented 2 years ago

This issue is rather identical to #5225, just with a specific proposal on a solution. I still consider DNS pinning to be superior though as it's fully transparent to the application.

andrewdavidwong commented 2 years ago

This issue is rather identical to #5225, just with a specific proposal on a solution. I still consider DNS pinning to be superior though as it's fully transparent to the application.

@DemiMarie, do you agree that these two issues are duplicates? If so, is there a strong reason to favor one over the other as the one to keep open? (The default is to keep the older issue open, which would be this one.)

DemiMarie commented 2 years ago

This issue is rather identical to #5225, just with a specific proposal on a solution. I still consider DNS pinning to be superior though as it's fully transparent to the application.

@DemiMarie, do you agree that these two issues are duplicates? If so, is there a strong reason to favor one over the other as the one to keep open? (The default is to keep the older issue open, which would be this one.)

Not really; they are two different approaches and not mutually exclusive. Both have advantages and disadvantages.

DemiMarie commented 2 years ago

What about dante proxy? It is also available in the debian repo and was quite simple to setup up for domain filtering.

Never heard of it. I have considered writing my own in Go, though.

milahu commented 7 months ago

One solution is to use a filtering SOCKS5 proxy instead.

This allows users to whitelist based on domain name, rather than on IP address.

note: this requires clients to use the socks5h protocol to enforce sending DNS requests over the proxy server = to avoid DNS leaks