In a previous post I mentioned that my router’s RADIUS client only takes an IPv4 address for the RADIUS server field and that I was using a dynamic IP. The solution I proposed was to have a script run periodically to poll the RADIUS server for its current IP address, then update the relevant field in the router’s NVRAM. Then I got busy being lazy but it’s been raining all week and I had nothing better to do. So here goes.

#!/bin/sh
NEW_IP=$(curl --silent https://api.cloudflare.com/client/v4/zones/<your-zone-id>/dns_records/<radius-server-hostname> \
-H 'X-Auth-Email: <cloudflare-email>' \
-H 'X-Auth-Key: <cloudflare-key>' \
-H 'Accept: application/json' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
OLD_IP=`nvram get wl0_radius_ipaddr`

if [ "$NEW_IP" == "$OLD_IP" ]; then
        logger "radius-update: IP unchanged"
        exit
fi

nvram set wl0_radius_ipaddr="$NEW_IP"
nvram commit
logger "radius-update: IP set to $NEW_IP, restarting wireless"
/sbin/restart_wireless

It’s simple, really. I use CloudFlare, and they have a convenient API for getting your records. You only need to grep the IP out of the JSON response. Of course, all of this could have been easily avoided if only my router’s firmware took a hostname or IPv6 address for the RADIUS server address…