This documents the steps I took to finally get SSL/TLS working with HA OS on Windows VirtualBox and using a Google WiFi. All of the information can be found in different places but I figured this was a common enough, and difficult enough, combination of components to be of interest to people new to Home Assistant.
Why is this even a thing?
Google WiFi is relatively simple to install and configure but they decided to make things easier by leaving out functionality that most routers have - specifically the ability to port-forward to an IP address. G-WiFi forwards to MAC addresses, and automatically disables MAC’s it can’t “ping” (I’m not sure how it actually looks for them, but it doesn’t matter). The result is that the bridged NIC that HA uses under VBox is only visible on the G-WiFi router when it’s actively talking on the network, making it unusable as a device to port-forward to.
My internet comes in through a modem and into a router - NOT the Google WiFi router. This means my network is double NATed. This isn’t an uncommon situation since many ISPs provide a modem/router combination to which a G-WiFi mesh is attached. Since the ISP router is usually NATed and G-WiFi always creates another NAT, this is also a double NATed configuration. This results in an extra step in the journey, which I’ll touch on later. Note that if you’re double NATed you’ll need to know how to forward a port in your particular brand of router.
My HA VM runs under VirtualBox (v 6.1.18 as of this writing) on a Windows 10 Home laptop that’s currently dedicated to this purpose.
I’m assuming you have HA OS configured and running on VirtualBox under Windows, and can access it via a browser and/or mobile app through HTTP. I’m also assuming you’re using Google Wi-FI; some of the instructions here will work for more generic HA OS installs and for different routers, but no promises.
Note that this was documented after the fact. I got everything working, but there were some dead-ends and missteps that I’ve left out. If it doesn’t work for you let me know and I’ll try to figure out what I did that didn’t get in the document. That said, if you ask about configurations that are significantly different from mine I probably won’t bother to reply.
To get around the G-WiFi port-forwarding issue described above, I decided to add another NIC to the HA VirtualBox VM and use it for the connections to the HA UI (both Web and Mobile). To start this process, shut down the HA VM from the VBox UI. Under Settings for it, go to Network and click on the Adapter 2 tab. Check Enable Network Adapter and select NAT from the Attached to: drop-down. Expand the Advanced properties and UNCHECK the Cable Connected box - more on that in a minute. Click the Port Forwarding button and add a port-forwarding rule. You can give it a name if you want, and put 8123 in both the Host Port and Guest Port boxes. The protocol should default to TCP, which is fine. Leave the Host IP and Guest IP boxes empty. OK out and then restart your HA VM.
In the HA console, login as root then get into the VM by typing login. Execute nmcli device to get a list of NICs as seen by the VM. One will have a “CONNECTION” of HassOS default and the other should be disconnected. For me, the HassOS default was on device enp0s3 and the disconnected device was enps0s8.
If you forgot to uncheck the Cable Connected box in the VM your default connection may have moved to the new NIC, disabling UI access to HA and generally causing havoc. In this case, shut down the VM again, uncheck Cable Connected and restart. For some reason the default seems to get set to the highest numbered active adapter(maybe??) which messes things up. There’s probably an arcane Linux incantation that will force it to the correct adapter (UDEV persistent rules) but I didn’t bother.
Back in the HA console, run nmcli con. Here you should only see one connection for the HassOS default. We need to create a new connection on the new device to make it available. To do so run nmcli con add type ethernet con-name “HA-NAT” ifname enp0s8 ← use the name for the new device, and you can give the connection whatever name you wish.
Now, in the VBOX UI, enable Cable Connected to “plug-in” your NIC. Restart the HA VM and login as root again. The System Information displayed should show two IPV4 addresses and two IPV6 addresses. One (the default) will be on your G-WiFi network (probably 192.168.86.xxx, unless you changed the default subnet range) and one will be the new NIC on 10.0.3.15, which is the VBox default for a NAT NIC.
Now you should be able to reach the HA UI from a web browser using either the HA VM IP, or the IP of the Windows host itself (both on port 8123).
Set up SSL with the DuckDNS add-on
If you haven’t already, install and configure the DuckDNS Add-On. The documentation for it is pretty complete, although I missed the step about adding the *http section to my configuration.yaml, which cost me a few hours or head scratching and debugging. Note that once you enable SSL in HA you won’t be able to access the web UI without bypassing the dire warnings about an unsigned certificate. Don’t worry, we’ll deal with that shortly. Also, the mobile UI will completely refuse to connect.
My hat goes off to the person(s) that wrote and maintain the DuckDNS Add-on. If you follow the instructions (which I apparently can’t do), installing and configuring it is dead simple.
Set up ssl-secured external access to HA
At this point your communication is SSL encrypted, but you can’t access it without bypassing the SSL certificate check, which doesn’t do a lot of good. Also, you can’t access it at all from outside your internal network, so let’s fix that.
Open the Google WiFi app on your phone and click on the four circles at the top left of the screen. I have no clue what they’re supposed to represent so I’m not going to even try to name them. Under Settings go to Network & general → Advanced Networking → DHCP IP reservations. Click the green + in the bottom right corner. Scroll through your device list and select the hostname for the Windows system running your VirtualBox. Note this is NOT the hostname/IP of the VM itself, which may or may not show up in your list. This tells the Google router to always assign that IP to the Windows system.
Go back to Advanced Networking and select Port management. Again click the green + to add a new port forwarding rule. Select the hostname of your Windows box again then Next. Use 8123 for both the Internal ports and External port and set the type to TCP. Hit Done to save the rule.
IF you are double NATed now’s the time to go into your second router and set up another port forwarding rule. This time you need to forward port 8123 as both the source and destination ports, and the IP address of your Google router as the destination IP - NOT the IP of the Windows system. At this point we’re telling your external router to forward anything that comes in from the WAN on port 8123 to port 8123 on the Google router. Since we told the Google router to forward anything coming in to it on port 8123 to port 8123 on the Windows system, and we told VBox to forward anything that comes in to the Windows machine on port 8123 to the new NIC on the HA OS VM, we’ve now got a complete path from the internet to HA.
If you haven’t already, change the HA configuration to use the DuckDNS domain name as the External URL, and remove the Internal URL if it’s been set. It should look like https://myduckdnsdoamin.duckdns.org:8123.
You can test the port forwarding by turning off wireless on your phone and using mobile data to make a connection to HA via either the mobile app or a web browser through your DuckDNS domain. Remember to use https if testing with a web browser. Let there be much rejoicing.
But wait! It doesn’t work from inside my house!
This one left me scratching my head for a while. This is because when you go to https::/myduckdomain.duckdns.org:8123 it gets redirected back to your WAN address, which is where it originated. This is bad. With a normal router you can configure something called a hairpin NAT, which says “Hey! I’m going out to to the same place I’m coming in, so I’m just not going to go out and screw things up”. The Google support web page says they support a hairpin NAT, but the instructions say to simply “Use the correct ports”. Huh? Nothing I could find on the web said anyone had ever gotten a hairpin NAT to work so I had no working example. In the end, I punted on getting Google configured with one and went looking for another option.
Enter Dnsmasq, which is an HA add-on the acts as a DNS server. When you make a DNS query it will first go to Dnsmasq running on your HA VM and, if Dnsmasq doesn’t know how to resolve the hostname, it relays the query to an external DNS server. By default it uses the Google DNS servers as the secondary, which is the same thing Google WiFi uses. The trick, however, is that you can add your myduckdomain.duckdns.org hostname to Dnsmasq with an IP of your Windows VM. Then systems that are inside your network that try to access your HA via the DuckDNS hostname get short-circuited directly to the HA VM, avoiding the issues a hairpin NAT would solve.
From the HA Supervisor Add-On store, install Dnsmasq. Once it’s installed open the configuration page and add your DuckDNS hostname to the hosts section. It should look like this:
hosts: - host: myduckdnsdomain.duckdns.org ip: 192.168.86.xxx`
Of course you’ll need to use your own domain name, and the IP address for the Windows system running your HA VM. Start Dnsmasq and check the log to make sure it’s happy.
Back in your Google WiFi app on your phone, go back to Advanced Networking, select DNS and create a Custom DNS configuration. The first server should be the IP address of your HA VM - NOTE this is NOT the IP address of the Windows system itself, but the original IP of the HA VM. Since we didn’t forward the ports needed for DNS across the NAT’ed NIC, DNS queries to it would be blocked.
Try accessing the HA UI from a system connected to your Google via either the mobile app or a browser. Now, with any luck, you’ll be able to connect without any nasty SSL certificate issues. External connections should likewise work when you’re on a network other than the one at home.
Rejoice and weep in your greatness.