#!/bin/bash
#< Wrapper for "vi /etc/named.conf" with lock file editing protection
# This script is part of my DNS named.conf transfer scripts. The scripts
# are designed to be used for the transferral of a frequently changing
# named.conf file from a primary nameserver to a secondary nameserver.
# The scripts assume a lot. The zone files used in my test environment
# were very "bare-bones" and simple. Example:
# Any additional configuration options present in the file would
# require script modifications (sync_to_slave.sh) to accomodate parsing
# the other configuration options. This script is designed to be easily
# modified, and should be considered a template for named.conf transfers.
# The scripts revolve around a central lock file mechanism, which aims to
# ensure that no incomplete named.conf files are transferred whilst they are
# being edited - although it will not parse a file for syntactical correctness.
# Also, this assumes that all edits to the named.conf file are made using the
# vinamed wrapper, or a custom tool that uses the lockfile mechanism used in
# these scripts.
# The scripts provided are:
# vinamed Lock file protected named.conf editing wrapper
# sync_to_slave.sh Intended to be scheduled via cron on the
# primary nameserver, BEFORE the script below
# runs on the slave nameserver.
# install_slave_config.sh Schedule this to run a few minutes after
# the sync_to_slave.sh script runs on the
# primary nameserver. This script contains
# various checks (lockfile, confirms whether
# the newly transferred named.conf file is
# modified, etc.) This script also creates
# backups of named.conf prior to, and after
# modification. Then it restarts BIND.
# Example cron jobs (depending on the frequency of your named.conf file
# edits).
# master# crontab -l | grep sync_to_slave
# 0,30 * * * * /usr/local/dns/bin/sync_to_slave.sh
# slave# crontab -l | grep install_slave_config
# 15,45 * * * * /usr/local/dns/bin/install_slave_config.sh
# You will also need to check the paths presented in the scripts, and ensure
# that the appropriate backup directories are created, or the paths
# referenced in the scripts are changed.
# For the key-based file transfer to work, I'm using a "namesync" user on each
# server.
# Executables
CHMOD="/bin/chmod"
ECHO="/bin/echo"
ID="/usr/bin/id"
RM="/bin/rm"
TOUCH="/usr/bin/touch"
VI="/usr/bin/vi"
# Paths and Files
NAMED_CONF="/etc/named.conf"
LOCKFILE="/var/lock/vinamed.lock"
# Error Codes
SUCCESS=0
ENOCONF=1
ELOCKFILE=1
# Function: print_error
# Arguments: $@
# Returns: Nothing
# Description: echo wrapper to output to STDERR
function print_error {
${ECHO} "Error: $@" >&2
}
# Function: print_msg
# Arguments: $@
# Returns: Nothing
# Description: echo wrapper to output to STDOUT with prefix
function print_msg {
${ECHO} "--> $@"
}
# Function: check_root_user
# Arguments: None
# Returns: Nothing - will exit on failure
# Description: Checks whether the script is being executed as root user
function check_root_user {
WHOAMI=$( ${ID} -u )
if [ "${WHOAMI}" -ne "0" ]; then
print_error "You must be root to run this program"
exit ${ENOTROOT}
fi
}
# Function: check_named_conf
# Arguments: None
# Returns: Nothing - will exit on failure
# Description: Exits if the named.conf file cannot be found
function check_named_conf {
if [ ! -e "${NAMED_CONF}" ]; then
print_error "${NAMED_CONF} does not exist"
exit ${ENOCONF}
fi
}
# Function: remove_lockfile
# Arguments: None
# Returns: Nothing
# Description: Removes the lockfile
function remove_lockfile {
print_msg "Removing lockfile..."
${RM} -f ${LOCKFILE}
print_msg "Lockfile removed"
}
# Function: check_lockfile
# Arguments: None - accepts user input
# Returns: Nothing - exits on failure
# Description: Prompts the user, if the lock file exists, whether or not
# they would like to continue with the edit
function check_lockfile {
if [ -e "${LOCKFILE}" ]; then
print_msg "${LOCKFILE} exists! Do you want to remove it?"
${ECHO} -e "<-- Type YeS (Case Sensitive) to confirm: \c"
read RESPONSE
case ${RESPONSE} in
YeS) remove_lockfile
;;
*) print_error "Lock file NOT removed"
exit ${ELOCKFILE}
;;
esac
fi
}
# Function: create_lockfile
# Arguments: None
# Returns: Nothing
# Description: Creates the lockfile and changes its mode to 400
function create_lockfile {
print_msg "Creating lockfile..."
${TOUCH} ${LOCKFILE}
${CHMOD} 400 ${LOCKFILE}
print_msg "Lockfile created"
}
# Function: edit_named_conf
# Arguments: None
# Returns: Nothing
# Description: Starts vi to edit the named.conf file
function edit_named_conf {
print_msg "Starting ${VI} to edit ${NAMED_CONF}..."
${VI} ${NAMED_CONF}
}
#
# main
#
#
check_root_user
check_named_conf
check_lockfile
create_lockfile
edit_named_conf
remove_lockfile
exit ${SUCCESS}