Simple DynDNS shell script for deSEC

Hi there

After my GO script, I decided to write something simpler in bash.

deSEC_DynDNS is a very basic bash script that caches the last set IP and only issues an update command, when it changed.

It can’t catch errors and is unable to handle timeouts or anything like that. It also can only handle a single domain.

If you have any feedback or suggestions, I am happy to hear them. I don’t know if I can implement them, since I currently don’t have a lot of time and I am not a coder.

Maybe this is of use for some of you.

Hi,

Thanks for sharing!

We recently had some performance issues that stem from everyone updating their dynDNS at the same time. Popular times are full hours, quarter hours, and at the top of each minute.

A great improvement for deSEC would be if the script incentives avoiding these times somehow, e.g. by adding a randomized sleep (0 to 60seconds). Also, the readme could contain a note to avoid rush hour times or ok how to randomize execution time.

Thanks!
Nils

1 Like

Just a small nit, but when you try to obey the filesystem hierarchy standard and put your script to /usr/local/sbin (as opposed to, /root or /opt), you should put the cache files to /var/local as they are variable and not static data.

1 Like

Since the script is run by crontab, my guess is that probably it is best to use some kind of sleep in the crontab. Something like this:

sudo */5 * * * * sleep $(( RANDOM % 300 )); /usr/local/sbin/deSEC_DynDNS.sh > /dev/null

but then again, I am unsure what this would achieve. As I said, the script only sends an update request to deSEC, if the IP changes. So in 99% of the cases this is run, it won’t connect to deSEC. On the other hand, if the IP actually changed, you probably don’t want even more delay than the 5min you already have because of the crontab. Or am I missing something?

Cheers for that, will edit it.
While we are at it, even though I did some reasearch, I wasn’t able to find a good answer for this; wouldn’t it be even better to not run this script as root? I tried to put it in /usr/local/bin but even that folder is set to root permissions. Some people suggest /opt/bin, but at the same time it is gone from newer Ubuntu installations.

The average delay until an IP change is detected is 2.5 minutes, regardless whether you start it at full 5 minute, or offset by a constant amount of seconds, or offset by a random amount of seconds. Think that way - if the IP changes at 12:51, without delay you would have a 4 minute delay, but when your delay happend to be 70 seconds, it would have only a 10 seconds delay.

This is true under the assumption that IP changes happen randomly - if your ISP times IP changes to always happen at the same time, it is more advisable to check at that time or one minute later.

by the way, crontab also supports 2-59/5 syntax to run at minutes 2,7,12,…

In general, yes. Running as nobody won’t work as nobody has no write permissions anywhere except /tmp, so you would need to create a dedicated user (and group) for it.

Difference between /bin and /sbin is not about who may put binaries there (bot only root), but who is supposed to run them (/sbin is in $PATH only for root).

If your program running as a different user needs variable files that it has to edit, the convention is to put them below a custom directory /var/{local/}spool/<programname> or /var/{local/}/cache/<programname> (by convention, cache may be cleared by the OS or sysadmin if it desires while spool should be preserved), and change the permissions of that directory to be group writable (or even sgid) and add your files in there.

The convention would be /opt/<programname>/bin while other files for the same program would go to /opt/<programname>. Note that this is not in $PATH for anybody by default, so binaries that should be ran by regular users are often symlinked elsewhere.

And while directories from the filesystem hiearchy standard need not exist, the convention for installers is to use /bin/install instead of /bin/cp to copy the files there, which will create missing directories and set the permissions correctly as well.

I have done some improvements, but there is still a lot to be done.

Currently struggle with why crontab does not seem to run it.
Any ideas why I can run it manually but it wont run from crontab?

Probably because $(( RANDOM % 300 )) does not work in a crontab?

Also your maximum sleep value is 300 (5 min.) and your cron interval is also 5 min. You are risking having the script run twice at the same time. Use e.g. 290 for the maximum sleep time. Or better yet 240 to get at least 60 s separation between runs.

1 Like

To be more precise: In my crontab(5) it states SHELL=/bin/sh at the top. So the crontab(5) entries are running in a sh(1) environment and sh(1) does not have the RANDOM parameter.

I would not advocate changing the shell in the crontab(5). So either build a small script using a different shell that has RANDOM to call, e.g. random_sleep.sh or use a different method to generate a random integer (jot(1), shuf(1), awk(1) depending on your OS).

Or you could put the delay into your update script. Pass the value as a parameter if you want to keep the flexibility of setting it in the crontab(5). (But keep in mind that currently it also uses sh(1): #!/bin/sh.)

HTH
fiwswe

2 Likes

Thank you so much!

I will try that.

I thought that putting the delay on crontab maybe is easier on the system (since it does not have to open and stall a script) but putting it into the script seems more portable across different systems.

Yeah :blush: I am happy to report that it works in its very primitive state :wink:

There is still lot to be improved, but it does the basics of updating DynDNS and not overwhelming deSEC servers.

Changed the delay logic, thanks to @fiwswe :pray:
It now has a delay between 10 and 290 seconds.

The reasoning behind it is, that I assume that most users will update right at every 5 min mark. By delaying it to at least 10 seconds after that, but still at least 10 seconds before the next one, we can hopefully have less impact on deSEC servers.

But I am also happy to change these values, what do you think @peter?

That sounds reasonable! Thanks for doing this.

Stay secure,
Peter

2 Likes

Big thanks to @fiwswe!

Even though he probably would have been faster by writing that script himself, he took the time to open up issues and explain stuff to a noob like me :grin:

The script is no longer bash but now shell and has little to do with the original.

It should work on OPNsense, macOS and Linux.

1 Like