Lightweight FreeDDNS IP Updater for afraid.org, based on a Docker container.
The motivation behind the project is that it is not necessary to use a lot of resources to keep the IP address of your DDNS address fresh. So, for example, this Docker image is an excellent replacement for ddclient. Smaller size, less resources, less code, less chance of something going wrong.
Just a quick comparison of Docker image sizes:
ddclient: 24.26MB
freednsupdater: 4.02MB
It is also resource-efficient from a network point of view, because it only makes an API call to afraid.org when the container is started (it checks once to see if it is in sync) or when it needs to update the IP address because it has been changed. Otherwise it is stored locally and works from a cache file. And it retrieves the external IP address from different providers, selecting them randomly, so no provider is overloaded.
version: '3'
services:
freednsupdater:
image: feriman25/freednsupdater
container_name: freednsupdater
environment:
- APIURL=https://freedns.afraid.org/api/?action=getdyndns&v=2&sha=yourrandomshastring
# - DDNSDOMAIN=
# - CheckAgainInXSec=300
restart: always
network_mode: bridge
APIURL
Required. Go to https://freedns.afraid.org/api/, login and click on the "ASCII" link. Add the URL to your browser as a variable.
Note: You will need to update this every time you change your password on afraid.org
DDNSDOMAIN
Optional. If you have one DDNS address, the script will recognize it. However, if you have multiple domains, define them, otherwise the script will exit.
CheckAgainInXSec
Optional. If you set a valid number, the external IP will be checked for changes every $CheckAgainInXSec seconds. The minimum value is 10.
All logs are stored in the /tmp/afraid-ddns-ip-updater.log file inside the container.
70: APIURL variable is missing. You have to define it in the docker-compose.yml file
71: You have multiple DDNS addresses, and have not defined the DDNSDOMAIN variable
72: Failed to get DDNSDOMAIN variable. Do you have an Internet connection?
73: wget command not found (not installed or not placed in default paths)
74: Do not flood anyone. You have set the CheckAgainInXSec value too low. It's a built-in feature to avoid overloading afraid.org or any IP check provider.
2025-02-23
- Fix:
LOGandIPSTOREvariables are now defined before first use. Previously the first error message was piped intotee ""(empty filename) and never written to the log file - Fix:
wgetavailability check moved before anywgetcall. Previously the check ran after wget was already used, so a missing wget caused silent failures with empty variables - Fix: After the IP provider loop, an invalid (non-empty but malformed) response could slip through the
if [ "$CURRENT_IP" ]check and trigger a DDNS update with garbage data. Replaced withvalidateip "$CURRENT_IP" - Fix: IP providers now use HTTPS instead of HTTP. HTTP allowed a MITM attacker to return a fake IP and cause the DDNS record to be updated with an arbitrary address
- Fix:
$IPSTOREis now properly quoted in thecatcall - Optimization: The afraid.org API URL is fetched only once at startup (previously called 3 separate times) and the result is parsed in memory
- Optimization: Array shuffling now uses
mapfileinstead of unquoted command substitution, which is safer against word splitting and glob expansion - Optimization: All log messages now consistently use
tee -a(append mode) and write to both stdout and the log file. Previously some INFO messages were stdout-only andteewas overwriting the log file on each call
- All software has bugs, but we have not yet found any in this one. If you find one, open an issue for it here on GitHub.
If you found my work helpful, I would greatly appreciate it if you could make a donation through PayPal to support my efforts in improving and fixing bugs or creating more awesome scripts. Thank you!