Snmpd是服务端的,snmp是客户端的,snmp-mib-downloader用来更新本地mib库的软件,snmp trap是snmp的一部分,用于对特定事件向服务器发送报警。
基本概念不多说了,今天主要讲一下操作实例。要达成的目标是收到SNMP TRAP的特定消息后,发消息到Slack频道通知。
服务器:Ubuntu 18.04 设备:华为OLT MA5800X7
服务器侧:
1、SNMP和SNMPTrap的安装。
1.1 惯例,服务器上先更新软件再安装。
axing@84:~$ sudo apt update
axing@84:~$ sudo apt upgrade
axing@84:~$ sudo apt install snmpd snmp snmp-mibs-downloader snmptrapd
1.2 安装完成,看下snmp服务状态正常, 看到“Active: active (running)”
axing@84:~$ sudo service snmpd status
#或者sudo systemctl status snmpd
● snmpd.service - LSB: SNMP agents
Loaded: loaded (/etc/init.d/snmpd; bad; vendor preset: enabled)
Active: active (running) since Thu 2019-01-10 15:12:24 GMT; 1h 9min ago
Docs: man:systemd-sysv-generator(8)
CGroup: /system.slice/snmpd.service
└─2152 /usr/sbin/snmpd -Lsd -Lf /dev/null -u snmp -g snmp -I -smux mt
Jan 10 15:12:23 Docker_LD8 systemd[1]: Starting LSB: SNMP agents...
Jan 10 15:12:24 Docker_LD8 snmpd[2144]: * Starting SNMP services:
Jan 10 15:12:24 Docker_LD8 snmpd[2150]: Created directory: /var/lib/snmp/mib_ind
Jan 10 15:12:24 Docker_LD8 snmpd[2150]: /etc/snmp/snmpd.conf: line 145: Warning:
Jan 10 15:12:24 Docker_LD8 snmpd[2150]: /etc/snmp/snmpd.conf: line 147: Warning:
可以用snmpwalk看下本机信息,返回类似以下信息说明正常。
axing@Docker_LD8:~$ snmpwalk -v 2c -c public localhost 1.3.6.1.2.1.1.1
iso.3.6.1.2.1.1.1.0 = STRING: "Linux Docker_LD8 4.4.0-141-generic #167-Ubuntu SMP Wed Dec 5 10:40:15 UTC 2018 x86_64”
1.3 对服务器snmp和snmpd的配置文件进行修改优化
1.3.1 先改 etc/snmp/snmpd.conf 文件
axing@84:~$ sudo vim /etc/snmp/snmpd.conf
#找到下面两行,注释掉,添加第三句,这样就可获取更多的节点信息。
…
#view systemonly included .1.3.6.1.2.1.1
#view systemonly included .1.3.6.1.2.1.25.1
view systemonly included .1
…
#修改通讯密码
#Full access from the local host
#rocommunity public localhost
#Default access to basic system info
rocommunity password default -V systemonly
#rocommunity6 is for IPv6
rocommunity6 password default -V systemonly
...
改完重启服务,跑一下snmpwalk看看swap大小
axing@84:~$sudo service snmpd restart
axing@84:~$sudo snmpwalk -v 2c -c password localhost .1.3.6.1.4.1.2021.4.3.0
iso.3.6.1.4.1.2021.4.3.0 = INTEGER: 1003516
axing@84:~$sudo free -m
total used free shared buff/cache available
Mem: 991 218 195 23 578 562
Swap: 979 27 952
觉得这样不够直观,再改下snmp.conf文件
axing@84:~$sudo vim snmp.conf
...
#mibs:
mibdirs +/usr/share/mibs
mibdirs +/usr/share/mibs/iana
mibdirs +/usr/share/mibs/ietf
mibs +ALL
#注释掉: mibs, 增加mibs存放目录,默认snmp-mibs-downloader 安装了在/usr/share/mibs下面会有两个文件夹iana和ietf
重启服务,再运行一下snmpwalk,现在就翻译过来了
axing@84:~$ sudo service snmpd restart
axing@84:~$ sudo snmpwalk -v 2c -c public localhost .1.3.6.1.4.1.2021.4.3.0
UCD-SNMP-MIB::memTotalSwap.0 = INTEGER: 1003516 kB
另外,为提高snmp安全性,最好修改下snmp community密码
目前为止,snmp只允许本机访问,要想允许远程主机访问,还有一些要改下:修改/etc/snmp/snmpd.conf,
按照下面修改。
# Listen for connections from the local system only
#agentAddress udp:127.0.0.1:161
# Listen for connections on all interfaces (both IPv4 *and* IPv6)
agentAddress udp:161,udp6:[::1]:161
重启服务
我们可以对比下修改前后侦听端口的变化
Before
axing@84:~$ sudo netstat -antup | grep 161
udp 0 0 127.0.0.1:161 0.0.0.0:* 6177/snmpd
After
axing@84:~$ sudo netstat -antup | grep 161
udp 0 0 0.0.0.0:161 0.0.0.0:* 6284/snmpd
udp6 0 0 ::1:161 :::* 6284/snmpd
如果使用ufw防火墙的话,别忘记开放161/162端口。
现在就可以远程获取主机snmp信息了。
snmpwalk -v2c -c password xx.xxx.xx.xx HUAWEI-XPON-TRAP-MIB::hwXponOntInitiativeDownAlarmTrap
2、 SNMPTRAPD配置
要启用SNMPTRAPD,修改配置文件/etc/snmp/snmptrap.conf,添加一句制定community字串
vim /etc/snmp/snmptrapd.conf
authCommunity log,execute,net public
#这里的参数,log表示记录日志,execute表示传递给特定处理程序,比如python脚本,net允许把trap传递给其他服务器。
#public是密码,随便改
在要监控的设备上配置snmp trap,不同设备的配置大同小异,主要是服务器地址和通讯字串,比如我配置华为OLT,配置看起来是这样的:
snmp-agent community read cipher "password"
snmp-agent target-host trap-hostname "ax-84" address xx.xxx.xxx.xx udp-port 162 trap-paramsname "trapname"
snmp-agent target-host trap-paramsname "trapname" v2c securityname cipher "password"
改完新开一个窗口,重启snmp trap服务,可以看到服务器开始接收trap信息
axing@84:~$ sudo snmptrapd -d -f -Lo
2019-01-18 16:23:16 [UDP: [10.111.108.2]:58058->[46.102.170.84]:162]:
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (2186314094) 253 days, 1:05:40.94 SNMPv2-MIB::snmpTrapOID.0 = OID: HUAWEI-XPON-TRAP-MIB::hwXponProfOntPortStatusTrap HUAWEI-SNMP-NOTIFICATION-MIB::hwTrapSN.0 = INTEGER: 0 HUAWEI-SNMP-NOTIFICATION-MIB::hwTrapLevel.0 = INTEGER: warning(4) HUAWEI-SNMP-NOTIFICATION-MIB::hwSpecificTrapType.0 = INTEGER: maintain(3) HUAWEI-DEVICE-MIB::hwSysIpAddr.0 = IpAddress: 10.111.108.2 HUAWEI-SNMP-NOTIFICATION-MIB::hwTrapID.0 = INTEGER: 400 HUAWEI-LINE-COMMON-MIB::hwReservedValue.0 = INTEGER: 0 HUAWEI-XPON-TRAP-MIB::hwXponTrapOperType.0 = INTEGER: modify(2) IF-MIB::ifIndex.4194312960 = INTEGER: -100654336 HUAWEI-XPON-MIB::hwXponDeviceOntIndex.4194312960.3 = INTEGER: 3 HUAWEI-XPON-MIB::hwXponOntUniPhyType.4194312960.3.eth.4 = INTEGER: eth(47) HUAWEI-XPON-MIB::hwXponOntUniPhyIndex.4194312960.3.eth.4 = INTEGER: 4 HUAWEI-XPON-TRAP-MIB::hwXponDeviceOntPortRunStatus.0 = INTEGER: 1
^C2019-01-18 16:23:17 NET-SNMP version 5.7.3 Stopped.
Stopping snmptrapd
Sending 24 bytes to Local IPC: /var/agentx/master
0000: 01 02 00 00 08 00 00 00 00 00 00 00 F6 3D A4 49 .............=.I
0016: 04 00 00 00 05 00 00 00 ........
3、配置输出信息到slack
首先你要知道slack的LACK_INCOMING_WEB_HOOK, 通常你需要有slack频道管理员权限或向管理员申请,得到类似以下链接:
SLACK_INCOMING_WEB_HOOK = "https://hooks.slack.com/services/T03MQU5DA/B1HJ8Ndf19A/bZr5UEanVdL3wROtWTssmgC"
然后修改snmptrapd.conf文件,主要改下面几个参数
#服务器地址
snmpTrapAddr udp:xx.xxx.xxx.xx:161
#通讯字串
authCommunity log,execute trapname
authCommunity log,execute password
ignoreAuthFailure yes
#收到trap后如何处理,下面这句的意思是收到HUAWEI-XPON-TRAP-MIB::hwGponProfOntDiscoveryAlarmTrap的告警后,去执行 /usr/local/bin/snmphandler_general.py 程序,参数HUAWEI-XPON-TRAP-MIB::hwGponProfOntDiscoveryAlarmTrap
traphandle HUAWEI-XPON-TRAP-MIB::hwGponProfOntDiscoveryAlarmTrap /usr/local/bin/snmphandler_general.py HUAWEI-XPON-TRAP-MIB::hwGponProfOntDiscoveryAlarmTrap
在python脚本里引用以下内容,具体python脚本就不写了
SLACK_INCOMING_WEB_HOOK = "https://hooks.slack.com/services/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mgC"
SLACK_INCOMING_USER = "snmp-bot"
SLACK_INCOMING_CHANNEL = "#snmptrap"
...
def post_to_slack(text):
payload = {
"text": text,
"username": SLACK_INCOMING_USER,
"channel": SLACK_INCOMING_CHANNEL,
}
req = requests.post(SLACK_INCOMING_WEB_HOOK, json.dumps(payload), headers={'content-type': 'application/json'}) #request to post the message
...