dt.iki.fi

Firewall for SFOS AppSupport Applications

Android’s security model uses one user ID for each application. This makes it easy to create iptable rules to block network access of some apps.

However, I prefer a whitelist approach: block all network access for AppSupport, then punch holes for those apps I need & trust.

Android is not a very important part of my Sailfish experience. The only apps I have installed are the F-Droid store, Signal and the DuckDuckGo mobile browser. I’m willing to accept some annoyances from this, but so far it has been working without any.

It took me a while to figure out how to make it as strict as possible while still allowing my three apps to access the internet. Because apparently these apps can request network-related things - maybe even access the internet - through Android system apps, which then use a different user ID.

Also it seems that if I don’t allow the root user to access the internet, Android then tries to switch to another user ID. I did some research with netstat, and that much was clear.

However, if I allow the root user, that seems to be enough to make my apps work.

The Setup

This file allows my apps to access the internet:

cat /etc/connman/firewall.d/60-block-android-apps-firewall.conf
[General]
IPv4.OUTPUT.RULES = -m owner --uid-owner 510040 -j ACCEPT ;#com.duckduckgo.mobile.android; -m owner --uid-owner 510038 -j ACCEPT ;#org.fdroid.fdroid; -m owner --uid-owner 510039 -j ACCEPT ;#org.thoughtcrime.securesms;
IPv6.OUTPUT.RULES = -m owner --uid-owner 510040 -j ACCEPT ;#com.duckduckgo.mobile.android; -m owner --uid-owner 510038 -j ACCEPT ;#org.fdroid.fdroid; -m owner --uid-owner 510039 -j ACCEPT ;#org.thoughtcrime.securesms;

I found the user IDs like this:

cd /home/.appsupport/instance/defaultuser/data/data
app=com.duckduckgo.mobile.android
ls -ld $app
drwx------   10 510040   510040   4096 Aug 24  2025 com.duckduckgo.mobile.android

And this file blocks everything else:

cat /etc/connman/firewall.d/79-block-all-android-stuff-firewall.conf
## Reject all appsupport user IDs, starting with 500 000 (appsupport-root)
## Maximum: see
## /opt/appsupport/init/prepare-hook.d/75-generate-privilege-config.sh
## MAX_UIDS=200000
##
## root apparently needs network access

[General]

IPv4.OUTPUT.RULES = -m owner --uid-owner 500001-700000 -j REJECT ;
IPv6.OUTPUT.RULES = -m owner --uid-owner 500001-700000 -j REJECT ;

Connman

SFOS’ Connman version is quirky, to be polite. Restarting or reloading its config can be unpredictable. The above files are for connman, but these rules can also be applied to iptables directly, like so:

iptables -A connman-OUTPUT <everything after the = in the firewall.conf files>

Each *-firewall.conf file can only contain one of IPv4.OUTPUT.RULES and IPv6.OUTPUT.RULES respectively, the rest is ignored. Multiple rules can be added on one line separated by semicolons ;.

AFAICS each such rule, separated by semicolons ;, needs its own iptables command, and iptables does not require separate commands for IPv4 and IPv6. Try it, then check with iptables -L.

After a reboot however, connman should reliably do what is told in the config files.

Thank you to @chr1s from the forums who wrote a less strict firewall script. We discussed the ins and outs of it all in this thread.

Explanation

So why the numerical user IDs 500001-700000?

SFOS’ appsupport is based on LXC, i.e. Linux Containers. It maps user ids from the container system to the host system, starting with 500 000.

Afaics it is limited to 200 000 mappings, but in any case SFOS’ appsupport is, as can be seen in the file /opt/appsupport/init/prepare-hook.d/75-generate-privilege-config.sh.

By that logic 500 000 is Android’s root user, and the rule blocks everything above that.

PS

It’s possible - as root i.e. with devel-su - to attach to a running appsupport instance:

appsupport-attach

The default is to open a shell, but one can also execute single commands or little shell one-liners:

appsupport-attach sh -c "do some stuff here; exit"