Alexa, Teleport Me!

Overview

Introduction

One day I was thinking to myself...

Wouldn't it be cool if I was able to just ask Alexa to teleport me to another country... Wait a minute... hold my beer.

I proceeded to create some simple automation and a private Alexa Skill called 'Teleport Machine'.

Alexa, ask Teleport Machine to teleport me to Canada.

Upon asking Alexa to teleport me, my router is automatically re-configured and a full-tunnel VPN is established to the country that was specified in the request.

There's a few things that I wanted to achieve in this small project:

  • Find a creative way to use AWS Free Tier in my personal account
  • Implement a project using the AWS CDK version 2
  • Learn about Alexa, and create a useful Alexa Skill

Architecture

The Teleport Machine Architecture

The first prototype, I initially used a Raspberry Pi with a service to SSH into my EdgeRouter X router to run the commands. However, since the Raspberry Pi is behind the router, it was using NAT to connect out to SQS and traverse the very VPN it established. I ran into an issue where if (for whatever reason), the VPN wasn't working, I needed to manually intervene by logging into the router. It was another piece of hardware, so I decided to simplify the design and run the script on the EdgeRouter X.

Cost

This project should be able to operate within the AWS free usage tier, so total estimated AWS usage costs are $0.00 (zero dollars)

  • The Amazon SQS free usage tier includes 1 million requests, and up to 1 GB/month data transfer out.
  • The AWS Lambda free usage tier includes 1M free requests per month and 400,000 GB-seconds of compute time per month.

Long polling allows us to poll the queue for messages for a period before disconnecting.

Calculation:

  • 1x receiveMessage per minute * 60 minutes = 60 API calls per hour
  • 60 calls per hour * ~744 hours in a month (to be safe) = 44,640 receive messages per month
  • ~20 teleportation requests to my Echo per month = ~20 Lambda function invocations per month

How it works

Upon asking the Teleport Machine to teleport me to a specific country, an AWS Lambda function will place a message onto an Amazon SQS Queue. My router polls the queue, processing any requests to teleport by establishing pre-defined VPN configurations.

The Alexa Skill and TeleportSkill Lambda function

The Alexa Skill is implemented with 2x Intents.

  • TeleportIntent - With a slot for capturing the Country
  • ReturnHomeIntent - To deprovision the VPN

Alexa has a Slot type called AMAZON.Country, which seems pretty good at capturing country names.

Each of these intents invoke a single AWS Lambda function which I call TeleportSkill. The purpose of this AWS Lambda function is to send a message to an Amazon SQS Queue with the name of the country we'd like to appear from, or just "Home". Super simple.

Teleport Machine

I'm using the Ubiquity EdgeRouter X.

On the router, I'm running a cronjob every minute, which polls the queue for 20 seconds before disconnecting. If there is a message in the queue, it will be processed, and my router configuration will be updated to include a VPN tunnel to destination country.

I'm using Surfshark VPN (referral link) if you're interested in achieving the same setup described here.

Steps

Clone the github repository to your local computer.

git clone https://github.com/devnull/teleport-machine/

Create an Alexa Skill in the Amazon Alexa Developers console https://developer.amazon.com/alexa/console/, and import the alexa_model.json file under the interaction model. Under the Endpoint menu, copy the Your Skill Id, as you'll use this to link a trigger.

Use cdk deploy with a parameter to deploy the TeleportSkill AWS Lambda function, Amazon SQS Queue, and limited access IAM user.

cdk deploy --parameters skillId=YOUR_SKILL_ID_HERE

Once you have deployed the TeleportSkill lambda function, take note of its ARN. Go back to the Endpoints page in the Alexa Developers Console, and paste in the ARN into the "Default Region" textbox.

Surfshark provide a handy 'OpenVPN configuration files' ZIP file, which includes all the VPN endpoints for all the countries where they have exit nodes. Each of the configuration files are prefixed with a ISO 3166 country code. I have a simple dictionary lookup method, which takes the countries name, and finds the associated country code. Since there are multiple exit nodes per country, I'm randomly selecting one of the configuration files and applying the OpenVPN configuration.

Download the 'OpenVPN configuration files' ZIP file from the portal here: https://my.surfshark.com/vpn/manual-setup/router.

By default, each OpenVPN configuration file has an auth-user-pass option, which will ask for the OpenVPN username and password during tunnel establishment. Since we want our tunnel to be established without user interaction, we'll want to pass in the username and password via a credentials file. To do this, replace the line using a simple sed command.

sed -i 's/^auth-user-pass$/auth-user-pass \/config\/surfshark\/creds.txt/g' *.ovpn

Since I want full control over the routes being populated into the router, I'm specifying another OpenVPN option for "route no-pull". I'm just going to add this option directly after the auth-user-pass line we updated.

sed -i '/^auth-user-pass.*/a route no-pull' *.ovpn

Create a new directory on the router, and copy across all the OpenVPN config files:

ssh your-router-ip 'mkdir -p /config/surfshark/'
scp *.ovpn router-username@your-router-ip:/config/surfshark

Create a file for OpenVPN credentials. These credentials can be found in the Surfshark portal.

username >> creds.txt
password >> creds.txt
scp creds.txt router-username@your-router-ip:/config/scripts/surfshark

The EdgeRouter X v 2.0.9 comes with Python 2.7.13. I didn't want to mess with python versions and potentially break functionality on the router. Following this guide, I added the debian package repository and installed the AWS boto3 python package.

configure
set system package repository stretch components 'main contrib non-free' 
set system package repository stretch distribution stretch
set system package repository stretch url http://http.us.debian.org/debian
commit ; save
sudo apt-get update
sudo apt-get install boto3

Update the Secret Key and Access Key in the teleport.py file based on the limited access IAM user that was created, and copy the and copy the teleport.py, teleport.sh and gohome.sh script to the router.

scp teleport.py teleport.sh gohome.sh router-username@your-router-ip:/config/scripts/surfshark

Add a cron entry, so the TeleportMachine can poll the Amazon SQS Queue regularly

echo '* 9-23 * * * root /usr/bin/python /config/surfshark/teleport.py >/dev/null 2>&1' >> /etc/crontab

Learnings

  • Most VPNs don't support IPv6, so when connecting to the VPN, I had to disable IPv6-PD client from delegating IPv6 prefixes to my network

Where can I get my own teleport machine skill?

This Alexa Skill is a private skill - it's not available in the Alexa Skills Store. Although, I've made the solution available on github, so feel free to fork or clone the github repo and deploy it for yourself.

Conclusion

Hope you enjoyed my teleport adventures! Thanks for reading.

comments powered by Disqus