After a few years of neglect, I decided to go back through my networked devices and make sure net-snmp is installed consistetnly and more minimaly. Doing this let me return to using Cacti and provide a check against what Prometheus and Grafana are telling me.

Approach to Net-SNMP Install

What I want to set up is a minimal v3 SNMP server service running on all of my machines so Cacti, and Greenbone can query the machines and do their needful. Essentially what I am hoping for is a standard, current installation and configuration accross all my machines, replacing all the varied existing installs I have done over the years. To that end I have the Salt state file to reapply my settings when needed.

Plan for Each Machine

  • Install Net-SNMP if missing.
  • Stop snmpd service if running.
  • Replace /usr/share/snmp/snmpd.conf file with salt managed file (Location varies by OS).
  • Replace /var/net/snmpd.conf file with Salt managed file (Location varies by OS).
  • Enable and start service.

I created app_snmp and app_snmp/files/ directories under /srv/salt on my Salt master machine. I saved the below Salt state file as init.sls in the /srv/salt/app_snmp directory.

init.sls

# Install and configure net-snmp package for linux machines
# Create 2021-11-11

# Install software if missing.
net-snmp:
  pkg.installed:
    - pkgs:
      - {{ pillar['snmpd'] }}

# Stop snmpd service. Running if already installed, and started by some package managers upon a new install.
stop_snmpd.service:
  service.dead:
    - name: snmpd.service

# copy snmpd.conf to /usr/share/snmp/ (system configuration)
/usr/share/snmp/snmpd.conf:
  file.managed:
    - source: salt://app_snmp/files/ssnmpd.conf
    - user: root
    - group: root
    - mode: 644
    - backup: minion
    - makedirs: True

# Create symlink /etc/snmp/snmpd.conf to /usr/share/snmp/snmpd.conf
/etc/snmp/snmpd.conf:
  file.symlink:
    - name: /etc/snmp/snmpd.conf
    - target: /usr/share/snmp/snmpd.conf
    - force: True
    - backupname: orig_snmpd.conf
    - mode: 644
    - makedirs: True

# copy snmpd.conf to /var/lib/net-snmp/snmpd.conf (User authentication information)
{% if (grains['os_family'] == 'Debian') %}
  {% set location = '/var/lib/snmp/snmpd.conf' %}
{% elif (grains['os_family'] == 'Arch' or grains['os_family'] == 'Manjaro-ARM') %}
  {% set location = '/var/net-snmp/snmpd.conf' %}
{% else %}
  {% set location = '/var/lib/net-snmp/snmpd.conf' %}
{% endif %}
{{ location }}:
  file.managed:
    - source: salt://app_snmp/files/vsnmpd.conf
    - user: root
    - group: root
    - mode: 644
    - backup: minion
    - makedirs: True

# enable service
snmpd.service:
  service.running:
    - name: snmpd.service
    - enable: True

I installed net-snmp manually on a test vm runnning Arch Linux and configured it to the point it would respond to a remote machine wher I ran the following query: snmpwalk -v 3 -u USERNAME -a sha -A AUTHPASSWORD -x aes -X PRIVPASSWORD -l authPriv REMOTETESTVM. USERNAME is replaced by the SNMP username set up in configuration, AUTHPASSWORD and PRIVPASSWORD are also as specified in snmp.conf file gusiall stored under /var/ directory, and REMOTETESTVM is replaced by DNS name or IP address of the remote machine I am testing.

I intially followed directions offered on the Arch Wiki (see references section for link). When things got to the point where they were working, I copied /usr/share/snmp/snmpd.conf from the test machine to my Salt master, saving it as /srv/salt/app_snmp/files/ssnmpd.conf. The contents of the file are as bellow, with LOCATION, CONTACTINFO and USERNAME shanged to reflect values appropriate for my setup.

ssnmpd.conf

###########################################################################
#
# snmpd.conf
#

syslocation  "LOCATION"

syscontact  "CONTACTINFO"

# sysservices: The proper value for the sysServices object.
#   arguments:  sysservices_number

sysservices 76

#   This section defines who is allowed to talk to your running
#   snmp agent.

# rouser: a SNMPv3 read-only user

rouser  USERNAME  

I then used the following command on the remote machine, with the snmpd.service stopped to generate the snmpd.conf file that usually is stored under /var directory somewhere, # echo createUser read_only_user SHA password1 AES password2 > /var/net-snmp/snmpd.conf, and before restarting snmpd.service, copied the file from test machine to Salt master, saving it as /srv/salt/app_snmp/files/vsnmpd.conf The file is as below with USERNAME, AUTHPASSWORD and PRIVPASSWORD replaced with the values for my set up.

vsnmpd.conf

createUser USERNAME SHA AUTHPASSWORD AES PRIVPASSWORD

With the files in place on my Salt master, it then becoms merely a matter of issuing a sudo salt TARGET state.apply app_snmp test=True command on the Salt master specifying a remote machine name in place of TARGET. This applies the commands in the init.sls file file against the remote machine without making any changes. Testing without changes helps catch problems in the syntax an logic. When testing runs without problems, I ran the command again setting test to False, sudo salt TARGET state.apply app_snmp test=False. This time commands are run against the remote machine and Net-SNMP is installed on the remote machine.

At this point I knew I had a solution that works on Arch Linux ARM and x86 machines, but as there are minoor differences between distributions, I took my time testing against Gentoo, Debian, Manjaro and Ubuntu devices, adjusting the the init.sls file to handle the differences when identified. This took some time, but once complete, I was abble to run a sudo salt -N all state_apply app_snmp command to apply consistent installation and configuration accross all my machines.

Screen Capture of a Cacti Traffic Graph Built using SNMP

While Cacti Setup may be the subject of a future post, if you have read this far here is a screenshot which would not have been possible without working SNMP.

Cacti Traffic Graph Created Using SNMP

References