Auto-connect to ProtonVPN on untrusted WiFi with Tasker
I recently shared how I use Tasker and Home Assistant to keep my phone from charging past 80%. Today, I'm going to share the setup I use to automatically connect my phone to a VPN on networks I don't control.
- The apps
- OpenVPN config file
- Configuring OpenVPN for Android
- Tasker profiles
- Epilogue: Working with Google's VPN
Android has an option to set a VPN as Always-On so for maximum security I could just use that. I'm not overly concerned (yet?) with my internet traffic being intercepted upstream of my ISP, though, and often need to connect to other devices on my home network without passing through a VPN (or introducing split-tunnel complexity). But I do want to be sure that my traffic is protected whenever I'm connected to a WiFi network controlled by someone else.
I've recently started using ProtonVPN in conjunction with my paid ProtonMail account so these instructions are tailored to that particular VPN provider. I'm paying for the ProtonVPN Plus subscription but these instructions should also work for the free tier as well. (And this should work for any VPN which provides an OpenVPN config file - you'll just have to find that on your own.)
ProtonVPN does provide a quite excellent Android app but I couldn't find a way to automate it without root. (If your phone is rooted, you should be able to use a Tasker shell to run
cmd statusbar click-tile ch.protonvpn.android/com.protonvpn.android.components.QuickTileService and avoid needing to use OpenVPN at all.)
You'll need a few apps to make this work:
It's important to use the open-source 'OpenVPN for Android' app by Arne Schwabe rather than the 'OpenVPN Connect' app as the latter doesn't work with the Tasker plugin.
OpenVPN config file
You can find instructions for configuring the OpenVPN client to work with ProtonVPN here but I'll go ahead and hit the highlights. You'll probably want to go ahead and do all this from your phone so you don't have to fuss with transferring files around, but hey, you do you.
- Log in to your ProtonVPN account (or sign up for a new free one) at account.protonvpn.com/login.
- Use the panel on the left side to navigate to Downloads > OpenVPN configuration files.
- Select the Android platform and UDP as the protocol, unless you have a particular reason to use TCP.
- Select and download the desired config file:
- Secure Core configs utilize the Secure Core feature which connects you to a VPN node in your target country by way of a Proton-owned-and-managed server in privacy-friendly Iceland, Sweden, or Switzerland
- Country configs connect to a random VPN node in your target country
- Standard server configs let you choose the specific VPN node to use
- Free server configs connect you to one of the VPN nodes available in the free tier
Feel free to download more than one if you'd like to have different profiles available within the OpenVPN app.
ProtonVPN automatically generates a set of user credentials to use with a third-party VPN client so that you don't have to share your personal creds. You'll want to make a note of that randomly-generated username and password so you can plug them in to the OpenVPN app later. You can find the details at Account > OpenVPN / IKEv2 username.
Configuring OpenVPN for Android
Now what you've got the config file(s) and your client credentials, it's time to actually configure that client.
- Launch the OpenVPN for Android app and tap the little 'downvote-in-a-box' "Import" icon.
- Browse to wherever you saved the
.ovpnconfig files and select the one you'd like to use.
- You can rename if it you'd like but I feel that
us.protonvpn.com.udpis pretty self-explanatory and will do just fine to distinguish between my profiles. Tap the check mark at the top-right or the floppy icon at the bottom right to confirm the import.
- Now tap the pencil icon next to the new entry to edit its settings, and paste in the OpenVPN username and password where appropriate. Use your phone's back button/gesture to save the config and return to the list.
- Repeat for any other configurations you'd like to import. We'll only use one for this particular Tasker profile but you might come up with different needs for different scenarios.
- And finally, tap on the config name to test the connection. The OpenVPN Log window will appear, and you want the line at the top to (eventually) display something like
I don't like to have a bunch of persistent notification icons hanging around (and Android already shows a persistent status icon when a VPN connection is active). If you're like me, long-press the OpenVPN notification and tap the gear icon. Then tap on the Connection statistics category and activate the Minimized slider. The notification will still appear, but it will collapse to the bottom of your notification stack and you won't get bugged by the icon.
Open up Tasker and get ready to automate! We're going to wind up with at least two new Tasker profiles so (depending on how many you already have) you might want to create a new project by long-pressing the Home icon at the bottom-left of the screen and selecting the Add option. I chose to group all my VPN-related profiles in a project named (oh-so-creatively) "VPN". Totally your call though.
Let's start with a profile to track whether or not we're connected to one of our preferred/trusted WiFi networks:
- Tap the '+' sign to create a new profile, and add a new State > Net > Wifi Connected context. This profile will become active whenever your phone connects to WiFi.
- Tap the magnifying glass next to the SSID field, which will pop up a list of all detected nearby network identifiers. Tap to select whichever network(s) you'd like to be considered "safe". You can also manually enter the SSID names, separating multiple options with a
FBI Surveillance Van/TellMyWifiLoveHer/Pretty fly for a WiFi). Or, for more security, identify the networks based on the MACs instead of the SSIDs - just be sure to capture the MACs for any extenders or mesh nodes too!
- Once you've got your networks added, tap the back button to move forward to the next task (Ah, Android!): configuring the action which will occur when the context is satisfied.
- Tap the New Task option and then tap the check mark to skip giving it a name (no need).
- Hit the '+' button to add an action and select Variables > Variable Set.
- For Name, enter
%TRUSTED_WIFI(all caps to make it a "public" variable), and for the To field just enter
- Hit back to save the action, and back again to save the profile.
- Back at the profile list, long-press on the Variable Set... action and then select Add Exit Task.
- We want to un-set the variable when no longer connected to a trusted WiFi network so add a new Variables > Variable Clear action and set the name to
- And back back out to admire your handiwork. Here's a recap of the profile:
Profile: Trusted Wifi State: Wifi Connected [ SSID:FBI Surveillance Van/TellMyWifiLoveHer/Pretty fly for a WiFi MAC:* IP:* Active:Any ] Enter: Anon A1: Variable Set [ Name:%TRUSTED_WIFI To:1 Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:0 ] Exit: Anon A1: Variable Clear [ Name:%TRUSTED_WIFI Pattern Matching:Off Local Variables Only:Off Clear All Variables:Off ]
VPN on Strange WiFi
This profile will kick in if the phone connects to a WiFi network which isn't on the "approved" list - when the
%TRUSTED_WIFI variable is not set.
- It starts out the same way by creating a new profile with the State > Net > Wifi Connected context but this time don't add any network names to the list.
- For the action, select Plugin > OpenVpn Tasker Plugin, tap the pencil icon to edit the configuration, and select your VPN profile from the list under Connect using profile
- Back at the Action Edit screen, tap the checkbox next to If and enter the variable name
%TRUSTED_WIFI. Tap the '~' button to change the condition operator to Isn't Set. So while this profile will activate every time you connect to WiFi, the action which connects to the VPN will only fire if the WiFi isn't a trusted network.
- Back out to the profile list and add a new Exit Task.
- Add another Plugin > OpenVpn Tasker Plugin task and this time configure it to Disconnect VPN.
Profile: VPN on Strange Wifi State: Wifi Connected [ SSID:* MAC:* IP:* Active:Any ] Enter: Anon A1: OpenVPN [ Configuration:Connect (us.protonvpn.com.udp) Timeout (Seconds):0 ] If [ %TRUSTED_WIFI !Set ] Exit: Anon A1: OpenVPN [ Configuration:Disconnect Timeout (Seconds):0 ]
Give it a try - the VPN should automatically activate the next time you connect to a network that's not on your list. If you find that it's not working correctly, you might try adding a short 3-5 second Task > Wait action before the connect/disconnect actions just to give a brief cooldown between state changes.
Epilogue: working with Google's VPN
My Google Pixel 5 has a neat option at Settings > Network & internet > Wi-Fi > Wi-Fi preferences > Connect to public networks which will automatically connect the phone to known-decent public WiFi networks and automatically tunnel the connection through a Google VPN. It doesn't provide quite as much privacy as ProtonVPN, of course, but it's enough to keep my traffic safe from prying eyes on those public networks, and the auto-connection option really comes in handy sometimes. Of course, my Tasker setup would see that I'm connected to an unknown network and try to connect to ProtonVPN at the same time the phone was trying to connect to the Google VPN. That wasn't ideal.
I came up with a workaround to treat any network with the Google VPN as "trusted" as long as that VPN was active. I inserted a 10-second Wait before the Connect and Disconnect actions to give the VPN time to stand up, and added two new profiles to detect the Google VPN connection and disconnection.
Google VPN On
This one uses an Event > System > Logcat Entry. The first time you try to use that you'll be prompted to use adb to grant Tasker the READ_LOGS permission but the app actually does a great job of walking you through that setup. We'll watch the
Vpn component and filter for
Established by com.google.android.apps.gcs on tun0, and then set the
Profile: Google VPN On Event: Logcat Entry [ Output Variables:* Component:Vpn Filter:Established by com.google.android.apps.gcs on tun0 Grep Filter (Check Help):Off ] Enter: Anon A1: Variable Set [ Name:%TRUSTED_WIFI To:1 Recurse Variables:Off Do Maths:Off Append:Off Max Rounding Digits:3 ]
Google VPN Off
This one is pretty much the same but the opposite:
Profile: Google VPN Off Event: Logcat Entry [ Output Variables:* Component:Vpn Filter:setting state=DISCONNECTED, reason=agentDisconnect Grep Filter (Check Help):Off ] Enter: Anon A1: Variable Clear [ Name:%TRUSTED_WIFI Pattern Matching:Off Local Variables Only:Off Clear All Variables:Off ]