DIY Personal VPN with Banana Pi OpenVPN

Personal VPN with Banana Pi

There has been a hype over the internet about government surveillance and eavesdropping. One of the best way one can protect their digital privacy is by using a VPN to access the internet. Though the locations we can put our Banana Pi is limited, a Virtual Private Network can also help jump over firewalls at remote locations or connect securely to your home network from your work.

OpenVPN

OpenVPN is an opensource software that allows the secure connection from a computer, smartphone, to a server. VPN, virtual private networks, can be used to hop over firewalls, access the internet without restrictions, or hide your traffic behind a server. With the Banana Pi M1, we will be creating a OpenVPN server that will provide your with a free personal VPN. 

What we will use

A Banana Pi M1 with SD card, Bananian installed
Internet connection (with cable)
Port Forwarding on Router
A computer / smartphone

The whole process can be done with JuiceSSH app in Android instead of using a computer. Check out my JuiceSSH overview

Video


Outline

Making your OpenVPN server is one of the hardest projects here. It involves a lot configuration. It is not the normal copy n' paste project! I made a outline showing the steps involved. 
  1. Getting ready (updating, changing default passwords, and installing OpenVPN)
  2. Generating Keys (set key size and generate encrypted keys)
  3. Server side configuration for connection
  4. Creating .ovpn profile for client side use
  5. Port forwarding on router
  6. Connection testing

Starting the Project

First, you will want to update your OS to make sure it is up to date and not vulnerable to known bugs. 
apt-get update
apt-get upgrade
It is highly recommended to change the default password, many routers were hacked because people did not bother to change the default password.
passwd 
Next, let's install OpenVPN
apt-get install openvpn 

Generating Keys

Once OpenVPN is installed, we have to begin to generate keys and modify settings.
First, we will make a new directory for our keys
mkdir /etc/openvpn/easy-rsa/
cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/easy-rsa/
So we just copied some example configuration to the directory which we will be modifying the settings and generate the keys.

We can continue by editing the server configuration
I decided to change the encryption key size from 1024 bit to 2048 bit for extra security.
sed -i 's/KEY_SIZE=1024/KEY_SIZE=2048/' /etc/openvpn/easy-rsa/vars
Now to change the easy-rsa directory to the one we just created
nano /etc/openvpn/easy-rsa/vars 
Change theeasy-rsa directory from `pwd` to
/etc/openvpn/easy-rsa 

Now we can start generating keys. We need to erase all example keys and generate keys for your new server.

I had trouble in the video now this command will help you a lot! It gives you permission to execute programs in the folder.
chmod  -R 777 /etc/openvpn/
cd /etc/openvpn/easy-rsa
source ./vars 
./clean-all
 Building keys
./build-ca
A series of prompts will pop up, I highly recommend you to leave them default and just 'enter' them away. If you do change the defaults, be very careful as things may not work out.

Building a server key. 'bananapi' is the name of my server, you can change it if you want.
./build-key-server bananapi 
Generate another key
openvpn --genkey --secret ta.key
cd 
cp ca.key /etc/openvpn/easy-rsa/keys/ta.key 
Build a random prime key, it will take a long time. 10 to 20 minutes
./build-dh
Build a key for user1
./build-key-pass user1
You can change 'user1' to any name you want, but remember it when we are creating user profiles.
When prompted enter a PEM password of your choice, but leave everything else blank!

Server config

We can proceed by configuring the server, since we will be inputting lines from scratch, it may be a good idea for you to copy and paste below lines
nano /etc/openvpn/server.conf
nano will open up a blank document and paste below lines into it
local 192.168.x.xxx
#(fill in with local IP of your Banana Pi)
dev tun
proto tcp
port 443
ca /etc/openvpn/easy-rsa/keys/ca.crt
cert /etc/openvpn/easy-rsa/keys/Server.crt
key /etc/openvpn/easy-rsa/keys/Server.key
dh /etc/openvpn/easy-rsa/keys/dh2048.pem
server 10.8.0.0 255.255.255.0
ifconfig 10.8.0.1 10.8.0.2
push "route 10.8.0.1 255.255.255.255"
push "route 10.8.0.0 255.255.255.0"
push "route 192.168.x.xxx 255.255.255.0"
#(fill in with Banana Pi IP)
push "dhcp-option DNS 192.168.x.x
#(fill in with your router IP)
push "redirect-gateway def1"
client-to-client
duplicate-cn
keepalive 10 120
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0
cipher AES-256-CBC
comp-lzo
persist-key
persist-tun
status openvpn-status.log
verb 3

now we have to enable ipv4 forwarding on Banana Pi Server and modify firewall settings
nano /etc/sysctl.conf
Find the line 'uncomment to enable IPv4 packet forwarding' and delete teh '#' at the beginning of the script under that line.
nano /etc/firewall-openvpn-rules.sh

We are creating a new file that will contain the configurations, fill it in with settings below
#!/bin/bash
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 192.168.XX.X 
NOTE the red lines are one line of command.

Now we need to set the file to run at start up
chmod 700 /etc/firewall-openvpn-rules.sh
chown root /etc/firewall-Openvpn-rules.sh
We made the file 'firewall-openvpn-rules.sh' executable
nano /etc/network/interfaces
After 'iface eth0 inet dhcp', indent and add below line like the picture
pre-up /etc/firewall-openvpn-rules.sh

We made the file 'firewall-openvpn-rules.sh' run automatically the easy way. In breif, we added the line 'sh /etc/firewall-openvpn-rules.sh' after 'exit 0' at the end of the document '/etc/rc.local'

Now it is time to create a config file for the client to open up on Android.
Create a new file
nano /etc/openvpn/easy-rsa/keys/user1.ovpn
It will open up a blank document, so we need to put below lines there
client
dev tun
proto tcp
remote (public IP of your house) 443
#(443 is the port)
resolv-retry infinite
persist-key
persist-tun
mute-replay-warnings
ca ca.crt
cert user1.crt
key user1.key
ns-cert-type server
cipher AES-256-CBC
comp lzo
verb3
mute 20
Or to see the original example configuration, copy the conf file as user1.ovpn (red is 1 line)
cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/user1.ovpn

Now use FileZilla to connect and download files from Banana Pi. Download 'ca.cert' 'user1.crt''user1.key'and'user1.opvn'

Once the file is on your PC, upload it to Google drive so you can download it on your Android.

Start Open VPN and debug

To start and restart the server
service openvpn restart
If the server does not start, debug it with
grep ovpn /var/log/syslog

Port Forwarding

You should be quiet familiar with port forwarding and it is easy! Just go in to your router's control page by typing your router IP and it often looks like this
192.168.1.1
Forward port 443 tcp to local IP of Banana Pi If you followed this guide

Connection Testing

Move files from your Banana Pi to your desktop or cloud with FileZilla using sftp
under directory
/etc/openvpn/easy-rsa/keys/
files to copy
ca.crt
user1.crt
user1.key
ta.key
user1.ovpn

Firewall Jumping 

I did research in firewall jumping and if it is a basic firewall, then set the port to 443 and protocol to tcp and you should be set.
But there are also packet sniffing firewalls that are harder to hide from and I think a SSL tunnel will do the trick and I will do more research and experiment with it.


So that was intense and we can now download OpenVPN connect from Play Store to test out our VPN:)
Import the .opvn file from SD card and you are set!


Speed up Apache2 Banana Pi Web Server with RAM Cache

Lightning Web Server

This is for people who want to shave a fraction of a second off their website loading time on Banana Pi! So you have your nice and speedy Apache 2 or Nginx website hosted on your Banana Pi, but it is not fast enough or you want to push it to the limits? Well, this is where the 1GB RAM on Banana Pi comes in handy. 

Options before us

System cache (automatic)
Apache cache module (mod_cache)
Manual cache (tmpfs)

note: all above caching options are for server sided caching. Also can be thought of as the first visit, upon the next visit during the same session, your computer will go to a local cache on your device.

RAM basics

The basics steps of loading a website:
  1. Client send request to server
  2. Server reads file from storage and send it back to client

Storage Devices


  1. Random Access Memory - Really fast, limited in size (expensive), volatile (will lose data on reboot)
  2. SD card - Much slower than RAM, larger in size (cheaper), non-volatile (will retain data without power)
RAM in Banana Pi writes at 120MB/s compared to SD card <30MB/s

In this guide, what we are trying to do is to speed up the loading speed of a website by storing the website on the RAM instead of the slower SD card. 

Automatic System Caching  (Recommended)

Guess what? Your website is already cached in the RAM by default, well at least hopefully. Modern Linux operating systems automatically caches files that are frequently accessed in to the RAM for a faster system performance. This process is only slower for the first load of a website after server restart.

Manual Cache 

tmpfs is a file system in Linux that mounts a folder in the RAM of a computer. Manual caching will place website files in a RAM folder and direct Apache2 the location of the website on the RAM server. 

To start we need to create a folder for the tmpfs file system
mkdir /var/wwwc
Then we need to mount this file system at start up
nano /etc/fstab
 Add the line below to '/etc/fstab'
tmpfs /var/wwwc tmpfs defaults,size=128M 0 0
You can change the directory and the default size to your customization

Now we have to copy the files from the old folder to the new RAM folder
If you have questions about uploading your files, see my Apache2 web server guide.
rsync -av /var/www/ /mnt/wwwc/
It sync files from the first directory to the second one, you can see '/var/wwwc' take up 61MBs



Now we can edit the configuration in Apache2 to direct requests to the RAM folder
nano /etc/apache2/sites-enabled/000-default
change document root and directory to '/var/wwwc/' in lines 4 and 9
DocumentRoot /var/wwwc/
<Directory /var/wwwc/>
restart Apache server
service apache2 restart

Apache Cache Module 

An integrated module is built into Apache 2 that will cache websites with correct HTTP headers.
Enabled the module by
a2enmod cache
a2enmod file_cache
service apache2 restart
 Now that we enabled all the modules, it is time to configure them.
nano /etc/apache2/mods-enabled/file_cache.load

It should open up a text editor,edit the files by adding lines at the end
MMapFile [directory to file] [directory to file] ...
'MMap' Directive in Apache2 maps one or more files (note spaces in between) into memory at server start up time.

A example of the code can look like this
MMapFile /var/www/index.html /var/www/images/banner.jpg
So this is how to cache files with the Apache cache module
service apache2 restart

So All for Nothing?

I did some intense testing on all options, though some data varied, I can conclude that both Manual cache and system cache are the better options. Apache module cache gets on the complicated side. 

Which one is faster? Well test it out on your own website!

Real world testing

I uploaded a real site to Apache2 and did some testing. I used both Android and Windows platform and different browsers. 

notes: I did not include every file with Apache Module Cache
notes: The results may not be the most accurate
notes: The Android website speed app might be the most reliable

Automatic System Cache Android

Apache Module Cache Android

Manual Cache Android

I made sure to reset cache on my local device after each test.

Automatic System Cache 1st request on server Chrome

Automatic System Cache Chrome

Apache Module Cache Chrome

Manual Cache Chrome

Automatic System Cache Firefox

Manual Cache Firefox

Conclusion

So is it worth your time going through all the steps to see no real performance gains? Well, it definitely gives us valuable experiences. 

Sorry to spoil the ending :) but you should still try to RAM cache your server manually!

If i made any mistakes regarding this topic, feel free to comment. We are all learning.