I Discovered ASUS Router Scripts Functions
Some, like my wife, may wonder why I have two Internet connections. It's really because I have a set-up for some servers, like the one serving this blog, and have tried to update it to faster service, but the faster service doesn't offer the bits needed for serving from the servers.
Most noteworthy is the lack of static IPs. While I do use a CDN to front these few sites, the CDN needs to be able to find the servers, and static IPs makes that really easy. There are other tricks, like dynamic DNS, and I could leverage that in concert with the CDN, but there's a lag when Internet IPs change and when the CDN can be updated that static IPs eliminate.
I use ASUS routers, and I run the Asuswrt Merlin firmware for a few extras. I started this when playing with IPv6 on a different set of routers, and the DD-WRT for that old router offered IPv6 while its out-of-the-box firmware didn't. The Merlin software is pretty close to the ASUS firmware, with a few extras. These have proven to be a lot helpful.
As I started, I also have two Internet connections, and this router connects to both. I have it configured to use the faster, GB fiber connection most of the time. Should that connection falter, it fails over to the slower DSL connection. When the GB fiber recovers (or I restart its router), the router corrects back to the faster connection.
It happens more than it should. Sometimes, as expected, I don't even notice. Once, though, it happened for a few days that the DSL was being used instead of the fiber. For whatever reason, the fiber router was running, but its Internet connection was disconnected. Checking the logs revealed the delay in noticing it. I noticed when trying to do a system update and it said it would take far too long for the 10x connection.
I found some hints and made a little script that I run on my workstation that checks its Internet address, and if it notices a change then sends a Slack message to a channel I have using a web hook. Sounds slick, but still has a lag, as the job only runs once a minute, and I'd hate for it to constantly hammer some upstream to usually learn nothing's changed.
After checking something with some routine maintenance, I thought "I bet I can get the router to tell me when it does something with this." After a little consideration, I realized that the router with the Merlin software doesn't know the Internet IP, because it's behind the fiber router. It can tell when the WAN flip happens, from fiber to DSL, but it also needs to run the probing script on occasion. Small win.
While poking around, I found the Merlin scripts add-on to the ASUS firmware. After toggling a setting in the web interface (or via command line), there are a set of events that will trigger scripts if they exist in a special folder on the router, which is the /jffs/scripts
folder. This was a great find, because while I was able to get it to do the things I needed, it wasn't able to survive rebooting the router. Finding the custom scripts helped.
I copied my IP checking script from the other system, which is a barely a little different than the following bits. I put the file in the /jffs/scripts
folder, even though I don't think there's any benefit to it, but it does provide proximity for the other script.
#!/bin/bash # Quick hack to check Internet IP for changes, alert via Slack OLDIP=$(head -n 1 /tmp/lastip) NEWIP=$(curl -s ipinfo.io/ip) if [ "$OLDIP" != "$NEWIP" ] then PAYLOAD="\"icon_emoji\":\":exclamation:\", \"username\":\"$(hostname)\"" ATTACHMENT="\"fallback\": \"System Alert - IP Change\"" ATTACHMENT="${ATTACHMENT}, \"pretext\": \"System Alert\"" ATTACHMENT="${ATTACHMENT}, \"author_name\": \"${hostname}\"" FIELDS="{\"title\":\"Date\", \"value\":\"$(date)\", \"short\":true}" FIELDS="${FIELDS}, {\"title\":\"Action\", \"value\":\"IP Address Change\", \"short\":true}" FIELDS="${FIELDS}, {\"title\":\"Old IP\", \"value\":\"\`\`\`${OLDIP}\`\`\`\",\"short\":true}" FIELDS="${FIELDS}, {\"title\":\"New IP\", \"value\":\"\`\`\`${NEWIP}\`\`\`\",\"short\":true}" FIELDS="${FIELDS}, {\"title\":\"Uptime\", \"value\":\"\`\`\`$(uptime)\`\`\`\",\"short\":false}" ATTACHMENT="${ATTACHMENT}, \"fields\": [ ${FIELDS} ]" SLACK=$(curl -s -X POST --data-urlencode "payload={${PAYLOAD}, \"attachments\":[{ ${ATTACHMENT} }]}" %%SLACK_WEBHOOK_DETAILS%%) echo "$NEWIP" > /tmp/lastip fi
Note that the SLACK_WEBHOOK_DETAILS
needs to match the webhook details from Slack...I'm not sharing mine here so that I don't get someone else's alert. Other things than Slack could be used instead, so adjust to however it needs to be.
I made a choice to use http://ipinfo.io/ip to gain my Internet IP after a little investigation into the alternatives. I also thought to make a simple script to get it from my own server, who I don't mind bothering, but that'll be another task for another day. Should a different service be used, make sure it provides the IP on its first (hopefully only) line.
Note also that the head
command fails if the file /tmp/lastip
doesn't exist. I toyed with a variety of ways to fix this, like touching the file or whatever, but decided that I could use this to give me a transition status when the system starts up.
I tested this by creating the lastip file and running the script. Almost immediately, the message appeared in my Slack channel with the message and IP.
I then created a /jffs/scripts/services-start
script, as directed in the Merlin docs. It's pretty simple, creating that lastip file and setting up the cron job.
#!/bin/bash echo 'Startup' > /tmp/lastip cru a ipcheck "* * * * * /jffs/scripts/ipcheck"
This very simply puts a string in that lastip file and configures the ipcheck script to run as a cron job every minute.
As directed in the Merlin docs, these are in the /jffs/scripts
folder, and the +x attribute was added with a chmod
command.
I tested by running the script directly, and it worked. After running the script, the file and cron job existed. After a minute or so, the message about the IP changing appeared in my Slack, with "Startup" as the "old IP."
I then rebooted my router, and it correctly told me again that "Startup" and the WAN IP were as expected!