Almost free Netflix VPN on Amazon EC2 set up in 30 minutes using Ansible

This is a hacker/developer/sysadmin oriented guide to set up on demand VPN on Amazon EC2 server. Amazon EC2 t2.micro instance costs 0.013 USD per hour, so the deal is very light for your purse, beating commercial VPN pricing by an order of magnitude. Further, Amazon provides 750 hours of free of t2.micro instance usage for new users.

We automatize the cumbersome server configuration tasks using Ansible automatization tool. With Ansible, you’ll get your own VPN service up’n’running in 30 minutes. The instructions work on OSX and Linux systems and Ansible won’t run on Windows.

Screenshot_2015-04-12-19-37-04

We set up PPTP VPN. The VPN is good for watching Netflix where US region enjoys wider availability of entertainment. The VPN is also good defeating other US geofencing services and protecting your privacy on open Wi-Fi hotspots. Android, iOS (iPhone / iPad), OSX, Linux and Windows all support PPTP protocol out of the box, so no additional software is needed on your device.

Prerequisites

Setting up EC2

Go to AWS and sign up for an account. The payment options include all common credit cards.

Sign up for t2.micro on demand instance using Ubuntu 14.04 image. Pick an instance from US East Coast (N. Virginia) availability zone for the maximum speed from Europe. AWS prompts yoy to download SSH keys to access the instance. Store them safely. Below we assume you download keys named amazon and store them in your SSH folder:

mv ~/Downloads/amazon.pem ~/.ssh
chmod 400 ~/ssh/amazon.pem

By default, EC2 instances are firewalled. In your EC2 instance list, click Security Group for the instance (Security group name should be like launch-wizard-1). Go to Inboud > Edit and choose All traffic. This allows access to PPTP service and Squid proxy which will be installed on the server.

Screen Shot 2015-04-12 at 19.03.25

Installing PPTP using Ansible

Install Ansible. Packages available for Ubuntu, OSX Homebrew and others. Ansible is a tool installed on your local computer and it will connect the server over SSH.

Clone the Ansible playbook which automates PPTP installation on your server.:

git clone https://github.com/liangshan/drill-ansible.git

Replace hosts file in the playbook. Change the IP address to your instance IP address as shown in Amazon AWS console:

[amazon]
1.2.3.4 ansible_ssh_user=ubuntu ansible_sudo=true ansible_ssh_private_key_file=~/.ssh/amazon.pem

You need to wait until instance state says Running in AWS console. Then proceed to install and configure PPTP on the server using Ansible:

ansible-playbook -i hosts site.yml --extra-vars '{"hosts":"1.2.3.4","username":"vpn","password":"changeme"}'

Now you can connect to your VPN using the instance IP address, username vpn and password changeme.

Connecting to VPN with Android

Test your VPN on Android by going to menu Settings > Wireless & networks > More > VPN. Hit + to add new entry. Choose PPTP, enter your server IP, username and password. Choose the created entry to connect. In few seconds you should see Connected status and a key icon appears in Android status bar.

Please note that the instance IP address changes on every start and stop. You can update the VPN IP address by doing a long press on the entry in Android VPN menu.

Starting and stopping EC2 instance on demand

Download AWS Console app from Google Play Store or from App Store for your mobile. The app takes your AWS credentials and allows you to start and stop the EC2 instances  with a single click.

After starting you’ll see the new IP address of the instance in Public IP field of AWS Console app.

Screenshot_2015-04-12-19-43-00

Other

Please note that PPTP does not work on cheap OpenVZ virtual machines due to lack of kernel support – a full virtual machine is required. The Ansible playbook is kindly provided by Liang Shan.

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Linux server ghetto duplication

This blog post is about how to duplicate your Linux services and configuration from one server to another. We use simple and hackable SSH, rsync and shell scripting to copy the necessary files to make a cold spare from your existing server installation.

Screen Shot 2014-03-26 at 00.17.09

1. Preface

The method describes here is quite crude and most suitable for making a spare installation of your existing server. In the case you lose your production server, you can boot your cold spare, point your (fail-over) IP address to the spare server and keep business going – something you might want to do if you run mom’n’pop web hosting business. Because of the simplicity of the method it works on default Linux installations, bare metal servers and old-fashioned file systems like Ext4.

The instructions here have been tested with Ubuntu Linux 12.04, but should work with other versions with minor modifications. I have used this method successfully  with Heztner hosting (highly recommended for all the cheapskates out there) by having one production machine and one spare machine. The spare is mirrored weekly. Daily Duplicity backups can be restored on the spare if week is too long data loss period. Though in my case the servers are bare metal, the method works for VPSes as well.

The duplication script might be also useful for setting up a staging server from your production server for software developer and testing.

2. More powerful duplication tools

More fail safe, more engineer-oriented duplication approaches exist, but usually require additional preparation and tuning on the top of the default Linux installation. Applying these to existing running Linux installation might be tricky.

3. Building and running the duplication script

This script is run on the target server (cold spare) and it will clone the content of the source server (actual production machine) on itself. It uses SSH keys and SSH agent to create the initial connection, so make sure you are familiar with them.

Assumptions

  • The target server must be clean Linux installation, the same exact version as on your source server.
  • Your server has standard /etc/passwd user account management. This is copied first so that we correctly preserve file ownership (related ServerFault discussion).
  • Services you run (PHP, Django, Plone, Node.js, you-name-it) are under /srv as recommended by Linux filesystem hierarchy standard
  • Source and target MySQL servers must have initialy same password for the root. Set this when the script runs apt-get install mysql-server for the first time.

Limitations

  • The first run is interactive, as apt-get install asks bunch of stuff for packages like MySQL and Postfix.
  • MySQL dumping and loading the dump does not guarantee all of your data survives intact, especially when skip-lock option is used for the performance reason. For ordinary CMS operations this isn’t a big issue.
  • If you other services beside MySQL needing special flush or lock handling follow the related instructions.

For MySQL duplication make sure you have the following /root/.my.cnf file on the source server, as it allows you to interact with MySQL:

[mysqldump]
user=root
password=YOUR PASSWORD HERE

[client]
user=root
password=YOUR PASSWORD HERE

Run the script inside a screen, because the duplication process may take a while and you do not want to risk losing the process because your local internet connectivity issue.

scp mirror-ubuntu.bash targetserver:/tmp
ssh targetserver
screen 
cd /tmp
bash mirror-ubuntu.bash

4. Testing the spare server

After the duplication script has successfully finished mirroring the server you want to check if the services can be successful started and interacted on the cold spare.

Change internet-facing IP addresses in the related services to be the public IP address of the spare server. E.g. the following files might need changes:

  • /etc/default/varnish
  • /etc/apache2/ports.conf
  • /etc/apache2/sites-available/*

Spoof your local DNS to point the spare server on the tested sites. Edit your local /etc/hosts and add spoofed IP addresses like:

1.2.3.4 www.service1.example.com www.service2.example.com opensourcehacker.com

Access the sites from your web browser, see that database interaction works (login) and file interaction works (upload and download files).

5. mirror-ubuntu.bash

#!/bin/bash
#
# Linux server ghetto duplication script
# Copyright 2014 Mikko Ohtamaa http://opensourcehacker.com
# Licensed under MIT
#

# Everything is copied from this server
SOURCE=root@myserv.example.com

# Our network-traffic and speed optimized rsync command
RSYNC="rsync -a --inplace --delete --compress-level=9"

# Which marker string we use to detect custom init.d scripts
INIT_SCRIPT_MARKER="### BEGIN INIT INFO"

# As we will run in screen we need to detach
# from the forwarded SSH agent session and we use a local
# SSH key to perform the operations.
# Also overriding /root destroys our key.
# Create a key we use for the remaining operations.
TEMP_SSH_KEY=/tmp/mirror_rsa

# The software stack might have touched the following places.
# This list is compliled through trial-and-error,
# sweat and cursing.
# We cannot take /etc as a whole, because it contains
# some computer specific stuff (hard disk ids, etc.)
# and copying it as a whole leads to unbootable system.
CHERRYPICKED_ETC_TARGETS=(\
    "/etc/default" \
    "/etc/varnish" \
    "/etc/apache2" \
    "/etc/ssl" \
    "/etc/nginx" \
    "/etc/postfix" \
    "/etc/php5" \
    "/etc/cron.d" \
    "/etc/cron.daily" \
    "/etc/cron.monthly" \
    "/etc/cron.weekly" \
    "/etc/init.d")

# Create a key without a passphrase
# and put the public key on the source server
rm $TEMP_SSH_KEY 2>&1 > /dev/null
ssh-keygen -N '' -f $TEMP_SSH_KEY
ssh-copy-id -i $TEMP_SSH_KEY $SOURCE
# Detach from the currently used SSH agent
# by starting a session specific to this shell
eval `ssh-agent`
ssh-add $TEMP_SSH_KEY

# Assume the system have same Ubuntu base installation and no extra repositories configured.
# Bring target system up to date.
apt-get update -y
apt-get upgrade -y

# TODO: check that the kernel uname is same
# on the source and the target systems

# This is somewhat crude method to try to install all the packages on the source server.
# If the package is missing or replaced this command will happily churn over it
# (apt-get may fail). This MAY cause user interaction with packages
# like Postfix and MySQL which prompt for initial password. Not sure
# what would be the best way to handle this?
ssh $SOURCE dpkg --get-selections|grep --invert-match deinstall|cut -f 1|while read pkg
do
    apt-get install -y $pkg
done

# As some packages might have changed due to version upgrades and
# deb renames the following step needs interaction
ssh $SOURCE dpkg --get-selections|grep --invert-match deinstall|cut -f 1

# Copy user credentials first to make sure we
# get the user permissions and ownership correctly.
# http://serverfault.com/a/583336/74975
echo "Copying users"
$RSYNC $SOURCE:/etc/passwd /etc
$RSYNC $SOURCE:/etc/shadow /etc
$RSYNC $SOURCE:/etc/group /etc
$RSYNC $SOURCE:/etc/gshadow /etc

# Copy home so we have user home folders available
# Skip duplicity backup signatures
echo "Copying root"
$RSYNC $SOURCE:/root / --exclude=/root/.cache
# lost+found content is generated by fsck, uninteresting
echo "Copying home"
$RSYNC $SOURCE:/home / --exclude=/home/lost+found

echo "Copying /etc targets"
for i in "${CHERRYPICKED_ETC_TARGETS[@]}"
do
   $RSYNC $SOURCE:$i /etc
done

# Most of your service specific stuff should come here
echo "Copying /srv"
$RSYNC $SOURCE:/srv /

# Make sure stuff which went to /etc/init.d gets correctly reflecte across runlevels,
# as our /srv stuff has placed its own init scripts
for i in  /etc/init.d/*
do
    service=`basename $i`
    # Separate from upstart etc. jobs
    if grep --quiet "$INIT_SCRIPT_MARKER" $i ; then
        update-rc.d $service defaults
    fi
done

# Copy MySQL databases.
# Assume source and target root can connect to MySQL without a password.
# You need to set up /root/.my.cnf file on the source server first
# for the passwordless action.
# http://stackoverflow.com/a/9293090/315168
echo "Copying MySQL databases"
ssh -C $SOURCE mysqldump \
    --skip-lock-tables \
    --add-drop-table \
    --add-drop-database \
    --compact \
    --all-databases \
    > /root/all-mysql.sql

# MySQL dump restore woes
# http://stackoverflow.com/a/21087946/315168
mysql -u root -e "SET FOREIGN_KEY_CHECKS = 0; source /root/all-mysql.sql ; SET FOREIGN_KEY_CHECKS = 1;"

# Remove the key we used for the duplication
rm $TEMP_SSH_KEY

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Firefox SOCKS proxying with SSH to get unhindered internet access

This is a short guide how to get unhindered Internet access (HTTP) in a country or network which limits internet connectivity. You need access to OpenSSH server somewhere outside the network. These instructions were tested on OSX (Snow Leopard), but should work on other operating systems too.

SOCKS proxy is built into OpenSSH terminal connection software. OSX comes with ssh client.

Open Applications -> Utilities -> Terminal (on OSX) and type the command

ssh -D 8080 username@yoursshhost.com

Login to the SSH and leave the connection open. If ssh complains about binding the port 8080, then you might have another ssh already running. Also the SSH server might prohibit using itself as a proxy.

Now, In Firefox (Firefox 4 or later) go Preferences -> Advanced -> Network -> Settings

Turn on Manual proxy configuration.

Socks hosts: localhost

Port: 8080

Hit ok. If you lose network connectivity just restore proxy settings back to the automatic.

Go to www.whatismyip.com and see that it gives you the IP address of the SSH server, not your local internet connection as the result.

Firefox will start complain about proxy error when SSH connection is terminated.

If you also want to use non-proxied connection (faster) simulateneously, just open another browser e.g. Safari.

1. More info

\"\" Subscribe to RSS feed Image Follow me on Twitter Image Follow me on Facebook Image Follow me Google+

Could not open a connection to your authentication agent on Ubuntu 9.10 Linux

I just run into this when tried to enable Github SSH to perform git push.

The workaround is to run command

`eval ssh-agent`

Which sets series on environment variables making ssh-add to work.

I don’t know why this doesn’t work anymore – I am quite sure it worked on earlier Ubuntu versions out of the box.

Related bug report.