mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 10:37:22 +00:00
FR: 35 - Script to setup redirection of SNMP to/from BMC
Provides configuration script, systemd unit and sysconfig defaults. On hosts running net-snmp and PEF alerting on BMC: 1. Redirect SNMP get requests to BMC (Service Processor). 2. Redirect SNMP Traps from BMC (Service Processor) to the Hosts' configured Trap sink.
This commit is contained in:
parent
8525fdd2a3
commit
157132be8c
@ -35,5 +35,5 @@ dist_pkgdata_DATA = oem_ibm_sel_map
|
|||||||
EXTRA_DIST = README \
|
EXTRA_DIST = README \
|
||||||
bmclanconf ipmi.init.basic ipmi.init.redhat \
|
bmclanconf ipmi.init.basic ipmi.init.redhat \
|
||||||
ipmievd.init.redhat ipmievd.init.suse ipmievd.init.debian \
|
ipmievd.init.redhat ipmievd.init.suse ipmievd.init.debian \
|
||||||
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh
|
collect_data.sh create_rrds.sh create_webpage_compact.sh create_webpage.sh \
|
||||||
|
bmc-snmp-proxy bmc-snmp-proxy.service bmc-snmp-proxy.sysconf
|
||||||
|
381
ipmitool/contrib/bmc-snmp-proxy
Normal file
381
ipmitool/contrib/bmc-snmp-proxy
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#############################################################################
|
||||||
|
#
|
||||||
|
# bmc-snmp-proxy: Set SNMP proxy to BMC (Baseboard Management Controller)
|
||||||
|
#
|
||||||
|
# version: 0.6
|
||||||
|
#
|
||||||
|
# Authors: Charles Rose <charles_rose@dell.com>
|
||||||
|
# Jordan Hargrave <jordan_hargrave@dell.com>
|
||||||
|
#
|
||||||
|
# Description: Script to set snmp proxy to the BMC for certain OID
|
||||||
|
# See here for details:
|
||||||
|
# https://fedoraproject.org/wiki/Features/AgentFreeManagement
|
||||||
|
#
|
||||||
|
# Assumptions: This script will work only when /etc/snmp/ is writable.
|
||||||
|
#
|
||||||
|
#############################################################################
|
||||||
|
# GLOBALS
|
||||||
|
#############################################################################
|
||||||
|
SYSCONF_DIR="/etc/sysconfig"
|
||||||
|
CONFIG="${SYSCONF_DIR}/bmc-snmp-proxy"
|
||||||
|
|
||||||
|
SNMPD_LOCAL_CONF_DIR="/etc/snmp/bmc"
|
||||||
|
SNMPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmpd.local.conf"
|
||||||
|
TRAPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmptrapd.local.conf"
|
||||||
|
|
||||||
|
TRAPD_CONF="/etc/snmp/snmptrapd.conf"
|
||||||
|
|
||||||
|
LOCKFILE="/var/lock/subsys/bmc-snmp-proxy"
|
||||||
|
BMC_INFO="/var/run/bmc-info"
|
||||||
|
|
||||||
|
IPMITOOL=`which ipmitool`
|
||||||
|
|
||||||
|
#Default config
|
||||||
|
BMC_COMMUNITY="public"
|
||||||
|
BMC_OID=".1.3.6.1.4.1.674.10892.2" # Dell iDRAC
|
||||||
|
TRAP_FORWARD="no"
|
||||||
|
RELOAD_SERVICES="yes"
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
#TODO: Use inotify and daemonize when $BMC_INFO changes
|
||||||
|
|
||||||
|
# source config
|
||||||
|
[ -r ${CONFIG} ] && . ${CONFIG}
|
||||||
|
|
||||||
|
. gettext.sh
|
||||||
|
|
||||||
|
SCRIPT_NAME=$(basename $0)
|
||||||
|
RETVAL=0
|
||||||
|
|
||||||
|
# Check if bmc-info created by exchange-bmc-os-info
|
||||||
|
bmc_info_exists()
|
||||||
|
{
|
||||||
|
if [ -r "${BMC_INFO}" ]; then
|
||||||
|
. ${BMC_INFO}
|
||||||
|
else
|
||||||
|
RETVAL=2
|
||||||
|
fi
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
check_snmp()
|
||||||
|
{
|
||||||
|
if [ ! -d /etc/snmp ] && [ ! -x /usr/sbin/snmpd ]; then
|
||||||
|
RETVAL=12
|
||||||
|
fi
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# configure SNMP proxy
|
||||||
|
#############################################################################
|
||||||
|
write_snmp_conf()
|
||||||
|
{
|
||||||
|
# SNMPv3 security: bmcview, bmc_ctx, bmc_sec, bmc_grp, bmc_cmty
|
||||||
|
printf "###############################################\n"
|
||||||
|
printf "# Automatically created by %s #\n" "${SCRIPT_NAME}"
|
||||||
|
printf "###############################################\n"
|
||||||
|
printf "view bmcview included %s 80\n" "${BMC_OID}"
|
||||||
|
printf "com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n"
|
||||||
|
printf "group bmc_grp v1 bmc_sec\n"
|
||||||
|
printf "access bmc_grp bmc_ctx any noauth exact bmcview none none\n"
|
||||||
|
printf "proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}"
|
||||||
|
printf "###############################################\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_ip()
|
||||||
|
{
|
||||||
|
#Thanks to mkyong.com
|
||||||
|
octet="([01]?[[:digit:]][[:digit:]]?|2[0-4][[:digit:]]|25[0-5])"
|
||||||
|
|
||||||
|
printf -- "%s" "${1}"| grep -Eq \
|
||||||
|
"^${octet}\\.${octet}\\.${octet}\\.${octet}$"
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
|
||||||
|
check_vars()
|
||||||
|
{
|
||||||
|
[ -z ${BMC_COMMUNITY} ] && BMC_COMMUNITY="public"
|
||||||
|
[ -z ${BMC_OID} ] && return 1
|
||||||
|
|
||||||
|
if [ -n "${BMC_IPv4}" ] && valid_ip ${BMC_IPv4}; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
set_snmp_proxy()
|
||||||
|
{
|
||||||
|
if check_vars; then
|
||||||
|
PROXY_TOKEN="-c ${BMC_COMMUNITY} ${BMC_IPv4} ${BMC_OID}"
|
||||||
|
|
||||||
|
if [ ! -d ${SNMPD_LOCAL_CONF_DIR} ] && \
|
||||||
|
mkdir ${SNMPD_LOCAL_CONF_DIR}; then
|
||||||
|
write_snmp_conf > ${SNMPD_LOCAL_CONF}
|
||||||
|
[ $? -ne 0 ] && RETVAL=4
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
RETVAL=3
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
set_snmpd_conf_path()
|
||||||
|
{
|
||||||
|
for SYSCONF in ${SYSCONF_DIR}/snmp*d;
|
||||||
|
do
|
||||||
|
if grep -q "${SNMPD_LOCAL_CONF_DIR}" "${SYSCONF}" > \
|
||||||
|
/dev/null 2>&1; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
printf "SNMPCONFPATH=%s\n" "${SNMPD_LOCAL_CONF_DIR}" \
|
||||||
|
>> ${SYSCONF} || RETVAL=7
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
disable_snmp_proxy()
|
||||||
|
{
|
||||||
|
if [ -f ${SNMPD_LOCAL_CONF} ]; then
|
||||||
|
rm -f ${SNMPD_LOCAL_CONF}
|
||||||
|
[ $? -ne 0 ] && RETVAL=5
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
#############################################################################
|
||||||
|
# Trap Forwarding
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
pick_alert_dest()
|
||||||
|
{
|
||||||
|
test_ip="$1"
|
||||||
|
for ALERT_DEST in `seq 1 4`
|
||||||
|
do
|
||||||
|
temp_ip=$(${IPMITOOL} lan alert print ${CHANNEL} ${ALERT_DEST}\
|
||||||
|
2>/dev/null| sed -n "s#^Alert IP Address.*: ##p")
|
||||||
|
|
||||||
|
[ "${temp_ip}" = "${test_ip}" ] && return 0
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
set_alert_dest_ip()
|
||||||
|
{
|
||||||
|
${IPMITOOL} lan alert set ${CHANNEL} ${ALERT_DEST} ipaddr ${1} \
|
||||||
|
retry 4 type pet >/dev/null 2>&1
|
||||||
|
[ $? -ne 0 ] && RETVAL=8
|
||||||
|
}
|
||||||
|
|
||||||
|
bmc_alert_dest()
|
||||||
|
{
|
||||||
|
# Pick the first active LAN channel
|
||||||
|
for CHANNEL in `seq 1 14`
|
||||||
|
do
|
||||||
|
[ $(${IPMI_TOOL} -I open channel info ${CHANNEL} 2>/dev/null \
|
||||||
|
| grep -q "802\.3") ] || break
|
||||||
|
done
|
||||||
|
|
||||||
|
# If TRAPD_IP is already set as an alert dest,
|
||||||
|
if pick_alert_dest "${TRAPD_IP}"; then
|
||||||
|
# reset: reset it if we are called with reset
|
||||||
|
[ "${1}" = "reset" ] && \
|
||||||
|
set_alert_dest_ip "0.0.0.0"
|
||||||
|
# else, find the next free alert dest,
|
||||||
|
elif pick_alert_dest "0.0.0.0"; then
|
||||||
|
[ "${1}" = "reset" ] && \
|
||||||
|
return $RETVAL
|
||||||
|
# set: the TRAPD_IP
|
||||||
|
set_alert_dest_ip "${TRAPD_IP}"
|
||||||
|
else
|
||||||
|
# No free alert destinations
|
||||||
|
RETVAL=9
|
||||||
|
fi
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
set_ipmi_alert()
|
||||||
|
{
|
||||||
|
${IPMITOOL} lan set ${CHANNEL} alert "${1}" >/dev/null 2>&1
|
||||||
|
[ $? -ne 0 ] && RETVAL=10
|
||||||
|
}
|
||||||
|
|
||||||
|
get_host_ip()
|
||||||
|
{
|
||||||
|
# Get host's IP that the BMC can reach.
|
||||||
|
IFACE=$(/usr/sbin/ip -o -f inet address |awk '!/: lo/ {print $2}')
|
||||||
|
for dev in ${IFACE}
|
||||||
|
do
|
||||||
|
ping -c 1 -I ${dev} ${BMC_IPv4} > /dev/null 2>&1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
config_bmc_alert()
|
||||||
|
{
|
||||||
|
# Get Host's IP that the BMC can send traps to
|
||||||
|
TRAPD_IP=$(get_host_ip)
|
||||||
|
|
||||||
|
# Set Host's IP as the alert destination in the BMC
|
||||||
|
valid_ip ${TRAPD_IP} && bmc_alert_dest "${ACTION}"
|
||||||
|
|
||||||
|
# Enable alerting on the LAN channel
|
||||||
|
[ $RETVAL -eq 0 ] && set_ipmi_alert "${ACTION}"
|
||||||
|
}
|
||||||
|
|
||||||
|
write_trapd_conf()
|
||||||
|
{
|
||||||
|
printf "###############################################\n"
|
||||||
|
printf "# Automatically created by %s #\n" "${SCRIPT_NAME}"
|
||||||
|
printf "forward %s %s\n" "${BMC_OID}*" "${FORWARD_HOST}"
|
||||||
|
printf "###############################################\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
config_trapd()
|
||||||
|
{
|
||||||
|
# Proceed only if snmptrapd is available on the system
|
||||||
|
if [ -f ${TRAPD_CONF} ]; then
|
||||||
|
write_trapd_conf > ${TRAPD_LOCAL_CONF}
|
||||||
|
[ $? -ne 0 ] && RETVAL=11
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
trap_sink_exists()
|
||||||
|
{
|
||||||
|
# TODO: We only set the first match. We should be able to set
|
||||||
|
# multiple
|
||||||
|
FORWARD_HOST=$(awk '/^trap.*sink/{print $2}; /^informsink/{print $2}' \
|
||||||
|
/etc/snmp/snmpd*conf | head -1)
|
||||||
|
if [ -z "${FORWARD_HOST}" ]; then
|
||||||
|
# there is no trapsink setup.
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Forward SNMP traps from the BMC to trapsink.
|
||||||
|
trap_forward()
|
||||||
|
{
|
||||||
|
NO_TRAP=0
|
||||||
|
ACTION=${1} # set or reset
|
||||||
|
|
||||||
|
if [ "${ACTION}" = "set" ]; then
|
||||||
|
# Get trapd config,
|
||||||
|
if trap_sink_exists; then
|
||||||
|
config_trapd && config_bmc_alert
|
||||||
|
else
|
||||||
|
# exit silently if there is no sink
|
||||||
|
NO_TRAP=1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ -f ${TRAPD_LOCAL_CONF} ]; then
|
||||||
|
rm -f ${TRAPD_LOCAL_CONF} >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
NO_TRAP=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
service_reload()
|
||||||
|
{
|
||||||
|
#TODO: do this in systemd
|
||||||
|
if [ ${RETVAL} -eq 0 ] && [ "${RELOAD_SERVICES}" = "yes" ]; then
|
||||||
|
service $1 reload
|
||||||
|
[ $? -ne 0 ] && RETVAL=6
|
||||||
|
fi
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
start()
|
||||||
|
{
|
||||||
|
if bmc_info_exists && check_snmp; then
|
||||||
|
touch ${LOCKFILE}
|
||||||
|
set_snmpd_conf_path && set_snmp_proxy
|
||||||
|
[ $RETVAL -eq 0 ] && service_reload snmpd
|
||||||
|
|
||||||
|
if [ "${TRAP_FORWARD}" = "yes" ]; then
|
||||||
|
trap_forward "set"
|
||||||
|
[ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \
|
||||||
|
service_reload snmptrapd
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
stop()
|
||||||
|
{
|
||||||
|
[ ! -f ${LOCKFILE} ] && return
|
||||||
|
if bmc_info_exists && check_snmp; then
|
||||||
|
disable_snmp_proxy
|
||||||
|
[ $RETVAL -eq 0 ] && service_reload snmpd
|
||||||
|
|
||||||
|
if [ "${TRAP_FORWARD}" = "yes" ]; then
|
||||||
|
trap_forward "reset"
|
||||||
|
[ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \
|
||||||
|
service_reload snmptrapd
|
||||||
|
fi
|
||||||
|
rm -f ${LOCKFILE}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
status()
|
||||||
|
{
|
||||||
|
eval_gettext "${SCRIPT_NAME}: snmp proxy to BMC is "
|
||||||
|
# Checking for lockfile is better.
|
||||||
|
#if grep -q "^proxy" "${SNMPD_LOCAL_CONF}" > /dev/null 2>&1 ; then
|
||||||
|
if [ -f ${LOCKFILE} ]; then
|
||||||
|
eval_gettext "set"
|
||||||
|
else
|
||||||
|
eval_gettext "not set"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
RETVAL=0
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
eval_gettext "Usage: $0 {start|stop|status}"; echo 1>&2
|
||||||
|
RETVAL=1
|
||||||
|
}
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# MAIN
|
||||||
|
#############################################################################
|
||||||
|
case "$1" in
|
||||||
|
start) start ;;
|
||||||
|
stop) stop ;;
|
||||||
|
status) status ;;
|
||||||
|
*) usage ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$RETVAL" in
|
||||||
|
0|1) ;;
|
||||||
|
2) eval_gettext "${SCRIPT_NAME}: failed to read ${BMC_INFO} " 1>&2 ;;
|
||||||
|
3) eval_gettext "${SCRIPT_NAME}: failed to get proxy config." 1>&2 ;;
|
||||||
|
4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_LOCAL_CONF}." 1>&2 ;;
|
||||||
|
5) eval_gettext "${SCRIPT_NAME}: failed to disable snmp proxy." 1>&2 ;;
|
||||||
|
6) eval_gettext "${SCRIPT_NAME}: failed to reload snmpd." 1>&2 ;;
|
||||||
|
7) eval_gettext "${SCRIPT_NAME}: failed to update ${SYSCONF}." 1>&2 ;;
|
||||||
|
8) eval_gettext "${SCRIPT_NAME}: failed to set IPMI alert dest." 1>&2 ;;
|
||||||
|
9) eval_gettext "${SCRIPT_NAME}: no free IPMI alert dest." 1>&2 ;;
|
||||||
|
10) eval_gettext "${SCRIPT_NAME}: failed to set IPMI PEF." 1>&2 ;;
|
||||||
|
11) eval_gettext "${SCRIPT_NAME}: failed to write snmptrapd.conf." 1>&2 ;;
|
||||||
|
12) eval_gettext "${SCRIPT_NAME}: snmpd not found." 1>&2 ;;
|
||||||
|
*) eval_gettext "${SCRIPT_NAME}: unknown error." 1>&2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ ${RETVAL} -gt 1 ]; then
|
||||||
|
eval_gettext " Return code: ${RETVAL}"; echo
|
||||||
|
fi
|
||||||
|
exit ${RETVAL}
|
||||||
|
#############################################################################
|
||||||
|
# end of file
|
||||||
|
#############################################################################
|
18
ipmitool/contrib/bmc-snmp-proxy.service
Normal file
18
ipmitool/contrib/bmc-snmp-proxy.service
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Setup SNMP proxy to BMC
|
||||||
|
|
||||||
|
After=exchange-bmc-os-info.service
|
||||||
|
Requires=exchange-bmc-os-info.service
|
||||||
|
PartOf=exchange-bmc-os-info.service
|
||||||
|
|
||||||
|
ConditionPathExists=/var/run/bmc-info
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
ExecStart=/usr/libexec/bmc-snmp-proxy start
|
||||||
|
ExecStop=/usr/libexec/bmc-snmp-proxy stop
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
48
ipmitool/contrib/bmc-snmp-proxy.sysconf
Normal file
48
ipmitool/contrib/bmc-snmp-proxy.sysconf
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
# bmc-snmp-proxy
|
||||||
|
#
|
||||||
|
# Config file to control SNMP redirection between
|
||||||
|
# the OS and Service Processor/Baseboard Management Controller (BMC)
|
||||||
|
#
|
||||||
|
# bmc-snnmp-proxy helps redirect certain SNMP requests (to this host)
|
||||||
|
# destined to the Service Processor. We will need the Service Processor's
|
||||||
|
# SNMP community string and the OID of the Service Processor's SNMP agent.
|
||||||
|
#
|
||||||
|
# For redirecting Traps from the Service Processor to the trap sink
|
||||||
|
# configured in the host (this system), we will have to set
|
||||||
|
# TRAP_FORWARD below.
|
||||||
|
#
|
||||||
|
# See here for details
|
||||||
|
# https://fedoraproject.org/wiki/Features/AgentFreeManagement
|
||||||
|
|
||||||
|
### Configure SNMP proxy to BMC/Service Processor ###
|
||||||
|
|
||||||
|
### Service Processor/BMC SNMP Community String.
|
||||||
|
# Name: BMC_COMMUNITY
|
||||||
|
# Description: Set community string of the Service Processor (BMC)'s
|
||||||
|
# SNMP agent.
|
||||||
|
# Default: public
|
||||||
|
#
|
||||||
|
BMC_COMMUNITY="public"
|
||||||
|
|
||||||
|
### OEM Specific OID of Service Processor
|
||||||
|
# Name: BMC_OID
|
||||||
|
# Description: SNMP OID that we would like to redirect to the Service
|
||||||
|
# Processor (BMC). This can be unique to each OEM.
|
||||||
|
# Default: ".1.3.6.1.4.1.674.10892.2"
|
||||||
|
BMC_OID=".1.3.6.1.4.1.674.10892.2" # Dell iDRAC
|
||||||
|
|
||||||
|
### Forward Traps from the Service Processor to trap sink
|
||||||
|
# Name: TRAP_FORWARD
|
||||||
|
# Description: Enabling this will allow traps from the Service Processor
|
||||||
|
# to be directed to this system and configure snmptrapd
|
||||||
|
# Note: This option will have no effect if trap sink on the system is
|
||||||
|
# not configured
|
||||||
|
# Default: "no"
|
||||||
|
TRAP_FORWARD="yes"
|
||||||
|
|
||||||
|
### Reload snmpd and snmptrapd
|
||||||
|
# Name: RELOAD_SERVICES
|
||||||
|
# Description: Reload snmpd and snmptrapd after making changes to their config
|
||||||
|
# files.
|
||||||
|
# Default: "yes"
|
||||||
|
RELOAD_SERVICES="yes"
|
Loading…
x
Reference in New Issue
Block a user