Use Signal messenger to get informed about IP changes

I'm running my own Nextcloud server on a Raspberry PI. This is accessible from the internet. It works really fine.

But sometimes my internet provider changes my IP address overnight. In the beginning, I used a dyndns service to update the IP address immediately from my browser. But I wanted to use my own domain name and not the one from the dns service and it shouldn't cost anything.

So I created subdomains for my own domain and redirect those from my domain provider to my home router. From there I go to reverse proxy (nginx) and then to my Nextcloud server.

Browser —> domain provider —> home router —> nginx —> Nextcloud server

But every time my internet provider gives me a new IP address, my Nextcloud is not accessible anymore.

In this blog post I describe how I (semi-automatically) solved the problem.

The problem

Everytime I got a new IP address I had to

This does not sound to be a time-consuming task and of course it's done in 5 minutes. But I didn't get informed about the change of the IP address and so I recognized the IP change when I tried to access my Nextcloud the next time.
Because also my family, who live in their own houses, use the Nextcloud they also could not access it.
You all know that if people use an internet service they want it to be available 24/7. If the service is not available a lot of times they don't use it. But I want my family to use my Nextcloud and not those data hungry services from the big Data octopuses.

The solution

So I thought about how I could minimize the downtime of my service.

Unfortunately my domain provider does not offer an API to manage my subdomains. They only offer a web-ui.

That's why I created this semi-automactic solution.

On my Nextcloud server every early morning (the ip address change happens at night) I run a cron job which checks the public IP address of my router and the public IP address of my subdomain.

If they are not the same I know that the public IP adress of my router has been changed. I then send a message to myself via the signal messenger. This message of course already contains the new IP address.
When I awake in the morning I see the message at my smartphone and can quickly change the IP address for my subdomain at my domain provider.
So there should only be a few hours of unavailability during the night, which is absolutely ok for my usecase.

Technical details

Getting the IP addresses

I first had to retrieve the IP addresses of my router and of my subdomain. On Linux there is the dns lookup utility with the program dig. Sending

dig +short <url>

returns the IP address of the url.

Sending a message from Linux via Signal

Next I had to figure out how to send a signal message from a Linux pc. I quickly found this github repository. The docker container, that gets setup if you follow the description of the repo lets you send messages via http. So I only have to use curl from my Linux system. I of course could have used the official Signal API but using this docker container was a no-brainer.

Combining in a bash script

I then wrote a small bash script that retrieves the IP addresses, compares them and sends a message if they differ.

#! /bin/bash

public_ip=$(dig +short xxx.myfritz.net)
nextcloud_ip=$(dig +short mynextcloudsubdomain.tammen-it-solutions.de)
if [[ $public_ip != $nextcloud_ip ]]; then 
  message="Die Fritzbox IP Adresse hat sich geändert\nBitte beim domain provider die A-records der Sub-Domains anpassen\nNeue IP: $public_ip"
  data="{\"message\": \"$message\", \"number\": \"+4911111111\", \"recipients\": [\"+4911111111\"]}"
  $(curl --silent -X POST -H "Content-Type: application/json" 'http://localhost:8090/v2/send' -d "$data")
fi

Creating the cron job

The last step was to create a crontab entry that invokes my script early in the morning every day.
crontab -e
opens the crontab editor. I added this line and that's it.
5 5 * * * /home/helmutpi/signal/public_ip_monitor

Every morning at 05:05 the system checks if the IP address has changed and, if so, sends me a message.