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)
-
Login with user pi and password raspberry
-
Run the following commands to ensure the pi is up-to-date
sudo apt-get update
sudo apt-get upgrade
-
enable SSH - to manage the Pi from the PC its best to install SSH
sudo raspi-config
Option 5 then 2
-
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
-
Use Putty to SSH to your pi - using [email protected]
Install Home Assistant as a Python Virtual Environment
-
Once Logged in run the following and follow the prompts
sudo apt-get install python3-venv
-
Follow the install part of this guide to install Home Assistant https://www.home-assistant.io/docs/installation/virtualenv/
-
You’ll need to run Home assistant at least once to create you a default config directory under /home/pi/.homeassistant
hass --open-ui
-
Then configure it to auto-start using the following
sudo nano /etc/systemd/system/[email protected]
-
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
- Save the file and run
sudo systemctl --system daemon-reload
sudo systemctl enable home-assistant@pi
sudo systemctl start home-assistant@pi
-
Reboot
-
Home assistant should now be running on your Pi - http://192.168.0.x:8123
Install Open VPN
-
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
-
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
-
-
Now save your changes and exit.
-
Enable Packet Forwarding
sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
-
Make this change perminant by un-commenting net.ipv4.ip_forward=1
sudo nano /etc/sysctl.conf
-
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
-
Edit the ufw
sudo nano /etc/default/ufw
Change DEFAULT_FORWARD_POLICY=“DROP” to DEFAULT_FORWARD_POLICY=“ACCEPT” -
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
-
Enable the Uncomplicated Firewall
sudo ufw enable
-
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
-
Copy in the easy-rsa config
sudo cp -r /usr/share/easy-rsa/ /etc/openvpn
-
Make the keys folder
sudo mkdir /etc/openvpn/easy-rsa/keys
-
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
-
Generate the Server Cert - this takes a very long time (my Pi took 2 hours)
openssl dhparam -out /etc/openvpn/dh2048.pem 2048
-
CD to the easy-dir
cd /etc/openvpn/easy-rsa
-
type
sudo su
to swithc to root -
Run the following command (copy exactly)
source ./vars
-
Run this command to fix the bug with Easy RSA
sudo cp openssl-1.0.0.cnf openssl.cnf
-
Run this command to clean up
./clean-all
-
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
Bypass the values again - but this time you will be asked for a password - leave this blank
- Final two questions will be
-
Sign the certificate? [y/n]
-
1 out of 1 certificate requests certified, commit? [y/n]
Answer yes to both
-
Copy the new certs to the OpenVPN folder
cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn
-
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
-
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.)
-
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
-
Edit the client config
nano /etc/openvpn/easy-rsa/keys/client.ovpn
-
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)
-
Edit client.ovpn
-
Comment the following by adding a ; in front of each line
;ca ca.crt
;cert client.crt
;key client.key -
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
-
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
-
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
-
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.