三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

Ubuntu 20.04 SNMP服务安装与安全配置实战指南

Ubuntu 20.04 SNMP服务安装与安全配置实战指南

1. 项目概述与核心价值

在运维和网络管理的日常工作中,我们经常需要监控服务器、网络设备乃至各种物联网终端的运行状态。想象一下,你管理着几十台Ubuntu服务器,需要实时了解它们的CPU负载、内存使用率、磁盘空间和网络流量。如果每台都登录上去敲命令,那工作量简直无法想象。这时候,一个标准、高效的监控协议就显得至关重要,而SNMP(Simple Network Management Protocol,简单网络管理协议)正是为此而生。

SNMP是一个应用层协议,它允许网络管理员从网络设备(如路由器、交换机、服务器)上收集信息并进行修改,以实现监控和管理。它的核心思想很简单:在被管理设备上运行一个代理(Agent),这个代理维护着一个管理信息库(MIB);管理端(Manager)通过向代理发送请求,就能获取或设置MIB中的信息。对于Ubuntu 20.04 LTS这样的主流服务器操作系统,安装和配置SNMP服务是将其纳入集中监控体系的第一步,也是构建自动化运维平台的基础。

很多人觉得SNMP配置很麻烦,或者担心安全性。其实,只要理解了它的工作原理和几个关键配置项,在Ubuntu 20.04上部署SNMP服务可以非常快速和稳定。我管理过数百台基于Ubuntu的生产服务器,SNMP是监控栈里雷打不动的一环。接下来,我就带你从零开始,完成一次清晰、安全且可直接投入生产的SNMP服务安装与配置。

2. SNMP服务选型与原理浅析

在动手之前,我们有必要花几分钟了解一下在Linux世界里,我们通常安装的是什么。Ubuntu的软件源里,最主流、最成熟的SNMP实现是Net-SNMP套件。它包含了SNMP代理(snmpd)、管理端工具(snmpget,snmpwalk等)、一个可扩展的代理开发库以及一系列工具。

2.1 为什么选择Net-SNMP?

你可能会有疑问,有没有其他选择?对于绝大多数场景,Net-SNMP是唯一且最佳的选择。原因有三:第一,它是开源软件,经过了长达二十多年的发展和社区检验,极其稳定;第二,它被几乎所有Linux发行版(包括Ubuntu、CentOS、Debian)的官方仓库收录,安装和升级都通过包管理器,非常方便;第三,它的功能最为完整,不仅实现了完整的SNMPv1, v2c, v3协议支持,还提供了丰富的MIB模块和强大的扩展能力。

注意:有些教程会提到通过源码编译安装以获得“最新特性”。对于生产环境的Ubuntu服务器,我强烈反对这样做。使用apt安装官方维护的版本,意味着你能获得稳定的安全更新和系统兼容性保证。自己编译可能会引入依赖库冲突,并且后续升级维护是个噩梦。

2.2 SNMP协议版本选择:v2c vs v3

这是配置前最重要的决策点,直接关系到安全性和复杂性。

  • SNMPv2c:这是目前使用最广泛的版本。它使用“共同体名”(Community String)作为简单的密码进行认证。配置简单,但安全性很低,因为共同体名在网络上以明文传输。仅建议在受信任的、隔离的内部网络中使用,比如监控服务器和受监控设备在同一安全的机房网络内。
  • SNMPv3:这是当前推荐的版本。它提供了基于用户的安全模型(USM),支持消息完整性校验(防止数据包被篡改)、加密(防止窃听)和认证。配置稍复杂,但能提供企业级的安全性。对于任何需要通过公网或安全性要求较高的环境,必须使用SNMPv3。

在接下来的配置中,我会以SNMPv3作为主要配置目标,因为这是符合安全最佳实践的做法。同时,我也会说明如何配置SNMPv2c,以便你在完全可控的内网环境中快速测试。

3. 安装Net-SNMP套件

安装过程本身非常简单,但有一些细节值得注意。

3.1 更新系统与安装

首先,通过SSH连接到你的Ubuntu 20.04服务器。建议先更新一下软件包列表,确保安装的是最新稳定版的软件。

sudo apt update

然后,安装snmpd(SNMP代理守护进程)和snmp(SNMP管理端命令行工具)。通常我们会把这两个包一起装上,因为管理端工具snmp在我们本地测试配置是否成功时非常有用。

sudo apt install snmpd snmp -y

这个命令会自动安装snmpd以及它所依赖的libsnmp-base等包。安装完成后,snmpd服务会自动启动,并设置为开机自启。你可以通过以下命令验证:

sudo systemctl status snmpd

你应该能看到类似active (running)的状态信息。

3.2 理解默认配置文件

安装完成后,Net-SNMP的主配置文件位于/etc/snmp/snmpd.conf。在修改之前,我强烈建议你先备份一下原始文件:

sudo cp /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.backup

cat命令看一眼初始内容,你会发现它可能几乎是空的,或者只有几行注释。这是因为Ubuntu的snmpd包使用了一个“增量配置”机制。实际的默认配置是通过snmpd在启动时动态生成的,或者从/etc/snmp/snmpd.conf/etc/snmp/conf.d/目录下的其他文件读取。

这种设计的好处是,我们只需要在/etc/snmp/snmpd.conf里写我们想要覆盖新增的配置即可,避免了直接修改一个庞大而复杂的默认文件。这比一些其他发行版(如CentOS)的默认配置方式要清晰得多。

4. 配置SNMPv3(推荐安全方式)

配置SNMPv3的核心是创建一个具有认证和加密功能的用户。Net-SNMP提供了一个交互式命令来简化这个过程:snmpusm。但更常用、更易于脚本化的方式是使用net-snmp-config工具来创建用户,并手动将配置写入snmpd.conf

4.1 创建SNMPv3用户

我们将创建一个用户,比如叫monitor_user。SNMPv3支持不同的安全级别:

  • noAuthNoPriv:无认证无加密(不安全,不推荐)。
  • authNoPriv:有认证(MD5或SHA),但无加密。
  • authPriv:有认证且有加密(DES或AES)。这是最安全的级别。

我们选择authPriv级别。这意味着我们需要提供:

  1. 认证密码:用于验证用户身份。
  2. 加密密码:用于加密数据负载。

这两个密码最好不同,且遵循强密码策略。以下命令将创建一个使用SHA进行认证、AES-128进行加密的用户:

sudo net-snmp-config --create-snmpv3-user -a SHA -x AES -A "YourAuthPass123!" -X "YourEncryptPass456!" monitor_user

参数解释:

  • -a SHA:指定认证协议为SHA(也可以选MD5,但SHA更安全)。
  • -x AES:指定加密协议为AES(也可以选DES,但AES更安全)。
  • -A “YourAuthPass123!”:设置认证密码。
  • -X “YourEncryptPass456!”:设置加密密码。
  • monitor_user:要创建的用户名。

实操心得:这个命令实际上会在/var/lib/snmp/snmpd.conf中生成一行关于该用户的配置。但为了配置的集中管理,我更倾向于将关键的v3用户配置直接写入主配置文件/etc/snmp/snmpd.conf,这样一目了然,也便于版本控制。

4.2 手动编辑主配置文件

让我们直接编辑主配置文件,这是一种更透明、更可控的方式。

sudo vim /etc/snmp/snmpd.conf

首先,清空或注释掉里面所有现有的非注释内容(因为我们是从头配置)。然后,添加以下配置段落:

# 1. 定义SNMPv3用户 # 格式:createUser <用户名> <认证类型> <认证密码> <加密类型> <加密密码> # 密码需要是明文,snmpd启动时会自动将其转换为本地存储的密钥。 createUser monitor_user SHA “YourAuthPass123!” AES “YourEncryptPass456!” # 2. 定义访问控制视图(View) # 视图定义了用户可以访问MIB树的哪一部分。 # .1 代表整个ISO MIB树(即所有对象)。在生产中,你可能需要限制得更严格。 view systemview included .1 # 3. 定义SNMPv3组和访问权限 # 将用户monitor_user加入到组v3group,并赋予其对systemview的读权限。 # authPriv 表示需要认证和加密。 group v3group v3 monitor_user access v3group “” any authPriv systemview none none # 4. 允许SNMP代理监听所有网络接口(默认只监听127.0.0.1) # 注释掉下面这行,或将其改为 agentAddress udp:161 # 默认行:agentAddress udp:127.0.0.1:161 agentAddress udp:161

关键点解析:

  • createUser:这一行是核心。密码在这里以明文写下,但不用担心,当snmpd服务重启时,它会读取这个文件,将密码处理并存储到/var/lib/snmp/snmpd.conf中,然后自动从/etc/snmp/snmpd.conf中删除这一行(或将其替换为createUser ... DES等占位符),以防止密码泄露。这是Net-SNMP的安全机制。
  • view systemview included .1:这是一个非常宽松的视图,允许查看所有MIB对象。在实际生产环境,你应该根据监控需求创建更精细的视图,例如只包含系统、接口和存储相关的OID子树,以遵循最小权限原则。
  • agentAddress udp:161:将监听端口从默认的本地回环(127.0.0.1)改为所有接口(0.0.0.0)的161端口。这样监控服务器才能远程访问它。请确保你的防火墙(如UFW)已经允许了161端口的入站访问。

4.3 重启服务并测试

保存配置文件后,重启snmpd服务以使配置生效:

sudo systemctl restart snmpd sudo systemctl status snmpd # 确认服务运行正常

现在,我们可以在本机上使用刚创建的v3用户进行测试。使用snmpget命令(属于之前安装的snmp包)来获取一个标准的系统信息,比如系统描述(sysDescr,其OID是.1.3.6.1.2.1.1.1.0)。

snmpget -v 3 -u monitor_user -l authPriv -a SHA -A “YourAuthPass123!” -x AES -X “YourEncryptPass456!” localhost .1.3.6.1.2.1.1.1.0

命令参数解释:

  • -v 3:指定使用SNMPv3。
  • -u monitor_user:指定用户名。
  • -l authPriv:指定安全级别为认证且加密。
  • -a SHA -A “密码”:指定认证协议和密码。
  • -x AES -X “密码”:指定加密协议和密码。
  • localhost:目标主机(这里测试本机)。
  • 最后是你要查询的OID。

如果配置正确,你会看到类似下面的输出,其中包含了你的系统信息:

SNMPv2-MIB::sysDescr.0 = STRING: Linux ubuntu-server 5.4.0-xx-generic #xx-Ubuntu SMP ... x86_64

恭喜,这说明你的SNMPv3代理已经成功运行并可以安全地提供数据了!

5. 配置SNMPv2c(简易内网方式)

如果你的环境是高度可信的内网,并且希望配置最简单,可以使用SNMPv2c。配置它只需要在/etc/snmp/snmpd.conf中添加几行。

再次编辑配置文件:

sudo vim /etc/snmp/snmpd.conf

在文件中添加(如果你之前配置了v3,这些可以共存,但建议一种协议为主):

# SNMPv2c 配置 # 1. 定义一个只读共同体名(类似密码),这里设为 ‘public_ro’。强烈建议不要使用默认的 ‘public’。 rocommunity public_ro # 你可以限制该共同体名只能从特定网段访问,例如: # rocommunity public_ro 192.168.1.0/24 # 2. 同样需要确保代理监听所有接口(如果之前v3配置已加,则无需重复) # agentAddress udp:161

这里rocommunity public_ro就定义了一个只读的共同体,任何知道这个字符串的主机都可以读取信息。rocommunity public_ro 192.168.1.0/24则限制了只允许来自192.168.1.0/24网段的请求。

重启服务后,可以使用v2c协议测试:

snmpget -v 2c -c public_ro localhost .1.3.6.1.2.1.1.1.0

重要警告:SNMPv2c的共同体名以明文传输。在任何可能暴露给不信任网络的环境中,使用v2c等同于敞开大门。我曾见过因为使用默认的public共同体名且暴露在公网,导致服务器信息被爬取甚至被恶意篡改配置的案例。务必谨慎。

6. 扩展配置与自定义监控项

默认的SNMP配置已经暴露了大量的系统信息,但有时我们需要监控一些特定的东西,比如某个特定进程是否存活,或者一个自定义脚本的输出。Net-SNMP的extend指令非常强大。

6.1 监控特定进程数量

例如,我们需要监控Nginx工作进程的数量。在/etc/snmp/snmpd.conf中添加:

# 扩展指令,定义一个名为 nginx_proc 的监控项 # 它会执行 ‘pgrep -c nginx’ 命令,并将其输出作为监控值。 extend nginx_proc /bin/bash -c “pgrep -c nginx”

重启snmpd后,你可以通过查询一个特定的OID来获取这个值。Net-SNMP会自动为extend指令分配OID。通常可以通过nsExtendOutput1Line等节点访问。更简单的方法是使用snmpwalk来发现:

snmpwalk -v 3 -u monitor_user -l authPriv -a SHA -A “YourAuthPass123!” -x AES -X “YourEncryptPass456!” localhost NET-SNMP-EXTEND-MIB::nsExtendObjects

在输出中,你会找到nsExtendOutput1Line.”nginx_proc”对应的行,其值就是Nginx进程数。

6.2 暴露磁盘挂载点信息

默认配置可能不会暴露所有磁盘挂载点。为了监控所有磁盘空间,需要确保snmpd能访问/proc/。检查配置文件中是否有以下行(通常默认有,但被注释了):

# 取消注释以下两行,允许访问 /proc 和 / 目录,以获取完整的磁盘和内存信息 view systemview included .1.3.6.1.4.1.2021.8.1 view systemview included .1.3.6.1.4.1.2021.9.1

另外,确保disk检查模块被加载且配置了需要监控的挂载点:

# 监控根分区 ‘/‘,警告阈值设为90% disk / 90% # 你可以添加更多挂载点,如 /home, /var 等 disk /home 90%

7. 防火墙与安全加固

配置好了服务,安全防护必须跟上。

7.1 配置UFW防火墙

Ubuntu 20.04默认使用UFW。你需要允许SNMP端口(UDP 161)的入站流量,最好只允许来自你的监控服务器IP地址。

# 允许来自特定监控服务器(例如 192.168.1.100)的SNMP访问 sudo ufw allow from 192.168.1.100 to any port 161 proto udp # 如果你暂时需要开放给整个内网测试(生产环境请收紧) # sudo ufw allow from 192.168.1.0/24 to any port 161 proto udp # 启用UFW(如果尚未启用) sudo ufw enable # 查看规则 sudo ufw status numbered

7.2 安全配置检查清单

  1. 禁用SNMPv1/v2c:如果确定只使用v3,可以在配置文件中明确禁用旧版本协议,减少攻击面。在/etc/snmp/snmpd.conf中添加:

    # 禁用SNMPv1和SNMPv2c disableSNMPv1 yes disableSNMPv2c yes

    注意:某些版本的Net-SNMP可能不支持此语法,更通用的做法是只配置v3,不配置v2c的rocommunity行,并将agentAddress行改为只监听需要协议的端口(但通常一个端口支持多版本)。

  2. 使用非标准端口:可以考虑将SNMP服务运行在非标准的161端口,例如agentAddress udp:1161。但这需要你的所有监控工具都同步修改,管理成本较高。

  3. 最小权限视图:如前所述,不要使用.1这样的全开放视图。根据你的监控需求,定义精确的视图。例如,只允许读取系统、接口和主机资源MIB:

    view restrictedview included .1.3.6.1.2.1.1 # system view restrictedview included .1.3.6.1.2.1.2 # interfaces view restrictedview included .1.3.6.1.2.1.25 # host-resources # 然后在access行中使用这个restrictedview

8. 常见问题排查与调试实录

即使按照步骤操作,你也可能会遇到一些问题。这里记录了几个我踩过的坑和解决方法。

8.1 问题:snmpget命令返回Timeout: No Response

可能原因及排查:

  1. 服务未运行sudo systemctl status snmpd检查状态。如果未运行,查看日志sudo journalctl -u snmpd -f寻找错误信息。
  2. 防火墙阻挡:这是最常见的原因。确认UFW或iptables规则允许了161端口的UDP流量。可以在监控服务器上用telnet <目标IP> 161测试端口连通性(虽然SNMP是UDP,但telnet TCP测试能看出端口是否被完全屏蔽)。
  3. 监听地址错误:确认/etc/snmp/snmpd.confagentAddress配置为udp:161(监听所有接口)或udp:<IP>:161,而不是仅udp:127.0.0.1:161
  4. 认证信息错误:对于v3,请仔细检查用户名、认证/加密密码、协议(SHA/AES)是否完全匹配,包括大小写和特殊字符。一个快速测试方法是先在本地(localhost)执行命令,如果本地通而远程不通,问题大概率在防火墙或网络。

8.2 问题:SNMPv3用户创建失败或认证失败

可能原因:

  • 密码长度:SNMPv3对密码长度有要求。认证密码和加密密码通常需要至少8个字符。确保你的密码符合要求。
  • 配置文件权限/etc/snmp/snmpd.conf/var/lib/snmp/snmpd.conf的权限和所有者必须是root:root
  • createUser行消失:如前所述,snmpd启动后会将/etc/snmp/snmpd.conf中的createUser明文密码行移除或替换。这是正常现象,用户信息已安全存储。不要手动重新添加该行。

8.3 问题:无法获取磁盘或内存信息

排查步骤:

  1. 检查配置文件中对应的view是否已取消注释(如.1.3.6.1.4.1.2021.9.1.3.6.1.4.1.2021.8)。
  2. 检查disk指令配置的挂载点路径是否正确。
  3. 使用snmpwalk遍历整个MIB树,看看是否有任何磁盘信息被暴露出来,定位问题范围:
    snmpwalk -v 3 -u monitor_user -l authPriv -a SHA -A “YourAuthPass123!” -x AES -X “YourEncryptPass456!” localhost .1.3.6.1.4.1.2021.9

8.4 调试利器:详细日志

当问题复杂时,开启snmpd的调试日志非常有用。可以临时修改systemd服务参数:

sudo systemctl edit snmpd

在弹出的编辑器中,添加以下内容(这会创建一个覆盖配置片段):

[Service] ExecStart= ExecStart=/usr/sbin/snmpd -f -Lf /var/log/snmpd.log -Dusm,md5,sha -a

参数解释:

  • -f:保持在前台运行(配合systemd需谨慎,这里主要用于调试)。
  • -Lf /var/log/snmpd.log:将日志输出到指定文件。
  • -Dusm,md5,sha:开启特定模块(usm, md5, sha)的调试信息。-Dall可以开启全部,但日志量巨大。
  • -a:记录请求的来源地址。

保存退出后,重启服务:sudo systemctl daemon-reload && sudo systemctl restart snmpd。然后查看/var/log/snmpd.log文件。调试完成后,务必删除这个覆盖配置sudo systemctl edit snmpd,然后删除添加的内容,再重启服务。

9. 与监控系统集成

配置好SNMP服务后,最终目的是为了被监控系统(如Zabbix, Prometheus with SNMP Exporter, Nagios, LibreNMS等)采集数据。

Zabbix为例,你需要:

  1. 在Zabbix Web控制台创建一个主机,IP地址填你的Ubuntu服务器地址。
  2. 为主机添加一个SNMP接口,端口161。
  3. 如果使用SNMPv3,在主机配置的“宏”中,或SNMP接口的高级设置里,填入:
    • {$SNMP3_AUTHALGO}: SHA
    • {$SNMP3_PRIVALGO}: AES
    • {$SNMP3_SECNAME}: monitor_user
    • {$SNMP3_AUTHPASSPHRASE}: YourAuthPass123!
    • {$SNMP3_PRIVPASSPHRASE}: YourEncryptPass456!
    • {$SNMP3_SECLEVEL}: authPriv
  4. 链接一个SNMP模板,如“Template OS Linux by SNMPv3”。Zabbix就会自动开始采集CPU、内存、磁盘、网络等指标。

对于Prometheus,你需要部署snmp_exporter,并为其编写一个配置文件,定义你需要采集的OID。然后在Prometheus的scrape_configs中指向这个exporter。

配置过程中最关键的是确保监控系统端的SNMP版本、共同体名(v2c)或用户认证信息(v3)与你在Ubuntu服务器上配置的完全一致。第一次集成时,建议先在监控服务器上使用snmpwalksnmpget命令行工具测试连通性和数据获取,确认无误后再配置监控系统,这样可以有效隔离问题。

← 返回列表