Set up comprehensive SNMP trap monitoring with snmptrapd, automated alerting via email and webhooks, and integration with monitoring platforms like Nagios and Zabbix for proactive network management and real-time issue detection.
Prerequisites
- Root access
- Basic SNMP knowledge
- Network devices that support SNMP traps
- Email server (postfix) for notifications
What this solves
SNMP trap monitoring provides proactive network management by receiving and processing unsolicited notifications from network devices when events occur. This tutorial sets up a complete trap monitoring system with Net-SNMP 5.9, automated alerting through multiple channels, and integration with existing monitoring platforms for comprehensive network visibility.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions of SNMP packages.
sudo apt update && sudo apt upgrade -yInstall SNMP packages and MIB tools
Install Net-SNMP daemon, utilities, and MIB management tools for comprehensive trap handling.
sudo apt install -y snmp snmp-mibs-downloader snmptrapd postfix mailutils curl jqCreate trap handler directory structure
Set up directories for trap handlers, logs, and configuration files with proper permissions.
sudo mkdir -p /etc/snmp/traphandlers
sudo mkdir -p /var/log/snmp/traps
sudo mkdir -p /var/lib/snmp/trapdb
sudo chown -R snmp:snmp /var/log/snmp
sudo chown -R snmp:snmp /var/lib/snmp
sudo chmod 755 /etc/snmp/traphandlersConfigure snmptrapd daemon
Create the main snmptrapd configuration file with trap receiving settings and handler definitions.
# SNMP Trap Daemon Configuration
Listen on all interfaces, port 162 (standard SNMP trap port)
snmpTrapdAddr udp:162,udp6:162
Authentication settings
disableAuthorization yes
Logging configuration
logOption s 6
logTimestamp yes
Output format for traps
format1 %.4y-%.2m-%.2l %.2h:%.2j:%.2k [%B] %N: %W\n\t%V\n
format2 %.4y-%.2m-%.2l %.2h:%.2j:%.2k [%B] %N: Enterprise Specific Trap (%w) Uptime: %#T\n\t%v\n
Trap handlers for different trap types
traphandle default /etc/snmp/traphandlers/default_handler.sh
traphandle SNMPv2-MIB::coldStart /etc/snmp/traphandlers/system_handler.sh
traphandle SNMPv2-MIB::warmStart /etc/snmp/traphandlers/system_handler.sh
traphandle SNMPv2-MIB::linkDown /etc/snmp/traphandlers/interface_handler.sh
traphandle SNMPv2-MIB::linkUp /etc/snmp/traphandlers/interface_handler.sh
traphandle SNMPv2-MIB::authenticationFailure /etc/snmp/traphandlers/security_handler.sh
Create PID file
pidFile /var/run/snmptrapd.pid
Run as snmp user
agentuser snmpCreate default trap handler script
Build the main trap processing script that logs all traps and triggers alert mechanisms.
#!/bin/bash
Default SNMP Trap Handler
Processes all incoming SNMP traps and triggers alerts
TRAP_LOG="/var/log/snmp/traps/default.log"
ALERT_CONFIG="/etc/snmp/alert_config.conf"
TRAP_DB="/var/lib/snmp/trapdb/traps.db"
Source alerting configuration
if [ -f "$ALERT_CONFIG" ]; then
source "$ALERT_CONFIG"
fi
Get trap information from environment variables
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
OID="${SNMP_COMMAND}"
UPTIME="${SNMP_ARG2:-Unknown}"
TRAP_OID="${SNMP_ARG3:-Unknown}"
Read all trap variables
TRAP_DATA=""
while read line; do
TRAP_DATA+="$line\n"
done
Log trap to file
echo "[$TRAP_TIME] Source: $SOURCE_IP, OID: $TRAP_OID" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
Store in simple database for tracking
echo "$TRAP_TIME|$SOURCE_IP|$TRAP_OID|$(echo -e "$TRAP_DATA" | tr '\n' ' ')" >> "$TRAP_DB"
Determine trap severity
SEVERITY="INFO"
case "$TRAP_OID" in
coldStart|warmStart)
SEVERITY="WARNING"
;;
linkDown|authenticationFailure)
SEVERITY="CRITICAL"
;;
linkUp)
SEVERITY="INFO"
;;
esac
Send alerts based on severity
if [ "$SEVERITY" = "CRITICAL" ] || [ "$SEVERITY" = "WARNING" ]; then
/etc/snmp/traphandlers/send_alert.sh "$SEVERITY" "$SOURCE_IP" "$TRAP_OID" "$TRAP_DATA"
fi
exit 0sudo chmod 755 /etc/snmp/traphandlers/default_handler.shCreate specialized trap handlers
Create specific handlers for different types of network events with targeted processing logic.
#!/bin/bash
System Event Trap Handler (coldStart, warmStart)
TRAP_LOG="/var/log/snmp/traps/system.log"
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
Read trap data
TRAP_DATA=""
while read line; do
TRAP_DATA+="$line\n"
done
Determine event type
EVENT_TYPE="System Event"
if [[ "$SNMP_ARG3" == "coldStart" ]]; then
EVENT_TYPE="System Cold Start"
elif [[ "$SNMP_ARG3" == "warmStart" ]]; then
EVENT_TYPE="System Warm Start"
fi
Log system event
echo "[$TRAP_TIME] $EVENT_TYPE from $SOURCE_IP" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
Trigger system event alert
/etc/snmp/traphandlers/send_alert.sh "WARNING" "$SOURCE_IP" "$EVENT_TYPE" "Device restarted: $TRAP_DATA"
exit 0#!/bin/bash
Interface Event Trap Handler (linkUp, linkDown)
TRAP_LOG="/var/log/snmp/traps/interface.log"
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
Read trap data
TRAP_DATA=""
INTERFACE_ID="Unknown"
while read line; do
TRAP_DATA+="$line\n"
# Extract interface ID if present
if [[ "$line" == "ifIndex" ]]; then
INTERFACE_ID=$(echo "$line" | grep -o '[0-9]\+' | head -1)
fi
done
Determine link status
LINK_STATUS="Unknown"
SEVERITY="INFO"
if [[ "$SNMP_ARG3" == "linkDown" ]]; then
LINK_STATUS="Link Down"
SEVERITY="CRITICAL"
elif [[ "$SNMP_ARG3" == "linkUp" ]]; then
LINK_STATUS="Link Up"
SEVERITY="INFO"
fi
Log interface event
echo "[$TRAP_TIME] $LINK_STATUS on interface $INTERFACE_ID from $SOURCE_IP" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
Send alert for link down events
if [ "$SEVERITY" = "CRITICAL" ]; then
/etc/snmp/traphandlers/send_alert.sh "$SEVERITY" "$SOURCE_IP" "Interface Down" "Interface $INTERFACE_ID is down on device $SOURCE_IP"
fi
exit 0#!/bin/bash
Security Event Trap Handler (authenticationFailure)
TRAP_LOG="/var/log/snmp/traps/security.log"
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
Read trap data
TRAP_DATA=""
while read line; do
TRAP_DATA+="$line\n"
done
Log security event
echo "[$TRAP_TIME] SECURITY ALERT: Authentication failure from $SOURCE_IP" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
Always send critical alert for security events
/etc/snmp/traphandlers/send_alert.sh "CRITICAL" "$SOURCE_IP" "Authentication Failure" "SNMP authentication failure detected from $SOURCE_IP"
exit 0sudo chmod 755 /etc/snmp/traphandlers/*.shCreate alert configuration and sender script
Configure email and webhook alert settings with the alert dispatch script.
# SNMP Trap Alert Configuration
Email settings
EMAIL_ENABLED=true
EMAIL_TO="admin@example.com"
EMAIL_FROM="snmp-monitor@example.com"
EMAIL_SUBJECT_PREFIX="[SNMP Alert]"
Webhook settings
WEBHOOK_ENABLED=true
WEBHOOK_URL="https://hooks.example.com/snmp-alerts"
WEBHOOK_SECRET="your-webhook-secret-here"
Slack webhook (optional)
SLACK_ENABLED=false
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK"
Alert throttling (seconds between duplicate alerts)
ALERT_THROTTLE=300
Log settings
ALERT_LOG="/var/log/snmp/traps/alerts.log"#!/bin/bash
SNMP Trap Alert Sender
Sends alerts via email, webhook, and other channels
ALERT_CONFIG="/etc/snmp/alert_config.conf"
THROTTLE_FILE="/var/lib/snmp/trapdb/alert_throttle"
Source configuration
if [ -f "$ALERT_CONFIG" ]; then
source "$ALERT_CONFIG"
else
echo "Alert configuration not found: $ALERT_CONFIG"
exit 1
fi
SEVERITY="$1"
SOURCE_IP="$2"
EVENT_TYPE="$3"
MESSAGE="$4"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
Throttle duplicate alerts
ALERT_KEY="${SOURCE_IP}_${EVENT_TYPE}"
if [ -f "$THROTTLE_FILE" ]; then
LAST_ALERT=$(grep "^$ALERT_KEY" "$THROTTLE_FILE" | cut -d'|' -f2)
if [ -n "$LAST_ALERT" ]; then
TIME_DIFF=$(($(date +%s) - $LAST_ALERT))
if [ $TIME_DIFF -lt $ALERT_THROTTLE ]; then
echo "[$TIMESTAMP] Alert throttled: $ALERT_KEY" >> "$ALERT_LOG"
exit 0
fi
fi
fi
Update throttle file
grep -v "^$ALERT_KEY" "$THROTTLE_FILE" 2>/dev/null > "${THROTTLE_FILE}.tmp" || touch "${THROTTLE_FILE}.tmp"
echo "$ALERT_KEY|$(date +%s)" >> "${THROTTLE_FILE}.tmp"
mv "${THROTTLE_FILE}.tmp" "$THROTTLE_FILE"
Log alert
echo "[$TIMESTAMP] Sending $SEVERITY alert for $SOURCE_IP: $EVENT_TYPE" >> "$ALERT_LOG"
Send email alert
if [ "$EMAIL_ENABLED" = "true" ]; then
EMAIL_BODY="SNMP Trap Alert\n\nSeverity: $SEVERITY\nSource: $SOURCE_IP\nEvent: $EVENT_TYPE\nTime: $TIMESTAMP\n\nDetails:\n$MESSAGE"
echo -e "$EMAIL_BODY" | mail -s "$EMAIL_SUBJECT_PREFIX $SEVERITY - $EVENT_TYPE from $SOURCE_IP" "$EMAIL_TO"
fi
Send webhook alert
if [ "$WEBHOOK_ENABLED" = "true" ] && [ -n "$WEBHOOK_URL" ]; then
WEBHOOK_PAYLOAD=$(cat <Send Slack alert
if [ "$SLACK_ENABLED" = "true" ] && [ -n "$SLACK_WEBHOOK_URL" ]; then
SLACK_COLOR="good"
case "$SEVERITY" in
"CRITICAL") SLACK_COLOR="danger" ;;
"WARNING") SLACK_COLOR="warning" ;;
esac
SLACK_PAYLOAD=$(cat < sudo chmod 755 /etc/snmp/traphandlers/send_alert.shConfigure Nagios integration
Create Nagios passive check integration for SNMP trap events.
#!/bin/bash
Nagios SNMP Trap Integration
Sends passive check results to Nagios based on trap events
NAGIOS_COMMAND_FILE="/var/lib/nagios3/rw/nagios.cmd"
NAGIOS_CONFIG="/etc/snmp/nagios_trap_config.conf"
Source Nagios configuration
if [ -f "$NAGIOS_CONFIG" ]; then
source "$NAGIOS_CONFIG"
else
# Default settings
NAGIOS_ENABLED=false
NAGIOS_SERVICE_PREFIX="SNMP_"
fi
if [ "$NAGIOS_ENABLED" != "true" ]; then
exit 0
fi
SOURCE_IP="$1"
EVENT_TYPE="$2"
SEVERITY="$3"
MESSAGE="$4"
Map severity to Nagios states
NAGIOS_STATE=0
case "$SEVERITY" in
"CRITICAL") NAGIOS_STATE=2 ;;
"WARNING") NAGIOS_STATE=1 ;;
"INFO") NAGIOS_STATE=0 ;;
esac
Create service name
SERVICE_NAME="${NAGIOS_SERVICE_PREFIX}${EVENT_TYPE}"
Map IP to hostname if configured
HOSTNAME="$SOURCE_IP"
if [ -f "/etc/snmp/ip_hostname_map.conf" ]; then
MAPPED_HOST=$(grep "^$SOURCE_IP" /etc/snmp/ip_hostname_map.conf | cut -d' ' -f2)
if [ -n "$MAPPED_HOST" ]; then
HOSTNAME="$MAPPED_HOST"
fi
fi
Submit passive check result
TIMESTAMP=$(date +%s)
echo "[$TIMESTAMP] PROCESS_SERVICE_CHECK_RESULT;$HOSTNAME;$SERVICE_NAME;$NAGIOS_STATE;$MESSAGE" >> "$NAGIOS_COMMAND_FILE"
exit 0# Nagios SNMP Trap Integration Configuration
NAGIOS_ENABLED=true
NAGIOS_SERVICE_PREFIX="SNMP_"
Command file location (check your Nagios installation)
NAGIOS_COMMAND_FILE="/var/lib/nagios3/rw/nagios.cmd"# IP to Hostname mapping for Nagios integration
Format: IP_ADDRESS HOSTNAME
203.0.113.10 router-01
203.0.113.11 switch-01
203.0.113.12 server-01sudo chmod 755 /etc/snmp/traphandlers/nagios_integration.shCreate Zabbix integration script
Build Zabbix integration for trap data using zabbix_sender utility.
#!/bin/bash
Zabbix SNMP Trap Integration
Sends trap data to Zabbix server using zabbix_sender
ZABBIX_CONFIG="/etc/snmp/zabbix_trap_config.conf"
Source Zabbix configuration
if [ -f "$ZABBIX_CONFIG" ]; then
source "$ZABBIX_CONFIG"
else
# Default settings
ZABBIX_ENABLED=false
ZABBIX_SERVER="127.0.0.1"
ZABBIX_PORT=10051
fi
if [ "$ZABBIX_ENABLED" != "true" ]; then
exit 0
fi
SOURCE_IP="$1"
EVENT_TYPE="$2"
SEVERITY="$3"
MESSAGE="$4"
Map IP to Zabbix hostname if configured
ZABBIX_HOST="$SOURCE_IP"
if [ -f "/etc/snmp/zabbix_host_map.conf" ]; then
MAPPED_HOST=$(grep "^$SOURCE_IP" /etc/snmp/zabbix_host_map.conf | cut -d' ' -f2)
if [ -n "$MAPPED_HOST" ]; then
ZABBIX_HOST="$MAPPED_HOST"
fi
fi
Create trap item key
ITEM_KEY="snmp.trap[${EVENT_TYPE}]"
Send data to Zabbix
echo "$ZABBIX_HOST $ITEM_KEY $MESSAGE" | zabbix_sender -z "$ZABBIX_SERVER" -p "$ZABBIX_PORT" -T -i - >/dev/null 2>&1
Send trap count metric
COUNT_KEY="snmp.trap.count[${EVENT_TYPE}]"
echo "$ZABBIX_HOST $COUNT_KEY 1" | zabbix_sender -z "$ZABBIX_SERVER" -p "$ZABBIX_PORT" -T -i - >/dev/null 2>&1
exit 0# Zabbix SNMP Trap Integration Configuration
ZABBIX_ENABLED=true
ZABBIX_SERVER="203.0.113.100"
ZABBIX_PORT=10051# IP to Zabbix Hostname mapping
Format: IP_ADDRESS ZABBIX_HOSTNAME
203.0.113.10 Router-Office-01
203.0.113.11 Switch-Floor-01
203.0.113.12 Server-Web-01Install Zabbix sender utility
Install zabbix_sender for sending trap data to Zabbix server.
sudo apt install -y zabbix-senderUpdate trap handlers with integrations
Modify the main trap handlers to call monitoring system integrations.
sudo cp /etc/snmp/traphandlers/default_handler.sh /etc/snmp/traphandlers/default_handler.sh.backup#!/bin/bash
Enhanced Default SNMP Trap Handler with Monitoring Integration
TRAP_LOG="/var/log/snmp/traps/default.log"
ALERT_CONFIG="/etc/snmp/alert_config.conf"
TRAP_DB="/var/lib/snmp/trapdb/traps.db"
Source alerting configuration
if [ -f "$ALERT_CONFIG" ]; then
source "$ALERT_CONFIG"
fi
Get trap information from environment variables
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
OID="${SNMP_COMMAND}"
UPTIME="${SNMP_ARG2:-Unknown}"
TRAP_OID="${SNMP_ARG3:-Unknown}"
Read all trap variables
TRAP_DATA=""
while read line; do
TRAP_DATA+="$line\n"
done
Log trap to file
echo "[$TRAP_TIME] Source: $SOURCE_IP, OID: $TRAP_OID" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
Store in simple database for tracking
echo "$TRAP_TIME|$SOURCE_IP|$TRAP_OID|$(echo -e "$TRAP_DATA" | tr '\n' ' ')" >> "$TRAP_DB"
Determine trap severity and event type
SEVERITY="INFO"
EVENT_TYPE="Generic"
case "$TRAP_OID" in
coldStart)
SEVERITY="WARNING"
EVENT_TYPE="ColdStart"
;;
warmStart)
SEVERITY="WARNING"
EVENT_TYPE="WarmStart"
;;
linkDown)
SEVERITY="CRITICAL"
EVENT_TYPE="LinkDown"
;;
linkUp)
SEVERITY="INFO"
EVENT_TYPE="LinkUp"
;;
authenticationFailure)
SEVERITY="CRITICAL"
EVENT_TYPE="AuthFailure"
;;
esac
Send alerts based on severity
if [ "$SEVERITY" = "CRITICAL" ] || [ "$SEVERITY" = "WARNING" ]; then
/etc/snmp/traphandlers/send_alert.sh "$SEVERITY" "$SOURCE_IP" "$EVENT_TYPE" "$TRAP_DATA"
fi
Send to monitoring systems
/etc/snmp/traphandlers/nagios_integration.sh "$SOURCE_IP" "$EVENT_TYPE" "$SEVERITY" "$(echo -e "$TRAP_DATA" | head -1)" &
/etc/snmp/traphandlers/zabbix_integration.sh "$SOURCE_IP" "$EVENT_TYPE" "$SEVERITY" "$(echo -e "$TRAP_DATA" | head -1)" &
exit 0Configure systemd service
Create and configure the systemd service for snmptrapd with proper security settings.
[Unit]
Description=Net-SNMP Trap Daemon
After=network.target
Wants=network.target
[Service]
Type=forking
PIDFile=/var/run/snmptrapd.pid
ExecStart=/usr/sbin/snmptrapd -Lsd -p /var/run/snmptrapd.pid
ExecReload=/bin/kill -HUP $MAINPID
User=snmp
Group=snmp
Restart=on-failure
RestartSec=5
Security settings
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/log/snmp /var/lib/snmp /var/run
[Install]
WantedBy=multi-user.targetConfigure firewall for SNMP traps
Open UDP port 162 for incoming SNMP trap traffic.
sudo ufw allow 162/udp comment 'SNMP Traps'
sudo ufw reloadCreate log rotation configuration
Set up log rotation to prevent trap logs from consuming excessive disk space.
/var/log/snmp/traps/*.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
create 644 snmp snmp
postrotate
if [ -f /var/run/snmptrapd.pid ]; then
/bin/kill -HUP cat /var/run/snmptrapd.pid
fi
endscript
}Enable and start the service
Enable snmptrapd to start automatically and start the service.
sudo systemctl daemon-reload
sudo systemctl enable snmptrapd
sudo systemctl start snmptrapd
sudo systemctl status snmptrapdConfigure alert settings
Update alert configuration
Customize the alert configuration file with your specific email and webhook settings.
sudo nano /etc/snmp/alert_config.confUpdate the EMAIL_TO, WEBHOOK_URL, and other settings according to your environment. The system needs a working mail server for email alerts. You can learn more about comprehensive monitoring setups in our Nagios SNMP monitoring guide.
Test email configuration
Verify that email alerts are working properly with the mail system.
echo "Test email from SNMP trap system" | mail -s "SNMP Test Alert" admin@example.comVerify your setup
sudo systemctl status snmptrapd
sudo netstat -ulnp | grep :162
sudo tail -f /var/log/snmp/traps/default.logTest trap reception by sending a test trap from another system:
snmptrap -v2c -c public localhost '' 1.3.6.1.4.1.8072.2.3.0.1 1.3.6.1.4.1.8072.2.3.2.1 i 42Check trap handler permissions and logs:
ls -la /etc/snmp/traphandlers/
sudo tail -20 /var/log/snmp/traps/alerts.log
wc -l /var/lib/snmp/trapdb/traps.dbIntegration with monitoring systems
For Nagios integration, ensure your Nagios configuration includes passive service definitions for SNMP trap events. For comprehensive Zabbix monitoring, check our Zabbix network automation guide. Configure your network devices to send traps to your monitoring server's IP address on port 162.
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| snmptrapd won't start | Configuration syntax error | sudo snmptrapd -f -Lo -c /etc/snmp/snmptrapd.conf to check config |
| No traps received | Firewall blocking port 162 | Check firewall rules and open UDP port 162 |
| Permission denied errors | Incorrect file permissions | sudo chown -R snmp:snmp /var/log/snmp /var/lib/snmp |
| Handler scripts not executing | Scripts not executable or wrong path | sudo chmod 755 /etc/snmp/traphandlers/*.sh |
| Email alerts not working | Postfix not configured | Configure postfix: sudo dpkg-reconfigure postfix |
| Webhook alerts failing | Network connectivity or wrong URL | Test with curl: curl -X POST $WEBHOOK_URL |
Next steps
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m'
# Global variables
SCRIPT_NAME=$(basename "$0")
SNMP_USER="snmp"
TRAP_PORT="162"
usage() {
echo "Usage: $SCRIPT_NAME [--email email@domain.com] [--webhook-url http://webhook.url]"
echo " --email Email address for trap alerts"
echo " --webhook-url Webhook URL for notifications"
exit 1
}
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
cleanup_on_error() {
log_error "Installation failed. Cleaning up..."
systemctl stop snmptrapd 2>/dev/null || true
rm -rf /etc/snmp/traphandlers 2>/dev/null || true
}
trap cleanup_on_error ERR
parse_args() {
EMAIL=""
WEBHOOK_URL=""
while [[ $# -gt 0 ]]; do
case $1 in
--email)
EMAIL="$2"
shift 2
;;
--webhook-url)
WEBHOOK_URL="$2"
shift 2
;;
-h|--help)
usage
;;
*)
log_error "Unknown option: $1"
usage
;;
esac
done
}
detect_distro() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
SNMP_PACKAGES="snmp snmp-mibs-downloader snmptrapd postfix mailutils curl jq"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
SNMP_PACKAGES="net-snmp net-snmp-utils postfix mailx curl jq"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
SNMP_PACKAGES="net-snmp net-snmp-utils postfix mailx curl jq"
;;
*)
log_error "Unsupported distro: $ID"
exit 1
;;
esac
else
log_error "Cannot detect distribution"
exit 1
fi
}
check_prerequisites() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root"
exit 1
fi
if ! command -v systemctl &> /dev/null; then
log_error "systemd is required"
exit 1
fi
}
install_packages() {
echo "[2/8] Installing SNMP packages..."
$PKG_UPDATE
$PKG_INSTALL $SNMP_PACKAGES
log_info "SNMP packages installed"
}
create_directories() {
echo "[3/8] Creating directory structure..."
mkdir -p /etc/snmp/traphandlers
mkdir -p /var/log/snmp/traps
mkdir -p /var/lib/snmp/trapdb
if ! id "$SNMP_USER" &>/dev/null; then
useradd -r -s /sbin/nologin -d /var/lib/snmp "$SNMP_USER" 2>/dev/null || true
fi
chown -R $SNMP_USER:$SNMP_USER /var/log/snmp /var/lib/snmp
chmod 755 /etc/snmp/traphandlers
chmod 755 /var/log/snmp/traps
chmod 755 /var/lib/snmp/trapdb
log_info "Directory structure created"
}
configure_snmptrapd() {
echo "[4/8] Configuring snmptrapd..."
cat > /etc/snmp/snmptrapd.conf << 'EOF'
snmpTrapdAddr udp:162,udp6:162
disableAuthorization yes
logOption s 6
logTimestamp yes
format1 %.4y-%.2m-%.2l %.2h:%.2j:%.2k [%B] %N: %W\n\t%V\n
format2 %.4y-%.2m-%.2l %.2h:%.2j:%.2k [%B] %N: Enterprise Specific Trap (%w) Uptime: %#T\n\t%v\n
traphandle default /etc/snmp/traphandlers/default_handler.sh
traphandle SNMPv2-MIB::coldStart /etc/snmp/traphandlers/system_handler.sh
traphandle SNMPv2-MIB::warmStart /etc/snmp/traphandlers/system_handler.sh
traphandle SNMPv2-MIB::linkDown /etc/snmp/traphandlers/interface_handler.sh
traphandle SNMPv2-MIB::linkUp /etc/snmp/traphandlers/interface_handler.sh
traphandle SNMPv2-MIB::authenticationFailure /etc/snmp/traphandlers/security_handler.sh
pidFile /var/run/snmptrapd.pid
agentuser snmp
EOF
chmod 644 /etc/snmp/snmptrapd.conf
log_info "snmptrapd configuration created"
}
create_alert_config() {
echo "[5/8] Creating alert configuration..."
cat > /etc/snmp/alert_config.conf << EOF
ALERT_EMAIL="$EMAIL"
WEBHOOK_URL="$WEBHOOK_URL"
SMTP_SERVER="localhost"
ENABLE_EMAIL=$([ -n "$EMAIL" ] && echo "true" || echo "false")
ENABLE_WEBHOOK=$([ -n "$WEBHOOK_URL" ] && echo "true" || echo "false")
EOF
chmod 644 /etc/snmp/alert_config.conf
log_info "Alert configuration created"
}
create_trap_handlers() {
echo "[6/8] Creating trap handler scripts..."
cat > /etc/snmp/traphandlers/default_handler.sh << 'EOF'
#!/bin/bash
TRAP_LOG="/var/log/snmp/traps/default.log"
ALERT_CONFIG="/etc/snmp/alert_config.conf"
TRAP_DB="/var/lib/snmp/trapdb/traps.db"
[ -f "$ALERT_CONFIG" ] && source "$ALERT_CONFIG"
TRAP_TIME=$(date '+%Y-%m-%d %H:%M:%S')
SOURCE_IP="${SNMP_TRANSPORT_ADDRESS}"
TRAP_OID="${SNMP_ARG3:-Unknown}"
TRAP_DATA=""
while read line; do
TRAP_DATA+="$line\n"
done
echo "[$TRAP_TIME] Source: $SOURCE_IP, OID: $TRAP_OID" >> "$TRAP_LOG"
echo -e "$TRAP_DATA" >> "$TRAP_LOG"
echo "---" >> "$TRAP_LOG"
echo "$TRAP_TIME|$SOURCE_IP|$TRAP_OID|$(echo -e "$TRAP_DATA" | tr '\n' ' ')" >> "$TRAP_DB"
SEVERITY="INFO"
case "$TRAP_OID" in
*coldStart|*warmStart) SEVERITY="WARNING" ;;
*linkDown|*authenticationFailure) SEVERITY="CRITICAL" ;;
*linkUp) SEVERITY="INFO" ;;
esac
if [ "$SEVERITY" = "CRITICAL" ] || [ "$SEVERITY" = "WARNING" ]; then
/etc/snmp/traphandlers/send_alert.sh "$SEVERITY" "$SOURCE_IP" "$TRAP_OID" "$TRAP_DATA"
fi
EOF
cat > /etc/snmp/traphandlers/send_alert.sh << 'EOF'
#!/bin/bash
ALERT_CONFIG="/etc/snmp/alert_config.conf"
[ -f "$ALERT_CONFIG" ] && source "$ALERT_CONFIG"
SEVERITY="$1"
SOURCE_IP="$2"
TRAP_OID="$3"
TRAP_DATA="$4"
MESSAGE="SNMP Trap Alert - $SEVERITY
Source: $SOURCE_IP
OID: $TRAP_OID
Time: $(date)
Data: $TRAP_DATA"
if [ "$ENABLE_EMAIL" = "true" ] && [ -n "$ALERT_EMAIL" ]; then
echo "$MESSAGE" | mail -s "SNMP Trap: $SEVERITY from $SOURCE_IP" "$ALERT_EMAIL"
fi
if [ "$ENABLE_WEBHOOK" = "true" ] && [ -n "$WEBHOOK_URL" ]; then
curl -X POST -H "Content-Type: application/json" -d "{\"text\":\"$MESSAGE\"}" "$WEBHOOK_URL" >/dev/null 2>&1
fi
EOF
for handler in system_handler.sh interface_handler.sh security_handler.sh; do
ln -sf default_handler.sh /etc/snmp/traphandlers/$handler
done
chmod 755 /etc/snmp/traphandlers/*.sh
chown root:root /etc/snmp/traphandlers/*.sh
log_info "Trap handler scripts created"
}
configure_firewall() {
echo "[7/8] Configuring firewall..."
if command -v firewall-cmd &> /dev/null; then
firewall-cmd --permanent --add-port=$TRAP_PORT/udp
firewall-cmd --reload
log_info "Firewalld configured"
elif command -v ufw &> /dev/null; then
ufw allow $TRAP_PORT/udp
log_info "UFW configured"
fi
}
start_services() {
echo "[8/8] Starting services..."
systemctl enable snmptrapd
systemctl start snmptrapd
systemctl enable postfix
systemctl start postfix
log_info "Services started"
}
verify_installation() {
echo "Verifying installation..."
if systemctl is-active --quiet snmptrapd; then
log_info "snmptrapd is running"
else
log_error "snmptrapd is not running"
return 1
fi
if netstat -ulnp 2>/dev/null | grep -q ":$TRAP_PORT "; then
log_info "snmptrapd is listening on port $TRAP_PORT"
else
log_warn "snmptrapd may not be listening on port $TRAP_PORT"
fi
if [ -f /var/log/snmp/traps/default.log ]; then
log_info "Trap logging is configured"
fi
log_info "Installation completed successfully!"
echo "Test with: snmptrap -v 2c -c public localhost '' 1.3.6.1.4.1.2.3.4 1.3.6.1.4.1.2.3.4.1 s 'Test trap'"
}
main() {
echo "[1/8] Checking prerequisites and detecting distribution..."
check_prerequisites
detect_distro
parse_args "$@"
install_packages
create_directories
configure_snmptrapd
create_alert_config
create_trap_handlers
configure_firewall
start_services
verify_installation
}
main "$@"
Review the script before running. Execute with: bash install.sh