This is going to sound strange, and please don't judge the impracticality of doing something like this, but I need to add support for controlling out bound network traffic from an Android device. Doesn't have to be selective. I basically need to put the device in a mode where out bound communication is silenced over WIFI. (primarily) The reason for this is I have a networked application that's remotely controlled and I need to be able to put it to "communication sleep" on-demand and then "wake it up" after a period of time, or on-demand. The on-demand aspect is controlled remotely. Hence the need to put the device in a state where it'll only accept in bound communication.
I'm primarily interested in TCP/UDP blocking of out bound traffic. I'm not interested in a separate firewall app. My application includes a service that's already implementing all the communication code required. I just need some suggestions on how to control out bound communication.
FYI, I have a mix of 2.3 and 4.0 devices to work with.
Could I have my service implement some basic firewall support? Maybe a simple proxy that the device is configured to use? (similar to the Ad Block app)
Thanks in advance for any suggestions. If it's at all possible, I'll try to share the code for it here.
UPDATE: Sorry, I have and require root on these devices anyways.
On the proxy idea, really I just need a black hole listening on a port. If I can set the system proxy settings from my app, when the out bound communication needs to be disabled, I can enable the proxy and drop all connections.
If I can't set the system proxy settings, I'll have to implement a working proxy, require the user configure the proxy, and control it's behavior accordingly when connections are received.
I might as well answer my own question. With root you can include iptables and make some command line calls to control the traffic flow. Note that you should have some experience with stateful firewall concepts, as mucking with outbound DENYs will lead you to confusion unless you know exactly what the system/app is supposed to do. (random response ports, etc...)
A proxy service would work for Android devices and versions which allow for network proxy support. Unfortunately not all my devices allow for it. (my Ginger Bread devices don't have proxy support, it's just not present in the UI, and the API is read only for the HTTP_PROXY System setting)
So there's no example code to offer. I'm playing with iptables on my devices. I'll likely include it in my application, which requires root anyways.
Related
I'm developing a mobile app that uses WiFi without internet connection (in order to communicate to an IOT device) and it uses cellular data as well (see TL;DR section for more).
The problem -> some devices don't automatically switch their default route to cellular (rmnet interface) while others are capable.
The workaround -> create a *"local" VPN in order to manage and re-routing network traffic via cellular interface (there are apps like Speedify that can do this by assigning priority to interfaces)
The question -> there is a simple way to accomplish this or it's pretty tricky? When I say "simple" I mean the calls of several well documented API and when I say "tricky" I mean to starting read and parse routing table with customized rules depending on every vendors?
"*local" = a VPN without web server or VPN gateway because I'm not actually interested to do the VPN's job (I seem to have understood that I need a VPN level to manage network traffic of others app but I'm pretty newbie of VPN topic)
TL;DR
My goal is to remaining connected to my access point (in order to call its APIs) AND use cellular data for all others requests I.e: login via my backend, use Google Maps and so on.
Handle this scenario it's quite easy because combining network objects, socketFactory and bindProcessToNetwork I'm able to do this.
Troubles come for others app like YouTube, WhatsApp that stop working because as default network they are using my access point without internet (Android doesn't switch default interface to a cellular)
I'm going crazy because seems that each vendor (or Android OS version?) handles "WiFi without connectivity" with cellular active in a different way.
There are certain devices that all work fine (similar to iOS) but there are others that it's a nightmare.
See this question for further details
Thanks for reading, I really love Android but those issues make me sadder every day more and I'm thinking to pass to the Dark Side of mobile development (iOS).
You've the chance to change my mind ;)
I would like to make an app that allows you to block certain internet sites on Android. For instance, you set what sites to block in my app, then when you try to access that site through chrome (or another browser on Android) you are denied access.
The trend micro app can do this, as can some others, however I cannot work out how. Possible ideas I have are as follows (although I am not an android dev, not sure on feasibility):
Set up VPN / proxy that runs in-app, routing all device traffic through this. Seems like a lot of work to tunnel all traffic via your app.
Set up a DNS proxy, however that only will filter at domain level (rather than URL level) and has some other issues
Edit hosts table. Requires root access.
Is there any other way I missed? How do similar apps do this, and how would you go about it? It would be great if there was some way to hook in to network calls to accept / block / redirect traffic rather than having to tunnel all network data through my app. Thanks
I'd suggest using the app "Netguard" in this case. Although per site traffic filtering requires a pro package, I think it's worth the shot. Netguard filters trafiic quite well and also has packet capture option by default.
The use case is that:
all the applications on the android phone would connect to internet through a wifi.
And I want to have an application that eavesdrops on the http traffic from all apps so that I can find what sites they visit.
This application would be distributed as an apk and users would install this app on their phone.
How do I achieve this ?
I will tell what I tried:
Used a Custom Vpn Service application where an activity triggers a service derived from VpnService.
The Custom VpnService calls builder and sets Mtu, addRoute, addAddress, and then addDnsServer.
Then the service reads from the file descriptor associated with the interface generated from builder's establish() call.
Now if the addRoute is called with ("0.0.0.0", 0), Iam able to intercept the traffic and see packet contents. But Iam not able to route the packets without creating udp tunnel to an external server which I dont want to do.
If the addRoute is called with the Wifi router IP, then routing automatically happens for all packets generated. But I am not able to intercept the packets on the file descriptor associated with the virtual interface. It simply doesnt receive any data on read() call.
What I want to do is:
intercept the traffic to inspect the http headers
at the same time, do routing as usual like a normal wifi connection does.
Have everything self contained in the phone. There should be no external server.
this appliction should not require any rooting or such. It should install the way a normal app does.
I would suggest 1) setting a proxy and 2) running an app which acts as one. The combination of these two won't require root privileges.
SETTING THE PROXY
This first point is probably the most tricky one. The only way of setting a software-level proxy (without requiring root) is by navigating to the Wi-Fi connection settings and manually set the proxy. However, there is an open-source application that can eventually bypass this particular step: ProxySettings.
INTERCEPTING THE TRAFFIC
In my opinion, your best bet is using SandroProxy, an open-source proxy application for Android. It is extremely well written, currently maintained and supported, and will allow you to intercept the HTTP traffic and even modify it. The code can be found here, while the example application can be found here.
This solution should fulfil all of your requirements:
Intercept the traffic (even edit it): thanks to the proxy setting, all the network traffic goes through the proxy address, which corresponds to your application
Edit is optional: everything will keep working as no proxy is set
Everything is local: no need for external servers, your proxy is the installed application
No root is required
My app connects with a persistent connection to a server. If the device is currently using 3G it will connect over 3g.
The problem is that if it connected using 3G and moved into wifi the connection drops. How do I prevent it from disconnecting?
Sounds like the server is unable to accommodate clients seamlessly switching to a different IP address, or it may be using something like keep-alive packets to maintain connection state, and when the 3G connection drops, it disconnects your session.
This may not be something you have control over. From the Android point of view - the device will prefer WiFi depending on user preferences and you will likely not have any direct control over that either.
In a nutshell - if you can't modify or reconfigure the communications protocol to allow client IP changes on the fly, then there's nothing you can do with Android to mitigate the problem.
All mobile devices, and to a lesser extent, desktops/laptops will at some point change their public facing IP address, so it sounds like a bug or oversight in the server/protocol design to me.
EDIT:
In response to your comment, and in the interests of UX, you should be very careful about finding a way to force your app (possibly even the entire device) to remain on 3G when the user has requested that it use WiFi.
Most people have capped data plans with their device and wouldn't be very pleased if they think they are using WiFi (which is most likely free, or at least no additional cost) when in fact you've forced their device to continue using potentially very expensive 3G data instead.
This is especially important when any method would likely be actively circumventing the reasonable limits the Android environment presents you with, and therefore would probably not be flagged as a "Service that costs you money" when installed.
EDIT 2:
So, there may be a way for you to do it, but it relies on unsupported, private Android APIs which may change at any moment - usual disclaimer applies.
Take a look here where they access the ConnectivityManager object to allow you to enable mobile data.
This method does require you to build against the Android source tree, and use a shared user ID with "system" so may or may not be suitable, but these APIs are private (as apps are not supposed to be able to do this without user action), but it may help you.
This is how Android works. You're app should not maintain a persistent connection, it should only open a connection when needed.
Just a quick question as Google isn't throwing up much.
Is it possible to create a VPN connection using native code in
Android?
And if so does the VPN offer support for keep alives?
I believe it would be more of a permissions issue than of an exposed or not exposed issue. Most VPN connections would need you to modify and access the network filtering calls of your kernel. Since your app should really be operating in it's own sandbox this is something I would doubt is exposed by default (to apps at least) since you would essentially be modifying the way the entire OS routes network traffic. For the same reason that in order to modify iptables in the OS, it needs to be rooted so that your app can actually alter such things. At that point I would assume the connection would be made similar to any other vpn connection in any other linux os (via an ipsec daemon or some proxy dameon that you create), but the calling entity would need the actual access level necessary to complete the call to the kernel.
Rooting of the device is needed for creating a VPN connection. We need access to /data/misc/keystore and /data/misc/vpn/profiles in our programm.