As part of my shenanigans with high altitude balloons, I built a fairly simple Pi-in-a-box that combines a GPS and RTL-SDR. It provides APRS packets (Direwolf) and GPS position data (gpsd) to WiFi/Ethernet clients as well as beacons over the internet to APRS-IS with SmartBeaconing.
Currently it's being upgraded for GPSL 2017 with a Baofeng UV-82 to provide redundant receive and transmit for APRS. More to come in a future post.
This build serves a multitude of environments:
- Anywhere, usually in the car
- Connected to my phone WiFi hotspot
- Connected to my portable, dedicated WiFi hotspot
- Connected to my pfSense box with redundant cell connections (Ethernet and WiFi)
- At home, on the normal WiFi, for testing and development
- Anywhere, directly connected to a laptop (Static Ethernet)
Each of the networks listed provides different IPs, net masks, and varying options for configuration. They generally all provide internet access, though.
Sometimes the Pi will be connected to multiple, too. For example, it may be connected to my hotspot and also connected to my laptop over Ethernet. (If, say, I can't get WiFI access to work)
When deploying the build in my car, my friend's car, etc, I don't want to have to configure anything. I just want to plug it in to power/data and go, as I frequently switch between internet sources in the field.
This brings up a problem: I need to connect to this thing, on many different networks, but I will rarely know its IP address.
I'm not going to carry around a monitor just so I can look at the console. I could put it on an LCD screen, but isn't the point of this thing to be headless?
Configuring DHCP static leases is not an option for phone hotspots, which is what I use the most. I could hack something together where it has a whitelist of networks and picks a static IP based on the network, but each one will have separate netmasks, so I'll still have to pick the right IP when I want to connect.
What about when I want to connect on a random network, and haven't been able to set the whitelist in advance? That would mean getting up and plugging a cable in first. I hate getting up.
That's when it hit me. I use Cloudflare for my DNS on all my websites. At home, I also use it as my Dynamic DNS. So why not use it on the Pi, too?
I found this repo with a script for updating Cloudflare DNS, xlandgroup/ddns-cloudflare, which I liked because it was simple, easy to configure, and didn't have many dependencies.
The Pi is set to auto-connect to several WiFi networks of mine. On Ethernet, it will try to get an IP, and fallback to 192.168.10.10/24 if it fails (see my last post!).
I wanted to have two DDNS domains, one for Ethernet and one for WiFi, so I split the shell script into two with their own requisite files. For the domains, I came up with:
Go ahead, look them up! The idea here is that it's the interface prefix and the device name. So if I had another Pi named bob with a 3G modem, I could just use ppp.bob.ub3rk1tten.com.
I changed the IP lookup in the script to use this internal IP instead of the public one, added the right tokens, and it worked!
Then, of course, was the standard cron job:
* * * * * bash /home/michael/cloudflare-wlan.sh
* * * * * bash /home/michael/cloudflare-eth.sh
Now, when I set up my APRS, GPS, SSH, or other clients, I use
wlan.aprs.ub3rk1tten.com and it just works.
Another good thing about this script. It stores the previous IP, and will only update it on Cloudflare if it changes. Then, it won't save the new IP unless it gets a CloudFlare success message. This means that I can go in and out of cell coverage, but it will still eventually get the new IP.
It's not perfect, of course. It requires occasional internet access. For my scenario, I'm usually setting everything up near a large city, and then driving far out to catch a balloon or chase a storm. There's ample time for the Pi to get its current IP out before I lose connectivity, and for the laptop to cache it.
Currently the DNS records are set to 5 minute TTL. I am not entirely certain how Windows DNS Cache works when it loses internet access, it seems to still use the cached record even when over max TTL. This needs more testing, but it seems to work.
Check out my forked version of the ddns-cloudflare repository here: T3hUb3rK1tten/ddns-cloudflare.