Skip to content

SNMP 协议实验二

复制本地路径 | 在线编辑

这篇文章介绍 SNMP Trap 通信,即 agent 向 manager 发送信息。第一篇文章讲的是 manager 向 agent 发送消息。本来以为会很轻松的,结果折腾了好久。

介绍

在 SNMP 协议中,当 agent 发现自己可能有问题时,可以向 manager 发送信息。这个信息就是 SNMP Trap。

配置 SNMP manager

下载 snmptrapd,然后修改配置文件:

# /etc/snmp/snmptrapd.conf
createUser test_demo MD5 test_password DES test_password
authUser log,execute,net test_demo

首先 createUser 是创建一个用户,上一篇中我们配置 manager 向 agent 发送消息也是需要一个用户。这里我是故意用的 test_demo,表明和上一篇文章不一样,即 agent 发送 manager trap 消息,和 manager 向 agent 发送查询/操作指令,这两个通信所用的用户不强求要一样。

上一篇中使用了临时用户,然后再去创建真正用户,这里没有。因为现在配置这是在我们的 manager 中,也就是我们是保证 manager 这个管理员是绝对安全的。上一篇的 createUser 是在 agent 上,无法完全保证所有设备(即 agent)安全,所以用了临时用户。

authUser 是对用户进行一些授权,这个没有什么好说的。

配置修改完成后,然后可以直接关闭 snmptrapd,因为我们这里直接命令行启动 snmptrapd。这样它是一直监听,并且会把结果输出到标准输出上:

systemctl stop snmptrapd.socket
snmptrapd -C -c /etc/snmp/snmptrapd.conf -f -Lo

配置 SNMP agent

直接使用 snmptrap 指令发送消息:

snmptrap -v3 -u test_demo -l authPriv \
  -a MD5 -A test_password -x DES -X test_password \
  manager_ip '' 1.3.6.1.6.3.1.1.5.1

继续配置

但是并没有输出,这里我就一直在拷打 AI,结果它越说越乱,有跟我说是 snmptrapd 的指令,有跟我说是权限,有跟说是什么 agentX 的原因,越说越离谱了。

当时服务器又是 Digital Ocean,外网速度太慢了,卡的要死,烦躁的很。后来第二天冷静下来,然后买了阿里云,重新开始,再阅读官方文档,终于最终搞定了。

确认防火墙

在 manager 上监听,然后 agent 使用上面的 snmptrap 指令发一个消息,确保包到达了:

tcpdump -i any udp port 162

如果没有输出,那最好还是看看云服务器管理界面上是不是被禁止了。

EngineID

首先官方文档的链接如下:

其实官方文档讲的很好:

TRAPs and INFORMs get a little more complex with respect to SNMPv3. The reason behind it is how the user database is maintained. SNMPv1 and SNMPv2c community based messages merely always display the message to the end user. SNMPv3 mandates that the message is rejected unless the SNMPv3 user sending the trap already exists in the user database. Sounds simple enough, right? Except for one small problem: the user database in a SNMPv3 application is actually referenced by a combination of the user's name (called a "security Name") and an identifier for the given SNMP application you're talking to (called an "engineID"). Normally when you use the rest of the SNMP applications (snmpget, snmpwalk, ...) the application "discovers" the remote engineID for you and then inserts the username, engineID and passwords into the user database based on this remote engineID. Makes things all nice and simple when talking to a remote agent.

这段话告诉我们:在 SNMPv3 中,判定一个用户实际上是由 username 和所通信的特定 SNMP 应用的标识符(engineID)组合来引用的。

SNMPv3 TRAPs are a bit more complicated in some ways, but it makes sense the protocol works this way if you spend a long time thinking about it. The difference is that SNMPv3 TRAPs use the engineID of the local application sending the trap rather than the engineID of the remote application. This means that you have to create users in your remote user database with a bit more care and need to create one for every engineID you wish to send traps from. This means that if you want to have 100 snmp agents send snmpv3 traps to your trap receiver, you need 100 createUser directives in your /var/net-snmp/snmptrapd.conf file.

上面这段话中 local application 其实就是 agent,remote application 其实就是 manager。总之意思就是说我们要在 remote 即 manager 上创建我们的用户数据库,其每个条目是 (username, engineID) 这种组合。

获取 engineID

所以我们要知道 agent 的 engineID,才能在 manager 上创建用户数据库。怎么获取,这个链接帮了忙,如下:

snmpget -v 3 -u test -l authPriv -a SHA -A paloalto -x AES -X paloalto 172.17.128.23 1.3.6.1.6.3.10.2.1.1.0

这个命令是直接从对应链接上复制的,按照我们上一篇文章的配置,我们是可以直接使用:

snmpget -v 3 agent_ip 1.3.6.1.6.3.10.2.1.1.0

得到:

SNMP-FRAMEWORK-MIB::snmpEngineID.0 = Hex-STRING: 80 00 1F 88 80 E1 3A 53 3C 7D 6C C7 69 00 00 00

0x80001F8880E13A533C7D6CC769000000

重新配置 manager

现在我们修改 manager 的配置,在 manager 上创建用户数据库:

# /etc/snmp/snmptrapd.conf
# update this:
createUser -e 0x80001F8880E13A533C7D6CC769000000 test_demo MD5 test_password DES test_password

createUser 的参数中,多了一个 -e 参数,表示 engineID。

尝试连接

在 agent 上尝试连接:

snmptrap -e 0x80001F8880E13A533C7D6CC769000000 -v3 -u test_demo -l authPriv -a MD5 -A test_password -x DES -X test_password manager_ip '' 1.3.6.1.6.3.1.1.5.1

如果还是不行

没错,我那天做了很久还是不行,因为这个折腾了好久好久。问 AI 也是回答各种千奇百怪的原因。后来我突然发现我在 manager 自己执行 snmptrap 时,如果把 manager_ip 改成 localhost 就可以了:

# do this in manager
snmptrap -e 0x80001F8880E13A533C7D6CC769000000 -v3 -u test_demo -l authPriv -a MD5 -A test_password -x DES -X test_password localhost '' 1.3.6.1.6.3.1.1.5.1

那答案就很明显了,它只接受 localhost 的包?防火墙有问题,果然一看,我们的 manager 居然没有进行设置 ufw,上一篇文章中我们只设置了 agent 的防火墙... 这里要开放 162 端口:

sudo ufw allow proto udp to any port 162
sudo ufw reload

之后再次测试,终于搞定了。

其他

其实现在还有一个安全问题,就是 agent 发送的时候用的明文密码。这个貌似是通过 trapsess 这个关键字来完成的,具体的我就不继续往下尝试了。做到这里也已经算是完成了我当时的预期目标,下面这个链接或许有帮助:

总结

可算是完成了当时的目标。本来以为会很轻松的,结果折腾了好久。中间各种拷打 AI,还是没搞出来,算下来当天下午+晚上五个小时没搞定。然后第二天去的自习室,下午一点半开始,搞到三点多,终于好了。

当时也是折腾了半天,然后放弃了。当时没有 AI 这么好的工具,回顾以前的大学生活,天啊,真不知道自己是咋在没有 AI 辅助下学下去的。遇到难一点的问题,就是在互联网上搜索,在犄角旮旯的地方发现类似的苦命人。

所以现在的我们是多么幸福,学习知识的效率提高那么多。上大学我没有珍惜时间,现在我真的太想过好每一分钟了,想多多吸取知识。虽然说这些对我现在没有什么用,但完成这个实验是大学补全计划的一部分,经历了操作系统等等补全后,至少我可以自信说我的大学课程实验都体验过了;更重要的是,这种不断探索、解决问题的过程,真的很有趣。这就是过好每一分钟,按照当下的想法大胆去做!

Comments