361 lines
8.5 KiB
Bash
361 lines
8.5 KiB
Bash
#!/bin/bash
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
#
|
|
# Rx3 DNS Library
|
|
#
|
|
# Copyright (C) 2025-2026 Arnaud G. GIBERT
|
|
# mailto:arnaud@rx3.net
|
|
#
|
|
# This is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Lesser General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program 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 Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this program; If not, see
|
|
# <https://www.gnu.org/licenses/>.
|
|
#
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
if [[ "${RX3_DNS_LIB}" != "" ]]
|
|
then
|
|
return
|
|
else
|
|
declare -g RX3_DNS_LIB=1
|
|
fi
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
# Includes
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
: "${RX3_LIB_DIR:=/usr/lib/rx3}"
|
|
. "${RX3_LIB_DIR}/ip.bash"
|
|
|
|
|
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
# Global Variable
|
|
#-----------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
declare -Ag DNS_A_TAB
|
|
declare -g DNS_A_ID_LIST=""
|
|
|
|
declare -Ag DNS_PTR_TAB
|
|
declare -g DNS_PTR_ID_LIST=""
|
|
|
|
declare -g DNS_CACHE_FILE=""
|
|
declare -g DNS_CACHE_LOCK=""
|
|
#declare -g DNS_CACHE_LOCK="${DNS_CACHE_FILE}"
|
|
|
|
declare -g DNS_CACHE_UPDATED=0
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_tab_load
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_tab_load()
|
|
{
|
|
log_trace "DNS" "Loading DNS cache..."
|
|
|
|
file_lock "${DNS_CACHE_LOCK}" READ 9
|
|
|
|
if [[ ( -e "${DNS_CACHE_FILE}" ) && ( "${NETWORK_CONFIG_FILE}" -ot "${DNS_CACHE_FILE}" ) ]]
|
|
then
|
|
log_trace "DNS" "Read CacheFile"
|
|
|
|
while IFS= read -r line
|
|
do
|
|
line=${line%%#*}
|
|
if [[ ! -z "$line" ]]
|
|
then
|
|
set ${line}
|
|
|
|
dtl_type="$1"
|
|
dtl_key="$2"
|
|
dtl_value="$3"
|
|
|
|
dns_tab_put ${dtl_type} "${dtl_key}" "${dtl_value}"
|
|
fi
|
|
done < ${DNS_CACHE_FILE}
|
|
else
|
|
log_trace "DNS" "Init CacheFile"
|
|
|
|
>${DNS_CACHE_FILE}
|
|
fi
|
|
|
|
file_unlock 9
|
|
|
|
DNS_CACHE_UPDATED=0
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_tab_save
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_tab_save()
|
|
{
|
|
log_trace "DNS" "Saving DNS cache..."
|
|
|
|
if [[ "${DNS_CACHE_UPDATED}" != "0" ]]
|
|
then
|
|
file_lock "${DNS_CACHE_LOCK}" WRITE 9
|
|
|
|
log_trace "DNS" "Write CacheFile"
|
|
|
|
(
|
|
for key in "${!DNS_A_TAB[@]}"
|
|
do
|
|
echo "A ${key} ${DNS_A_TAB[${key}]}"
|
|
done
|
|
|
|
for key in "${!DNS_PTR_TAB[@]}"
|
|
do
|
|
echo "PTR ${key} ${DNS_PTR_TAB[${key}]}"
|
|
done
|
|
) | sort -n >${DNS_CACHE_FILE}
|
|
|
|
file_unlock 9
|
|
|
|
DNS_CACHE_UPDATED=0
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_tab_get
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_tab_get()
|
|
{
|
|
dns_type="$1"
|
|
dns_key="$2"
|
|
|
|
|
|
case ${dns_type}
|
|
in
|
|
"A")
|
|
if [[ -v DNS_A_TAB["${dns_key}"] ]]
|
|
then
|
|
dns_value="${DNS_A_TAB["${dns_key}"]}"
|
|
else
|
|
log_trace "DNS" "Lookup failed: Type: [${dns_type}] Key: [${dns_key}]"
|
|
return 1
|
|
fi
|
|
;;
|
|
|
|
"PTR")
|
|
if [[ -v DNS_PTR_TAB["${dns_key}"] ]]
|
|
then
|
|
dns_value="${DNS_PTR_TAB["${dns_key}"]}"
|
|
else
|
|
log_trace "DNS" "Lookup failed: Type: [${dns_type}] Key: [${dns_key}]"
|
|
return 1
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
log_trace "DNS" "Lookup succeed: Type: [${dns_type}] Key: [${dns_key}] Value: [${dns_value}]"
|
|
|
|
return 0
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_tab_put
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_tab_put()
|
|
{
|
|
dtp_type="$1"
|
|
dtp_key="$2"
|
|
dtp_value="$3"
|
|
|
|
|
|
if [[ "${dtp_value}" == "" ]]
|
|
then
|
|
log_trace "DNS" "Skiping cache entry: Type: [${dtp_type}] Key: [${dtp_key}] Value: [${dtp_value}]"
|
|
else
|
|
log_trace "DNS" "Update cache entry: Type: [${dtp_type}] Key: [${dtp_key}] Value: [${dtp_value}]"
|
|
|
|
var_assign DNS_${dtp_type}_ID_LIST "${dtp_key}" INC
|
|
tab_assign DNS_${dtp_type}_TAB "${dtp_key}" "${dtp_value}"
|
|
|
|
DNS_CACHE_UPDATED=1
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_lookup
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_lookup()
|
|
{
|
|
dl_type="$1"
|
|
dl_key="$2"
|
|
dl_flag="$3"
|
|
|
|
|
|
if [[ "${dl_flag}" != "NOCACHE" ]]
|
|
then
|
|
{ dns_tab_get ${dl_type} ${dl_key}; rc=$?; } || true
|
|
else
|
|
rc=1
|
|
fi
|
|
|
|
if [[ "${rc}" != "0" ]]
|
|
then
|
|
#log_trace "DNS" "Out of Cache: Type: [${dl_type}] Key: [${dl_key}] Flag: [${dl_flag}]"
|
|
|
|
case ${dl_type}
|
|
in
|
|
"A")
|
|
dns_value="$( dig +short ${dl_key} 2>/dev/null | ip_ip_filter)"
|
|
;;
|
|
|
|
"PTR")
|
|
dns_value="$( dig +short -x ${dl_key} 2>/dev/null)"
|
|
dns_value="${dns_value%.}"
|
|
;;
|
|
esac
|
|
|
|
if [[ "${dl_flag}" != "NOCACHE" ]]
|
|
then
|
|
dns_tab_put "${dl_type}" "${dl_key}" "${dns_value}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_tab_dump
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_tab_dump()
|
|
{
|
|
echo "DNS_A_ID_LIST: [${DNS_A_ID_LIST}]"
|
|
echo
|
|
|
|
echo "DNS_A_TAB:"
|
|
|
|
for key in "${!DNS_A_TAB[@]}"
|
|
do
|
|
echo "[${key}]: [${DNS_A_TAB[${key}]}]"
|
|
done | sort -n
|
|
|
|
echo
|
|
|
|
echo "DNS_PTR_ID_LIST: [${DNS_PTR_ID_LIST}]"
|
|
echo
|
|
|
|
echo "DNS_PTR_TAB:"
|
|
|
|
for key in "${!DNS_PTR_TAB[@]}"
|
|
do
|
|
echo "[${key}]: [${DNS_PTR_TAB[${key}]}]"
|
|
done | sort -n
|
|
|
|
echo
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_host_update
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_host_update()
|
|
{
|
|
local host="$1"
|
|
local zone="$2"
|
|
local ip="$3"
|
|
local ttl="$4"
|
|
|
|
local date
|
|
|
|
date="$(date --rfc-3339=seconds)"
|
|
|
|
log_info "DNS" "Host: [${host}] Zone: [${zone}] IP: [${ip}] TTL: [${ttl}] Date: [${date}]"
|
|
|
|
(
|
|
echo "prereq yxrrset ${host}.${zone}. A"
|
|
echo "update delete ${host}.${zone}. A"
|
|
echo "update add ${host}.${zone}. ${ttl} A ${ip}"
|
|
echo "update delete ${host}.${zone}. TXT"
|
|
echo "update add ${host}.${zone}. ${ttl} TXT ${date}"
|
|
echo ""
|
|
) | sudo nsupdate
|
|
|
|
if [[ "$?" == "0" ]]
|
|
then
|
|
dns_tab_put "A" "${host}.${zone}" "${ip}"
|
|
fi
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_init
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_init()
|
|
{
|
|
file_dir_init "${DNS_CACHE_FILE}" root apache
|
|
file_dir_init "${DNS_CACHE_LOCK}" root apache
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
# dns_deinit
|
|
#--------------------------------------------------------------------------------------------------------------------------
|
|
|
|
dns_deinit()
|
|
{
|
|
DNS_A_TAB=()
|
|
DNS_A_ID_LIST=""
|
|
|
|
DNS_PTR_TAB=()
|
|
DNS_PTR_ID_LIST=""
|
|
|
|
DNS_CACHE_UPDATED=0
|
|
|
|
# :;
|
|
}
|
|
|