Open DemiMarie opened 5 years ago
This could also enable wildcard whitelisting of subdomains (e.g. *.domain.tld), which is not currently possible.
* 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:
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.
What about multiplexing several SOCKS connections over a single qrexec connection? That’s what OpenSSH does (though with SSH instead of qrexec).
@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).
@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.
@DemiMarie @marmarek what PRs are associated with the resolution of this issue?
@tlaurion none so far
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.
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.)
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.
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.
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
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