Guide : OpenVPN Access to Home Assistant

Cool thats a good start.

On the VPN server under /etc/openvpn/server.conf

Do you have a route push to your LAN (I take it the VPN server is on the lan?)

# Push routes to the client to allow it
# to reach other private subnets behind
# the server.  Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.
push "route 192.168.0.0 255.255.255.0"

Once added you should be able to ping something on the LAN side from the Pixcel.

If not - UFW needs configuring I allo all traffic from the VPN to LAN

also in the openvpn conf file you want…

# If enabled, this directive will configure
# all clients to redirect their default
# network gateway through the VPN, causing
# all IP traffic such as web browsing and
# and DNS lookups to go through the VPN
# (The OpenVPN server machine may need to NAT
# or bridge the TUN/TAP interface to the internet
# in order for this to work properly).
push "redirect-gateway def1 bypass-dhcp"

I did not have the first line. However, is that still correct given that my ip configuration is this?

   IPv4 Address. . . . . . . . . . . : 192.168.86.25
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.86.1

As for push redirect-gateway def1 bypass-dhcp, that was there already.

Still no ping though.

And I don’t have UFW rule allowing all VPN to LAN as you indicated. How do I get that in?

I think I managed to add the last one there by doing sudo ufw allow from 10.8.0.0/24 but no cigar. I also disabled/enabled ufw after.

ufw status is now:

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
1194/udp                   ALLOW       Anywhere
Anywhere                   ALLOW       10.8.0.0/24
22 (v6)                    ALLOW       Anywhere (v6)
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)
1194/udp (v6)              ALLOW       Anywhere (v6)

1 Like

You want push route To 192.168.86.0

And you need a route on the vpn server back to 10.8.0.0

Note the eth is tun0

So basically a route into the lan and a route out of the lan

Route push - pushes routes to the clients.

Sorry, I’m stuck here again. I can’t figure what I need to do from your last post.
This is what I get out of route command now:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         testwifi.here   0.0.0.0         UG    202    0        0 eth0
10.8.0.0        0.0.0.0         255.255.255.0   U     0      0        0 tun0
192.168.86.0    0.0.0.0         255.255.255.0   U     202    0        0 eth0

What am I missing? Like what command to execute?

not to derail what you guys are working on…

But is the only thing running on the Pi the VPN?

If so it might be less trouble to just install PiVPN on it and be done.

I used it before I realized my router had OpenVPN capability built in and it was a breeze to set up. I never had to do anything like you guys are discussing above. It just worked.

I have a procedure written up that I followed if you want to go that route.

1 Like

Yes please! I don’t mind a few rounds of troubleshooting, but if your suggestion gets it working quicker, I’m in. Please share your write-up.

Here is the write-up for a complete install from a blank SD card to having it running and connected on your phone. Obviously, feel free to skip any parts you’ve already done.

Install Openvpn using PiVPN


- Burn image Raspbian-Stretch-lite (or whichever you choose - I used Stretch at the time)

- Enable SSH:
  
  you need to know the drive letter of the SD card where you burned Raspbian on the PC
  
  open command prompt on the Windows PC 

  substitute your drive letter for <drive letter> (use the first > but not the <> around the drive letter)
  
  echo><drive letter>:\ssh

- Update Raspbian:

  $ sudo apt-get update
  $ sudo apt-get upgrade


- Modify raspi-config:

  $ sudo raspi-config
    -	Password
    -	Localization options – time zone
    -	Interfacing options – SSH
    -	Advanced options – expand file system
    
    reboot the Pi

- Setup a static IP 

  $ sudo nano /etc/dhcpcd.conf

- Edit /etc/dhcpcd.conf as follows:

  Add the following after "#here is an example which configures a static address, routes and dns".
  
  interface eth0
  static ip_address=192.168.1.4/24
  static routers=192.168.1.1
  static domain_name_servers=192.168.1.1 8.8.8.8

  save & reboot

- Set up a Key for encrypting SSH:

  Generate key using puttygen

  Create a new .ssh directory (if not already created by default…)

  $ mkdir .ssh

  Change permissions on .ssh to 700 (if not done by default…)

  $ chmod 700 .ssh

  Create a file called “authorized_keys” using nano

  $ nano ~/.ssh/authorized_keys


  Copy the key from puttygen:

  ssh-rsa the-really-really-long-key-created-by-puttygen-goes-here
  (using the same password as on RPi)

- Save file

- Change permissions of “authorized_keys” to 600

  $ chmod 600 ~/.ssh/authorized_keys

- Restart SSH service

  $ sudo service ssh restart

- Exit putty session 

- Open saved session info & add key to “auth” under SSH

- Change ssh to not allow password login

  $ sudo nano /etc/ssh/sshd_config

  Add the following line

  PasswordAuthentication no

- Save 

- Restart ssh service

  $ sudo service ssh restart

- Get rid of iv6

  $ sudo nano /etc/sysctl.conf

  Add:

  net.ipv6.conf.all.disable_ipv6=1

- Save file

- Commit changes

  $ sudo sysctl -p


- Setup duckdns 

  create a dynamic dns name (using duckdns)

  your_domain.duckdns.org
  token = your_token

- install duckdns

  $ mkdir duckdns
  $ cd duckdns
  $ nano duck.sh

  create an update script by entering the following:

  echo url="https://www.duckdns.org/update?domains=your_domain&token=your_token" | curl -k -o ~/duckdns/duck.log -K -

- save file

- change permissions on file

  $ sudo chmod 700 duck.sh

- set it to update the public ip every 5 minutes

  $ sudo crontab -e

  Pick default editor (selection 1)

  Add line:

  */5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1

- Save file

- Test the file

  $ ./duck.sh
  $ cat duck.log

  Should see ‘OK’


- Install PiVPN:

  $ curl -L https://install.pivpn.io | bash

  follow on screen prompts

  $ sudo apt-get upgrade

- Add client:

  $ openvpn add

  copy .ovpn file to phone

  install “openvpn connect” app on phone

  open openvpn app on phone and select .ovpn file

  connect

The only thing not in here is opening the correct port on your router. I picked a really high numbered port for better anonymity.

1 Like

This worked, awesome!

Now the next question: I notice when I connect, I can access internal stuff via IP but not using host names. Is that because I have to set OpenVPN to use my internal DNS? What would the command for that be?

Thanks again guys!

Not a clue…:slightly_smiling_face:

That’s going to be set in the OpenVPN conf file. Same one you were editing for the push route.

Thanks @Robbrad. I managed to alter server.conf to point to the internal DNS as primary (verified by seeing the filter rules working) but that didn’t help resolve local host names. Do I need to list those one by one somewhere? I just want to be able to write “hassio” instead of the IP…

Just to check - does that work when not on the vpn?

What dns server is set on the push? Is it your routers ip? Or a something else?

Also see the post from begleysm https://forum.netgate.com/topic/110431/local-hostnames-won-t-resolve-over-openvpn/13

DNS becomes quite complicated when working in this scenario.

Thanks, turns out this was solved by adding a filtering rule on my AdGuard that also functions as the internal DNS. I’m finally there! :champagne:

1 Like

So a follow up question on pivpn setup: I’ve been running this successfully for a while now, and I’ve generated various .ovpn files for three laptops, few android phones and a travel router. Every device connects ok, but one of the laptops for some reason cannot see any internals, like accessing hassio:8123 or a NAS server. Connection is ok, public IP is my home IP and I can’t for the life of me figure why only that one laptop doesn’t work. It’s a standard Windows 10 Home, nothing special set up in any way. All other clients can access these resources as expected. Any clues?

Initially I’d say if other clients are working it must not be the setup but the laptop itself

  1. Check for the windows firewall or bit defender or something else blocking - on the servers do you see a connection initiating?

  2. Regenerate the ovpn file just incase that one isn’t working.

I’m stuck. When I get to the step of running the script to generate the ovpn file, I get

./make_config.sh: line 9: /root/client-configs/files/steeleio2.ovpn: No such file or directory.

Any suggestions?

I’m quite new to VPNs in general and I was wondering whether it is possible to act as a client on a VPN service like NordVPN and access HA via that route instead of creating a server on the Pi?
Currently I’m using a private NordVPN on my laptop, and I know I can use the same NordVPN on RPI via OpenVPN (as a client). As mentioned I am new to this so please let me know if this is a very dumb idea, if I use NordVPN on my phone as well when not at home would it be possible to connect to my RPI via that route (when choosing a dedicated VPN server)? Or is the only way to connect to HA remotely via this route, hosting a OpenVPN server.

The key difference here is inbound vs outbound. Nord vpn is an outbound service - it masks your traffic from your isp to the internet. It purely for securing your outbound traffic. Your sort of accessing the internet from the nord vpn network. Hence why your public ip would change. Vs accessing from your home network.

Running a local vpn is much the same but it’s in the other direction. Your vpn’ing into your home network so it appears as if your on your home network. By doing this your accessing the internet from your home network rather than say your mobile network.

Think about it like this. Vpn to nord makes you on nord. If you vpn’ed back to home you would be back on your home lan.

Make sense?

1 Like