First world problems and iOS automation

The environment

At the house, I have a pfSense router set up for Dual-WAN connectivity that uses a Netgear 4G LTE Modem for the primary link because my ADSL connection maxes out at 8Mbps while I can get up to 40Mbps on the 4G connection. This if course is made possible by living in France where I have access to an uncapped 4G service.

The only problem with this setup is that the 4G connection will sometimes drop connectivity at random moments for random amounts of time. Very annoying. It’s easily corrected by resetting the 4G modem.

Due to the potential instability of the 4G connection, I use the ADSL line primarily to link the VPN connections to the office and hosted environments. This means that even if the 4G connection goes down, there is still a VPN connection to the office (which is used primarily for cross-site backups).

The partial solution

The first attempt at fixing this was to use a HomeKit controlled plug on the 4G router and just use HomeKit to reset it as required. Which worked fine as long as I was at home. But this gets complicated when we left on vacation and had someone house sitting for the cats. Trying to explain to non-IT folks about your strange and fragile networking setup and how to deal with it is a non-starter.

A better solution

Since I have a complete infrastructure at the office and servers running all of the time, I went looking for a way to bridge the IT infrastructure world and the HomeKit one. And unlike a few years ago where there were only gum and baling wire solutions, there is now a rich ecosystem around the iOS automation frameworks.

The tool that quickly jumped to the top of the heap was Pushcut. Hat tip to the Automators podcast for bringing it across my radar. Pushcut has an “automation server” mode which allows it to respond to requests that are sent via the Pushcut servers so that you can request automation actions via an API on their servers.

After some testing, I put together the following script that runs on a cron job every 5 minutes (using ssh authorized keys to login automatically).

#!/bin/bash
ssh -q "root@192.168.2.1" exit
if [[ $? > 0 ]]; then
	echo "Can't connect to gw.infrageeks.lan - check VPN connection'"
	exit 1
fi

CHECK=`ssh root@192.168.2.1 ifconfig re0 | grep "inet " | cut -d" " -f2 | grep ^10 | wc -l`

if [[ $CHECK -eq 1 ]];then
	echo `date` ": 4G OK" >> "/home/automation/Dropbox/Infrageeks/4G_house.log"
else 
	echo `ssh root@192.168.2.1 ifconfig re0 | grep "inet "`
	echo `date` ": Turning off 4G Bridge" >> "/home/automation/Dropbox/Infrageeks/4G_house.log"
	curl "https://api.pushcut.io/<API Key>/execute?homekit=House:%20Internet%20Off"
	sleep 30
	echo `date` ": Turning on 4G Bridge" >> "/home/automation/Dropbox/Infrageeks/4G_house.log"
	curl "https://api.pushcut.io/<API Key>/execute?homekit=House:%20Internet%20On"
fi

The 4G provider (Free.fr) uses a private 10.0.0.0 address space so that if the connection starts with anything other than 10, I know that the connection is broken. (For the networking nerds: yes this means that I’m in a double-NAT configuration which is a bit of a pain, but OK for a home connection.)

The only additional modification required was to change the default routing rules for the HomePod at the house to always use the ADSL connection instead of depending on the pfSense Gateway group failover operation. This ensures that the request to change the scene will be handled reliably.

If all goes well, there is just a note saying 4G OK in a log file, but if anything else happens I receive an email about the incident.