Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per-app address filtering #15

Open
alex-barinov opened this issue Oct 29, 2012 · 25 comments
Open

Per-app address filtering #15

alex-barinov opened this issue Oct 29, 2012 · 25 comments
Labels

Comments

@alex-barinov
Copy link

Make it possible to filter traffic by address/subnet on a per-application basis without using scripts. Will probably require creating a dialog to enter addresses permitted for the application and marking such application with an icon in the application list.

@Honusnap
Copy link

Honusnap commented Feb 1, 2013

Following Alex on this one,

Would be good to add, for each application a black or white list of "accepted" or "non accepted" IPs, example :

Black list mode : Access all IP BUT the ones listed :
Browser 88.12.123.1.2

White list mode : Access no IP BUT the ones listed :
Browser 186.12.32.12:8080
129.38.41.221

@fedeocchio
Copy link

I hope it's the right place to post my question, otherwise, excuse me and please, let me know where I can do it.
I decided to install AFwall and I'm very happy. Thanks for everything. This APP is very precious.

But connecting my Windows PC to internet via tethering wifi hotspot (in order to use cellular data connection on my Samsung S2), misterious windows processes start in background downloading so many megabyte without inform me.
Thus, I'd like to block everything except navigation via browser to a specific website.
(for instance: rejecting all traffic except navigation into XDAdevelopers web site).

Someone suggested me to turn off (into my pc) "windows update" and so on, but I'm not sure to identify all the processes involved in background downloads.
And also reaching this goal, I should repeat it for each PC I want to connect in this way.
I have also tried a firewall (e.g. "private firewall") installed into Windows PC: I managed to split good traffing from bad traffic (blocking the second one) but , again, I should install and set up a firewall into each PC I want to connect to internet via Hotspot Android.

So, I'd like to apply a server side filtering (thinking my smartphone as a server).
Using AFwall, I've tried to set some custom scripts catched on internet, but without success.

May someone helps me?

thanks in advance

Federico
Samsung S2 GTI9100
Android 4.1.2 rooted

@cernekee
Copy link
Contributor

But connecting my Windows PC to internet via tethering wifi hotspot (in order to use cellular data connection on my Samsung S2), misterious windows processes start in background downloading so many megabyte without inform me.
Thus, I'd like to block everything except navigation via browser to a specific website.
(for instance: rejecting all traffic except navigation into XDAdevelopers web site).

You can use netfilter/iptables to whitelist specific IP addresses or ranges, e.g.

$IPTABLES -A FORWARD -d 50.23.216.69 -j ACCEPT
$IPTABLES -A FORWARD -d 184.172.3.199 -j ACCEPT
$IPTABLES -A FORWARD -j DROP

This can get a little clumsy, though, and tends to break for sites like Google which dynamically send you to different IPs depending on geographic location and server load. Different components of each page could reside on different IPs, and constructing a suitable whitelist may take some trial-and-error.

What might work better is to set up a proxy autoconfig (PAC) script in your Windows proxy settings. This would allow fine-grained control and pattern matching based on hostnames and URLs.

Or just run tinyproxy, squid, etc. on one of the hosts and use that to filter the requests.

Some other Windows-specific solutions are listed here.

@fedeocchio
Copy link

thanks for replying. I'm going to set up your scripts hoping it'll work.

@c33s
Copy link

c33s commented Apr 16, 2014

the feature that apps can be controlled seperatly is really important to protect the phone from inside. some apps, like for example a mail app, have to access the internet but i only want it to access mymailserver.example.com and not to search for updates at home or maybe also send my mailserver data to the company providing the app.

i really like the interface the NoRoot Firewall provides.
unnamed

the only problem with this firewall is that you cannot use vpn if you use the firewall. also i think boot leakage is a problem.

so i would really happy to see a good visual interface for afwall+
NoRoot Firewall also has the really nice feature, that on access to a new ip:port i get a notification that an app wants to connect outside and i only have to press "allow" or "deny"

so i am +1 for this feature

@c33s
Copy link

c33s commented Aug 10, 2016

would it be possible to add an example script on how to whitelist an app for some domains and block the rest? would be realy awesome for those of us who don't know iptables.

https://serverfault.com/questions/218707/iptables-rules-to-allow-http-traffic-to-one-domain-only

# Allow loopback
iptables -I INPUT 1 -i lo -j ACCEPT

# Allow DNS
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

# Now, allow connection to website serverfault.com on port 80
iptables -A OUTPUT -p tcp -d serverfault.com --dport 80 -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Drop everything
iptables -P INPUT DROP
iptables -P OUTPUT DROP

now i would really like to know how to adapt this code, to for example allow access to the app k9 mail only to mail.example.com

@migueldemoura
Copy link

I believe this would require some significant effort to bring to life. Is there any plans on tackling this specific feature, @ukanth?

@T-vK
Copy link

T-vK commented Sep 26, 2017

Shouldn't this be rather straight forward to implement?
I mean every app has their own user account in Android, so it should be quite simple to define iptable rules that only allow an app(/user) to access certain hosts. Maybe something like that:
iptables -A OUTPUT -p tcp -m tcp -d google.com --dport 80 -m owner --uid-owner APP_USER_ID -j ACCEPT

@ukanth

@Jabb0
Copy link

Jabb0 commented Nov 3, 2017

Hi guys,
this is exactly the feature I want too.

My idea is a prompt every time an app (that is allowed) wants to access a unknown ip adress.
That prompt should also contain the resolved hostname of that ip.

I will fork the project and try around.

@migueldemoura
Copy link

@Jabb0, if you get a working prototype, I'll be happy to test!

@T-vK
Copy link

T-vK commented Nov 4, 2017

@Jabb0 The reverse lookup is probably not too useful because you can have unlimited numbers of domains associated to a single IP address. This feature could also be abused for tracking if the app developer runs his own DNS server.

@Jabb0
Copy link

Jabb0 commented Nov 4, 2017

@T-vK I wonder if it is neccessary to block by domains instead of ips.
Let's say the content and the tracking service of the app is hosted on the same machine, but with different domains. In this case you can't only block the tracking service by IP.

So far the domain is resolved before the IPtables block takes effect.

@T-vK
Copy link

T-vK commented Nov 4, 2017

@Jabb0 I'm not sure how AFWall is handling DNS queries, but when blocking an app with AFWall, I was not able to resolve DNS queries with that app. You are of course right about IPtables, I totally forgot about that. IPtables fall more into the category of a filter (i.e. not a proxy). Generally on Linux dnsmasq would be the way to go when it comes to analyzing DNS queries to filter by host name. I don't know how AFWall is set up though.
And yeah, it's kinda tricky, on the one hand multiple domains can be associated with one IP, but on the other hand one domain could be associated with multiple IP addresses (round robin DNS).
For the latter you can safely assume that they all belong to the same company though.

I think a good solution would be to allow both, whitelists/blacklists for IPs and whitelists/blacklists for domains. But there would have to be a caching mechanism that keeps track of which IP addresses have been returned to all DNS queries.

The most difficult challenge that I see is having a [allow once] and [deny once] option. I think it can be implemented by temporarily adding the rules and removing them again as soon as the iptables log shows that a request has been made. I'm not sure if that could cause problems with receiving a an answer for protocols such as TCP and HTTP, though.

If it can be implemented the way that I assume it could, then I think this might be the way to go:

afwall-idea

I hope this makes sense. I'm not an Android developer, so I'm making a few assumptions here and there.

@Jabb0
Copy link

Jabb0 commented Nov 5, 2017

@T-vK looks reasonable to me. Thank you!
Currently I am trying to understand the networking/firewall features of android. The documentation isn't very detailed and there are two tools to set a firewall "iptables" as used by AFWall and "ndc", which I don't know much about yet. Maybe @ukanth can help me out here. Also in Android 8 they seem to do a lot of work on the kernel interface including the network stack.

After I understood that part and how AFWall works I want to extend the functionality.
I wonder if there is a way to block by domain without setting up a DNS proxy.

@T-vK
Copy link

T-vK commented Nov 5, 2017

I've never heard about ndc, but it seems to be a command line utility to create/configure/remove network interfaces (ndc network) and to change dns server settings (ndc resolver). I was not able to find that utility on my Android 6 phone, though. So this might be something that only existed on older devices.
I know that DNS settings can be changed to a certain degree using the settings utility, e.g settings put global default_dns_server "64.6.64.6".

And I would say that it is by definition not possible to block by domain without a proxy.
A packet filter can only filter by analyzing the IP packet headers which contains information like source IP, destination IP and protocol. Everything beyond that (e.g. analyzing DNS packet bodies) would fall into the category of a proxy.

You could do without a DNS proxy, but you would still need a proxy.
Xprivacy has an interesting approach for this. Xprivacy actually intercepts the API calls using Xposed to essentially create the behavior that we are looking for. Unfortunately Xprivacy hasn't been updates in years and there are lots of critical issues.
So that would be an API proxy, if you will.

I'm not a big fan of the concept, though. Because APIs change and Xposed development can't really keep up.

@Jabb0
Copy link

Jabb0 commented Nov 11, 2017

Current status:

  • Got the ruleset to block specific ip:port(range) for given app (per app whitelist and blacklist)
  • Found the code line to inject it
  • Currently developing the GUI to set the rules (in the AppDetailActivity. The one you get, when you click on an app in the list)

-> First attempt is to block IP/Port per APP without a prompt or anything. Also possible with domain blocking, but via Iptables (which is probably a one time lookup)

Still missing:

  • Block by domain (it is possible to specify a domain with iptables, but this seems to result in a one time DNS lookup). Setting up a DNS proxy is more work (including a good log method)
  • Notification at first connection to unknown ip with Allow/Deny Request. (A lot of work). Need to extend the current background service here.
  • Temporary settings (e.g. allow once)

My fork is here (no changes yet): https://github.com/Jabb0/afwall

@ukanth
Copy link
Owner

ukanth commented Nov 11, 2017

Domain names can't be resolved without dns level proxy (cernekee did work on those few years back). The reason I haven't done those changes because there are few design level changes required ( like profiles/whitelist/blocklist/ etc.,) Also where does this gets stored and at what stage it gets executed. There are still many areas I need to make changes, before that we can't implement these changes without affecting the existing

Please get in touch with me if you need more details. I'm little occupied with actual work and couldn't get enough time to go over github/xda questions. But will spend some time tomorrow on it.

@Jabb0
Copy link

Jabb0 commented Nov 13, 2017

@ukanth how can I get in touch with you?

@tristan-k
Copy link

tristan-k commented Dec 11, 2017

What about the context menu in the log section? I searched the wiki for informations but found none. What does the Action "Add to custom rule" actually do? Is this some sort of per app filtering mechanism? If so so how do I use it?

@deepanshu830
Copy link

@Jabb0 hello , can you please guide how to install your forked version. I am asking for a guide for beginners. I have a rooted phone , how can i install it. The guide on the github page is not sufficient for me.

@Jabb0
Copy link

Jabb0 commented Jan 29, 2018

Hi @deepanshu830 Until now I haven't commited any changes, because I only had time to do some gui stuff. Also I discussed with ukanth, that there need to be some changes to the way the app applies the IPTable rules before we can efficiently store per app rules. For example a new database structure.

In general:
You need to install android studio (as described at the official google dev docs) and pull the github directory.
Afterwards let the project load and simply hit run.
This will compile the code and deploy the apk to your connected phone.
It is the same as for every android dev project.

@fareloz
Copy link

fareloz commented Feb 26, 2018

Signing up for the request. Would be great to have it!

@Timmmy001
Copy link

This function would be really useful.

@franzmueller
Copy link

@Jabb0 Do you still have your parts lying around by any chance? I would like to help implementing this feature, but I'm still overwhelmed by the complexity of some Classes (like Api). Overall, I find it kinda hard to read the source of this app. A hint into the right direction would surely help :)

@Jabb0
Copy link

Jabb0 commented Mar 28, 2019

@franzmueller Great that you like to pick this up. I have been too busy to continue with my work.
Alright, let me check my code. I will check it in my fork of the repo. But I am not sure if it works with the new changes merged from the original repo. However I did not do that many changes, mostly research. I will try to share everything that might be usefull.

Here are some insights:

  1. The app is using iptables (and iptablesv6) to configure each apps permissions on the network. The availablity of filters depends on the android kernel used. This means that not every option works on every system.
    1.1 Each app is identified by its UID and this UID is used to filter the apps traffic. Different network types 3G, WIFI etc. are represented by different iptables rule chains.
    1.2. Depending if you want to whitelist or blacklist rules are applied differently. For example whitelist makes a default "block all" rule if no other rule matches.
  2. One thing the maintainer wanted to tackle is to use a sqlite database to store the rules. Maybe he already did this by now. Because when I checked the app it stored all rules as a serialized string and parsed it before applying them to the system.
  3. The iptables implementation does not support bulk insertion of rules. In other words the time to apply all rules scales with the number of rules.
  4. Resolving DNS entries and blocking domains can be difficult. DNS is managed by the Android system therefore it needs to be checked how this information can be utilized. Maybe by running a local DNS server as proxy on the device.
  5. The logs about blocking is extracted from the Kernel logs.

I already started to create a screen to set ip/port based rules per app. I think it would be best to setup the database to store all rules.

Inside the Api.java addRulesForUidlist method the rules are applied for each application UID.
Right now this is either block or allow (as far as I remember) and needs to be exchanged for port and IP specific rules.

        for (Integer uid : uids) {

            // TODO: HERE IS THE PART FOR APP BASED RULES
           // Check if the app is enabled for app based rules and process them in case
           if (uid != null && uid >= 0) {

                     cmds.add("-A " + chain + " -m owner --uid-owner " + uid + action);
           }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests