• Development
  • Arguement against GOS firewall makes no sense to me

The arguement for GOS not using Android's native Netfilter firewall (IPTables rules) to harden security device makes no sense to me. GOS developers basically say that Netfitler does not help because it is out-dated and because applicatins use their own firewalls based on Berkley Packet Filter (BPF), which is still based on Netfitler but with better efficiency and is applied on per-app basis rather than per-device basis.

That only makes sense if you assume all applications protect themselves with BPF, but they don't. Only modern and secure apps do that. What about the rest? Many apps that do use BPF simply stick with super-loose "accept all inbound and outbound traffic" (0 filtering) rules. Doing so is the fault of developers of those apps, but GOS can still compensate by creating at least moderate Netfilter rules that affect the whole device.

Currently GOS simply allows to cut off all network access for selected apps, but that is overly simple and crude and again, only protected against specific apps, not the entire device.

Can't we get some additional toggles, such as "drop all new inbound traffic" (for all apps on all non-local interfaces or at least for all apps on non-local non-VPN interfaces) ??? That is the most standard and basic rule to keep bad guys away from trying to connet to your device. I tested it thoroughly on rooted Pixel 1 (which doesn't even support BPF) and it blocked a ton of unwanted inbound traffic on from my carrier and on WiFi networks without negatively impacting any network-utilizing functions of any applications. Such a rule is only a problem is you host a server.

    OpenSource-Ghost it would help others if you linked to the other conversations and message threads.

    This is the first time I've heard about this stance and position by the GOS team.

      Statements about firewalls being useless was on GOS main site. BPF-based modernization and reliance was provided as reason in comments on GitHub when I inquired further as to why GOS was using stock/default super-loose Android IPTables chains.

      BPF is also not very safe. It uses Just-In-Time processing that is considered unsafe-enough for Linux kernels to include SysCTL parameters to harden BPF security.

      I understand that developers want to correctly assign responsibilities. If some app is vulnerable when accepting new inbound traffic over some TCP/UDP port, then is it the port's fault? No, ports are innocent, you can send any data over any port. Is it router's fault? No, routers simply route. Its whichever app's fault and yet moderately strict router (or OS netfilter) rules can compensate for such issues without forcing whichever app to not have any network access. Such rules do not solve root causes, but they are still solutions, crude solutions, but not as crude as blocking all network access to whichever app.

      Since Netfilter affects not only user apps, but system apps, it can be used to temporarily mitigate confirmed bugs, such as WiFi Calling domain resolution when WiFi calling is already disabled. A toggle can be programmed to insert or remove rules to block such domain resolution until a less crude method of doing the same is possible or until the root cause is fixed.

      Security is most efficient when pro-active approches are utilized. The "not a proper solution" or "does not remove the root cauae" ideology is not pro-active.

        guser39 You're correct that we haven't made these statements. It's a complete misrepresentation of how things work and our stance on them as a project.

        OpenSource-Ghost This is blatant misinformation.

        The arguement for GOS not using Android's native Netfilter firewall (IPTables rules) to harden security device makes no sense to me. GOS developers basically say that Netfitler does not help because it is out-dated and because applicatins use their own firewalls based on Berkley Packet Filter (BPF), which is still based on Netfitler but with better efficiency and is applied on per-app basis rather than per-device basis.

        This is completely wrong. It's not clear where you get the idea that we don't use the built-in firewall support or where you get the idea that we leave it up to applications. It's not true. We haven't stated these things and it's not how it works.

        That only makes sense if you assume all applications protect themselves with BPF, but they don't. Only modern and secure apps do that. What about the rest? Many apps that do use BPF simply stick with super-loose "accept all inbound and outbound traffic" (0 filtering) rules. Doing so is the fault of developers of those apps, but GOS can still compensate by creating at least moderate Netfilter rules that affect the whole device.

        This is not how things work at all.

        Currently GOS simply allows to cut off all network access for selected apps, but that is overly simple and crude and again, only protected against specific apps, not the entire device.

        The reason we have our Network toggle is because it's something that can be made to actually work properly as opposed to non-functional things which are trivially bypassed and leaky. Fine-grained filtering would require denying the Network toggle as a whole and then only permitting certain direct socket access. Most fine-grained filtering fundamentally doesn't work. If you permit using DNS, which is required to connect to any domain name, then you've permitted 2 way communication with any party through the DNS resolver without needing any direct connections from the app.

        Can't we get some additional toggles, such as "drop all new inbound traffic" (for all apps on all non-local interfaces or at least for all apps on non-local non-VPN interfaces) ??? That is the most standard and basic rule to keep bad guys away from trying to connet to your device. I tested it thoroughly on rooted Pixel 1 (which doesn't even support BPF) and it blocked a ton of unwanted inbound traffic on from my carrier and on WiFi networks without negatively impacting any network-utilizing functions of any applications. Such a rule is only a problem is you host a server.

        New inbound traffic is already entirely dropped by default. An application with the Network permission can listen on a port in order to receive new inbound connections, changing the default of dropping the traffic. In what sense is this an issue as opposed to the application connecting to any remote host? Very few applications listen on a port from connections. It has to be done very explicitly and requires the Network permission. It does not enable them to do anything fundamentally different from connecting to a remote host. In general, it will only even allow other hosts on the local network to connect to them. They could also simply connect to those hosts themselves. The Network permission controls all of this already. What reason is there to split up the permission toggle for connecting to a remote host from receiving a connection? It's fundamentally the same thing once a connection is established and there are no special privileges from which side received the initial connection.

        It's not true that additional inbound traffic would have been blocked by you setting up a firewall. It's also not clear why you have these strange incorrect ideas about BPF.

        Statements about firewalls being useless was on GOS main site. BPF-based modernization and reliance was provided as reason in comments on GitHub when I inquired further as to why GOS was using stock/default super-loose Android IPTables chains.

        This is all completely untrue. Our website doesn't state anything of the kind and nothing of the kind was stated about iptables or about BPF. The default firewall configuration is not 'loose' as you claim but rather the Network permission is what determines if apps are allowed to send and receive connections. It's not clear why you think it would be useful to divide that up into separate toggles. It's extremely uncommon to host servers in the first place and being able to listen on a port does grant any special privileges based on it. There has to be authentication to have security.

        BPF is also not very safe. It uses Just-In-Time processing that is considered unsafe-enough for Linux kernels to include SysCTL parameters to harden BPF security.

        This is also untrue. JIT compilation is not an inherent dependency of BPF. BPF is also used for many things at this point, not all of which are even networking related. You're making incorrect assumptions.

        I understand that developers want to correctly assign responsibilities. If some app is vulnerable when accepting new inbound traffic over some TCP/UDP port, then is it the port's fault? No, ports are innocent, you can send any data over any port. Is it router's fault? No, routers simply route. Its whichever app's fault and yet moderately strict router (or OS netfilter) rules can compensate for such issues without forcing whichever app to not have any network access. Such rules do not solve root causes, but they are still solutions, crude solutions, but not as crude as blocking all network access to whichever app.

        This doesn't make any sense. There is nothing listening on any ports by default. The Network permission grants the ability to send and receive connections, both on actual networks and on localhost. It's not clear in what way you think an app receiving new connections is different from it making new connections or why you want to divide up the permission. It's extremely rare for anything to listen for new connections on the actual network connections. Android is not generally used to host servers that way, and only clients on a local network would be able to connect unless you've given the device an IP directly exposed to the public internet. You can't simply host a web server by listening on port 80 / port 443 beyond your local Wi-Fi network without further work. It won't work on mobile data either. The OS does control this via the Network permission and if you think that should be split up with separate toggles for listening sockets, you'll need to justify that by explaining why instead of making baseless blanket statements about it seemingly based on misinterpreting information elsewhere.

        OpenSource-Ghost Again making false claims about our statements and ideology, while making more false statements about how things work on a technical level.

        @OpenSource-Ghost You've been a member of the forum for a long time, and perhaps a member of the community elsewhere too. You've occasionally made posts that are very wrong and make claims about things you say have been said which haven't been said. You need to adjust your approach.

        I based my assumptions, statements, and conclusions on:

        "You're allowed to host servers via apps with the Network permission."

        • Network permissions toggle exists for each user app and controls all traffic just for that specific user app on all interfaces. If, as you say in this thread, GrapheneOS drops all new inbound traffic (which is traffic not established by user app and traffic not related to existing user app traffic) on all interfaces by default then whether a server user app accepts such traffic (via Network permissions) or not is not relevant because (as you sayd in this thread) GrapheneOS processes and drops all new inbound traffic by default before it can be processed by any user app. As such, the statement from mentioned GitHub discussion, is either false because both user app and OS must accept new inbound traffic for a server to serve and that is not possible if GrapheneOS processes and drops all new inbound traffic (before it can reach any user app) OR what you say is false and GrapheneOS does indeed allow all new inbound traffic to allow user apps to be ones performing filtering. Both statements cannot be true because any server that serves must accept new inbound traffic and if GrapheneOS drops such traffic by default, running a server that requires acceptance of new inbound traffic is not possible.
        • Running local DNS server software like AdGuard Home on Raspberry Pi (RPiOS/Linux) is a perfect example. You can enable AdGuard Home to accept or deny traffic from whichever source to itself as software on OS, not to OS itself, but only if OS accepts all traffic. If OS drops all new inbound traffic via Netfilter rules, then whether AdGuard Home allows such traffic or not is not revelent because OS drops all new inbound traffic before it can reach AdGuard Home.
        • Once again, if you can indeed run servers on GrapheneOS, then GrapheneOS itself must accept all new inbound traffic and have user apps decide if it accepts or drops such traffic. The GitHub response says that one can indeed run servers on GrapheneOS and that is controlled by Network permission toggle. If that is true, then GrapheneOS does not drop all new inbound traffic and allows user apps to be the one in control.

        "Also note that iptables has largely been replaced with eBPF in AOSP."

        • If my assumption about GrapheneOS accepting all new inbound traffic is true and GrapheneOS leverages eBPF as OS-wide firewall then it integrates eBPF in a way that allows applications to control new inbound traffic and GrapheneOS does not drop such traffic by default.

        Does GrapheneOS provide a firewall?
        Yes, GrapheneOS inherits the deeply integrated firewall from the Android Open Source Project, which is used to implement portions of the security model and various other features. The GrapheneOS project historically made various improvements to the firewall but over time most of these changes have been integrated upstream or became irrelevant.

        • What AOSP firewall? Android 11 AOSP still has 3 Netfilter IPTables - INPUT, FORWARD, OUTPUT and all 3 are set to "ACCEPT" policies and allow traffic whichever apps. Some rules use markers I can't figure out, but new inbound traffic is definitely not dropped by default. Setting custom rules (which requires root of course) resolves that issue.

          Network permissions toggle exists for each user app and controls all traffic just for that specific user app on all interfaces. If, as you say in this thread, GrapheneOS drops all new inbound traffic (which is traffic not established by user app and traffic not related to existing user app traffic) on all interfaces by default then whether a server user app accepts such traffic (via Network permissions) or not is not relevant because (as you sayd in this thread) GrapheneOS processes and drops all new inbound traffic by default before it can be processed by any user app. As such, the statement from mentioned GitHub discussion, is either false because both user app and OS must accept new inbound traffic for a server to serve and that is not possible if GrapheneOS processes and drops all new inbound traffic (before it can reach any user app) OR what you say is false and GrapheneOS does indeed allow all new inbound traffic to allow user apps to be ones performing filtering. Both statements cannot be true because any server that serves must accept new inbound traffic and if GrapheneOS drops such traffic by default, running a server that requires acceptance of new inbound traffic is not possible.

          Linux without any special configuration drops new inbound connections unless something is listening on the port. Network toggle controls whether something can listen on a port. Your statements are not accurate.

          Running local DNS server software like AdGuard Home on Raspberry Pi (RPiOS/Linux) is a perfect example. You can enable AdGuard Home to accept or deny traffic from whichever source to itself as software on OS, not to OS itself, but only if OS accepts all traffic. If OS drops all new inbound traffic via Netfilter rules, then whether AdGuard Home allows such traffic or not is not revelent because OS drops all new inbound traffic before it can reach AdGuard Home.

          Network toggle controls listening on ports including localhost. It could be split up between public networks and localhost in the future to permit one but not the other. Splitting it up almost any other way doesn't make sense.

          Once again, if you can indeed run servers on GrapheneOS, then GrapheneOS itself must accept all new inbound traffic and have user apps decide if it accepts or drops such traffic. The GitHub response says that one can indeed run servers on GrapheneOS and that is controlled by Network permission toggle. If that is true, then GrapheneOS does not drop all new inbound traffic and allows user apps to be the one in control.

          No, that's wrong, and it has been explained why it's wrong. Stop repeating misinformation.

          If my assumption about GrapheneOS accepting all new inbound traffic is true and GrapheneOS leverages eBPF as OS-wide firewall then it integrates eBPF in a way that allows applications to control new inbound traffic and GrapheneOS does not drop such traffic by default.

          It's not true. eBPF is used to drop all inbound traffic. Apps with the INTERNET permission (Network) are given an exception from the rule. VPN lockdown mode (block connections not through VPN) works in the same way. Your understanding of how eBPF works is wrong.

          What AOSP firewall? Android 11 AOSP still has 3 Netfilter IPTables - INPUT, FORWARD, OUTPUT and all 3 are set to "ACCEPT" policies and allow traffic whichever apps. Some rules use markers I can't figure out, but new inbound traffic is definitely not dropped by default. Setting custom rules (which requires root of course) resolves that issue.

          It was already explained repeatedly that iptables is legacy. It was replaced by nftables. Android moved to using eBPF for almost everything instead to have more control, higher performance and more dynamic configuration. New inbound traffic is dropped by default. Only apps added to the whitelist via the INTERNET permission can listen on a port. This has already been explained.

          OpenSource-Ghost Android uses eBPF to implement firewall rules including the INTERNET permission and VPN lockdown mode. You've had this repeatedly explained to you already. You read about it before you posted here. You wrongly believe that eBPF is something configured by applications. Applications cannot access eBPF on Android because eBPF is only allowed to be used from the bpfloader program which can only be used by netd.

          Android implementing filtering via eBPF instead of the iptables approach that you're familiar with does not mean that it isn't filtering traffic. You're making the incorrect assumption that not doing it the way you expect means it isn't being done.

          In the Linux kernel, iptables is deprecated and meant to be replaced by either nftables or eBPF depending on the use case. GrapheneOS uses nftables on our servers, not deprecated iptables. Android chose to build firewall features with eBPF to have more control, dynamic configuration and performance than iptables/nftables. It inherently had to use eBPF because functionality it needs is not available via iptables or nftables and they chose to stop depending on downstream patches. They were adding iptables functionality with Android-specific patches along with generic functionality like the INTERNET permission separate from it. Not doing stuff with iptables doesn't mean it isn't being done. Linux has multiple ways to do firewall rules and Android not doing it the way you are familiar with doesn't mean it isn't being done.

          The INTERNET permission implements both an outbound and inbound traffic filter and it applies to more than apps. It used to be implemented as gids providing the ability to create internet sockets. It gained the name INTERNET from the low-level naming used by the Linux socket APIs even though NETWORK would have made more sense. It would be possible to split up the INTERNET permission to an extent by making it possible to disable some sockets but not others, such as splitting out localhost access into a separate toggle. However, the permission enforced by the permission system will need to be denied if network access is partially denied. Otherwise, an application could bypass the direct traffic filtering with indirect access. This is something missed by other projects trying to make finer grained firewall toggles, including every firewall app implemented as a VPN service which do not really work properly.

          Linux without any special configuration drops new inbound connections unless something is listening on the port. Network toggle controls whether something can listen on a port. Your statements are not accurate.

          Default policies for all Netfilter chains in Linux are set ACCEPT. If there are no services listening on any ports, then of course traffic is dropped because there are no apps/services to which it can be destined. If some running P2P service/app is listening on a port and is internally (in service/app options) set to accept all new inbound traffic, then default Linux policies will allow all new, established, related, and invalid packets destined for that app/service to reach that service/app. The only way to stop that on GrapheneOS is to disable all network access for that app/service via Network toggle. There is no way to excusively stop new inbound traffic for apps/services that accept all traffic. Most network routers enforce dropping new inbound traffic (regardless of any running apps/services accepting new traffic) with a simple set of rules for inbound traffic, but such rules are not default Linux Netfilter rules:
          -P INPUT DROP
          INPUT -m conntrack --cstate ESTABLISHED,RELATED -j ACCEPT
          INPUT -m conntrack --ctstate INVALID -j DROP

          I am not going argue any with your expertise. I can run servers on my GrapheneOS phone, test to see if they accept new inbound traffic from devices on the same network, and provide logs (privately, not to start heated discussions).

          11 days later

          Thanks, there is a lot of detailed explanations here, this kind of thread could be tagged for reference.
          For now a reliable firewall seems complicate to implement.
          A network report, to know domains contacted by apps and inbounds allowed calls would be easier to implement properly ? (Like this)

          Huge thanks to GOS team for implementing BPF hardening in the latest GOS releases!

          I think network reports can be obtained through ADB commands, but ADB should only be enabled on devices dedicated to testing. I doubt an average GOS user would want such depth and/or granularity of information.