How to install OpenVPN on Raspberry Pi with Home Assistant

I did orginally put together a generic guide @ Guide : OpenVPN Access to Home Assistant - but I wanted to try and do this from scratch using a RaspberryPi 3 Raspbian image and HA as a virtual machine and see what steps were needed so I could share them here.

I’m doing this on a Raspberry Pi 3 from scratch - you could probably do this from any bit of hardware that can run Debian or Ubuntu.

Initial Setup
Download https://www.raspberrypi.org/downloads/raspbian/

RASPBIAN STRETCH LITE zip image file and use Etcher to write to your SD card

Boot your Pi (your going to need a monitor and a keyboard)

  1. Login with user pi and password raspberry

  2. Run the following commands to ensure the pi is up-to-date
    sudo apt-get update
    sudo apt-get upgrade

  3. enable SSH - to manage the Pi from the PC its best to install SSH

    sudo raspi-config

    Option 5 then 2

  4. Find the Pi’s local ip address by running ifconfig - its best at this stage to setup a DHCP reservation for the Pi in your router - so it get assigned the same local IP

    ifconfig

    Make note of the IP

  5. Use Putty to SSH to your pi - using [email protected]

Install Home Assistant as a Python Virtual Environment

  1. Once Logged in run the following and follow the prompts
    sudo apt-get install python3-venv

  2. Follow the install part of this guide to install Home Assistant https://www.home-assistant.io/docs/installation/virtualenv/

  3. You’ll need to run Home assistant at least once to create you a default config directory under /home/pi/.homeassistant

    hass --open-ui

  4. Then configure it to auto-start using the following

    sudo nano /etc/systemd/system/[email protected]

  5. Put the following in the file

[Unit]
Description=Home Assistant
After=network-online.target

[Service]
Type=simple
User=%i
ExecStart=/home/pi/homeassistant/bin/hass -c "/home/pi/.homeassistant"

[Install]
WantedBy=multi-user.target
  1. Save the file and run
sudo systemctl --system daemon-reload
sudo systemctl enable home-assistant@pi
sudo systemctl start home-assistant@pi
  1. Reboot

  2. Home assistant should now be running on your Pi - http://192.168.0.x:8123

Install Open VPN

  1. Run the following commands
    sudo apt-get install openvpn unzip easy-rsa

    sudo dpkg-reconfigure tzdata

    sudo gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /home/pi/server.conf

    sudo mv /home/pi/server.conf /etc/openvpn/

    sudo nano /etc/openvpn/server.conf

  2. Make the following changes to the file

    • Increase key security by Finding dh and makesure it reads dh dh2048.pem

    • Allow web traffic pass though to client by uncommenting push “redirect-gateway def1 bypass-dhcp” by removing the semi colon at the start of the line

    • Prevent DNS leak by overriding the default DNS - Uncomment push “dhcp-option DNS 208.67.222.222” and push "dhcp-option DNS 208.67.220.220"

    • Lower OpenVPNs run time auth - Uncomment user nobody and group nogroup

    • Change the port OpenVPN runs on it should current by port 1194 - choose something obscure and above 1024 e.g. port 50000 - leave it as UDP

  3. Now save your changes and exit.

  4. Enable Packet Forwarding

    sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'

  5. Make this change perminant by un-commenting net.ipv4.ip_forward=1

    sudo nano /etc/sysctl.conf

  6. Install and Configure ufw (uncomplicated firewall) once this is installed you will have a firewall running on the Pi for all connections local and remote (if you forward them). Even the Home Assistant port will be blocked until you enable it below.

    sudo apt-get install ufw

    Allow SSH (locally)
    sudo ufw allow ssh

    Allow the port you set OpenVPN to be
    sudo ufw allow 50000/udp

    Allow the port for home assistant to be
    sudo ufw allow 8123

    Allow VPN users to access all internal LAN services
    sudo ufw allow from 10.8.0.0/24

  7. Edit the ufw
    sudo nano /etc/default/ufw
    Change DEFAULT_FORWARD_POLICY=“DROP” to DEFAULT_FORWARD_POLICY=“ACCEPT

  8. Edit sudo nano /etc/ufw/before.rules
    Add the following lines after the first set of commented lines

    # START OPENVPN RULES
    # NAT table rules
    *nat
    :POSTROUTING ACCEPT [0:0]
    # Allow traffic from OpenVPN client to eth0
    -A POSTROUTING -s 10.8.0.0/8 -o eth0 -j MASQUERADE
    COMMIT
    # END OPENVPN RULES

  9. Enable the Uncomplicated Firewall

    sudo ufw enable

  10. You can check the status of the ufw with (remember in the future you might need to open another port or change a rule if you want to give access to a service or function.

    sudo ufw status

  11. Copy in the easy-rsa config
    sudo cp -r /usr/share/easy-rsa/ /etc/openvpn

  12. Make the keys folder
    sudo mkdir /etc/openvpn/easy-rsa/keys

  13. Edit the vars file
    sudo nano /etc/openvpn/easy-rsa/vars

Change the below to something more relevant to your region

export KEY_COUNTRY="US"
export KEY_PROVINCE="TX"
export KEY_CITY="Dallas"
export KEY_ORG="My Company Name"
export KEY_EMAIL="[email protected]"
export KEY_OU="MYOrganizationalUnit"

Change
export KEY_NAME="EasyRSA"
to
export KEY_NAME="server"

Save the file

  1. Generate the Server Cert - this takes a very long time (my Pi took 2 hours)

    openssl dhparam -out /etc/openvpn/dh2048.pem 2048

  2. CD to the easy-dir
    cd /etc/openvpn/easy-rsa

  3. type sudo su to swithc to root

  4. Run the following command (copy exactly)
    source ./vars

  5. Run this command to fix the bug with Easy RSA
    sudo cp openssl-1.0.0.cnf openssl.cnf

  6. Run this command to clean up
    ./clean-all

  7. Run this command to build the ca - bypass the prompts as you already set the values in vars

Generate a Certificate and Key for the Server

  1. While working in /etc/openvpn/easy-rsa
    ./build-key-server server

Bypass the values again - but this time you will be asked for a password - leave this blank

  1. Final two questions will be
  • Sign the certificate? [y/n]

  • 1 out of 1 certificate requests certified, commit? [y/n]

    Answer yes to both

  1. Copy the new certs to the OpenVPN folder
    cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn

  2. Verfiy the files are copied ls /etc/openvpn

Ready to start your OpenVPN server!!

exit root mode by pressing ctrl+d and run

`sudo service openvpn start`
`sudo service openvpn status`

All being well you should see Active: active (exited) since…

Client Cert Generation

Now you have a fully working OpenVPN server its time to generate some client certificates. You can generate one per user - but the key here is that without a cert they cant connect to your VPN

  1. Working out of /etc/openvpn/easy-rsa

    Run the following one by one
    sudo su
    source ./vars
    ./build-key client1

Leave the prompts blank - and decide if you want a challenge password on the cert (I’d advise setting one, because if your CERT fell in to the wrong hands - they would need the password to use it.)

  1. Copy the sample client config to the easy rsa folder
    cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/easy-rsa/keys/client.ovpn

  2. Edit the client config
    nano /etc/openvpn/easy-rsa/keys/client.ovpn

  3. First thing to change is you need to put the public IP or public DNS of your internet here (you can get a dynamic DNS setup if your internet IP changes) - also note the port number you set open VPN to run on

    remote your_server_ip 50000

    Again uncomment

    user nobody
    group nogroup

Ok - that’s it - you just setup your OpenVPN server, generated a server cert, a server key and a client side key, cert and config

The client cert, key and config are all part of the package that needs to be deployed to the client (On an iPhone you would need to use iTunes to copy these files over)

client1.crt
client1.key
client.ovpn
ca.crt

If your struggling with the multiple files - I would suggest combining the client1.crt, client1.key and ca.crt into the ovpn file and then just deploying the one file to the device

To combine the files into a unified file (unified ovpn file)

  1. Edit client.ovpn

  2. Comment the following by adding a ; in front of each line
    ;ca ca.crt
    ;cert client.crt
    ;key client.key

  3. Save the file and run the follow three commands
    echo '<ca>' >> /etc/openvpn/easy-rsa/keys/client.ovpn
    cat /etc/openvpn/ca.crt >> /etc/openvpn/easy-rsa/keys/client.ovpn
    echo '</ca>' >> /etc/openvpn/easy-rsa/keys/client.ovpn

  4. Run these 3 commands
    echo '<cert>' >> /etc/openvpn/easy-rsa/keys/client.ovpn
    cat /etc/openvpn/easy-rsa/keys/client1.crt >> /etc/openvpn/easy-rsa/keys/client.ovpn
    echo '</cert>' >> /etc/openvpn/easy-rsa/keys/client.ovpn

  5. Run these 3 commands
    echo '<key>' >> /etc/openvpn/easy-rsa/keys/client.ovpn
    cat /etc/openvpn/easy-rsa/keys/client1.key >> /etc/openvpn/easy-rsa/keys/client.ovpn
    echo '</key>' >> /etc/openvpn/easy-rsa/keys/client.ovpn

  6. If you run cat /etc/openvpn/easy-rsa/keys/client.ovpn you will see the 3 files have been appended to the client ovpn file

7.You now have one client.ovpn file that when you deploy it to your device - with the OpenVPN app you can VPN into your home network.

See https://nordvpn.com/tutorials/android/openvpn/ for more help on how to deploy ovpn files to your device

WARNING: DO NOT UNDER ANY CIRCUMSTANCE let these OVPN Client files get into the wrong hands, don’t email them to your device, only use trusted methods to copy them over. Remember with this file (and your challenge key if you set one) anyone could connect to your VPN

Once these files are on your remote device open port 50000 to on your router to your Pi

Consider setting up fail2ban for open VPN (this will ban IPs that try to connect to OpenVPN at port 50000) But with out a the above client config file - they are kind of wasting their time.

Just gonna recommend PiVPN as an OpenVPN install.

Sure - as mentioned on the other thread. However people expressed some concerns over installing it when they didn’t know how it was setup - another reason I wrote this guide.

OpenVPN is always a pain to set up no matter how you cut it. I’ve never found it easy but it does get easier to understand after like the 5th time

Does OpenVPN need to be installed on the same machine where Home Assistant is running? I already have it running on a box with Ubuntu 16.04 server and I was hoping I could set up OpenVPN on a RPi separately. I should be able to do this correct?

correct. It just needs to be on the same network, not necessarily the same same device

Any machine on the network will do. Arguably a machine that only runs the vpn, as then it is easy to physically shut the vpn down but powered down/disconnecting that one machine.

1 Like

Thanks for this awesome procedure!

I tried to setup a VPN using openvpn accessed via private internet access but then I figured oiut that they are so much a VPN tunnel between computers as they are an anonymizer to shield you from prying eys of your ISP. So that was a complete waste of time.

How would the above procedure change (if it does…) when running on a machine other than your HA machine? I’m going to run this (for now at least) on a spare Pi3B+ I’ve got laying here.

i.e. what ports need to be changed if any? I assume I leave the 8123 port out of the firewall config?

Any other differences?

If I need to connect two different phones to my home LAN do I need to create two different client certificates? one for each phone? Or just one client certificate and provide it to each phone?

and just so I understand completely, when I connect to the openvpn on my phone then all i need to do is use chrome to go to the internal LAN IP:PORT of my HA machine to get to the HA frontend just as I would if I’m sitting in front of any computer on my LAN?

@Robbrad

Following your procedure when I got to “install Open VPN” step 20 where it says:

20 .Run this command to build the ca - bypass the prompts as you already set the values in vars

Generate a Certificate and Key for the Server

While working in /etc/openvpn/easy-rsa
./build-key-server server

I get the following response:

root@openvpn:/etc/openvpn/easy-rsa# ./build-key-server server
pkitool: Need a readable ca.crt and ca.key in /etc/openvpn/easy-rsa/keys
Try pkitool --initca to build a root certificate/key.

Is there a part of step 20 missing? Is there supposed to be another command there or is the proper next step actually ./build-key-server server?

Just to be aware i found the missing command:

./build-ca

And in step 14 I got a permission denied when i tried generating the key. the command has to be run as sudo. At least it did on mine.

Pfsense has a wizard that makes it pretty simple to setup and auto generates the setup for different operating systems/devices to download.

That being said, pfsense is a whole different beast to learn to configure and setup. But if you already have it running its great. I love the granularity of the logging that you can setup and then e-mail to yourself regularly.

1 Like

In the firewall of the machine that runs HA, but not your router! The aim is to only be able to access the network (and machines running on it) via the vpn, therefore that port (default 1194 for openvpn) is the only port that should be forwarded through your router.

It is also advised to use a non-standard port number to reduce the chances of your vpn being picked up by a port sweep.

Yes. I meant in the vpn firewall settings.

I have a high port open on my router to the pi running the vpn

Do I need to have port 8123 open in the firewall settings on the vpn if I’m not running HA on that machine?

No - that’s only if your running Home Assistant on the same server as the OpenVPN

You will need a route from the OpenVPN server to your LAN - that way the client who connects will be able to access LAN services

So I must have missed something along the way. I was able to successfully install openvpn on a separate Rpi and create the key to pass to my phone and even successfully connect however I can no longer connect to my HA instance. Since I had a duckdns address I used this in my setup figuring it would continue to use a static ip. I then eliminated all the prior port forwarding and only have the new one created for the openvpn.

Do I need to change the base url back to the internal ip of my machine running HA in the config.yaml? Right now I cannot connect to HA internally or thru openvpn.

Can anyone help?

**Edit -> Many thanks to @Robbrad for getting me straightened out. (fyi - I needed to remove all prior duckdns references in my config.yaml file)

1 Like

Your project is very interesting. Do you know if it is possible to install on stretch together with HA also Volumio?

I’m a newbie to VPN, so does doing this mean my Pi connects to the internet using a VPN? So for example I could access things blocked in my country?

No, this is a VPN into your network. Basically secured direct access to your network from anywhere.

You are thinking of a VPN that routes all traffic out of your network through a single ‘tunnel’ so your location/IP/etc. is obscured.

Exactly correct - it’s creating the end point that you connect too. Much like an external service you pay for. You can set it up to route internet traffic via the VPN you setup, eg when your away from home say you go to a hotel, vpn into your network and browse the internet, this will be encrypted on the local hotel network and all internet will come via your home.

1 Like

Thanks, that makes thing a lot clearer. :slight_smile: I’ll have to try this as I’m having more and more things on my internal network that would be nice to access over the internet.

1 Like