John's Musings

Yeah, Me Neither

How to Make Your Own VPN Server

So the ISP's are selling your web history, and you never should trust the wifi network at the hotel, the restaurant, or the coffee shop. What's a soul to do? Get a Virtual Private Network (VPN).

Nowadays your fairly new router should have the ability to set up a VPN but you lack some control over configuration and security. It's really a piece of cake now to install a VPN server on a Raspberry Pi computer ($35) and leave it on 24/7. There is a program called PiVPN that makes it almost too easy to do.

What you need to pull this off is:

- Raspberry Pi 3 (recommended) Get the one I linked because it has a good 2.5 amp power supply with it for $41 total. Heck the Pi itself costs $35 to $40 usually.

- Micro SD card I like San Disk, and about 8GB is plenty good for this project. The card I linked is $10. You can get them cheaper than this especially if you get a Class 4 card. I personally run San Disk Class 10 cards in all my Pi's.

- Ethernet cable. (optional) I recommended running the Pi right off your router via ethernet. It'll be faster. The Pi 3 has on board wifi though so it isn't a must.

Now you have the hardware. Lets download the software. First you need the OS and we'll use Raspbian. There is a Raspbian and a Raspbian Lite. Either one will work. Technically the Lite version is enough to pull this off but I like to run the full Rasbian because you can VNC into it graphically and control the Pi from afar from its desktop interface. Download one or the other from here.

Rasbian and Raspberry Pi are nothing to be scared of. If you plugged Raspbian into your monitor, keyboard, and mouse, it looks just like any other Operating System. It's lean, mean and very intuitive. Click the little Raspberry in the top left corner and it's set up like a windows type desktop.

Now download Etcher. Once Etcher is downloaded put your micro SD card in your computer, point it towards your downloaded file and click the FLASH button. It's that easy.

Now this is kind of a sticking point. Because we are going to be running this Pi headless, which means without monitor, keyboard, or mouse we have to access it from the command line from another computer. Since November of last year Raspbian has disabled Secure Shell (SSH) from being enabled as default on a fresh install. You have to enable it. Two ways to do that. One is to hook up a monitor, keyboard, and mouse and open Raspi-Config put your SD card in and boot up. Once at the desktop you can open Raspi-Config. You can open it from terminal by typing:

sudo raspi-config

Select Number 5

Then number 2

Then "yes"

Okay, that's kind of a pain. (I'm doing this from a Mac, so it only works on a Mac. Google up your OS directions if you have something else).

While the SD card is still in after you run Etcher, open a terminal and type:

cd /Volumes


cd boot


touch ssh

Then place the SD card in the Raspberry Pi and boot it up.

To SSH into your Pi from a terminal type

ssh 192.168.x.xx -l pi (where x.xx is the IP address of your Pi) (i.e. ssh -l pi)

password = raspberry

Change the password once you boot up for the first time by going to Raspi-Config and selecting number 1.

Now go to a terminal and type:

curl -L | bash

Then follow along with the directions here. The directions are slightly outdated but the newer installation flow is much more intuitive. It probably takes 30 mins or so to complete. The lengthy part of the process is the generation of encryption keys. Everything else goes fast.

Once that is done use an SFTP client such as FileZilla to move your client certificates to your computer or tablet, or phone for installation. (All that is also covered in the directions).

Here's one thing I noticed though. The configuration file it generates DOES NOT route all traffic through the VPN and by golly that's what I want.

From a mac computer you can import your ovpn

file into a program called Viscosity. Once you tell Mac you want to open that .ovpn file with Viscosity it will import it then you can easily make it route all traffic through the VPN by doing this. I named my test file "VPNatMoms". Highlight and Click "Edit".

Now go to Networking Tab and click the radio button to route all traffic through the VPN. Then hit Save.

That works great for Viscosity, but if you want to ensure you route all traffic over the VPN on your IOS device it's not that easy. Back to Viscosity:

Highlight your connection then click "Export Connection" Save it wherever you want.


Now you can right click on the file and "Show Package Contents"

There will be a file called config.visc

Change it to whatever you want dot ovpn (i.e. john.ovpn)

Now make sure you have the OpenVPN app on your IOS device. Now hook your phone or tablet to your Mac and open iTunes to sync. Now go to the OpenVPN app under File Sharing on the "Apps" page which will give you a box called "OpenVPN Documents" to allow you to drag those 5 files into and then sync your phone or iPad. It's kind of weird because when you click on Apps in the left hand pane it kind of looks like a complete page, but you can scroll down to find the File Sharing section. It's a real head scratcher for sure. HIDDEN.

Now you should be able to open the OpenVPN app and connect. You'll have to add your password first time.

There's another way to do it but it's fairly geeky. Install a program called ruby on your mac. From a terminal type:

brew install ruby

Once installed click the "Download Zip" button from this page. Once unzipped the file will be called viscosity-to-ios-connect.rb. Open it with Text Editor. Find the 8th line of text and do this:

change line 8 from: do |line| to do |line|

config_files = Dir.glob("#{ENV['HOME']}/Library/Application Support/Viscosity/OpenVPN/*/config.conf")

config_files.each do |file|

  certificate_files = ['ca', 'cert', 'key', 'tls-auth']

  config_dir        = File.dirname(file)

  connection_name   = nil

  new_config        = [] do |line|


    if line.start_with?('#viscosity name')

      connection_name = line.match(/^#viscosity name (.*)/)[1]



    next if line.start_with?('#')

    (key, value) = line.split(/\s+/, 2)

    if certificate_files.include?(key)

      # Special case for tls-auth which is "key direction"

      if key == 'tls-auth'

        # add direction to config

        (value, direction) = value.split(/\s+/)

        new_config << "key-direction #{direction}" unless direction.nil?


      certificate ="#{config_dir}/#{value}")

      new_config  << "<#{key}>"

      new_config  << certificate

      new_config  << "</#{key}>"



    new_config << line


  raise "Unable to find connection name in #{file}. Aborting." if connection_name.nil?

  new_config.unshift("# OpenVPN Config for #{connection_name}")

  out_file = "#{connection_name}.ovpn", 'w') { |f| f.write(new_config.join("\n") + "\n") }

  puts "wrote #{out_file}"


Save the file.

Now go back to the terminal, make sure you are in the same directory that file is and type:

ruby viscosity-to-ios-connect.rb

It will take every Viscosity profile and change it to an OpenVPN profile. You can email it to yourself then just click on it in your iPad to import it. Note that I have 6 profiles for OpenVPN. Your mileage may vary.

Now the profiles you install in OpenVPN will ROUTE ALL TRAFFIC THROUGH THE VPN. Safety, Security. Ahhhhhhhhh.

They seem to have left out on vital detail. What happens if you don't have a static IP address and your ISP routinely changes your address? During configuration they have you select between IP address and DNS address (which I chose DNS address and configured it to And I thought that was cool but then I realized THERE IS NO TOKEN ADDED TO ACTUALLY CHANGE THE ADDRESS. It won't actually update the address.

So ......... go to and make a domain and click on "Add Domain". It will give you a token (which I have redacted in the photo below) Your domain can be anything, your name, your dogs name, nonsense letters.......anything. I made hagensiekerj

Now click the install tab on the DuckDNS toolbar, click on "Pi" and choose your domain from the dropdown box

That will give you a directions page to follow to install a script file which checks your IP address every 5 minutes and changes it as necessary.

I noticed some problems here so I'm going to lend a little advice. The script only ran if I ran it as super user. Go to the line that says "vi" and instead type

sudo nano

And because of the way the script is run and the permissions it wants to write the log file to the root owner. So on the second line of the script where it says


change that by removing the ~ to this:


Now click the Control Key plus the X key, then the Y key to accept and Enter to save.

Now you need to sudo the ownership command below:

sudo chmod 700

Then sudo the crontab -e command below as well.

sudo crontab -e

add this to the last line

*/5 * * * * /home/pi/duckdns/ >/dev/null 2>&1

Now click the Control Key plus the X key, then the Y key to accept and Enter to save.

Now when you run the command

cat duck.log

It should return OK but it showed in a bizarre place in my terminal.

If it says "KO" you suck. Try again.

Now when your computer boots it will check it's DDNS address every 5 minutes and update as required. So in the worst case scenario it could be down for 5 minutes if your ISP changes your address.

You is a steely eyed missile man.