Current File : //opt/managed_servers/scripts/dns_query.sh
readonly ZONES_DIR="/var/named";
readonly DNS_QUERY_CHECK_DATA="${BACKGROUND_DATA}/dns_query_check.data";
readonly DNS_QUERY_CHECK_ERRORS="${BACKGROUND_DATA}/dns_query_check.errors";
readonly DNS_QUERY_CASES=(named_zone_duplicate);
readonly REASON_UNKNOWN="unknown";
readonly DUPLICATE_ZONE="duplicate_definition_in_named_conf";
named_zone_duplicate() {
local zone_duplicate_keyword="already exists previous definition";
if [[ "$named_restart_result" =~ "$zone_duplicate_keyword" ]]; then
dns_query_data[dnq_query_issue_reason]="$DUPLICATE_ZONE";
# Backup the current, broken /etc/named.conf
local named_conf="/etc/named.conf";
local named_conf_bkp="/etc/$(basename "$named_conf")_$(date '+%F_%H-%M-%S')";
mv "$named_conf" "$named_conf_bkp";
# Rebuild /etc/named.conf
local named_rebuild_result=$(/usr/local/cpanel/scripts/rebuilddnsconfig 2>&1);
if [[ $? -eq 0 ]]; then
dns_query_data[service_status]="$SERVICE_ACTIVE";
dns_query_data[auto_fix_status]="$AUTO_FIX_SUCCESS";
return 0;
else
# Reverse changes in case the rebuilddnsconfig script failed
mv -f "$named_conf_bkp" "$named_conf";
dns_query_data[service_status]="$SERVICE_DOWN"
dns_query_data[auto_fix_status]="$AUTO_FIX_FAIL";
dns_query_data[named_rebuild_result]=$(base64 -w0 <<< "$named_rebuild_result");
return 0;
fi;
else
# Check for a different issue
return 1;
fi;
}
ns_pointed_to_server_check(){
local ips="$1";
local ip_a=$(ip a);
for ip in $ips; do
if [[ $ip_a =~ " $ip/" ]]; then
# One of the NS is pointed to the server
return 0;
else
# None of the NS are pointed to the server
return 1;
fi;
done;
}
create_hostname_zone(){
whmapi1 adddns domain="$(hostname)" trueowner='root' ip="${server_ips[0]}" 1>/dev/null 2>&1;
/scripts/restartsrv_named 1>/dev/null 2>&1;
local dig_res=$(dig $(hostname) @${server_ips[0]});
local dig_answer_section=$(grep -A1 "ANSWER SECTION:" <<< "$dig_res");
if [[ $dig_answer_section =~ "${server_ips[0]}" ]]; then
dns_query_data[service_status]="$SERVICE_ACTIVE";
dns_query_data[auto_fix_status]="$AUTO_FIX_SUCCESS";
else
dns_query_data[service_status]="$SERVICE_DOWN"
dns_query_data[auto_fix_status]="$AUTO_FIX_FAIL";
dns_query_data[dig_result]="$(sed -z "s/\n/\\\n/g" <<< "$dig_res")";
fi;
}
fix_hostname_record(){
local zones_backup_dir="${ZONES_DIR}/named_zone_bkp_$(date +%F)";
local zone_file="${ZONES_DIR}/$(hostname).db";
local serial="$(grep -A5 SOA $zone_file | grep -oE "[0-9]{10,}")";
mkdir $zones_backup_dir 2>/dev/null;
rsync ${ZONES_DIR}/$(hostname).db "$zones_backup_dir";
sed -i -E "/$(hostname).[\s\t]+[0-9]+[\s\t]+IN[\s\t]+A/d" $zone_file
whmapi1 mass_edit_dns_zone zone="$(hostname)" serial="$serial" add='{"dname":"'$(hostname).'", "ttl":14400, "record_type":"A", "data":["'${server_ips[0]}'"]}' 1>/dev/null 2>&1;
sleep 5;
local dig_res=$(dig $(hostname) @${server_ips[0]});
local dig_answer_section=$(grep -A1 "ANSWER SECTION:" <<< "$dig_res");
if [[ $dig_answer_section =~ "${server_ips[0]}" ]]; then
dns_query_data[service_status]="$SERVICE_ACTIVE";
dns_query_data[auto_fix_status]="$AUTO_FIX_SUCCESS";
else
dns_query_data[service_status]="$SERVICE_DOWN"
dns_query_data[auto_fix_status]="$AUTO_FIX_FAIL";
dns_query_data[dig_result]="$(sed -z "s/\n/\\\n/g" <<< "$dig_res")";
fi;
}
hostname_zone_fix(){
if [[ $(file ${ZONES_DIR}/$(hostname).db) =~ ": cannot open" ]]; then
create_hostname_zone;
else
fix_hostname_record;
fi;
}
named_service_check(){
local named_initial_status="$(/scripts/restartsrv_named --status 2>&1)";
local named_restart;
local disabled="$(grep named:1 /etc/chkserv.d/chkservd.conf)";
local inactive="service is down";
local active="is running";
if [[ -z "$disabled" ]]; then
# The named service was disabled manually
dns_query_data[service_status]="$SERVICE_DISABLED";
dns_query_data[auto_fix_status]="$AUTO_FIX_NOPE";
return 1;
elif [[ "$named_initial_status" =~ $active ]]; then
# The named service is running
hostname_check;
return 0;
else
/scripts/restartsrv_named --start 1>/dev/null 2>&1;
named_restart="$(/scripts/restartsrv_named --status 2>&1)";
if [[ "$named_restart" =~ "$inactive" ]]; then
# The named service has failed to start
dns_query_data[service_status]="$SERVICE_DOWN"
dns_query_data[auto_fix_status]="$AUTO_FIX_FAIL";
return 1;
else
# The named service was restarted successfully
return 0;
fi;
fi;
}
hostname_check(){
readarray -t server_ips <<< "$(whmapi1 listips | grep -P "public_ip:" | grep -oE "([0-9]{1,3}\.){3}[0-9]{1,3}$")";
local dig_res=$(dig $(hostname) @${server_ips[0]});
local dig_answer_section=$(grep -A1 "ANSWER SECTION:" <<< "$dig_res");
local hostname_ip=$(grep -P "[\s\t]+A[\s\t]+" <<< "$dig_answer_section" | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}");
if [[ ! $(ip a) =~ " ${hostname_ip}/" ]]; then
# The hostname is not pointed
# Check if NS are pointed to the server
local ns_ips=$(grep -A2 ";; ADDITIONAL SECTION:" <<< "$dig_res" | grep -oP "([0-9]{1,3}\.){3}[0-9]{1,3}");
ns_pointed_to_server_check "$ns_ips" && {
# At least one NS is pointed to the server
# Create zone for hostname or the A record
hostname_zone_fix;
} || {
# NS are not pointed to the server
dns_query_data[service_status]="$SERVICE_DOWN";
dns_query_data[dig_result]="$(json_escape <<< "$dig_res")";
};
else
# Hostname is pointed
dns_query_data[service_status]="$SERVICE_ACTIVE";
fi;
}
dns_query_check_main(){
declare -A dns_query_data;
local server_ips=();
local named_restart_result;
local named_restart_return_code=0; # Expected to be running by default
local disabled="$(grep named:1 /etc/chkserv.d/chkservd.conf)";
# In case the named service is not running, restart it
if ! /scripts/restartsrv_named --status &>/dev/null; then
named_restart_result="$(/scripts/restartsrv_named 2>&1)";
named_restart_return_code=$?;
fi;
if [[ -z "$disabled" ]]; then
# The named service was disabled manually
dns_query_data[service_status]="$SERVICE_DISABLED";
dns_query_data[auto_fix_status]="$AUTO_FIX_NOPE";
elif [[ $named_restart_return_code -eq 0 ]]; then
# The named service is running
# Check if the server hostname is pointed to the server
hostname_check;
else
# The named service is not running, look for reasons and attempt to fix
for case in ${!DNS_QUERY_CASES[@]}; do
# Each DNS_QUERY_CASES function should return 0 if the issues was identified
if eval ${DNS_QUERY_CASES[$case]}; then
break;
fi;
done;
if [[ -z ${dns_query_data[dnq_query_issue_reason]} ]]; then
dns_query_data[dnq_query_issue_reason]="$REASON_UNKNOWN";
fi;
fi;
bash_arr_to_json dns_query_data "${!dns_query_data[@]}" > "$DNS_QUERY_CHECK_DATA";
}
dns_query_check(){
run_check_in_background "dns_query_check_main" "$DNS_QUERY_CHECK_DATA" "$DNS_QUERY_CHECK_ERRORS"\
"${CHECK_LOCKS_DIR}/${FUNCNAME}.lock";
}