Files
shell_sequencer/seqs/snmp.sh

492 lines
14 KiB
Bash
Executable File

#!/bin/bash
seqDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >>/dev/null 2>&1 && pwd )"
toolName="snmpd"
toolConfigLoc="/etc/snmp"
toolConfig="${toolConfigLoc}/snmpd.conf"
toolSysUser="Debian-snmp"
step_1_info() { echo "Install packages for $toolName"; }
step_1_alias() { ALIAS="install"; }
step_1() {
exe apt update
if [ $QUIET != 0 ]; then
exe apt-get -qq install $toolName
else
exe apt install $toolName
fi
endReturn -o $? "$toolName installation failed"
}
step_2_info() {
echoinfoArgs "[-s]"
echo "Setup snmp v3 access"
echoinfo " -s : Stop after creating authentication entry"
}
step_2_alias() { ALIAS="v3access"; }
step_2() {
#
## Create authentication entry
exep "cat \"$v3AuthLoc\" | grep -e '^\s*usmUser'"
if [ "$?" == "0" ]; then
echoseq
exe read -p "User entry found. Continue: y/n(default)? " answer
case $answer in
[yY])
echoseq
echoseq "Continuing installation..."
;;
*)
echoseq
echoseq "Installation aborted"
return 1;
;;
esac
fi
read -p "SNMPv3 Username: " v3User
read -p "SNMPv3 Password: " v3Pass
echoseq
read -p "Repeat Password: " v3Pass2
if [ "$v3Pass" != "$v3Pass2" ] ; then
echoerr " [E] Password mismatch"
return 1
fi
echoseq
exe service snmpd stop
# this line will be replaced on start of snmpd with a line starting with:
# usmUser
v3AuthEntry="createUser ${v3User} SHA \"${v3Pass}\" DES"
addConf -a "$v3AuthEntry" "$v3AuthLoc"
shift
if [ ! -z $1 ] && [ "$1" == "-s" ] ; then
echoseq " [I] Stop after creating authentication config"
exe service snmpd start
return 0
fi
#
## Add custom base configuration
addConf -c "" "${toolConfig}"
exe cp "${seqDir}/snmpd.conf" "${toolConfig}"
#
## Add username as rouser
exe sed -i "s/authOnlyUser/${v3User}/" "$toolConfig"
#
## Write syslocation
exe read -p "sysLocation: " v3Location
exe read -p "sysContact (name <webmaster@example.com>): " v3Contact
exe sed -i "s/\(sysLocation\s*\).*/\1${v3Location}/" "$toolConfig"
exe sed -i "s/\(sysContact\s*\).*/\1${v3Contact}/" "$toolConfig"
exe service snmpd start
}
v3AuthLoc="/var/lib/snmp/snmpd.conf"
step_5_info() {
echoinfoArgs "[INTERFACE]"
echo "Add ufw rules for port 161 udp"
echoinfo " [INTERFACE] (default: eth0)"
}
step_5_alias() { ALIAS="ufw"; }
step_5() {
shift
local lInterface="eth0"
[ ! -z "$1" ] && lInterface="$1"
# Check if interface exists
ip -br a | grep -E "^$lInterface" >>/dev/null 2>&1
endReturn -o $? "Interface $lInterface does not exist"
exe ufw allow in on $lInterface to any port 161 proto udp comment "snmp"
}
step_20_info() { echo "Extend $toolName for Raspberry Pi"; }
step_20_alias() { ALIAS="raspberry"; }
step_20() {
checkExtend raspberry
if [ "$?" != "0" ]; then
return 1
fi
exe wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/raspberry.sh -O "${rpiExtendLoc}"
endReturn -o $? "Download failed"
exe chmod +x "$rpiExtendLoc"
addConf -a "extend raspberry /etc/snmp/raspberry.sh" "$toolConfig"
# VCHI initialization failed fix
exe usermod -aG video ${toolSysUser}
addConf -s "$rpiSudoersContent" "$rpiSudoersLoc"
exe service snmpd restart
}
rpiExtendLoc="${toolConfigLoc}/raspberry.sh"
rpiSudoersLoc="/etc/sudoers.d/snmprpi"
rpiSudoersContent="${toolSysUser} ALL=(ALL) NOPASSWD: /etc/snmp/raspberry.sh, /usr/bin/vcgencmd*"
step_22_info() { echo "Extend $toolName with OS update availablity"; }
step_22_alias() { ALIAS="osupdate"; }
step_22() {
checkExtend osupdate
if [ "$?" != "0" ]; then
return 1
fi
exe wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/osupdate -O "${osUpdateExtendLoc}"
endReturn -o $? "Download failed"
exe chmod +x "$osUpdateExtendLoc"
addConf -a "extend osupdate $osUpdateExtendLoc" "$toolConfig"
exe service snmpd restart
}
osUpdateExtendLoc="${toolConfigLoc}/osupdate"
step_23_info() { echo "Create cron job for periodical (every 8 hours) apt-get update"; }
step_23() {
addConf -s "$osUpdateCronContent" "$osUpdateCron"
}
osUpdateCron="/etc/cron.d/aptUpdate"
osUpdateCronContent="22 */6 * * * root /usr/bin/apt-get -qq update"
step_25_info() { echo "Prepare nginx to provide php-fpm status to $toolName"; }
step_25_alias() { ALIAS="phpfpm"; }
step_25() {
echo -e "\n [!] Please add the following to your default server:\n"
echo "$phpFpmStatusNginx"
echo
if [ $QUIET -ne 0 ] ; then
answer=n
else
exe read -p "Open new shell to configure y/[n]? " answer
fi
case $answer in
[yY])
echoseq " [I] Opening interactive shell. Type \"exit\" to return to this script."
exe bash -i
echoseq " [I] Interactive shell ended. Continuing with $0."
exe nginx -t
endReturn -o $? "Nginx configuration error"
exe service nginx restart
;;
*)
;;
esac
}
# TODO error when no php is installed
phpVersionStr="$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')"
phpFpmStatusNginx="# Provide php-fpm status
location ~ ^/(status|ping)\$ {
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php/php${phpVersionStr}-fpm.sock;
}"
step_26_info() { echo "Prepare php config for php-fpm status"; }
step_26_alias() { ALIAS="phpfpm_config"; }
step_26() {
exe sed -i "s/^;\(pm\.status_path\)/\1/" "$phpPoolConfigLoc"
exe php-fpm${phpVersionStr} -t
endReturn -o $? "Invalid php configuration"
service php${phpVersionStr}-fpm restart
}
phpConfigDir="/etc/php/${phpVersionStr}"
phpPoolConfigLoc="${phpConfigDir}/fpm/pool.d/www.conf"
step_27_info() { echo "Extend $toolName with parsing of php-fpm status"; }
step_27_alias() { ALIAS="phpfpm_extend"; }
step_27() {
checkExtend phpfpmsp
if [ "$?" != "0" ]; then
return 1
fi
exe wget https://github.com/librenms/librenms-agent/raw/master/snmp/phpfpmsp -O "${phpfpmExtendLoc}"
endReturn -o $? "Download failed"
exe chmod +x "$phpfpmExtendLoc"
addConf -a "extend phpfpmsp ${phpfpmExtendLoc}" "$toolConfig"
exe service snmpd restart
}
phpfpmExtendLoc="${toolConfigLoc}/phpfpmsp"
step_29_info() { echo "Prepare nginx to provide status to $toolName"; }
step_29_alias() { ALIAS="nginx"; }
step_29() {
echoseq -e "\n [!] Please add the following to your default server:\n"
echoseq "$nginxStatus"
echoseq
if [ $QUIET -ne 0 ] ; then
answer=n
else
exe read -p "Open new shell to configure y/[n]? " answer
fi
case $answer in
[yY])
echoseq " [I] Opening interactive shell. Type \"exit\" to return to this script."
exe bash -i
echoseq " [I] Interactive shell ended. Continuing with $0."
exe nginx -t
endReturn -o $? "Nginx configuration error"
exe service nginx restart
;;
*)
;;
esac
}
nginxStatus="# Provide nginx status
location /nginx-status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
}
"
step_30_info() { echo "Extend $toolName with parsing of nginx status"; }
step_30_alias() { ALIAS="nginx_extend"; }
step_30() {
checkExtend nginx
if [ "$?" != "0" ]; then
return 1
fi
exe wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/nginx -O "${nginxExtendLoc}"
endReturn -o $? "Download failed"
exe chmod +x "$nginxExtendLoc"
addConf -a "extend nginx ${nginxExtendLoc}" "$toolConfig"
exe service snmpd restart
}
nginxExtendLoc="${toolConfigLoc}/nginx"
# postfix
step_32_info() { echo "Extend for postfix detailed and queue"; }
step_32_alias() { ALIAS="postfix"; }
step_32() {
local aptOpt=
if [ $QUIET -ne 0 ];then
aptOpt="-y"
fi
exe wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfix-queues -O "${postfixQueuesExtendLoc}"
endReturn -o $? "Download postfix-queues failed"
exe wget https://github.com/librenms/librenms-agent/raw/master/snmp/postfixdetailed -O "${postfixScript}"
endReturn -o $? "Download postfixdetailed failed"
exe chmod +x "${postfixQueuesExtendLoc}"
exe chmod +x "${postfixScript}"
exe apt install $postfixDeps $aptOpt
}
postfixDeps="pflogsumm"
step_33_info() { echo "Prepare cache folder for postfixdetailed"; }
step_33() {
exe touch "$postfixCacheLoc"
exe chown root:$toolSysUser "$postfixCacheLoc"
exe chmod 770 "$postfixCacheLoc"
echoseq " [I] Create symlink /var/log/maillog which is used by postfixdetailed"
exe ln -fs /var/log/mail.log /var/log/maillog
echoseq " [I] Run /etc/snmp/postfixdetailed to create the initial cache file"
echoseq " so you don't end up with some crazy initial starting value."
exe sudo -u $toolSysUser "$postfixScript"
}
postfixCacheLoc="/var/cache/postfixdetailed"
postfixScript="${toolConfigLoc}/postfixdetailed"
postfixQueuesExtendLoc="${toolConfigLoc}/postfix-queues"
step_34_info() { echo "Create sudoers file for postfix scripts"; }
step_34() {
addConf -s "$postfixSudoersContent" "$postfixSudoersLoc"
echoseq " [I] Changing ${postfixQueuesExtendLoc} to add sudo for qshape"
exe sed -i -E "s/\`qshape/\`sudo qshape/" "${postfixQueuesExtendLoc}"
echoseq " [W] Reboot may be required to make these changes active"
}
postfixSudoersLoc="/etc/sudoers.d/snmppostfix"
postfixSudoersContent="${toolSysUser} ALL=(ALL) NOPASSWD: /usr/sbin/qshape"
step_35_info() { echo "Create postfix extends (postfixdetailed and postfix-queues)"; }
step_35() {
checkExtend postfix-queues
if [ $? -eq 0 ]; then
echoseq " [I] Create postfix-queues extend"
addConf -a "extend mailq ${postfixQueuesExtendLoc}" "$toolConfig"
fi
checkExtend postfixdetailed
if [ $? -eq 0 ]; then
echoseq " [I] Create postfixdetailed extend"
addConf -a "extend postfixdetailed ${postfixScript}" "$toolConfig"
fi
exe service snmpd restart
}
#fail2ban
step_37_info() { echo "Extend for fail2ban jail information"; }
step_37_alias() { ALIAS="fail2ban"; }
step_37(){
local aptOpt=
if [ $QUIET -ne 0 ];then
aptOpt="-y"
fi
exe wget https://github.com/librenms/librenms-agent/raw/master/snmp/fail2ban -O "${fail2banExtendLoc}"
endReturn -o $? "Download postfix failed"
exe chmod +x "$fail2banExtendLoc"
checkExtend fail2ban
if [ $? -eq 0 ]; then
echoseq " [I] Create fail2ban extend"
addConf -a "extend fail2ban ${fail2banExtendLoc} -c" "$toolConfig"
fi
exe apt install $fail2banDeps $aptOpt
}
fail2banDeps="libjson-perl"
fail2banExtendLoc="${toolConfigLoc}/fail2ban"
step_38_info() { echo "Create cron to update fail2ban cache"; }
step_38() {
addConf -s "$fail2banCron" "$fail2banCronLoc"
}
fail2banCronLoc="/etc/cron.d/fail2banCache"
fail2banCron="# Update cache for faster fail2ban polling
*/3 * * * * root ${fail2banExtendLoc} -u"
step_40_info() { echo "Create linux distribution detection extend (distro)"; }
step_40_alias() { ALIAS="distro"; }
step_40() {
checkExtend distro
if [ $? -ne 0 ]; then
return 0
fi
exe wget https://raw.githubusercontent.com/librenms/librenms-agent/master/snmp/distro -O "${distroExtendLoc}"
endReturn -o $? "Download distro detection script failed"
exe chmod +x "$distroExtendLoc"
echoseq " [I] Create distro extend"
addConf -a "extend distro ${distroExtendLoc}" "$toolConfig"
exe service snmpd restart
}
distroExtendLoc="${toolConfigLoc}/distro"
step_42_info() {
echo "Gather dhcp information from a dhcpd lease file"
echoinfo "pi-hole lease file not supported"
}
step_42_alias() { ALIAS="dhcp"; }
step_42() {
local locExtName="dhcpstats"
local locExtUrl="https://github.com/librenms/librenms-agent/raw/master/snmp/dhcp.py"
local locExtLoc="${toolConfigLoc}/dhcp.py"
checkExtend $locExtName
[ $? -ne 0 ] && return 0
exe apt install dhcpd-pools
endReturn -o $? "Install dhcpd-pools failed"
exe wget $locExtUrl -O "${locExtLoc}"
endReturn -o $? "Download $locExtName script failed"
exe chmod +x "$locExtLoc"
echoseq " [I] Create extend for $locExtName"
addConf -a "extend $locExtName ${locExtLoc}" "$toolConfig"
echoseq " [I] Create config for $locExtName"
addConf -s "$dhcpExtendConfig" "$dhcpExtendConfigLoc"
echo " [W] Adapt config $dhcpExtendConfigLoc manually and restart snmpd"
}
dhcpExtendConfigLoc="${toolConfigLoc}/dhcp.json"
dhcpExtendConfig="{\"leasefile\": \"/var/lib/dhcp/dhcpd.leases\"
}"
step_44_info() { echo "Extend unbound stats"; }
step_44_alias() { ALIAS="unbound"; }
step_44() {
local locExtName="unbound"
local locExtUrl="https://github.com/librenms/librenms-agent/raw/master/snmp/unbound"
local locExtLoc="${toolConfigLoc}/unbound"
checkExtend $locExtName
[ $? -ne 0 ] && return 0
exe wget $locExtUrl -O "${locExtLoc}"
endReturn -o $? "Download $locExtName script failed"
exe chmod +x "$locExtLoc"
echoseq " [I] Create extend for $locExtName"
addConf -a "extend /usr/bin/sudo $locExtName ${locExtLoc}" "$toolConfig"
echoseq " [I] Create config for $locExtName"
addConf -s "$unboundExtendConfig" "$unboundExtendConfigLoc"
exe systemctl restart unbound.service
exe systemctl restart snmpd.service
}
unboundExtendConfigLoc="/etc/unbound/unbound.conf.d/extended-stats.conf"
unboundExtendConfig=$(cat <<UB_EOF
# Enable extended statistics
server:
extended-statistics: yes
statistics-cumulative: yes
remote-control:
control-enable: yes
control-interface: 127.0.0.1
UB_EOF
)
step_45_info() { echo "Set sudoers file to execute unbount-control"; }
step_45() {
addConf -s "$unboundSudoer" "$unboundSudoerLoc"
}
unboundSudoerLoc="/etc/sudoers.d/snmpunbound"
unboundSudoer="Debian-snmp ALL=(ALL) NOPASSWD: /usr/sbin/unbound-control, ${toolConfigLoc}/unbound"
checkExtend() {
# adding dry run output for clarification
if [ $DRY -ne 0 ] ; then
echoseq " [I] check if \"extend ${1}\" exists..dry-run"
fi
exep "cat \"$toolConfig\" | grep -e '^\s*extend\s\+${1}' >>/dev/null 2>&1"
# Only warn if entry exists and dry-run is not seleted
if [ $? -eq 0 ] && [ $DRY -eq 0 ] ; then
return 1
fi
return 0
}
VERSION_SEQREV=14
. /usr/local/bin/sequencer.sh