mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
[GH-ISSUE #3631] DNS access control and DNS-controlled firewalling #2283
Labels
No labels
LTS merge
LTS merge
bug
bug
converted-to-discussion
doc-todo
documentation
duplicate
enhancement
file-transfer
firecfg
firejail-in-firejail
firetools
graphics
help wanted
information_old
installation
invalid
modif
moved
needinfo
networking
notabug
notourbug
old-version
overlayfs
packaging
profile-request
pull-request
question
question_old
removal
runtime-permissions
sandbox-ipc
security
stale
wiki
wiki
wontfix
wordpress
workaround
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/firejail#2283
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @topimiettinen on GitHub (Sep 16, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3631
This is similar to the new feature I'm proposing to systemd-resolved.
Is your feature request related to a problem? Please describe.
It's difficult to make useful firewalls based on filtering IP addresses since the internet operates on DNS domain names but the firewalls actually operate on IP addresses. In simple, static cases it could be possible to resolve the DNS addresses only once at resolver startup (boot etc), but not in general. Especially statically resolving domain names for address pools (e.g.
pool.ntp.org) at resolver startup would not work as the DNS servers may give a different address each time the name is resolved.Describe the solution you'd like
There are two parts in this idea.
*.example.com.www.example.comhas been resolved to an IP address (but before the DNS reply is given back to caller), update the firewall to allow access for port 443 for this IP address. The firewall rules would be removed simply just by application and Firejail exit, or perhaps with a timeout.The benefit would be more secure applications and much tighter firewalls. 1. would implement simple DNS based access control for applications. It would not block accesses with hard coded IP values. 2. would tighten 1. so that even known IP addresses would be blocked, unless a DNS request (subject to rules of 1.) was made in advance.
Part 1. would be already useful without 2. This could be also used for ad blocking for applications which don't have more user friendly ways like Adblock Plus and uMatrix for browsers.
Alternatively it could be possible at startup to resolve a set of addresses, configure the firewall and then inject the pre-resolved addresses. This would not work for entire domains (
*.example.com*).@topimiettinen commented on GitHub (Sep 16, 2020):
The syntax for profiles could be something like
(allow/whitelisting)
(deny/blacklisting)
Command line versions prefixed with
--.It probably would not make sense to distribute any ready made lists with Firejail, but much like adblockers, perhaps someone could specialize in offering regularly updated lists as a service, and even make money out of it if there's enough demand.
@matu3ba commented on GitHub (Sep 16, 2020):
The problem with
filtering IP addressesis that it is a big maintenance burden and you end up adding alot complexity (ie load-balancing, ip-forwarding etc), since the many websites are made intentional complex to break things, as prevention of exactly such use cases.[ Probably you can estimate this by testing ip filter programs. I do use
Noscriptand dont see alot additional use. ]How do you establish trust/quality control of the list?
What is the plan to establish DNS trust or do you think of a DNS-IP cache? Resolving the DNS address every time to obtain the ip address may be very slow and leaks privacy information.
Is there no other tool that can setup temporary ip filters? What is the advantage of including this functionality in firejail?
@SkewedZeppelin commented on GitHub (Sep 16, 2020):
I think this would be an awesome feature.
However I don't think the effort required to implement vs the benefit is worth it.
The traditional approach of pfBlockerNG/Pi-Hole and NetGuard/DNS66 already provide great benefit with minimal hassle. Simply deploying such a solution would already raise the bar much higher.
This would just be diminishing returns.
The effort IMO would be better suited towards making a feasible Little Snitch for Linux, like OpenSnitch and Douane attempted to do. Especially because then you don't have to rely on rule lists as much.
It wouldn't be feasible for browsers.
It might be possible for email clients, irc clients, and games.
It should be easy for things like: gnome-calculator, freshclam, keepass, and picard.
I've created/maintained many DNSBL lists over the years, I don't think there is much room for making money there.
@topimiettinen commented on GitHub (Sep 17, 2020):
For browsers there are indeed better solutions in form of extensions, they are more user friendly because they are integrated in the UI and there are regular updates to access lists etc. Though since they work at the mercy of the browser extensions API, they can't block requests from browser which don't go through the API.
Applications besides browsers probably are easier to manage since they are not used to connect to infinitely variable set hosts but just maybe a few. So it should be possible to manage the lists by the end user or system administrator and of course they are then responsible for quality.
The applications usually resolve the domain names only once per connection and only this is the point where this Firejail feature would be active. After a domain name has been resolved to an IP address, the application can (and will) use the address as it likes. I'm not planning to implement any caching or trust (with for example DNSSEC) features. Firejail should just forward the requests to the DNS resolver normally used in the system (for example unbound, bind, systemd-resolved, external IP like router etc.) which should do caching. If there's a MITM attack (man-in-the-middle) which forges the DNS requests, there's not much that an intermediate resolver can do, or perhaps this feature could enforce DNSSEC even if the application doesn't care (but I'm not planning to implement this).
Maybe there are, but I don't know of any tools which would use DNS requests for controlling the IP firewall, especially at application level. Some DNS proxies can filter DNS requests but they work at whole system level which is too coarse. For example, Turla malware used Facebook for botnet command and control (C2), but blocking it at system level would also block the user's legitimate access with a browser.
Different applications could use different filtering DNS proxies so different blocking rules could be used, but that would not implement firewall control. The DNS proxies could be extended to detect the application and also control firewalls, but they probably would have trouble to control the firewall created by Firejail in a private network namespace.
@topimiettinen commented on GitHub (Sep 17, 2020):
Please correct me if I'm missing something.
With a more centralized solution compared to Firejail, there still needs to be rules for each application, so I don't think there would be great savings. Also it may be possible to copy rules between applications.
Firejail already has the firewall feature (fnetfilter) which can be extended. There's already a very strong application focus: the purpose of Firejail is to sandbox applications with detailed rules for each application. What is missing is the DNS proxy and filter. The application can be requested to use the proxy by overmounting a new
/etc/resolv.conffile and this can be enforced by firewalling access to system resolver and any external DNS services. It may be possible to reuse code from existing DNS proxies.There are indeed better options, though this feature could implement additional DNS blacklisting to close any holes left by the browser design or different focus of the blacklists (blocking ads, trackers, countries, known bad guys, NSFW sites, organization rules etc).
These applications probably only want to access a few well defined domains, so it would not be hard for end users to implement and maintain the rules.
OK, I was not planning to do this myself anyway. Perhaps you could extend your operations here if you already have the experience?
@SkewedZeppelin commented on GitHub (Sep 17, 2020):
I bring up NetGuard and DNS66 to show how common and easy such solutions are compared to such a fine grained one like this.
And like you say in browsers we already have better options for browsers such as the extremely powerful uBlockOrigin and uMatrix extensions.
Not only are the pfSense/OpenWRT solutions easier to implement and to maintain they provide whole network protection.
FireHOL tracks many high quality IP lists. They are in standard ipset format. The level1-4 lists are a good starting place.
I have a list of DNS lists here with their licenses defined.
I still think there is great value in a feature like this. But it requires a lot of effort to implement and I don't think very many users would take advantage of the feature.
People already don't take advantage of the systemd unit hardening options or their compilers hardening options.
This is like a 99% "what else can we harden?" option when everyone is at 10%.
@topimiettinen commented on GitHub (Sep 18, 2020):
It looks like Pi-hole implemets a lot of what is needed. The group feature allows selecting different DNS filtering profiles. Currently selection of group is based on IP addresses, which would not allow using a different group for a browser and another for email client on a same IP address. Perhaps this could be extended so that several apps sharing an IP address can use different groups, or maybe even easier would be if Firejail configured each app to have a different IP address. Maybe set up a VPN from each Firejail instance to Pi-hole?
It would be also nice to not need a separate box but run Pi-hole in the same computer as the apps. Pi-hole seems to run also inside a container despite the name.
Maybe the automatic firewall controlled by DNS requests could be implemented in Pi-hole too.
So instead of adding a new feature for Firejail, just document how to set up Firejail with local Pi-hole to achieve the per-application DNS filtering.
@topimiettinen commented on GitHub (Sep 19, 2020):
I clearly didn't do great research before proposing the feature. Firejail already implements planting a new
/etc/resolv.confwith--dns=option. So to implement application specific DNS filtering (part 1.) it's enough to start instances of a filtering DNS proxy with rules specific to the application at different IP addresses (127.0.0.2, 127.0.0.3 etc.) and then direct the apps to corresponding proxies with--dns=127.0.0.2etc. It's also possible to use an external box. Firejail could optionally enforce the DNS filter by installing a firewall which would forward all port 53 accesses from an app to its proxy, but this is also already possible with existing--netfilter=feature. We could ship a new netfilter file in addition to existing/etc/firejail/webserver.netand/etc/firejail/nolocal.netand provide examples in the manual. dnscrypt-proxy is a DNS proxy with filtering capabilities.This leaves the part 2., firewall opened by DNS requests. Assuming an external DNS filter as above, this part doesn't have to do any filtering of the DNS requests, so this should be relatively simple to implement. I suspect that it's actually not even necessary to process or look at the outgoing DNS requests, the resolved IP addresses in the incoming responses should contain all that is needed.
This part does not need much configuration either, only which ports should be affected by the firewall (or all of them) and whether are they TCP and/or UDP (like
--dns.firewall=tcp:imaps,--dns.firewall=all). The simplest configuration would be to allow traffic to any TCP&UDP port from the resolved IP address (like--dns.firewallwith no ports). Maybe that would actually be good enough. For example, if a domain likegmail.comis trusted to be accessed with TCP/IMAP, allowing traffic to the domain with any port and UDP might not increase the risk level too much.@netblue30 commented on GitHub (Sep 23, 2020):
It is already running here: https://github.com/netblue30/fdns
My original intention was to put it in firejail, but the push was more towards privacy (DNS over HTTPS/TLS) than security, so I cut it down as a separate project. We could bring it in firejail, or make it as some sort of plugin. It comes with a full adblocker, you can blacklist/whitelist domains, very long list of DoH providers etc.
Is not a big deal to add it, it could be a lot of fun. There is an implementation in unbound: https://github.com/NLnetLabs/unbound/tree/master/ipset - I have no idea how they use it.
@topimiettinen commented on GitHub (Sep 23, 2020):
Awesome, it looks like the needed pieces are almost here! fdns can do whitelisting, so it would be great if it were part of Firejail.
Unbound ipset module simply adds the resolved addresses to an IPSet. Using an IPSet seems to be a nice approach to firewalling, especially performance would be better than many other options according to this blog. Also updating an IPSet would be a simple operation compared to managing the whole firewall, it wouldn't interfere with firewalls in the system or installed by Firejail.
@alexpyattaev commented on GitHub (Mar 6, 2023):
To add 50c to this thread - this would be very nice for IDEs. Specifically, build tools do need to fetch stuff from places like crates.io, npm, PyPi etc, but they do not need to access the general internet. Thus, when sandboxing an IDE one would allow e.g. own git server/github, and select package repos. Since all of them sit on CDN's doing so by IP group would be "non-trivial" at best.
@alexpyattaev commented on GitHub (Mar 8, 2023):
One way to do this would be to push all traffic into a proxy server. Proxy can then mess with connection filtering. I'll dig more into that direction.
@topimiettinen commented on GitHub (Mar 13, 2023):
Problem with proxies is that some of the context of the process useful for filtering may be lost or there's no secure/race-free way to check them. These include the identity of the Firejail instance, UID/GID, cgroup memberships, SELinux context etc. For example, it would be nice to allow the "bank browser" process to access only certain listed URLs, "email" process some others etc.
@alexpyattaev commented on GitHub (Mar 14, 2023):
Sure, but when you visit e.g. bankofepicfrauds.com, your browser will actually visit multiple CDNs and a whole bunch of random hosts to fetch stuff like fonts etc. How to turn that high level domain-based restriction into actual per-connection decisions that make sense for a given web app is a tricky question. I am quite certain that anything short of a proxy server will be insufficient for this.
Regarding security, the proxy server would need to be spawned per sandbox for this to make any sense (else processes from different sandboxes will talk through the same proxy with the same settings). The proxy server would then sit outside of the sandbox.
A good proxy server could be https://tinyproxy.github.io/