Skip to content

Instantly share code, notes, and snippets.

@nudzo
Last active August 29, 2015 14:26
Show Gist options
  • Save nudzo/6a4101960976cab0f4a7 to your computer and use it in GitHub Desktop.
Save nudzo/6a4101960976cab0f4a7 to your computer and use it in GitHub Desktop.
SNMP trap mailer from snmptrapd. Formating for Zabbix SNMP trap reader.
  • example focused to SUN iLOM MIBs
  • start with all MIBs imported, thus env. MIBS=ALL or cmdline snmptrapd -m ALL ...
  • start snmptrapd -C -c /etc/net-snmp/snmp/snmptrapd.conf -A -Lf /var/log/snmp.traps for example
  • Zabbix trap collector sucking traps from /var/log/snmp.traps
  • this way using on Ubuntu and Solaris 11
  • by default mails deliverred to snmptraps mail alias on localhost
  • mails are multipart plain text and html
doNotLogTraps no
doNotFork no
pidFile /var/run/snmptrapd.pid
printEventNumbers yes
format2 %02.2h:%02.2j:%02.2k %y/%02.2m/%02.2l ZBXTRAP %B\n\nPDUaddress: %b\nPDUhostname: %B\nDescription: %W\nEnterprise: %N\nType: %w\nSubType: %q\nSecurity: %P\nVarbinds:\n %V\n %v\n
authCommunity log,execute vts
traphandle SNMPv2-SMI::enterprises.42.2.2.6.4.2.0.* /root/bin/trapmailer.py
traphandle SNMPv2-SMI::enterprises.42.2.175.103.2.0.* /root/bin/trapmailer.py
#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
__author__ = 'nudzo'
MAIL_ALIAS = 'snmptraps'
SKIP_TRAP_OIDS = [
'SNMPv2-MIB::coldStart',
'SUN-HW-TRAP-MIB::sunHwTrapHeartbeat',
# 'SUN-ILOM-SYSTEM-MIB::ilomSystemTrapSystemWarning',
# 'SUN-HW-TRAP-MIB::sunHwTrapTestTrap',
]
MAIL_TEMPLATE = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>$m_title</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif;
font-size: 100%;
line-height: 1.6;
}
img {
max-width: 100%;
}
body {
-webkit-font-smoothing: antialiased;
-webkit-text-size-adjust: none;
width: 100%!important;
height: 100%;
}
a {
color: #348eda;
}
.btn-primary {
text-decoration: none;
color: #FFF;
background-color: #348eda;
border: solid #348eda;
border-width: 10px 20px;
line-height: 2;
font-weight: bold;
margin-right: 10px;
text-align: center;
cursor: pointer;
display: inline-block;
border-radius: 25px;
}
.btn-secondary {
text-decoration: none;
color: #FFF;
background-color: #aaa;
border: solid #aaa;
border-width: 10px 20px;
line-height: 2;
font-weight: bold;
margin-right: 10px;
text-align: center;
cursor: pointer;
display: inline-block;
border-radius: 25px;
}
.last {
margin-bottom: 0;
}
.first {
margin-top: 0;
}
.padding {
padding: 10px 0;
}
table.body-wrap {
width: 100%;
padding: 20px;
}
table.body-wrap .container {
border: 1px solid #f0f0f0;
}
table.footer-wrap {
width: 100%;
clear: both!important;
}
.footer-wrap .container p {
font-size: 12px;
color: #666;
}
table.footer-wrap a {
color: #999;
}
h1, h2, h3 {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
color: #000;
margin: 40px 0 10px;
line-height: 1.2;
font-weight: 200;
}
h1 {
font-size: 36px;
}
h2 {
font-size: 28px;
}
h3 {
font-size: 22px;
}
p, ul, ol {
margin-bottom: 10px;
font-weight: normal;
font-size: 14px;
}
ul li, ol li {
margin-left: 5px;
list-style-position: inside;
}
.container {
display: block!important;
max-width: 600px!important;
margin: 0 auto!important; /* makes it centered */
clear: both!important;
}
.body-wrap .container {
padding: 20px;
}
.content {
max-width: 600px;
margin: 0 auto;
display: block;
}
.content table {
width: 100%;
}
</style>
</head>
<body bgcolor="#f6f6f6">
<table class="body-wrap" bgcolor="#f6f6f6">
<tr>
<td></td>
<td class="container" bgcolor="#FFFFFF">
<div class="content">
<table>
<tr>
<td>
<h1>$m_header</h1>
<h3>$m_endpoint</h3>
<h2>VARBINDS</h2>
<table>
$m_varbinds
</table>
<p>If numerical notation seen, MIB was not imported.</p>
</td>
</tr>
</table>
</div>
</td>
<td></td>
</tr>
</table>
<table class="footer-wrap">
<tr>
<td></td>
<td class="container">
<div class="content">
<table>
<tr>
<td align="center">
<p>
Don't like these annoying emails?
<a href="mailto:[email protected]">
<unsubscribe>Unsubscribe</unsubscribe>
</a>.
</p>
</td>
</tr>
</table>
</div>
</td>
<td></td>
</tr>
</table>
</body>
</html>
"""
import re
import sys
import fileinput
import smtplib
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from socket import gethostname
oid_val_re = re.compile(r'^([^\s]+)\s+(.+)$')
DISMAN_UPTIME = [
"DISMAN-EXPRESSION-MIB::sysUpTimeInstance",
"DISMAN-EVENT-MIB::sysUpTimeInstance",
]
if __name__ == "__main__":
mail_from = 'trap@%s' % gethostname()
input_iter = fileinput.input()
host = input_iter.next().strip()
trap_conn = input_iter.next().strip()
sys_uptime_l = input_iter.next().strip()
trap_oid_l = input_iter.next().strip()
sys_uptime_m = oid_val_re.match(sys_uptime_l)
if sys_uptime_m: # Mandatory: DISMAN-EXPRESSION-MIB::sysUpTimeInstance
if sys_uptime_m.group(1) not in DISMAN_UPTIME:
sys.exit(11)
sys_uptime = sys_uptime_m.group(2)
else:
sys.exit(1)
trap_oid_m = oid_val_re.match(trap_oid_l)
if trap_oid_m: # Mandatory: SNMPv2-MIB::snmpTrapOID.0
if trap_oid_m.group(1) != "SNMPv2-MIB::snmpTrapOID.0":
sys.exit(21)
trap_oid = trap_oid_m.group(2)
else:
sys.exit(2)
if trap_oid in SKIP_TRAP_OIDS:
sys.exit(0)
# Assembly mail
m_subject = "Trap from %s | %s" % (host, trap_oid)
txt_mail = "\nTrap from %s on endpoint-> %s\n\n" % (host, trap_conn)
txt_mail += "VARBINDS:\n"
vbhtml = ""
for vbl in input_iter:
vbm = oid_val_re.match(vbl)
if vbm:
txt_mail += "\t%s %s\n" % (vbm.group(1), vbm.group(2))
vbhtml += "<tr><td>%s</td><td>%s</td></tr>" % (vbm.group(1), vbm.group(2))
else:
continue
htpl = Template(MAIL_TEMPLATE)
tvars = {
'm_title': "Trap from %s | %s" % (host, trap_oid),
'm_header': "Trap from %s<br/><small>%s</small>" % (host, trap_oid),
'm_endpoint': "Endpoint &#10172; %s" % trap_conn,
'm_varbinds': vbhtml,
}
html_mail = htpl.substitute(tvars)
msg = MIMEMultipart('alternative')
msg['Subject'] = m_subject
msg['From'] = mail_from
try:
msg['To'] = sys.argv[1]
except IndexError:
msg['To'] = MAIL_ALIAS
# Mail priority
if 'Fault' in trap_oid or 'Fail' in trap_oid or 'Error' in trap_oid:
msg['Importance'] = 'high'
msg['Priority'] = 'urgent'
elif 'Cleared' in trap_oid or 'Okay' in trap_oid or 'Ok' in trap_oid:
msg['Importance'] = 'low'
msg['Priority'] = 'non-urgent'
else:
msg['Importance'] = 'normal'
msg['Priority'] = 'normal'
msg.attach(MIMEText(txt_mail, 'plain'))
msg.attach(MIMEText(html_mail, 'html'))
smtp = smtplib.SMTP('localhost')
smtp.sendmail(msg['From'], msg['To'], msg.as_string())
smtp.quit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment