ukanth / afwall

AFWall+ (Android Firewall +) - iptables based firewall for Android
GNU General Public License v3.0
2.77k stars 456 forks source link

VPN for selected apps and Internet for all others #1096

Open timur-g opened 4 years ago

timur-g commented 4 years ago

I use L2TP to connect to work and it's working via custom script where I added VPN ports and IP addresses of VPN tunnel. But, when Android built-in VPN is on, I don't have Internet access.

I'd like to have, at the same time, VPN for selected apps (and private range I connect to, 10.x.0.0) and normal direct Internet for all other apps and public addresses. Point here are IP. I already added separate VPN control for apps.

Like: for Work.Net or work apps or 10.x.0.0 (what's possible) go thru VPN and use it's DNS, and for else use current internet (Wifi or 3G) and it's DNS and gateway.

Note: I searched issues and couldn't find (doesn't mean doesn't exist). I looked at Afwall "Custom Scripts" but couldn't figure this out. Thanks for help.

tusch001 commented 4 years ago

Can't you configure your VPN app for this? Most VPN apps I know let you choose on a per app basis in settings?

If not: you can put special iptable rules in a custom script for AFwall to be executed when applying the rules: I place mine in /data/local/dev.ukanth.ufirewall/custom_script.sh. When you put this path in the field in settings - custom script you need to put a dot in front of it (works with me, not sure why). Make sure AFwall also uses system iptables (in settings - binaries) or adjust the variable to your system.

Make sure you copy the lines where you determine the UID correctly with the backticks.

So here is the content of your custom script:

IPTABLES=/system/bin/iptables

#VPN local access
VPN_IP=10.yyy.yyy.yyy
VPN_PORT=zzzz

#get for each app that has to use the VPN the android name of the app (in AFwall in the app info directly under the appname when tapping on the line)
#app 1: org.organisation1.name1
#app 2: net.organisation2.name2
#app 3: com.organisation3.name3

#get system UID for the app
APP_UID=`dumpsys package org.organisation1.name1 | grep userId= | cut -d= -f2 - | cut -d' ' -f1 -`

#use  NAT tables to route packages:
$IPTABLES -t nat -A OUTPUT -m owner --uid-owner $APP_UID -j DNAT --to-destination $VPN_IP:$VPN_PORT

#repeat the last 2 commands for each app that uses the VPN

edit: for DNS there's no way to make one app use google dns and other apps use work dns. As the topic DNS and VPNs / Tor has been discussed several times before I quote freely one of the authors: DON'T MESS AROUND. It just opens a bunch of other security issues.

Having said this: In Android 9+ you could use DNS over TLS for encryption. Other VPNs like Orbot provide a port for DNS (5400) and you could use NAT rules to translate port 53 (unencrypted DNS) to this (Orbot doesn't need to run as VPN for this).