Configuring snmpd.conf

A working snmpd.conf example is worth more than a thousand words of theory, so this page hands you one and then explains every line of it. The file at /etc/snmp/snmpd.conf is where an SNMP agent learns four things: who's allowed to ask, what group that someone belongs to, which slice of the OID tree that group may see, and whether the whole arrangement is read-only. Those four decisions map to four directives — com2sec, group, view, access. Get them right and you have a tightly scoped, read-only agent that exposes exactly the metrics you monitor and nothing else. Get them wrong and you either expose the whole tree or expose nothing. Let's get them right.

Prerequisites

This page assumes the agent already exists. Before editing the snmpd.conf configuration, confirm:

  • snmpd is installed and enabled — if not, start at Install snmpd on Ubuntu/Debian.
  • You're running SNMPv2c, which is what the com2sec/group/access model here targets (v2c is defined across RFC 1901 and RFC 3416).
  • Root or sudo, since /etc/snmp/snmpd.conf is root-owned.
  • A shortlist of the OIDs you actually want to publish. You'll add one view line each, so know them in advance — the sensor & OID catalog is the reference.
  • A test machine with snmpwalk to confirm the rules do what you meant.

Have that OID list ready before you open the file. Writing view lines is faster when you're not tab-switching to look up numbers.

Screenshot: an annotated /etc/snmp/snmpd.conf showing com2sec, group, view and access directives with a read-only allowlist

Step-by-step

The classic Net-SNMP access model is four directives stacked in order. Here's how to build them.

  1. Open the file:
    sudo nano /etc/snmp/snmpd.conf
    
  2. Map a community string to a security name with com2sec. This says "any request arriving with this community, from this source, is known internally as ReadUser":
    #       sec.name    source    community
    com2sec ReadUser    default   <password>
    
    The source of default means any address; tighten it to a subnet or single IP for real deployments.
  3. Put that security name in a group, bound to the v2c model:
    #       group        sec.model  sec.name
    group   ReadGroup    v2c        ReadUser
    
  4. Define a view — the set of OIDs the group may read. One included line per OID is the safest pattern:
    #       view         incl/excl  subtree
    view    ReadData     included   .1.3.6.1.2.1.25.1.1.0
    
  5. Tie it together with access, granting the group read-only rights to that view, with no write and no notify:
    #       group        context  model  level   prefix  read      write  notify
    access  ReadGroup    ""       any    noauth  exact   ReadData  none   none
    
  6. Save and restart:
    sudo service snmpd restart
    

Read the four directives as a chain: a community becomes a security name (com2sec), the security name joins a group (group), the group is granted a view (access), and the view enumerates OIDs (view). Break any link and the request is refused. That refusal-by-default is a feature — it's why an allowlisted agent leaks so little.

The access line packs the most fields, so it's worth slowing down on. The context (empty quotes here) and model (any) are rarely changed for a basic v2c setup. noauth is the security level — correct for v2c, which has no authentication layer to require. exact is the view-matching prefix rule. Then come the three permission slots: read points at your view (ReadData), while write and notify are both none. Those two none values are quietly the most important thing in the file. They're what guarantee that even a leaked community can only read — it can never set a value or trigger a notification. A read-only agent is a fundamentally smaller target than a read-write one.

Configuration example

The five directives that make a read-only v2c agent work:

DirectiveRoleExample
agentAddresslisten address/portudp:161,udp6:[::1]:161
com2secmap community → sec.namecom2sec ReadUser default <password>
groupbind sec.name to a modelgroup ReadGroup v2c ReadUser
viewinclude an OID subtreeview ReadData included .1.3.6.1.2.1.25.1.1.0
accessgrant the group read on the viewaccess ReadGroup "" any noauth exact ReadData none none

Here's the complete snmpd.conf example, assembled, with the view expanded to a realistic metric set:

# /etc/snmp/snmpd.conf  — v2c read-only, allowlisted OIDs
agentAddress udp:161,udp6:[::1]:161        # change 161 to a random port for security

#       sec.name    source    community
com2sec ReadUser    default   <password>

#       group        sec.model  sec.name
group   ReadGroup    v2c        ReadUser

#       view         incl/excl  subtree
view    ReadData     included   .1.3.6.1.2.1.25.1.1.0
view    ReadData     included   .1.3.6.1.2.1.25.3.3.1.2
view    ReadData     included   .1.3.6.1.2.1.25.2.3.1.6
view    ReadData     included   .1.3.6.1.4.1.2021.10.1.3

#       group        context  model  level   prefix  read      write  notify
access  ReadGroup    ""       any    noauth  exact   ReadData  none   none

Each view ... included line publishes exactly one branch. Here that's host uptime (1.3.6.1.2.1.25.1.1.0, hrSystemUptime), per-CPU load (1.3.6.1.2.1.25.3.3.1.2, hrProcessorLoad), storage used (1.3.6.1.2.1.25.2.3.1.6, hrStorageUsed), and 15-minute system load (1.3.6.1.4.1.2021.10.1.3, laLoad from the UCD-SNMP-MIB). The first three live in the Host Resources MIB (RFC 2790). Add or remove lines to match what you chart — the discipline of one line per OID is covered in depth in the OID allowlist guide. Curating that list, rather than exposing .1.3.6.1, is the single biggest thing snmpd.conf configuration does for your security posture.

Verify it works

Restart, then prove the rules behave — both that allowed OIDs answer and that everything else stays hidden.

service snmpd status

From another machine, walk an OID you included, say per-CPU load:

snmpwalk -v2c -c <community> <host>:<port> 1.3.6.1.2.1.25.3.3.1.2

You should get one hrProcessorLoad line per core — the CPU sensor page explains those values. Now confirm the allowlist actually restricts. Walk something you did not include:

snmpwalk -v2c -c <community> <host>:<port> 1.3.6.1.2.1.1

An empty or "no such object" result is the correct answer — it proves the view is fencing the tree the way it should. If everything returns, your access line is probably pointing at a view broader than ReadData, or you left a default rocommunity line uncommented above. Check both.

Security note

The access model is your first line of defence, so treat these as non-negotiable:

  • Keep write and notify at none in the access line — a read-only agent can't be turned into a foothold.
  • Never expose .1.3.6.1 wholesale. Enumerate OIDs; the shorter the view, the smaller the blast radius.
  • Replace the community placeholder with a long random value — see Secure the community string.
  • Scope the com2sec source from default to your poller's subnet or IP.
  • Comment out stock rocommunity public lines that ship in the default file; they quietly override your careful ACL.
  • Read the wider threat model on the security overview.

The whole point of this file is least privilege. Every extra OID and every wildcard source chips away at it.

Next: connect external monitoring

A precisely configured agent is only half the system. It answers when asked — but something has to keep asking, and ideally from a place that won't fall over at the same moment the server does. Polling from inside the same failure domain is how outages go unnoticed: the box dies, and the poller dies with it. Watching from outside the network closes that gap, which is the reasoning behind double durability — more than one independent source of truth beats a single local one.

ostr.io Monitoring reads the very OIDs you just allowlisted, from outside your infrastructure, and raises real-time email and SMS alerts when a value crosses your threshold. Because it's agentless on the monitoring side, your snmpd.conf is the only server-side config it needs. The add-endpoint guide covers registering the host.

Diagram: how a request flows through com2sec to group to access to view before an OID value is returned

Frequently asked questions

What's the difference between com2sec, group, view, and access?

com2sec maps an incoming community and source to an internal security name. group collects security names under a model (v2c here). view lists which OID subtrees are visible. access binds a group to a view with a permission level. All four are required for the chain to grant access.

How do I add another OID to monitor?

Add one more view ReadData included .<oid> line for it, then restart snmpd. Nothing else changes — the group and access rules already point at the ReadData view.

Why does my walk return nothing even though snmpd is running?

The OID isn't in your view, or a leftover rocommunity/broad view line is conflicting. Confirm the exact OID has an included line and that no stock directive is overriding your ACL.

Can I use SNMPv3 instead of this v2c model?

Yes. SNMPv3 (RFC 3411–3418) replaces com2sec with user-based security (USM) and access control (VACM). It's the better choice on untrusted links; this page covers the widely used v2c community model.

Conclusion

A good snmpd.conf configuration is four directives doing one clear job: com2sec names the requester, group files it, view fences the OIDs, and access stamps it read-only. Copy the snmpd.conf example above, trim the view lines to the metrics you actually chart, swap in a real community string, restart, and verify that unlisted OIDs stay dark. Then hand the endpoint to an external checker — because a perfectly configured agent still can't alert you about the outage that takes it offline.

Monitor it from outside the network

SNMP only tells you a box is healthy while something is still asking. ostr.io polls your endpoints externally and fires email + SMS alerts the moment a reading crosses your line — or the agent goes silent.