Home Assistant Community Add-on: WireGuard

Are you actually receiving something (Rx) or just transmitting with the client? (Tx)

Only transmitting. It’s quite misleading that it presents this as a successful connection?

Never mind, I had some typos in the config. Working now and very smoothly, this is cool!

Yesterday I noticed something weird. I seem to have lost my configuration blocks for server aswell as for the peers part. Trying to view the code in yaml results in an empty screen too. I am running plug-in version 0.80 on :
Home Assistant 2023.3.6
Supervisor 2023.03.3
Operating System 9.5
Frontend-version: 20230309.1 - latest

Since I already had created 1 peer, I can confirm that WireGuard is operational.

Because I am fairly new to HA, I have no idea where to start investigating thuis issue, anyone noticed the same or have a clue what could have caused this?

Thanks for a great add-on!

So I’ve set up a network-to-network tunnel, unifying my home network with another home LAN. Basically it works well - for traffic coming into HASS. However traffic going from HASS into the remote network would (obviously) not find itself in the tunnel.
Specifically, I’d like traffic from ESPHome to find its ESP devices on the remote network. ESPHome runs in its own container and clearly does not see the routing table and NAT configs done by WG.

Is there a simple way to achieve that? I’d settle for a hack that’s specific to ESPHome. I tried some routing table manipulations but so far no luck. I’d appreciate any pointers. Thanks!

(HA OS, on Yellow.)

Add this in your Home Assistant configuration:

command_line:
  - sensor:
      name: Wireguard addon internal IP
      command: "host_result=$(host a0d7b954-wireguard); addon_ip=${host_result##* }; ip route replace 172.27.66.0/24 via $addon_ip; echo $addon_ip"

It will automatically create the necessary route.
Note auto-discovery is based on mDNS and won’t work with Wireguard; you’ll need to set up each ESPHome node manually with their Wireguard IP address.

4 Likes

Thank you @CarlosGS ! This is extremely helpful.
I ended up using it with one change - needed to append ...src <hass-visible-address> to the route so that the returning packets will come from the visible IP address of HASS.
Traffic seem to be flowing nicely now - thanks again!

2 Likes

I might be missing this, but is there instructions on how to set this up as a client? I would have Wireguard server on my UniFi UDM SE at home, and looking to have a Wireguard VPN connector to a Home Assisstant installation running on a VM at a vacation home so I can connect the two instances with ‘Remote Home Assistant’ or have easy access.

1 Like

Hi,

I’ve got running Wiregurd add-on fine. I can access local lan and browse the internet with my home ip when I’m abroad with ad blocking using the Adguard add on. All ok so far, but now I also got a dual stack fiber connection from KPN in the Netherlands. But when I am abroad on a different dual stack network, I only get an ipv4 connection. So I searched and tried to play with the configs.
I added my local adguard dns ipv6 address to the config and gave my clients an ipv6 address as well.

When I save the config and the add on restarts I see in the logs that the wg0 interface gets deleted:

Error: IPv6 is disabled on nexthop device.

[#] resolvconf -d wg0 -f

mv: can’t rename ‘/etc/resolv.conf.913.openresolv’: Resource busy

[#] ip link delete dev wg0

Is this an error or missing config in Docker? I run HA as a vm in Esxi.
Hope anybody has a clue.

Thanks and regards,

Renzo

The instruction video is no longer available -

Can’t find the folder where the QR codes are stored. My HA is hosted supervised on Debian. Anyone has a clue? I tried to search here but no luck.

Edit: Nevermind. The configurations are in /usr/share/hassio/ssl/wireguard

I want to use wireguard on hassos (raspberry pi).

My configuration:

  • static internal ip on hassos (192.168.0.69, my internal net is 192.168.0.0/24)
  • public ip on my router
  • port forward (51820 udp) to my hassos pi
  • wireguard net 192.168.1.0/24

No addons like dns, adguard only dhcp addon is used to assign ip addresses.

My wireguard config:

host: XX.152.155.70
addresses:
  - 192.168.1.1
dns:
  - 8.8.8.8
  - 8.8.4.4

client:

- name: christopher-phone
  addresses:
    - 192.168.1.2
  allowed_ips: []
  client_allowed_ips: []

I can connect to wireguard on hassos, my phone or laptop shows active.

But i’m not able to connect to any ressource on internal lan.

What’s the problem here?

→ after a reboot of hassos and phone it now works like expected. no error in configuration. thx

This post details the setup of a point-to-point Wireguard tunnel where a NAT local to Wireguard service running in the Wireguard Add-On allows external access to ssh and the web interface from the remote network.

This avoids sharing the entire HA Network which could lead to trouble if you have more than one Home Assistant setup connecting to the remote server as the network ranges to pass through would be similar/the same. Also this avoids exposing more than is needed from the Home Assistant setup and IMHO also simplifies the HA setup as the list of allowed ips is simplified.

This setup is not meant to use your HA server as a VPN server for clients, it does not provide access to your home network through the wireguards service neither. Its only goal is to provide access to the web interface(s) and SSH service.

I am not able to control the internet box through which home assistant connects to the internet, so I have HA connect to a remote wireguard server where I also have a ha-proxy that will provide https access.

So this setup works as follows.
There is a point-to-point wireguard connection, and access to the Web UI and SSH is provided through NAT on the home assistant instance.

  • Internet → Remote server [ha-proxy, ssh proxyjump] → Remote WG → HA WG / NAT → [HA Web interface, SSH].

HA Wireguard configuration:

server:
  host: redacted_local
  addresses:
    - 172.16.0.2
  dns:
    - 80.80.80.80
    - 80.80.81.81
  pre_up: /ssl/pre-up.sh
  pre_down: /ssl/pre-down.sh
peers:
  - name: redacted_remote
    public_key: redacted_public key
    addresses:
      - 172.16.0.1
    allowed_ips:
      - 172.16.0.1
    client_allowed_ips: []
    endpoint: RemoteServer:51825

I added the pre-up.sh and pre-down.sh scripts in the ‘/ssl’ folder as this is the only folder that is mounted in the wireguard instance.
The setup has to use scripts as ssh_ip=${ssh_ip##* } was cut off at the space when providing the individual commands in the yaml configuration.

The scripts get the ips of the containers using nslookup on the slug .
host was not available, so I resorted to nslookup

pre-up.sh:

#!/bin/bash -xv
ssh_ip=$(nslookup a0d7b954-ssh | grep Address | tail -1)
ssh_ip=${ssh_ip##* }
ha_ip=$(nslookup home-assistant.local.hass.io | grep Address | tail -1)
ha_ip=${ha_ip##* }

# sysctl -w net.ipv4.ip_forward=1;

# my_ip = Local Wireguard IP
my_ip=172.16.0.2
iptables -t nat -A PREROUTING -d $my_ip -p tcp --dport 22 -j DNAT --to-destination $ssh_ip
iptables -t nat -A PREROUTING -d $my_ip -p tcp --dport 8123 -j DNAT --to-destination $ha_ip

pre-down.sh is essentially the same as the pre-up.sh script - -A is replaced with -D.

#!/bin/bash -xv
ssh_ip=$(nslookup a0d7b954-ssh | grep Address | tail -1)
ssh_ip=${ssh_ip##* }
ha_ip=$(nslookup home-assistant.local.hass.io | grep Address | tail -1)
ha_ip=${ha_ip##* }
my_ip=172.16.0.2

iptables -t nat -D PREROUTING -d $my_ip -p tcp --dport 22 -j DNAT --to-destination $ssh_ip
iptables -t nat -D PREROUTING -d $my_ip -p tcp --dport 8123 -j DNAT --to-destination $ha_ip

More ports can be exposed by adding the appropriate iptables commands. For example, one could also expose the supervisor, appdaemon, etc. You may need to use extra ns_lookup to determine the IP-address of these other containers to forward the traffic to the best port/ip.

Scripts must be executable:

chmod +x /ssl/*.sh

I tested on the remote using the following on the remote server (unsuccesful prior to proper NATting):

curl http://172.16.0.2:8123
# results in HA web page
echo "HELO" | nc 172.16.0.2 22 
# results in response from SSH server:
SSH-2.0-OpenSSH_9.3
Invalid SSH identification string.

After finalising the remote setup I was able to SSH to the HA machine through the public internet address. I added some trusted proxies to configuration.yaml and restarted ha to gain access to the web interface (if not, I had an error “400: Bad Request”).

http:
  use_x_forwarded_for: true
  trusted_proxies:
    - XXX.XXX.XXX.XXX  # Remote Public IP   
    - 192.168.0.254  # Remote Firewall IP   
    - 172.30.33.0 # "Local" proxy     

The address to add can be found in ‘/config/home-assistant.log’:

assistant.components.http.forwarded] Received X-Forwarded-For header from an untrusted proxy 172.30.33.0

Hi @le_top, thank you for the guide. Your guide is exactly what i need to achieve in my environment.
I have done everything following your guide, but no avail. I wish you can help me on this matters.

My Connection flow:

Internet → Remote server → Remote WG → HA WG / NAT → [HA Web interface]

My HA Wireguard configuration:

server:
  host: 192.168.50.15 #HA local IP
  addresses:
    - 10.10.20.2 #WG Client local IP
  dns:
    - 1.1.1.1
    - 1.0.0.1
  pre_up: /ssl/pre-up.sh
  pre_down: /ssl/pre-down.sh
peers:
  - name: WG Server Remote
    public_key: haBUZbiyQ08a666666666llWdIKplucThFZuCv+TuGw= #WG Server Remote Public Key
    addresses:
      - 10.10.20.1 #WG Server Remote local IP
    allowed_ips:
      - 10.10.20.1 #WG Server Remote local IP
    client_allowed_ips: []
    endpoint: mywgremote.net:43231 #WG Server Remote Public IP

pre-up.sh:

#!/bin/bash -xv
ssh_ip=$(nslookup a0d7b954-ssh | grep Address | tail -1)
ssh_ip=${ssh_ip##* }
ha_ip=$(nslookup home-assistant.local.hass.io | grep Address | tail -1)
ha_ip=${ha_ip##* }

# sysctl -w net.ipv4.ip_forward=1;

# my_ip = Local Wireguard IP
my_ip=10.10.20.2
iptables -t nat -A PREROUTING -d $my_ip -p tcp --dport 8123 -j DNAT --to-destination $ha_ip

pre-down.sh:

#!/bin/bash -xv
ssh_ip=$(nslookup a0d7b954-ssh | grep Address | tail -1)
ssh_ip=${ssh_ip##* }
ha_ip=$(nslookup home-assistant.local.hass.io | grep Address | tail -1)
ha_ip=${ha_ip##* }
my_ip=10.10.20.2

iptables -t nat -D PREROUTING -d $my_ip -p tcp --dport 8123 -j DNAT --to-destination $ha_ip

Scripts must be executable: - DONE

chmod +x /ssl/*.sh

Trusted proxies to configuration.yaml - DONE

http:
  ip_ban_enabled: true
  login_attempts_threshold: 7
  use_x_forwarded_for: true
  trusted_proxies:
    - 192.168.0.0/24
    - 172.16.0.0/25
    - 172.30.33.0/24
    - 127.0.0.1
    - 266.22.74.13# Remote Public IP
    - 10.10.30.1 # Remote Firewall IP

Log from WG Addon:

s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service base-addon-banner: starting
-----------------------------------------------------------
 Add-on: WireGuard
 Fast, modern, secure VPN tunnel
-----------------------------------------------------------
 Add-on version: 0.8.1
 You are running the latest version of this add-on.
 System: Home Assistant OS 10.5  (amd64 / generic-x86-64)
 Home Assistant Core: 2023.9.2
 Home Assistant Supervisor: 2023.09.2
-----------------------------------------------------------
 Please, share the above information when looking for help
 or support in, e.g., GitHub, forums or the Discord chat.
-----------------------------------------------------------
s6-rc: info: service base-addon-banner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service base-addon-log-level: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service base-addon-log-level successfully started
s6-rc: info: service legacy-cont-init: starting
cont-init: info: running /etc/cont-init.d/config.sh
cont-init: info: /etc/cont-init.d/config.sh exited 0
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
services-up: info: copying legacy longrun api (no readiness notification)
services-up: info: copying legacy longrun status (no readiness notification)
services-up: info: copying legacy longrun wireguard (no readiness notification)
[17:32:11] INFO: Starting WireGuard...
s6-rc: info: service legacy-services successfully started
[#] /ssl/pre-up.sh
/bin/bash: -
: invalid option
Usage:	/bin/bash [GNU long option] [option] ...
	/bin/bash [GNU long option] [option] script-file ...
GNU long options:
	--debug
	--debugger
	--dump-po-strings
	--dump-strings
	--help
	--init-file
	--login
	--noediting
	--noprofile
	--norc
	--posix
	--pretty-print
	--rcfile
	--restricted
	--verbose
	--version
Shell options:
	-ilrsD or -c command or -O shopt_option		(invocation only)
	-abefhkmnptuvxBCEHPT or -o option
Unable to access interface: No such device
[#] ip link delete dev wg0
Cannot find device "wg0"
[17:32:41] INFO: Requesting current status from WireGuard...
[17:33:12] INFO: Requesting current status from WireGuard...

Happy to see that these instructions are useful !

As far as I remember I did have #!/bin/bash -xv.
However in your case the system complains : either there is an invisible character after the hyphen - or for a mysterious reason it’s not supported.
So #!/bin/bash should work - there is just less debug output from bash (-xv shows each command executed before and after resolving variables).

Edit: your log shows Shell options: -abefhkmnptuvxBCEHPT or -o option as well which lists x and v, so it looks more like there is an invisible character in the first line or “xv” is missing (but not the -)

Hi ,

Thank you for all the work done on such a fantastic addon.

I have it almost working for my needs however:

I cannot ping the peer (my phone) that is connected to wireguard. Everything works the other way around , I can access my LAN devices from my phone with no problem. I can ping all the lan devices from my phone but not the phone from devices on my LAN.

What am I missing here ?

Does your phone configuration have its own IP covered by the ‘allowed_ips’ argument?

Hi all.

First, sorry for my bad english.
I have a problem to set up a site2site connection.
Incoming traffic is all fine. No Problems.
After 2 days of reading and trying, i can now ping devices in the second LAN from the terminal of HA.
The problem i can´t solve is, that there seems to be no routing from the hassos eth0 to the wireguard-container. If i make a traceroute from my pc to a device in the second LAN, it just go to the raspberry-pi ip.
In the configuration.yaml i put this command:

command: "host_result=$(host a0d7b954-wireguard); addon_ip=${host_result##* }; ip route replace 192.168.10.0/24 via $addon_ip src 192.168.1.114; ip route replace 192.168.2.0/24 via $addon_ip src 192.168.1.114;

local-lan is 192.168.1.0
vpn is 192.168.10.0
second lan i 192.168.2.0
hassos on rasp4 is 192.168.1.114

route says:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         wpad.fritz.box  0.0.0.0         UG    100    0        0 eth0
172.30.32.0     *               255.255.254.0   U     0      0        0 hassio
172.30.232.0    *               255.255.254.0   U     0      0        0 docker0
192.168.1.0     *               255.255.255.0   U     100    0        0 eth0
192.168.2.0     a0d7b954-wiregu 255.255.255.0   UG    0      0        0 hassio
192.168.10.0    a0d7b954-wiregu 255.255.255.0   UG    0      0        0 hassio

I think i need some routing between eth0 and the hassio device.

I hope that my englishskills are enough, that you understand what i try to say :slight_smile:

MfG Manley

Hi thank you for the reply, this is my MIkrotik router as my WG Server Remote local IP. I have try swapping with 0.0.0.0/0, but no avail.

After a few days of struggling i Opted for the easier solution which have the same result, using Tailscale more details below, credit to @lmagyar and @OH1MAC

@devilization The first issue to solve was that the script adding the NAT rule was not working because the first line of the script was not ok. You probably did not need the swapping. (Note to other readers: this was for the point-to-point configuration).

@Manley According to your message, your site to site connection is at least partly working as you want, so the Wireguard connection is established. (Note to other readers: this is for a site-to-site configuration).

You want a PC in your network to use to use this Wireguard tunnel on your Home Assistant instance.
You need two conditions:

  1. Your PC directs traffic for this IP range to Home Assistant’s IP as a gateway.
    Either HA is your PC’s gateway, or, your PC has a route defined for that. Defining routes on a PC on every reconnect is a pain in the a** so I would be tempted to have HA as the DHCP server setting HA as the gateway, or configure the current DHCP server to distribute HA as the gateway.
  2. Home Assistant needs to accept this traffic and route it through the Wireguard tunnel. If you can ping devices on the remote site from the HA ssh add-on, then I think that routing is ok in the HA setup.

IMHO a better solution would be to install Wireguard on your PC and connect your PC to the remote site using Wireguard. Your PC’s Wireguard would add the route on your PC on every connection.

If you want to have any PC using HA’s WG tunnel to connect to the remote devices, then you definitively have to define HA as the gateway.

Thanks for the quick answer.
I have some devices in my local LAN, that need to talk with the second LAN. So i need the HA as gateway. The routing to the HA-Raspberry (192.168.1.114) is static in the router-configuration. A traceroute confirm that settings.
When i make a ping from the HA ssh i think the ping starts from the hassio-device. So the communication between the containers is correct. Just when a ping comes through the eth0 und have to be route to the hassio, it fails.

Traceroute from my pc to a VPN-client in the second LAN:

Routenverfolgung zu 192.168.10.3 über maximal 30 Hops

  1    <1 ms    <1 ms    <1 ms  FRITZBOX [192.168.1.1]
  2    <1 ms    <1 ms    <1 ms  homeassistant [192.168.1.114]
  3     *        *        *     Zeitüberschreitung der Anforderung.

A traceroute vom the HA Terminal to the same VPN-client:

traceroute to 192.168.10.3 (192.168.10.3), 30 hops max, 46 byte packets
 1  a0d7b954-wireguard.local.hass.io (172.30.33.1)  0.021 ms  0.018 ms  0.016 ms
 2  192.168.10.1 (192.168.10.1)  11.917 ms  10.823 ms  10.928 ms
 3  192.168.10.3 (192.168.10.3)  61.326 ms  29.283 ms  27.473 ms