]> yabddnsd

yabddnsd

NAME
SYNOPSIS
DESCRIPTION
OPTIONS
CONFIGURATION FILES
SYSTEMD SERVICE
BUGS
AUTHOR
COPYRIGHT
IDENTITIES OF AUTHORS


NAME

yabddnsd − Yet another bash dynamic DNS daemon

SYNOPSIS

yabddnsd

[--domainName domainName]
[--authTokenIpv4 authenticationTokenForIPv4]
[--authTokenIpv6 authenticationTokenForIPv6]
[--configFile sourcedConfigurationFile]
[--detectPublicAddrIpv4 method[@@argument][,method[@@argument]]...]
[--detectPublicAddrIpv6 method[@@argument][,method[@@argument]]...]
[--dnsServerIpv4 dnsServerForIPv4]
[--dnsServerIpv6 dnsServerForIPv6]
[--oneShot]
[--sleepTime sleepingTimeBetweenIterations]
[--updateProtocol updateProtocol]
[--verbose]

yabddnsd --help
yabddnsd --version
yabddnsd --listFunctions
yabddnsd
[other options]...

--callFunction function [functionArguments...]

For regular functionality --updateProtocol, --domainName and at least one authentication token are required.

DESCRIPTION

Periodically checks which IP addresses are listed in the given domain name’s DNS record, and which public IP address this system has.
If the system’s public IP address isn’t among the DNS record’s IP addresses, the DNS record is updated to the system’s public IP address.

OPTIONS

--authTokenIpv4 authenticationTokenForIPv4

The authentication token to use when updating the IPv4 address (DNS A record).
If no IPv4 authentication token is specified the domain’s IPv4 address will not be maintained.

--authTokenIpv6 authenticationTokenForIPv6

The authentication token to use when updating the IPv6 address (DNS AAAA record).
If no IPv6 authentication token is specified the domain’s IPv6 address will not be maintained.

--callFunction function [functionArguments...]

Call the given function and exit with the function’s return code. See --listFunctions for available functions.
May be used in combination with other options and particularly with configuration files; that way one can test one’s own custom functions or function overrides, see section CONFIGURATION FILES.
Everything after this option is considered to be function arguments, which means any other option(s) must be supplied before this option.
Be careful, there is little or no input validation at all for the function arguments, and some of the regular arguments that precede --callFunction will not be validated either.

--configFile sourcedConfigurationFile

The configuration file to use, see section CONFIGURATION FILES.
This option may be specified more than once; all specified configuration files will be sourced in order of declaration.

--detectPublicAddrIpv4 method[@@argument][,method[@@argument]]...

The method(s) that should be used to detect this host’s public IPv4 address, given as a comma-separated list, or, if the option is specified in a configuration file, as a bash array.
This script comes with these IPv4 address detection methods:
File@@path − extract the public IPv4 address from the given text file
NetDev[@@deviceName] − read the public IPv4 address from all network devices, or, if a network device name is given as method argument, from that specific network device
Upnp − use UPnP to determine the public IPv4 address
Url@@url − extract the public IPv4 address from the web site or plain text at the given web address, such as https://icanhazip.com/ or https://wtfismyip.com/text
The default methods for IPv4 address detection are NetDev,Upnp if the program upnpc is available, if it isn’t only NetDev is used.
The host’s public IPv4 address cannot be read from its network device(s) if it is behind a router that uses network address translation (NAT), which is usually the case for private internet connection setups.
For each declared method MethodX[@@argument] a function getIpv4AddrOfThisHostFromMethodX [argument] is called once, in the order as the methods are declared.
When one of them prints a result to STDOUT and returns with code 0, that result is assumed to be this host’s public IPv4 address, and any subsequent methods will not be tried.
It is entirely possible to declare a custom such function in a configuration file, e.g. getIpv4AddrOfThisHostFromCustom, and then include the corresponding method (Custom in this example) into the array of methods.
The function isPublicIpv4Addr IPv4Address may come in handy to filter out private/special addresses.

--detectPublicAddrIpv6 method[@@argument][,method[@@argument]]...

The method(s) that should be used to detect this host’s public IPv6 address, just like --detectPublicAddrIpv4.
This script comes with these IPv6 address detection methods:
File@@path − extract the public IPv6 address from the given text file
NetDev[@@deviceName] − read the public IPv6 address from all network devices, or, if a network device name is given as method argument, from that specific network device
Url@@url − extract the public IPv6 address from the web site or plain text at the given web address, such as https://icanhazip.com/ or https://wtfismyip.com/text
The default method for IPv6 address detection is NetDev.

--dnsServerIpv4 dnsServerForIPv4

The DNS server to use when looking up the domain’s current IPv4 address.

--dnsServerIpv6 dnsServerForIPv6

The DNS server to use when looking up the domain’s current IPv6 address.
Some routers filter DNS responses that point to IP addresses within the local network as a safety measure against DNS rebinding attacks. For IPv4 with network address translation (NAT) this is uncritical as the DNS record points to the router’s public IPv4 address, but without NAT, such as is usually the case with IPv6, this protective measure may prevent lookups of the domain name’s IP address.
If you are affected by this, the first thing you should check is whether your router offers a whitelist for domain names that should not be subject to the DNS rebinding attack protection. In case it doesn’t, specifying some other public IPv6 DNS server using this option may enable you to work around the issue.

--domainName domainName

The domain name whose IP address(es) to maintain, such as "your-domain.mooo.com".

--help

Print a help message to STDOUT and exit with code 1.

--listFunctions

Print information about the functions in this script to STDOUT and exit with code 0.

--oneShot

"One-shot" mode of operation, i.e. terminate after the main loop’s first iteration.

--sleepTime sleepingTimeBetweenIterations

The duration of the pause between iterations, default is "6m", i.e. 6 minutes. Must be something that is understood by the sleep command.
The reasoning for such a pause is that it does not make much sense to immediately check the current DNS record(s) after an update has been issued to the dynamic DNS service provider, because it may very well take a few minutes for the updated DNS record to be propagated to the world’s DNS servers.

--updateProtocol updateProtocol

The update protocol to use when updating the domain name’s DNS record.
This script comes with these update protocols:
DuckDns − Duck DNS update protocol (www.duckdns.org)
FreeDnsV1 − FreeDNS update protocol, version 1 (freedns.afraid.org)
FreeDnsV2 − FreeDNS update protocol, version 2 ([v6.]sync.afraid.org)
FreeDns − FreeDnsV1 or FreeDnsV2 update protocol, auto-detected from the authentication token
Custom update protocols for IPv4 or IPv6 can be implemented in configuration files by declaring custom functions updateIpv4AddrWithCustom and updateIpv6AddrWithCustom, respectively.

--verbose

Enable verbose output, which causes additional lines prefixed with DEBUG to be printed to STDERR.

--version

Print the version string to STDOUT and exit with code 0.

CONFIGURATION FILES

Instead of using arguments one can also use configuration files to set the various options; the path to a configuration file is set with the --configFile argument, which may be specified multiple times for multiple configuration files.

The configuration files are sourced by bash in the order as they occur in the arguments array. This means that subsequent configuration files may overwrite options that have been set by their predecessors.

Options are set by globally setting an option’s corresponding variable to the desired value, for example to set your-domain.mooo.com as domain name one would put this into a configuration file:

domainName=’your-domain.mooo.com

Likewise for the other options that expect a non-boolean single value. For boolean options such as --verbose the only allowed values are "true" and "false", and options that take multiple values at once, such as --detectPublicAddrIpv4, must be declared as a bash array, for example:

detectPublicAddrIpv4=( ’Upnp’ ’Url@@https://some-url.net/’ )

If an option is specified both in a configuration file and as a command line argument, then the command line argument takes precedence.

The primary advantage of using a configuration file instead of arguments is that one can easily create systemd instance services using the systemd service definition yabddnsd@.service that comes with this program; also if you use an operating system where usually any user can list any other user’s running processes including their command lines (I am looking at you, Linux) your authentication tokens won’t show up in such process listings.

Using configuration files instead of arguments, in combination with setting appropriately restrictive permissions on said configuration files, will keep your authentication tokens secret from other unprivileged users using the system.

Configuration files also enable you to implement certain bash functions to your liking, such as custom public IP address detection methods for the options --detectPublicAddrIpv4 and --detectPublicAddrIpv6, as well as these reserved functions that are used to resolve the domain name’s current IP addresses if they are declared:

getIpv4AddrsOfDomainCustom domainName [dnsServerIpv4]

getIpv6AddrsOfDomainCustom domainName [dnsServerIpv6]

If such a function returns with a code of 0, then its result takes precedence over the script’s own means of resolving the domain name’s IP addresses. The result is expected to be a newline-terminated list of the given domain name’s current IP addresses.
An empty list is a valid result; this means that the domain name currently does not have any IP addresses.

You generally may override any of this script’s functions provided you know what you are doing, see --listFunctions.

Should you decide to implement or override a function be aware that this script uses the bash options nounset, noclobber, pipefail and errexit combined with inherit_errexit.

SYSTEMD SERVICE

This script comes with a systemd instance service definition, yabddnsd@.service, that can be instantiated for a configuration file, one instance for each domain that should be maintained. In bash, for any single configuration file, such an instance may be created like this (as root):
systemctl enable yabddnsd@"$(systemd-escape ’
/absolute/path/to/configuration-file.conf’)".service

On a side note, this script does not require to be run as root; any non-privileged user should suffice, and it is good practice to not run stuff as root unnecessarily.
Systemd makes it easy to customize services without having to touch their .service unit files using unit drop-ins. Setting up a unit drop-in that runs all instances of yabddnsd@.service as a custom user would consist of simply creating this text file:
/etc/systemd/system/yabddnsd@.service.d/custom-user.conf

[Service]
User=
your-user

...So, systemd unit drop-ins. Maybe you would like to use certain defaults for all your service instances, seeing that you may declare multiple configuration files? This unit drop-in should do the trick:
/etc/systemd/system/yabddnsd@.service.d/custom-defaults.conf

[Service]
ExecStart=
ExecStart=/usr/bin/yabddnsd --configFile "
/absolute/path/to/defaults.conf" --configFile "%I"

BUGS

No bugs, this is perfect code.
Just kidding, there’s bound to be some bugs around, it just seems nobody has found any particular ones yet.

AUTHOR

eomanis

E-Mail: eomanis@web.de
PGP key fingerprint: F576 37E9 E5C2 8F91 EE64 277B 603E EF8F E0A9 9498

COPYRIGHT

Copyright 2014-2019 eomanis

yabddnsd is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.

yabddnsd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with yabddnsd. If not, see <http://www.gnu.org/licenses/>.

IDENTITIES OF AUTHORS

Should it be required to ascertain the identity of an author, the person who can prove to be in possession of the secret master key of an author’s PGP key is to be considered the respective author.

In case an author’s PGP key has been replaced by another PGP key, the person who can prove the key supersession in the most convincing manner is to be considered the respective author. For example, an author may document the existence of a properly signed key supersession declaration at a certain point in time in a provably tamper-proof way, such as embedding the declaration or a cryptographically secure hash of it in an irreversible blockchain.