Monday, April 17, 2017

Using Tasker to Connect to AnyConnect VPN

When I am home, I access local resources over my WiFi network. When I am away, I VPN into my house so I can access these resources. I decided to find a way to have my Android phone automatically connect to my home VPN whenever I'm not connected to my home WiFi network. Enter Tasker: Tasker can automate pretty much anything on an Android phone.

Here is the specific use case I decided to automate:

If connected to SSID "HomeSSID"
    Then disconnect from AnyConnect VPN
If not connected to SSID "HomeSSID"
    Then connect to AnyConnect VPN named "HomeVPN"

As you can see, this is pretty simple logic. However, it's a bit tricky to a accomplish with Tasker and AnyConnect. Here are the methods I looked into:
  1. Create AnyConnect widget and have Tasker "press" the widget:
    • At the time of this post, Tasker does not have the ability to interact with a widget directly.
    • I did not want to use any an additional app to simulate screen presses. TouchTask may be able to do this, but I haven't tried it.
  2. Call intent to tell AnyConnect to connect to VPN:
    • This is probably the most elegant solution. However, after a bit of trial and error, I wasn't able to figure out how to call the intent directly.
  3. Use AnyConnect browser link to call connect to VPN:
    • This is the option that I used.
    • This requires enabling external control of AnyConnect, and is a potential security risk. An attacker could create a link to connect to a VPN, tunnel all traffic, and use it for a man-in-the-middle attack. For my use case, the benefit outweighs the risk.
After a bit of research, I found that Tasker can call intents. According to Google's Android API guide, "An Intent is a messaging object you can use to request an action from another app component." I spent a while reviewing "adb logcat" output trying to determine exactly what intent is called when the AnyConnect widget is pressed hoping I could then call this intent directly. I also used the Android App "Intent Intercept" to no avail.

However, it turns out some apps have intents that can be called through browser links. AnyConnect is one such app. In order for this to work, the "External Control" setting must be set to "Enabled" in the AnyConnect app settings. Once this setting is changed, the following browser link will launch the AnyConnect profile "HomeVPN." This browser link can then be called through Tasker.
anyconnect:connect?name=HomeVPN
I ended up creating two Tasker tasks with two associated Tasker profiles - one to connect to my VPN when not connected to my home wireless network, and one to disconnect from my VPN when connected to my home wireless network. I use certificate-based AnyConnect authentication which makes connecting a bit easier, since I don't need Tasker to pass credentials to AnyConnect. I also found that a two-second delay before connecting to my VPN was often necessary to give my phone enough time to finish transitioning from WiFi to LTE.