The concept

Everyone likes watching movies (hopefully). Unfortunately sometimes we have to use a VPN for that, when we happen to be in the wrong country (by the judge of some bad company :). Up until recently I had to set up the VPN server manually and connect to it. That era was ended when I received a ESP8266 chip and decided to use it to automate the process with a push of a button.

The basic components I used for that are outlined on the picture below but very similar results can be achieved with different setup. Especially the NodeJS+Express component could be replaced with any other server. I just happened to play with NodeJS recently so I just grabbed it.

Basic components


For the Cloud part I used the Digital Ocean dropplets. The pros are obvious: it’s very cheap and starts very fast but of course it’s possible to use any other cloud provider as long as it’s not blocked as a source of VPN (as in in the case of AWS and Amazon Prime).


On my home server I used Ubuntu but it can be any Linux from Slackware to Proteus ;). Vagrant was used to setup and configure the box:

Download vagran

apt-get install libz-dev
vagrant plugin install vagrant-digitalocean
vagrant box add digital_ocean
vagrant init

Then I created the following Vagrantfile (make sure to use the proper token in place of DIGITAL_OCEAN_TOKEN = "digital_ocean"
  config.ssh.private_key_path = "~/.ssh/id_rsa"
  config.vm.provider :digital_ocean do |provider,override| = 'digital_ocean'
    provider.ssh_key_name = "chrzaszczyrzewoszyce"
    override.vm.box_url = ""
    provider.image = 'ubuntu-14-04-x64'
    provider.token = "DIGITAL_OCEAN_TOKEN"
    provider.region = 'nyc3'
    provider.size = '512mb'
 config.vm.provision :shell, path: ""

I left the rest of the file untouched. I used following tutorial for some help:

The only missing part was script to configure the machine to act as pptp server:

#!/usr/bin/env bash

apt-get update
apt-get install -y pptpd

echo "
" >> /etc/pptpd.conf

echo "
vpn pptpd vpnsecretpass *
" >> /etc/ppp/chap-secrets

echo "
" >> /etc/ppp/pptpd-options

echo "
" >> /etc/sysctl.conf

echo 1 > /proc/sys/net/ipv4/conf/all/forwarding

iptables -t nat -A POSTROUTING -s -j MASQUERADE

service pptpd restart

Pay attention to the following line :

echo "
vpn pptpd vpnsecretpass *
" >> /etc/ppp/chap-secrets

It defines the user (vpn) and password (vpnsecretpass). It’s worth to use something personal here :)

Once it’s all set I tested the Vagrant by issuing vagrant up. Once the server has booted I was able to conenct to it using my ipad providing the servrer’s IP address and the user and password in VPN configuration. I was happy to watch the movies but I was not happy with the procedure to start it up. Moreover I had to vagrant -f destroy once I was done with watching. I couldn’t stand that. :)


To overcome the need to log in via ssh and bring the vpn server up and down I created the web server  using NodeJS so I could invoke the vagrant up via a browser. First I installed nodejs:

apt-get install nodejs
ln -sf /usr/bin/nodejs /usr/bin/node
apt-get npm
npm init
npm install --save express

Then I wrote following supersimple server:

var express = require('express');

var app = express();

app.set('port', 3000);

function registerCall(url,command,args)
	app.get(url,function(req,res) {
		var spawn = require('child_process').spawn;
		var process = spawn(command, args);

		res.setHeader('Connection', 'Transfer-Encoding');
		res.setHeader('Content-Type', 'text/html; charset=utf-8');
		res.setHeader('Transfer-Encoding', 'chunked');

		writeData=function (data) {
			var str = data.toString();
			str = str.replace(/[\n\r]/gm,"");


		process.stderr.on('data', writeData);

		process.on('close',function(code) {
			console.log('process exit code ' + code);

registerCall('/vagrantUp', 'vagrant', ['up']);
registerCall('/vagrantStatus', 'vagrant', ['status']);
registerCall('/vagrantDestroy', 'vagrant', ['destroy', '-f']);

app.get('/',function(req,res) {
	res.writeHead(200, {'Content-Type': 'text/plain'})
	res.write('GO AWAY!\n');

app.use(function(req, res) {
	res.send('404 - Not Found');

app.use(function(err, req, res, next) {
	res.send('500 - Server Error');

app.listen(app.get('port'),function() {
	console.log('Started on port '+app.get('port')+'.');

Now I was able to start and stop my droplet using just a web browser and invoking http://MY_SERV_IP:3000/vagrantUP or http://MY_SERV_IP:3000/vagrantDestroy.


For the last part I used the NodeMCU board because it has a build in LED and a button. LED is useful to show some status beside transferring the data while for the button I planed very important function to start (and stop) my server.