Improvements to NTP plugins & other smaller fixes

This commit is contained in:
Patrick Van der Veken 2019-01-11 15:59:39 +01:00
parent 2b87e0dd6c
commit cbddbf0eec
6 changed files with 174 additions and 38 deletions

View File

@ -11,10 +11,14 @@
# [default: no] # [default: no]
log_healthy=yes log_healthy=yes
# maximum allowed offset (in milliseconds) # maximum allowed offset (in milliseconds (positive integers only))
# [default: 500] # [default: 500]
max_offset=500 max_offset=500
# use IPv4 for ntpq
# [default: no]
ntpq_use_ipv4=no
#****************************************************************************** #******************************************************************************
# End of FILE # End of FILE

View File

@ -11,10 +11,22 @@
# [default: no] # [default: no]
log_healthy=yes log_healthy=yes
# maximum allowed offset (in milliseconds) # whether to force the use of chronyd?
# [default: no]
force_chrony=no
# whether to force the use of ntpd?
# [default: no]
force_ntp=no
# maximum allowed offset (in milliseconds (positive integers only)
# [default: 500] # [default: 500]
max_offset=500 max_offset=500
# use IPv4 for ntpq
# [default: no]
ntpq_use_ipv4=no
#****************************************************************************** #******************************************************************************
# End of FILE # End of FILE

View File

@ -52,11 +52,11 @@ typeset -r TMP_DIR="/var/tmp"
typeset -r EXEC_USER="root" typeset -r EXEC_USER="root"
# ------------------------- CONFIGURATION ends here --------------------------- # ------------------------- CONFIGURATION ends here ---------------------------
# read-only settings (but should not be changed) # read-only settings (but should not be changed)
typeset -r SCRIPT_NAME=$(basename "$0") typeset -r SCRIPT_NAME=$(basename "$0" 2>/dev/null)
typeset -r SCRIPT_DIR=$(dirname "$0") typeset -r SCRIPT_DIR=$(dirname "$0" 2>/dev/null)
# shellcheck disable=SC2034 # shellcheck disable=SC2034
typeset -r HOST_NAME="$(hostname)" typeset -r HOST_NAME="$(hostname 2>/dev/null)"
typeset -r OS_NAME="$(uname -s)" typeset -r OS_NAME="$(uname -s 2>/dev/null)"
typeset -r LOCK_DIR="${TMP_DIR}/.${SCRIPT_NAME}.lock" typeset -r LOCK_DIR="${TMP_DIR}/.${SCRIPT_NAME}.lock"
typeset -r HC_MSG_FILE="${TMP_DIR}/.${SCRIPT_NAME}.hc.msg.$$" # plugin messages file typeset -r HC_MSG_FILE="${TMP_DIR}/.${SCRIPT_NAME}.hc.msg.$$" # plugin messages file
# shellcheck disable=SC2034 # shellcheck disable=SC2034

View File

@ -1478,7 +1478,7 @@ fi
# print header # print header
if [[ "${FACTION}" != "list" ]] if [[ "${FACTION}" != "list" ]]
then then
printf "%-30s\t%-8s\t%s\t\t%s\t%s\t%s\n" "Health Check" "State" "Version" "Config?" "Sched?" "H+?" printf "%-40s\t%-8s\t%s\t\t%s\t%s\t%s\n" "Health Check" "State" "Version" "Config?" "Sched?" "H+?"
# shellcheck disable=SC2183 # shellcheck disable=SC2183
printf "%100s\n" | tr ' ' - printf "%100s\n" | tr ' ' -
fi fi
@ -1562,7 +1562,7 @@ do
# show results # show results
if [[ "${FACTION}" != "list" ]] if [[ "${FACTION}" != "list" ]]
then then
printf "%-30s\t%-8s\t%s\t%s\t%s\t%s\n" \ printf "%-40s\t%-8s\t%s\t%s\t%s\t%s\n" \
"${FNAME#function *}" \ "${FNAME#function *}" \
"${FSTATE}" \ "${FSTATE}" \
"${FVERSION#typeset _VERSION=*}" \ "${FVERSION#typeset _VERSION=*}" \

View File

@ -26,6 +26,8 @@
# @(#) 2016-12-29: added threshold & config file [Patrick Van der Veken] # @(#) 2016-12-29: added threshold & config file [Patrick Van der Veken]
# @(#) 2018-10-28: fixed (linter) errors [Patrick Van der Veken] # @(#) 2018-10-28: fixed (linter) errors [Patrick Van der Veken]
# @(#) 2018-10-31: added support for --log-healthy [Patrick Van der Veken] # @(#) 2018-10-31: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-01-10: added configuration option 'ntpq_use_ipv4', fixed problem
# @(#) with offset calculation [Patrick Van der Veken]
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING! # DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -35,9 +37,10 @@ function check_hpux_ntp_status
{ {
# ------------------------- CONFIGURATION starts here ------------------------- # ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf" typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2018-10-31" # YYYY-MM-DD typeset _VERSION="2019-01-10" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
typeset _NTPQ_BIN="/usr/sbin/ntpq" typeset _NTPQ_BIN="/usr/sbin/ntpq"
typeset _NTPQ_OPTS="-pn"
# ------------------------- CONFIGURATION ends here --------------------------- # ------------------------- CONFIGURATION ends here ---------------------------
# set defaults # set defaults
@ -48,10 +51,12 @@ typeset _ARG=""
typeset _MSG="" typeset _MSG=""
typeset _STC=0 typeset _STC=0
typeset _CFG_HEALTHY="" typeset _CFG_HEALTHY=""
typeset _CFG_NTPQ_IPV4=""
typeset _LOG_HEALTHY=0 typeset _LOG_HEALTHY=0
typeset _CURR_OFFSET=0 typeset _CURR_OFFSET=0
typeset _MAX_OFFSET=0 typeset _MAX_OFFSET=0
typeset _NTP_PEER="" typeset _NTP_PEER=""
typeset _CHECK_OFFSET=0
# handle arguments (originally comma-separated) # handle arguments (originally comma-separated)
for _ARG in ${_ARGS} for _ARG in ${_ARGS}
@ -87,6 +92,16 @@ case "${_CFG_HEALTHY}" in
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0 (( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;; ;;
esac esac
_CFG_NTPQ_IPV4=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'ntpq_use_ipv4')
case "${_CFG_NTPQ_IPV4}" in
yes|YES|Yes)
log "forcing ntpq to use IPv4"
_NTPQ_OPTS="${_NTPQ_OPTS}4"
;;
*)
: # not set
;;
esac
# log_healthy # log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1 (( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
@ -108,7 +123,7 @@ then
warn "${_NTPQ_BIN} is not installed here" warn "${_NTPQ_BIN} is not installed here"
return 1 return 1
else else
${_NTPQ_BIN} -np 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG} ${_NTPQ_BIN} ${_NTPQ_OPTS} 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG}
# RC is always 0 # RC is always 0
fi fi
@ -121,7 +136,7 @@ then
log_hc "$0" 1 "${_MSG}" log_hc "$0" 1 "${_MSG}"
return 0 return 0
fi fi
case ${_NTP_PEER} in case "${_NTP_PEER}" in
\*127.127.1.0*) \*127.127.1.0*)
_MSG="NTP is synchronizing against its internal clock" _MSG="NTP is synchronizing against its internal clock"
_STC=1 _STC=1
@ -139,8 +154,9 @@ then
_CURR_OFFSET="$(grep -E -e '^\*' 2>/dev/null ${HC_STDOUT_LOG} | awk '{ print $9 }')" _CURR_OFFSET="$(grep -E -e '^\*' 2>/dev/null ${HC_STDOUT_LOG} | awk '{ print $9 }')"
case ${_CURR_OFFSET} in case ${_CURR_OFFSET} in
+([-0-9])*(.)*([0-9])) +([-0-9])*(.)*([0-9]))
# numeric, OK (negatives are OK too!) # numeric, OK (negatives are OK, force awk into casting c as a float)
if (( $(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { print (c>m) }') != 0 )) _CHECK_OFFSET=$(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { sub (/^-/, "", c); print ((c+0.0)>m) }' 2>/dev/null)
if (( _CHECK_OFFSET > 0 ))
then then
_MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}" _MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}"
_STC=1 _STC=1
@ -166,7 +182,12 @@ function _show_usage
cat <<- EOT cat <<- EOT
NAME : $1 NAME : $1
VERSION : $2 VERSION : $2
CONFIG : $3 CONFIG : $3 with:
log_healthy=<yes|no>
max_offset=<max_offset (ms)>
force_chrony=<yes|no>
force_ntp=<yes|no>
ntpq_use_ipv4=<yes|no>
PURPOSE : Checks the status of NTP synchronization PURPOSE : Checks the status of NTP synchronization
EOT EOT

View File

@ -19,7 +19,8 @@
# @(#) MAIN: check_linux_ntp_status # @(#) MAIN: check_linux_ntp_status
# DOES: see _show_usage() # DOES: see _show_usage()
# EXPECTS: see _show_usage() # EXPECTS: see _show_usage()
# REQUIRES: data_space2comma(), init_hc(), log_hc(), warn() # REQUIRES: data_space2comma(), init_hc(), log_hc(),
# linux_has_systemd_service(), warn()
# #
# @(#) HISTORY: # @(#) HISTORY:
# @(#) 2018-03-20: initial version [Patrick Van der Veken] # @(#) 2018-03-20: initial version [Patrick Van der Veken]
@ -28,6 +29,10 @@
# @(#) 2018-10-31: added support for chronyd, --dump-logs # @(#) 2018-10-31: added support for chronyd, --dump-logs
# @(#) & --log-healthy [Patrick Van der Veken] # @(#) & --log-healthy [Patrick Van der Veken]
# @(#) 2018-11-18: add linux_has_systemd_service() [Patrick Van der Veken] # @(#) 2018-11-18: add linux_has_systemd_service() [Patrick Van der Veken]
# @(#) 2019-01-10: add optional configuration+cmd-line parameters 'force_ntp' and
# @(#) 'force_chrony', added check on chronyd service alive, added
# @(#) run user for chronyd+ntpd, added forced IPv4 support for ntpq,
# @(#) fixed problem with offset calculation [Patrick Van der Veken]
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING! # DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -41,10 +46,13 @@ typeset _CHRONY_INIT_SCRIPT="/etc/init.d/chrony"
typeset _NTPD_INIT_SCRIPT="/etc/init.d/ntpd" typeset _NTPD_INIT_SCRIPT="/etc/init.d/ntpd"
typeset _CHRONYD_SYSTEMD_SERVICE="chronyd.service" typeset _CHRONYD_SYSTEMD_SERVICE="chronyd.service"
typeset _NTPD_SYSTEMD_SERVICE="ntpd.service" typeset _NTPD_SYSTEMD_SERVICE="ntpd.service"
typeset _VERSION="2018-11-18" # YYYY-MM-DD typeset _CHRONYD_USER="chrony"
typeset _NTPD_USER="ntp"
typeset _VERSION="2019-01-10" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
typeset _CHRONYC_BIN="/bin/chronyc" typeset _CHRONYC_BIN="/bin/chronyc"
typeset _NTPQ_BIN="/usr/sbin/ntpq" typeset _NTPQ_BIN="/usr/sbin/ntpq"
typeset _NTPQ_OPTS="-pn"
# ------------------------- CONFIGURATION ends here --------------------------- # ------------------------- CONFIGURATION ends here ---------------------------
# set defaults # set defaults
@ -54,12 +62,16 @@ typeset _ARGS=$(data_space2comma "$*")
typeset _ARG="" typeset _ARG=""
typeset _MSG="" typeset _MSG=""
typeset _STC=0 typeset _STC=0
typeset _CFG_FORCE_CHRONY=""
typeset _CFG_FORCE_NTP=""
typeset _CFG_NTPQ_IPV4=""
typeset _CFG_HEALTHY="" typeset _CFG_HEALTHY=""
typeset _LOG_HEALTHY=0 typeset _LOG_HEALTHY=0
typeset _CHECK_SYSTEMD_SERVICE=0 typeset _CHECK_SYSTEMD_SERVICE=0
typeset _CURR_OFFSET=0 typeset _CURR_OFFSET=0
typeset _MAX_OFFSET=0 typeset _MAX_OFFSET=0
typeset _NTP_PEER="" typeset _NTP_PEER=""
typeset _CHECK_OFFSET=0
typeset _USE_CHRONYD=0 typeset _USE_CHRONYD=0
typeset _USE_NTPD=0 typeset _USE_NTPD=0
@ -70,6 +82,14 @@ do
help) help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0 _show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
;; ;;
force_chrony)
log "forcing chrony since force_chrony was used"
_USE_CHRONYD=1
;;
force_ntp)
log "forcing ntp since force_ntp was used"
_USE_NTPD=1
;;
esac esac
done done
@ -97,6 +117,42 @@ case "${_CFG_HEALTHY}" in
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0 (( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;; ;;
esac esac
_CFG_FORCE_CHRONY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'force_chrony')
case "${_CFG_FORCE_CHRONY}" in
yes|YES|Yes)
log "forcing chrony since force_chrony was set"
_USE_CHRONYD=1
;;
*)
: # not set
;;
esac
# force_ntp (optional)
_CFG_FORCE_NTP=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'force_ntp')
case "${_CFG_FORCE_NTP}" in
yes|YES|Yes)
log "forcing ntp since force_ntp was set"
_USE_NTPD=1
;;
*)
: # not set
;;
esac
_CFG_NTPQ_IPV4=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'ntpq_use_ipv4')
case "${_CFG_NTPQ_IPV4}" in
yes|YES|Yes)
log "forcing ntpq to use IPv4"
_NTPQ_OPTS="${_NTPQ_OPTS}4"
;;
*)
: # not set
;;
esac
if (( _USE_CHRONYD > 0 && _USE_NTPD > 0 ))
then
warn "you cannot force chrony and ntp at the same time"
return 1
fi
# log_healthy # log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1 (( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
@ -113,20 +169,55 @@ else
fi fi
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# chronyd (prefer) or ntpd (fallback)? # chronyd (prefer) or ntpd (fallback)
if [[ -x ${_CHRONYC_BIN} ]] # but do not check if _USE_CHRONYD or _USE_NTPD is already set
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 ))
then then
_USE_CHRONYD=1 linux_get_init
elif [[ -x ${_NTPQ_BIN} ]] if [[ -x ${_CHRONYC_BIN} ]]
then then
# shellcheck disable=SC2034 # check that chrony is actually enabled
_USE_NTPD=1 (( ARG_DEBUG > 0 )) && debug "found ${_CHRONYC_BIN}, checking if the service is enabled"
else case "${LINUX_INIT}" in
_MSG="unable to find chronyd or ntpd" 'systemd')
log_hc "$0" 1 "${_MSG}" _CHECK_SYSTEMD_SERVICE=$(linux_has_systemd_service "${_CHRONYD_SYSTEMD_SERVICE}")
# dump debug info if (( _CHECK_SYSTEMD_SERVICE > 0 ))
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && dump_logs then
return 1 systemctl --quiet is-enabled ${_CHRONYD_SYSTEMD_SERVICE} 2>>${HC_STDERR_LOG} && _USE_CHRONYD=1
else
warn "systemd unit file not found {${_CHRONYD_SYSTEMD_SERVICE}}"
_USE_CHRONYD=0
fi
;;
'sysv')
chkconfig chronyd >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
if (( $? == 0 ))
then
_USE_CHRONYD=1
else
_USE_CHRONYD=0
fi
;;
*)
_USE_CHRONYD=0
;;
esac
(( ARG_DEBUG > 0 )) && debug "chronyd service state: ${_USE_CHRONYD}"
fi
if (( _USE_CHRONYD == 0 )) && [[ -x ${_NTPQ_BIN} ]]
then
# shellcheck disable=SC2034
_USE_NTPD=1
(( ARG_DEBUG > 0 )) && debug "ntpd service state: ${_USE_NTPD}"
fi
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 ))
then
_MSG="unable to find chronyd or ntpd (or they are not enabled)"
log_hc "$0" 1 "${_MSG}"
# dump debug info
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && dump_logs
return 1
fi
fi fi
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
@ -197,9 +288,9 @@ if (( _RC > 0 ))
then then
if (( _USE_CHRONYD > 0 )) if (( _USE_CHRONYD > 0 ))
then then
(( $(pgrep -u root chronyd 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1 (( $(pgrep -u "${_CHRONYD_USER}" 'chronyd' 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
else else
(( $(pgrep -u root ntpd 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1 (( $(pgrep -u "${_NTPD_USER}" 'ntpd' 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
fi fi
fi fi
@ -233,7 +324,7 @@ esac
log_hc "$0" ${_STC} "${_MSG}" log_hc "$0" ${_STC} "${_MSG}"
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# check ntpq results # check chronyc/ntpq results
_STC=0 _STC=0
if (( _USE_CHRONYD > 0 )) if (( _USE_CHRONYD > 0 ))
then then
@ -276,12 +367,14 @@ then
+([-0-9])*(.)*([0-9])) +([-0-9])*(.)*([0-9]))
# numeric, OK (negatives are OK too!) # numeric, OK (negatives are OK too!)
# convert from us to ms # convert from us to ms
_CURR_OFFSET=$(print "${_CURR_OFFSET} * 1000" | bc 2>/dev/null) _CURR_OFFSET=$(print -R "${_CURR_OFFSET} * 1000" | bc 2>/dev/null)
if (( $? > 0 )) || [[ -z "${_CURR_OFFSET}" ]] if (( $? > 0 )) || [[ -z "${_CURR_OFFSET}" ]]
then then
: :
fi fi
if (( $(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { print (c>m) }' 2>/dev/null) != 0 )) # force awk into casting c as a float
_CHECK_OFFSET=$(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { sub (/^-/, "", c); print ((c+0.0)>m) }' 2>/dev/null)
if (( _CHECK_OFFSET > 0 ))
then then
_MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}" _MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}"
_STC=1 _STC=1
@ -299,7 +392,7 @@ then
fi fi
else else
${_NTPQ_BIN} -np 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG} ${_NTPQ_BIN} ${_NTPQ_OPTS} 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG}
# RC is always 0 # RC is always 0
# 1) active server # 1) active server
@ -328,8 +421,9 @@ else
_CURR_OFFSET="$(grep -E -e '^\*' 2>/dev/null ${HC_STDOUT_LOG} | awk '{ print $9 }' 2>/dev/null)" _CURR_OFFSET="$(grep -E -e '^\*' 2>/dev/null ${HC_STDOUT_LOG} | awk '{ print $9 }' 2>/dev/null)"
case ${_CURR_OFFSET} in case ${_CURR_OFFSET} in
+([-0-9])*(.)*([0-9])) +([-0-9])*(.)*([0-9]))
# numeric, OK (negatives are OK too!) # numeric, OK (negatives are OK, force awk into casting c as a float)
if (( $(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { print (c>m) }' 2>/dev/null) != 0 )) _CHECK_OFFSET=$(awk -v c="${_CURR_OFFSET}" -v m="${_MAX_OFFSET}" 'BEGIN { sub (/^-/, "", c); print ((c+0.0)>m) }' 2>/dev/null)
if (( _CHECK_OFFSET > 0 ))
then then
_MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}" _MSG="NTP offset of ${_CURR_OFFSET} is bigger than the configured maximum of ${_MAX_OFFSET}"
_STC=1 _STC=1
@ -356,7 +450,12 @@ function _show_usage
cat <<- EOT cat <<- EOT
NAME : $1 NAME : $1
VERSION : $2 VERSION : $2
CONFIG : $3 CONFIG : $3 with:
log_healthy=<yes|no>
max_offset=<max_offset (ms)>
force_chrony=<yes|no>
force_ntp=<yes|no>
ntpq_use_ipv4=<yes|no>
PURPOSE : Checks the status of NTP service & synchronization. PURPOSE : Checks the status of NTP service & synchronization.
Supports chronyd & ntpd. Supports chronyd & ntpd.
Assumes chronyd is the preferred time synchronization. Assumes chronyd is the preferred time synchronization.