Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dns/rfc2136: delete cache files if nsupdate failed #4057

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions dns/rfc2136/src/etc/inc/plugins.inc.d/rfc2136.inc
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,6 @@ function rfc2136_configure_do($verbose = false, $int = '', $updatehost = '', $fo
if (($wanip != $cachedipv4) || (($currentTime - $cacheTimev4) > $maxCacheAgeSecs) || $forced) {
$upinst .= "update delete {$dnsupdate['host']}. A\n";
$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} A {$wanip}\n";
@file_put_contents($cacheFile, "{$wanip}|{$currentTime}");
log_error("Dynamic DNS: updating cache file {$cacheFile}: {$wanip}");
$need_update = true;
} else {
log_error("Dynamic DNS: Not updating {$dnsupdate['host']} A record because the IP address has not changed.");
Expand All @@ -184,8 +182,6 @@ function rfc2136_configure_do($verbose = false, $int = '', $updatehost = '', $fo
if (($wanipv6 != $cachedipv6) || (($currentTime - $cacheTimev6) > $maxCacheAgeSecs) || $forced) {
$upinst .= "update delete {$dnsupdate['host']}. AAAA\n";
$upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} AAAA {$wanipv6}\n";
@file_put_contents($cacheFile6, "{$wanipv6}|{$currentTime}");
log_error("Dynamic DNS: updating cache file {$cacheFile6}: {$wanipv6}");
$need_update = true;
} else {
log_error("Dynamic DNS: Not updating {$dnsupdate['host']} AAAA record because the IPv6 address has not changed.");
Expand All @@ -200,14 +196,33 @@ function rfc2136_configure_do($verbose = false, $int = '', $updatehost = '', $fo
if ($need_update) {
@file_put_contents("/var/etc/nsupdatecmds{$i}", $upinst);
unset($upinst);

/* invoke nsupdate */
$cmd = "/usr/local/bin/nsupdate -k {$keyfile}";
$updateCmd = "/usr/local/opnsense/scripts/OPNsense/rfc2136/nsupdate-apply.sh";
$updateCmd .= " --keyfile {$keyfile}";
$updateCmd .= " --scriptfile /var/etc/nsupdatecmds{$i}";

if (isset($dnsupdate['usetcp'])) {
$cmd .= " -v";
$updateCmd .= " --tcp";
}

if (isset($cacheFile) && !empty($cacheFile)) {
$updateCmd .= " --cachefile4 {$cacheFile}";
if (isset($wanip) && !empty($wanip)) {
$updateCmd .= " --ip4 {$wanip}";
}
}
$cmd .= " /var/etc/nsupdatecmds{$i}";
mwexec_bg($cmd);
unset($cmd);

if (isset($cacheFile6) && !empty($cacheFile6)) {
$updateCmd .= " --cachefile6 {$cacheFile6}";
if (isset($wanipv6) && !empty($wanipv6)) {
$updateCmd .= " --ip6 {$wanipv6}";
}
}

log_error("Dynamic DNS: update command: ".$updateCmd);
mwexec_bg($updateCmd);
unset($updateCmd);
}
}

Expand Down
137 changes: 137 additions & 0 deletions dns/rfc2136/src/opnsense/scripts/OPNsense/rfc2136/nsupdate-apply.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#!/bin/sh

# Copyright (c) 2024 Christian Blechert <christian@serverless.industries>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

# Execute dyndns nsupdate triggered by interface events in rfc2136 plugin

set -e
set -u

# Arguments
ARG_SCRIPTFILE=""
ARG_KEYFILE=""
ARG_USETCP=""
ARG_CACHEFILE4=""
ARG_IP4=""
ARG_CACHEFILE6=""
ARG_IP6=""
ARG_HELP=0
UNKNOWN_OPTION=0

if [ $# -ge 1 ]
then
while [ $# -ge 1 ]
do
key="$1"
case $key in
--scriptfile)
shift
ARG_SCRIPTFILE=$1
;;
--keyfile)
shift
ARG_KEYFILE=$1
;;
--tcp)
ARG_USETCP="-v"
;;
--cachefile4)
shift
ARG_CACHEFILE4=$1
;;
--ip4)
shift
ARG_IP4=$1
;;
--cachefile6)
shift
ARG_CACHEFILE6=$1
;;
--ip6)
shift
ARG_IP6=$1
;;
*)
# unknown option
UNKNOWN_OPTION=1
ARG_HELP=1
;;
esac
shift # past argument or value
done
else
# no arguments passed, show help
ARG_HELP=1
fi

# handle unknown options
if [ $UNKNOWN_OPTION -gt 0 ]
then
>&2 echo "Unknown options."
fi

# check parameters
if [ -z "$ARG_KEYFILE" ] || [ -z "$ARG_SCRIPTFILE" ]
then
ARG_HELP=1
fi

# show help and abort
if [ $ARG_HELP -gt 0 ]
then
>&2 echo "Usage: $0 --scriptfile nsupdatecmds --keyfile keyfile [--tcp] [--cachefile4 cachefile4] [--ip4 x.x.x.x] [--cachefile6 cachefile6] [--ip6 xxxx::xxxx]"
exit 1
fi

# execute nsupdate
now=$(date +%s)
/usr/local/bin/nsupdate -k $ARG_KEYFILE $ARG_USETCP $ARG_SCRIPTFILE
result=$?

# handle IPv4 cache file
if [ $result -eq 0 ] && [ -n "$ARG_CACHEFILE4" ] && [ -n "$ARG_IP4" ]
then
>&2 echo "Create IPv4 cache file in '$ARG_CACHEFILE4'"
echo -n "$ARG_IP4|$now" > $ARG_CACHEFILE4
elif [ -n "$ARG_CACHEFILE4" ]
then
>&2 echo "Delete IPv4 cache file in '$ARG_CACHEFILE4'"
rm -f $ARG_CACHEFILE4
fi

# handle IPv6 cache file
if [ $result -eq 0 ] && [ -n "$ARG_CACHEFILE6" ] && [ -n "$ARG_IP6" ]
then
>&2 echo "Create IPv6 cache file in '$ARG_CACHEFILE6'"
echo -n "$ARG_IP6|$now" > $ARG_CACHEFILE6
elif [ -n "$ARG_CACHEFILE6" ]
then
>&2 echo "Delete IPv6 cache file in '$ARG_CACHEFILE6'"
rm -f $ARG_CACHEFILE6
fi

# exit with nsupdate exit code
exit $result