How to use NetGuard + personalDNSFilter+ Any VPN, without root, without external self-hosted servers.

Together, with the people over at the personalDNSfilter Telegram group, we've discovered a way to run multiple "VPN"s at the same time by taking advantage of work profiles.

All of this started because I was trying to control Work-profile apps using the Netguard instance that I had on my main profile.

Screenshot. M66B saying that netguard has no work-profile support because "many Android versions do not handle the Android VPN service correctly".

After I read that comment from the Netguard dev, I realized that the work profile had a separate VPN slot, so therefor, it's possible for us to have an actual VPN and a SOCKS5 proxy server in the work profile, and then connect to this SOCKS5 proxy from the main profile using NetGuard. Below is a flowchart of how this whole thing is going to work:

A flowchart of how this whole setup works
A flowchart of how this whole setup works

Don't worry, the rest of this blog was written in a non-technical way, so it's easy to follow for non-technical people.

This has been tested on Android 9, on a Moto e6 plus. This blog assumes that you already know:

  • How to install an APK
  • How to use ADB

Requirements

  • Android 5.0+
  • 446.03 MB (446,030,000 bytes) of available storage
  • A computer
  • A cable to connect your phone to the computer.

Why so much storage?

Item Size
Work Profile: Island + ProtonVPN + SOCKS5 Proxy + System stuff 398.53MB
NetGuard 17.09MB
personalDNSFilter 5.67MB
Island 24.74MB
TOTAL 446.03MB

NOTE: This should be obvious, but I'm going to say it anyway: Because we're running multiple profiles and apps at the same time, this setup is fairly energy hungry. NetGuard and personalDNSfilter have a very small battery footprint, but the apps we'll have on the work profile are not as optimized.

NOTE 2: Some brands/devices do not fully support using a VPN in the work profile. To quote M66B (emphasis added):

NetGuard is supported in the primary profile only. It might or might not work in other profiles, but this scenario is not supported because is basically isn't supportable. I have wasted enough time on trying to support this in the past.

Something like "Shelter" is not standard Android and a manufacturer modification, which is the core problem because these modifications often do not take the Android VPN service into account too.

This setup might or might not work in your device, so make sure you test it before doing anything "risky". This guide is known not to work on some LG devices running Android 9.

Index

Glossary

Work Profiles

Island and Shelter are apps which take advantage of the Android work-profile  in order to create a "sandbox"; Using this sandbox, we can give privacy invasive apps their own "private data pools", aka, their own storage for:

  • SMS History
  • Call History
  • File Storage

Having a separate profile on android, also allows you to have multiple versions of a single app running simultaneously, without modifying the app's APK. In contrast to other "parallel apps" apps, this approach allows us to easily get security updates from the playstore, as the app doesn't have to be re-signed in the first place.

There's also the benefit of being able to hide an app from another app (For example, you can hide "Lucky Patcher" from a game).

And lastly, but most important, a work profile allows us to have two VPNs at the same time.

F-Droid

F-Droid is an app store and software repository for Android, serving a similar function to the Google Play store. The main repository, hosted by the project, contains only free and open source apps. Applications can be browsed, downloaded and installed from the F-Droid website or client app without the need to register for an account.

SOCKS5 Proxy

SOCKS is an Internet protocol that exchanges network packets between a client and server through a proxy server. SOCKS5 optionally provides authentication so only authorized users may access a server. Practically, a SOCKS server proxies TCP connections to an arbitrary IP address, and provides a means for UDP packets to be forwarded.

Network Port

In computer networking, a port is a communication endpoint. At the software level, within an operating system, a port is a logical construct that identifies a specific process or a type of network service. A port is identified for each transport protocol and address combination by a 16-bit unsigned number, known as the port number. The most common transport protocols that use port numbers are the Transmission Control Protocol (TCP) and the User Datagram Protocol (UDP).

A port number is always associated with an IP address of a host and the type of transport protocol used for communication. It completes the destination or origination network address of a message. Specific port numbers are reserved to identify specific services so that an arriving packet can be easily forwarded to a running application. For this purpose, port numbers lower than 1024 identify the historically most commonly used services and are called the well-known port numbers. Higher-numbered ports are available for general use by applications and are known as ephemeral ports.

IP Address

An Internet Protocol address (IP address) is a numerical label such as 192.0.2.1 that is connected to a computer network that uses the Internet Protocol for communication.[1][2] An IP address serves two main functions: network interface identification and location addressing.

Internet Protocol version 4 (IPv4) defines an IP address as a 32-bit number.[2] However, because of the growth of the Internet and the depletion of available IPv4 addresses, a new version of IP (IPv6), using 128 bits for the IP address, was standardized in 1998.[3][4][5] IPv6 deployment has been ongoing since the mid-2000s.

IP addresses are written and displayed in human-readable notations, such as 192.0.2.1 in IPv4, and 2001:db8:0:1234:0:567:8:1 in IPv6. The size of the routing prefix of the address is designated in CIDR notation by suffixing the address with the number of significant bits, e.g., 192.0.2.1/24, which is equivalent to the historically used subnet mask 255.255.255.0.

TL;DR: Your phone can have multiple IP Addresses (aka Network connections), and every port must be associated with an IP Address.

Setup

Island or Shelter?

We must install one of these two apps. Island contains Google trackers, but it has a bigger userbase, therefor, less bugs. Meanwhile, Shelter is completely open-source, but has a smaller userbase. For this tutorial I'll be using Island, since that's what I have already set-up, but feel free to use Shelter if you prefer so.

1) Download the app: https://play.google.com/store/apps/details?id=com.oasisfeng.island&gl=US

2) Launch the app and follow the setup instructions given by Island (Here's where you'll need your computer)

// I won't include a detailed guide here because the setup steps change a lot from phone to phone, and I believe that the setup is best explained by the app itself.

Netguard

Netguard is a FOSS app that allows us to control exactly which apps have access to the internet, and which don't. We can give an app WiFi access, mobile data access, or make it so that netguard doesn't control the app at all.

Installing the app

Here, we have two options: Installing from GitHub, or installing from F-Droid. We can't install netguard from the playstore because the playstore release doesn't support port-forwarding, and that feature is obligatory for us to be able to do our trick.

I recommend installing NetGuard from F-Droid, since it's easier to update it from there. If you don't already have an F-Droid client, I recommend using AuroraDroid. Simply download the APK file, and install it. After opening the app and finishing the setup, search for "NetGuard" and install the first result.

I recommend spending some time fine-tweaking which apps you give internet access to. Most apps only ask for internet access to show you ads/collect analytics.

Why personalDNSFilter?

Why use personalDNSfilter? Doesn't Netguard already have a hosts blocker?

You see, dear reader, NetGuard's hosts blocking mechanism only supports explicit hosts blocking, whereas personalDNSfilter supports wildcard hosts blocking. This makes it so we can use block lists that are more efficient, and easier to maintain.

Installing personalDNSfilter

This is easy. You can either install it from F-Droid (using AuroraDroid), or you can install it from the playstore. They're both the same.

After installing the app, tap on "Advanced settings" and make them match this:

Screenshot of Advanced settings in personalDNSFilter. CNAME Cloaking protection: ON. DNS proxy mode without local VPN: ON. Allow only local DNS proxy requests: ON. Root mode without local VPN: OFF.

What we're doing here, is configuring pDNSf so it doesn't use a VPN slot, but instead opens a "DNS proxy" on port 5300.

Installing the SOCKS5 proxy

Now, you must launch the Google Playstore from within Island:

Screenshot of Launching the Google Playstore from within the Island app

Now search and install "Every Proxy". "Every Proxy" has no ads, and no trackers, hence, why I picked it. Make sure NetGuard is up and running on the main profile, and then launch the EveryProxy app, and hit the three dots on the top left corner, then "Settings". Scroll down to the bottom and make your settings match this:

Screenshot of configuration for the SOCKS5 proxy in Every Proxy. IP Address: 10.1.10.1. Port: 1088. Power save: Off. Auto Start at startup: Off. Enable basic authentication: On. Username: redacted. Password: redacted. More secure: On.

Of course, you must create a username and password. You don't really need to remember the password. Just copy it to your clipboard. (IMPORTANT: DO NOT make the password 126 characters long, else netguard will enter a crash loop that might crash your entire phone). Now go back to the main screen of the app, and start the SOCKS5 proxy. Make sure to disable battery optimizations for "Every Proxy", else Android might kill the app unexpectedly. If you don't know how to disable these optimizations, go to dontkillmyapp.com.

Screenshot of Every Proxy with SOCKS5 On.
"Every Proxy" with the SOCKS5 proxy activated

Configuring Netguard

Now you must go back to your main profile and open Netguard. Do NOT "Deactivate" the work profile.

Here's the tricky part. Go into NetGuard -> Three Dots (on the top right corner) -> Settings -> Advanced Options -> Port Forwarding

Once you're inside that menu, click the "+" icon on the top right corner. Make the details match the following screenshot:

Screenshot of netguard configuration. Protocol: TCP. Destination address: 127.0.0.1. Destination port: 5300. Destination app: personalDNSFilter.

Click OK. Now do the exact same thing again, but instead of selecting "TCP", select "UDP".

Basically, what we're doing is configuring netguard so whenever an outbound DNS request goes through port 53, it will be redirected to localhost (127.0.0.1) to port 5300 to personalDNSFilter. We use port 5300 because that's the only port that pDNSf can work on without having root, without occupying the VPN slot.

Now go back to the main screen of the app. Look for "personalDNSFilter" and untick the "Apply rules and conditions" checkbox:

screenshot of personalDNSfilter being excluded from control by netguard.

We do this so that there isn't an infinite DNS loopback: For example, if Google Chrome wants to resolve example.com, then the request will go through NetGuard, which will use 127.0.0.1 as the DNS resolver. pDNSf will resolve it according to its configuration, but when it makes the outbound dns resolution request to it's configured DNS servers, that request will be caught by NetGuard, which will try to resolve it using 127.0.0.1, so pDNSf requests tries to resolve it, but its caught by NetGuard, who tries to resolve it using 127.0.0.1, so pDNSf requests tries to resolve it, and so on and so forth....

Now we have to configure netguard to use the SOCKS5 proxy. Go to NetGuard -> Three Dots (on the top right corner) -> Settings -> Advanced Options and scroll down to the section about the SOCKS5 Proxies:

Netguard config screenshot. SOCKS5 address: 10.1.10.1. SOCKS5 port: 1088. Socks5 username: redacted. Socks5 password: redacted.

The "SOCKS5 username" and the "SOCKS5 password" must match the username and password that you configured on "Every Proxy".

Lastly, we have to configure the VPN DNS. Go to "Settings" -> "Advanced Options" and scroll down. Set both "VPN DNS" settings to any WAN external server (Avoid "localhost", "127.0.0.1", "10.1.10.1", "192.168.0.1", and such. Copy me if you're not sure on what server to use). It doesn't matter what servers you pick here, your DNS requests won't be sent to these servers. The DNS requests will be redirected to pDNSf thanks to the forwarding rule we setup earlier.

Why not just put "127.0.0.1" as the VPN DNS you ask? To put it simply, NetGuard has DNS Leaks which can only be avoided using this hacky method. Without this workaround, who our ISP is would be exposed, and nobody wants that!

Installing the actual VPN

Finally! Just like you installed "Every Proxy" on the work profile, now do the same but instead look for the VPN that you want. In my case, I'll be using ProtonVPN.

After starting the VPN, if you did everything right, you should see some traffic starting to pop up on your VPN app:

Screenshot of ProtonVPN with traffic coming through.

You can verify that the VPN is working by going to any of the following sites with the VPN activated:

Just make sure that your browser is controlled by NetGuard, else it will just bypass the entire system.

If you wish to disconnect from the VPN without dropping any packets, do this, in this specific order:

  • Disable "Use SOCKS5 proxy" in NetGuard.
  • Stop your VPN app and the SOCKS5 proxy on "Every Proxy" (the order of these two steps doesn't matter, hence why they're combined in a single one).
  • "Deactivate" the work profile using the notification from Island.

Conclusion

And that's about it. I personally don't need to use this setup very often, because I live in a country that's not within the 14 eyes surveilance alliance. But I hope it benefits you, reader. If you have any unexpected problems with this setup, or just wanna say "thank you!", please leave a comment below.