Raspberry PI and patched openvpn server, built from source code 2.4.1

# Tested on
# Raspbian Jessie Lite version date: March 2017
# This post builds a scrambled openvpn server on a Raspberry PI
# from source code for openvpn 2.4.1 plus patch to add scramble functionality
# To get it working, you need both sides patched, the server and the client
# plus you need to add a scramble key to server and client scripts.
# Below we will use the following password scramble key "test"
# This password key must be the same in server and client openvpn scripts
# i.e. scramble obfuscate test

# For patched Windows Client see
# https://scramblevpn.wordpress.com/2013/09/28/build-patched-windows-openvpn-client/
# For patched OS X Client see
# https://tunnelblick.net/downloads.html
# For patched Android Client
# https://users.bolehvpn.net/clients/bolehvpn_0.6.64.apk
# https://www.dropbox.com/s/ixl90g19xzkgh53/bolehvpn_0.6.64.apk

# For details about the patch and options see
# https://forums.openvpn.net/topic12605.html
# https://forums.openvpn.net/viewtopic.php?f=15&t=12605
# https://tunnelblick.net/cOpenvpn_xorpatch.html
# This patch has been updated by designers at tunnelblick

# This post will use their patch
# https://github.com/Tunnelblick/Tunnelblick/tree/master/third_party/sources/openvpn
# https://github.com/clayface/openvpn_xorpatch

# Now to Raspberry PI
# Firstly, if you already have an earlier formal installation of openvpn, remove it
sudo mkdir $HOME/config_backup
sudo cp -rf /etc/openvpn/* $HOME/config_backup/
sudo apt-get purge openvpn -y

# We need to add a few components
sudo apt-get update
sudo apt-get install gcc make automake autoconf dh-autoreconf file patch perl dh-make debhelper devscripts gnupg lintian quilt libtool pkg-config libssl-dev liblzo2-dev libpam0g-dev libpkcs11-helper1-dev chkconfig git nano -y

# fetch source code & apply patch
cd $HOME/
wget http://swupdate.openvpn.org/community/releases/openvpn-2.4.1.zip
unzip openvpn-2.4.1.zip
cd openvpn-2.4.1/
wget https://raw.githubusercontent.com/Tunnelblick/Tunnelblick/master/third_party/sources/openvpn/openvpn-2.4.1/patches/02-tunnelblick-openvpn_xorpatch-a.diff
wget https://raw.githubusercontent.com/Tunnelblick/Tunnelblick/master/third_party/sources/openvpn/openvpn-2.4.1/patches/03-tunnelblick-openvpn_xorpatch-b.diff
wget https://raw.githubusercontent.com/Tunnelblick/Tunnelblick/master/third_party/sources/openvpn/openvpn-2.4.1/patches/04-tunnelblick-openvpn_xorpatch-c.diff
wget https://raw.githubusercontent.com/Tunnelblick/Tunnelblick/master/third_party/sources/openvpn/openvpn-2.4.1/patches/05-tunnelblick-openvpn_xorpatch-d.diff
wget https://raw.githubusercontent.com/Tunnelblick/Tunnelblick/master/third_party/sources/openvpn/openvpn-2.4.1/patches/06-tunnelblick-openvpn_xorpatch-e.diff

# We apply patch the long way

git apply 02-tunnelblick-openvpn_xorpatch-a.diff
git apply 03-tunnelblick-openvpn_xorpatch-b.diff
git apply 04-tunnelblick-openvpn_xorpatch-c.diff
git apply 05-tunnelblick-openvpn_xorpatch-d.diff
git apply 06-tunnelblick-openvpn_xorpatch-e.diff

# Comments about patch, the Tunnelblick guys remove the older revision patches
# when they update version, this means you might get "404: Not Found"
# if you do, check https://github.com/Tunnelblick/Tunnelblick/tree/master/third_party/sources/openvpn for current version

# This is the bit where we make and install the new openvpn server
sudo mkdir /etc/openvpn/
cd $HOME/openvpn-2.4.1/
./configure --prefix=/usr
sudo make install
sudo wget --no-check-cert https://www.dropbox.com/s/nz4dyons6tlsbr4/etcinitdopenvpn.sh -O /etc/init.d/openvpn
sudo chmod +x /etc/init.d/openvpn
sudo update-rc.d openvpn defaults

# Check startup script is correctly set
chkconfig --list | grep openvpn
# expect
# openvpn 0:off 1:off 2:on 3:on 4:on 5:on 6:off

# Now we create unique keys and certs using easyrsa3
# For test purposes only, here is an already prepared pair of scripts
# https://www.dropbox.com/s/u06t53fb7qwov47/client1.ovpn?dl=0
# https://www.dropbox.com/s/cxt7ajdxczifsqm/server.conf?dl=0

mkdir $HOME/clientside
mkdir $HOME/serverside
cd $HOME/serverside
wget https://github.com/OpenVPN/easy-rsa/archive/master.zip
unzip master.zip
cd easy-rsa-master/easyrsa3
openvpn --genkey --secret ta.key
./easyrsa init-pki
./easyrsa --batch build-ca nopass
./easyrsa --batch build-server-full server nopass
./easyrsa --batch build-client-full client1 nopass
./easyrsa gen-dh

cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/ca.crt $HOME/serverside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/issued/server.crt $HOME/serverside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/dh.pem $HOME/serverside/dh2048.pem
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/private/server.key $HOME/serverside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/ta.key $HOME/serverside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/issued/client1.crt $HOME/clientside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/ta.key $HOME/clientside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/ca.crt $HOME/clientside/
cp $HOME/serverside/easy-rsa-master/easyrsa3/pki/private/client1.key $HOME/clientside/

# Client Script
nano $HOME/clientside/raspberrypi.ovpn

dev tun
proto udp
scramble obfuscate test
remote change_this_to_server_address 34557
resolv-retry infinite
sndbuf 0
rcvbuf 0
ca ca.crt
cert client1.crt
key client1.key
tls-auth ta.key 1
remote-cert-tls server
cipher AES-256-CBC
verb 3

# Now merge certs and keys into client script, so we only have one file to handle
cd $HOME/clientside/
wget --no-check-cert https://www.dropbox.com/s/v228zvccef9d10c/merge.sh -O merge.sh
sudo chmod +x merge.sh
sudo ./merge.sh
sudo chown $USER $HOME/clientside/raspberrypi.ovpn

# Now transfer client script raspberrypi.ovpn
# in $HOME/clientside/ to your client PC
# Due to permissions, I had to transfer it to C:\
# Then in windows, copy the file
# to C:\Program Files (x86)\OpenVPN\config

# Server Script
nano $HOME/serverside/server.conf

port 34557
proto udp
scramble obfuscate test
dev tun
ca ca.crt
cert server.crt
key server.key
tls-auth ta.key 0
dh dh2048.pem
sndbuf 0
rcvbuf 0
chroot /etc/openvpn/jail
cipher AES-256-CBC
user nobody
group nogroup
status /etc/openvpn/openvpn-status.log
verb 3
push "redirect-gateway def1"
push "dhcp-option DNS"
push "dhcp-option DNS"
keepalive 5 30

# Now merge certs and keys into server script, so we only have one file to handle
cd $HOME/serverside/
wget --no-check-cert https://www.dropbox.com/s/9wc3we8ezfucj1j/merge_server.sh -O merge_server.sh
sudo chmod +x merge_server.sh
sudo ./merge_server.sh

# Now copy the merged server script to /etc/openvpn/ and make jail
sudo cp $HOME/serverside/server.conf /etc/openvpn/
sudo mkdir /etc/openvpn/jail/
sudo mkdir /etc/openvpn/jail/tmp/

# uncomment to allow data redirect
sudo nano /etc/sysctl.conf


# These firewall settings really screw everything up if you have ufw enabled
# There are a number of ways to configure the firewall, it depends of
# how you're using the PI.
# I am using it as a headless remote server, this means no desktop
# environment, and no other firewall conflicting data loaded.
# Alternative Firewall setting if static IP of PI is
# check with ifconfig. Also this should be the firewall.sh file
# iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source LOCALIP
# sudo iptables -t nat -A POSTROUTING -s -o eth0 -j SNAT --to-source
# And Start everything
# sudo sysctl -w net.ipv4.ip_forward=1

# Make file for firewall setting
# My firewall setting, may not suit all
sudo nano /usr/local/bin/firewall.sh

iptables -t filter -F
iptables -t nat -F
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s "" -j ACCEPT
iptables -A FORWARD -j REJECT
iptables -t nat -A POSTROUTING -s "" -j MASQUERADE

# Make firewall script executable, run it and check
sudo chmod +x /usr/local/bin/firewall.sh
sudo /usr/local/bin/firewall.sh
sudo iptables --list

# add new text line into file /etc/rc.local
# before ‘exit 0' to ensure the firewall rules are run at reboot or power up.
sudo nano /etc/rc.local


# reboot the pi
sudo reboot

# TIP: Check server can start ok
sudo /etc/init.d/openvpn restart

# TIP:Check tun0 interface started

# Connect VPN client from remote location
# does not work when client and server are connected
# to same router and you try external IP address.
# If you want to do a local test at home
# connect to local IP address of server e.g.
# when you go to your remote location, connect to no-ip address or external static IP

This entry was posted in Uncategorized. Bookmark the permalink.

7 Responses to Raspberry PI and patched openvpn server, built from source code 2.4.1

  1. Toke says:


    First of all, thank you so much for your detailed guide. It rocks!!

    Moreover, kindly I could request your help about configuration I have in mind and tell me if it could be feasible:

    – I have used your detailed guide for setup openvpn with obfuscated in my VPS and access mainly using android client. It works quite well.

    – Now I have configured my home raspberry to be used as openvpnclient and connecting to VPS server creating link between both and be able provide me open gateway for my LAN devices. It also works quite well.

    – Lastly, I will like to be able access from wherever place (basically use my 4G data) using either ssh tunnel or openvpn client running openvpn server also in raspberry since my inet connection at home is much better than whatever connection I find out of home besides give me access to my local devices.

    I have been playing with iptables but I am not able to make it working. Do you have idea how I could manage such setup using external device (4G) –> raspberry (home) –> VPS?

    Thank you very much in advance!!!

    • scramblevpn says:

      yes, I have set similar up, the easiest and quickest is shadowsocks and kcptun
      provided you are able to open ports on your home router, i.e. you have admin password.
      Note, the speed you get is your home upload speed, when you access it from outside.

      on your VPS, you set up shadowsocks server and kcptun server
      on raspberry pi at home, you set up kcptun client
      on phone you set up shadowsocks client

      its similar idea to obfsproxy, which can also work, in fact any envelope can work, also stunnel etc etc and no messing with iptables.

      From what I can see, openvpn does not work as a two stage proxy
      i.e openvpn client to openvpn server to openvpn client to openvpn server.

      If security is an issue, better use openvpn over kcptun, or openvpn over tor’s scramblesuit.

  2. Toke says:

    Thanks for your feedback!!

    Well, finally I have following setup:

    android client –> raspberry home (shadowsocks client) –> VPS (shadowsocks-r server)

    From android client, I access using SSH tunnel (https://play.google.com/store/apps/details?id=com.staf621.ki4a&hl=en) and it is totally transparent for me. So far is working well 🙂

    However, I will take a look to the guides and suggestion your provide me.

    Thanks again for your comments


    • scramblevpn says:

      depends on circumstances, e.g. in China they throttle ssh connections after a while, so always need to be flexible, bend around the new block.

      • Toke says:

        For sure in china it is (I suffer it directly :-() but in this case, I have tested that if ssh tunnel is done inside mailand using either 3G/4G or wifi hotspot, there is not throttling at all. Of course if ssh tunnel is against overseas VPS then it is.

        We will follow playing 🙂

  3. DANDY says:

    I’m stuck at “git apply” steps. I went to the github link as suggested and found 2.4.3 OpenVPN. Downloaded all the diff files but git apply gives me error “unrecognized inputs”. What to do with it?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s