master
yaml 400 lines 24.4 KB
Raw
1 # yamllint disable rule:line-length
2 ---
3 id: 'service-discovery-snmp'
4 meta:
5 kind: 'snmp'
6 name: 'SNMP'
7 tagline: 'SNMP-capable devices on configured network subnets.'
8 link: 'https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol'
9 icon_filename: 'SNMP.png'
10 keywords:
11 - 'service discovery'
12 - 'sd'
13 - 'snmp'
14 - 'snmpv3'
15 - 'usm'
16 - 'network'
17 - 'network devices'
18 - 'discovery'
19 overview:
20 description: |
21 Netdata can automatically discover SNMP-capable devices on your network and generate `snmp` collector jobs for each one. Configure the IP ranges to scan and the SNMP credentials to try, and the discoverer probes each address, reads basic system information, and produces collector configurations from a set of customisable service rules.
22
23 This page covers SNMP-specific setup. For the broader Service Discovery model (`discoverer:` and `services:` blocks, rule evaluation order, and the full template helper reference shared by all discoverers), see [Service Discovery](/src/collectors/SERVICE-DISCOVERY.md).
24 how_it_works: |
25 Each discovery cycle, the discoverer:
26
27 1. **Iterates** every IP in the configured `networks[]` subnets, in parallel.
28 2. **Probes** each IP over UDP/161 using the credential bound to that subnet, walking the standard `system` MIB (`sysDescr`, `sysName`, `sysContact`, `sysLocation`, `sysObjectID`).
29 3. **Caches** the result in a status file so re-probing is skipped while `device_cache_ttl` has not expired.
30 4. **Emits a target** per reachable device, exposing `.IPAddress`, `.SysInfo.*`, and `.Credential.*` to the rule engine.
31 5. **Runs the `services:` rules** against each target. The rules render Go templates to produce one (or more) `snmp` collector job configurations.
32
33 The discoverer never queries device-specific OIDs — those are queried later by the `snmp` collector once the job is created.
34 limitations: |
35 - Each subnet is capped at 512 IP addresses (a `/23` network or smaller). Split larger ranges into multiple `networks[]` entries.
36 - Discovery uses **UDP/161**. The Netdata Agent host must be able to reach that port on every scanned IP, and any device-side ACLs must allow the Netdata host.
37 - **One credential per subnet**: each `networks[]` entry is bound to exactly one credential. There is no automatic credential fallback. To probe the same subnet with multiple credentials, list it twice with different `credential` values; each device that responds to either credential will appear as a target (with its responding credential exposed via `.Credential.*`).
38 - **Outbound interface**: probes use the host's default routing. There is no per-pipeline bind-address or VRF option — on multi-homed hosts, configure the OS routing table so the Netdata host reaches each target subnet via the correct interface.
39 - The discoverer reads only the standard `system` MIB. Vendor-specific identification (`.SysInfo.Vendor`, `.Category`, `.Model`) is derived from `sysObjectID` and an enterprise-numbers table; values may be empty or `Unknown` for devices that are not in that table.
40 - **SNMPv3 engine ID**: gosnmp negotiates the engine ID at the start of each probe (one extra round-trip per probe — usually irrelevant unless `parallel_scans_per_network` is high and the device is rate-limited). Engine IDs are not cached across probes, so devices that rotate engine IDs (rare; some HA pairs do this on failover) are handled transparently.
41 - **Credential storage**: community strings and SNMPv3 passphrases are stored in plaintext both in `/etc/netdata/go.d/sd/snmp.conf` (file-based pipelines) and in the agent's dynamic-configuration store under `/var/lib/netdata/dyncfg/` (UI-managed pipelines). To avoid plaintext credentials on disk in either path, reference them via `${env:VAR}` or `${file:/path}` (see [Secrets Management](/src/collectors/SECRETS.md)).
42 setup:
43 prerequisites:
44 list:
45 - title: 'Plan your IP ranges and credentials'
46 description: |
47 Decide which subnets to scan and which SNMP credentials apply to each. SNMPv1 and SNMPv2c need a community string. SNMPv3 needs a USM username, security level, and (depending on the level) authentication and privacy passphrases.
48 - title: 'Allow UDP/161 reachability'
49 description: |
50 The Netdata Agent host must be able to reach UDP port 161 on every scanned IP. SNMP devices typically restrict which clients can query them — make sure the Netdata host is allowed by any device-side ACLs.
51 configuration:
52 file:
53 name: 'go.d/sd/snmp.conf'
54 options:
55 description: |
56 The configuration file has two top-level blocks: `discoverer:` (the options below) and `services:` (rules that turn discovered devices into `snmp` collector jobs — see [Service Rules](#service-rules)).
57
58 After editing the file, restart the Netdata Agent to load the updated discovery pipeline.
59 folding:
60 title: 'Discoverer options'
61 enabled: false
62 list:
63 - name: 'rescan_interval'
64 description: 'How often to rescan configured networks for devices.'
65 default_value: '30m'
66 required: false
67 detailed_description: |
68 Set to `0` to perform a single discovery scan when the agent starts and never rescan. Negative values also disable rescanning.
69 - name: 'timeout'
70 description: 'Maximum time to wait for an SNMP device response.'
71 default_value: '1s'
72 required: false
73 - name: 'device_cache_ttl'
74 description: 'How long to trust cached discovery results before re-probing a device.'
75 default_value: '12h'
76 required: false
77 detailed_description: |
78 Set to `0` to never expire cached results — once a device is discovered it is never re-probed (until the agent restarts and the cache is invalidated by configuration changes).
79 - name: 'parallel_scans_per_network'
80 description: 'How many IPs to probe concurrently within each subnet.'
81 default_value: 32
82 required: false
83 - name: 'credentials'
84 description: 'List of SNMP credentials referenced by entries in `networks`. At least one credential is required.'
85 default_value: ''
86 required: true
87 detailed_description: |
88 Each credential has a `name` (used by `networks[].credential`) and a `version`.
89
90 **Accepted `version` values:** `1`, `2`, `2c`, `3`. (`2` is an alias for `2c`.)
91
92 For SNMPv1 and SNMPv2c, set `community`.
93
94 For SNMPv3, set:
95
96 - `username` — USM user name.
97 - `security_level` — one of `noAuthNoPriv`, `authNoPriv`, `authPriv`.
98 - `auth_protocol` — one of `md5`, `sha` (HMAC-SHA-1, RFC 3414), `sha224`, `sha256`, `sha384`, `sha512` (HMAC-SHA-2, RFC 7860). Required for `authNoPriv` and `authPriv`.
99 - `auth_password` — authentication passphrase. Required when `auth_protocol` is set.
100 - `priv_protocol` — one of `des`, `aes` (AES-128), `aes192`, `aes256`, `aes192c`, `aes256c`. The `c` variants are the Cisco/Reeder draft; check your device's `show snmp user` output to pick the matching one. Required for `authPriv`.
101 - `priv_password` — privacy passphrase. Required when `priv_protocol` is set.
102 - `context_name` — only set this if your devices use a non-default SNMPv3 context.
103
104 **Naming note:** the YAML keys are `auth_password` and `priv_password`. The same fields are exposed inside service rule templates as `.Credential.AuthPassphrase` and `.Credential.PrivacyPassphrase` (the Go struct names). Both refer to the same value.
105
106 **Avoid plaintext on disk:** any of these fields can be sourced from environment variables or files using `${env:VAR_NAME}` or `${file:/absolute/path}` — see [Secrets Management](/src/collectors/SECRETS.md).
107 - name: 'networks'
108 description: 'List of subnets to scan, each tagged with the credential name to use. At least one network is required.'
109 default_value: ''
110 required: true
111 detailed_description: |
112 Each entry needs `subnet` (an IP range) and `credential` (the name of an entry from `credentials`).
113
114 **Supported subnet formats** (IPv4 and IPv6):
115
116 - CIDR — `192.168.1.0/24`, `2001:db8::/120`
117 - Range — `10.0.0.1-10.0.0.50`, `2001:db8::-2001:db8::ff`
118 - Subnet mask — `192.168.1.0/255.255.255.0`
119 - Single IP — `192.168.1.10`, `2001:db8::1`
120
121 Maximum **512 IPs** per subnet entry. Split larger blocks across multiple entries.
122
123 For CIDR notation, network and broadcast addresses are excluded (except `/31`, `/32`, `/127`, `/128`).
124 examples:
125 folding:
126 title: 'Configuration examples'
127 enabled: true
128 list:
129 - name: 'Single subnet, SNMPv2c'
130 description: 'Scan a single /24 with the default `public` community.'
131 config: |
132 disabled: no
133 discoverer:
134 snmp:
135 credentials:
136 - name: public-v2c
137 version: 2c
138 community: public
139 networks:
140 - subnet: 192.168.1.0/24
141 credential: public-v2c
142 services:
143 - id: snmp
144 match: '{{ true }}'
145 - name: 'Multiple subnets, mixed SNMPv2c and SNMPv3'
146 description: 'Mix SNMPv2c on one subnet with SNMPv3 (authPriv) on another. Credentials are referenced from environment variables to keep them out of plaintext on disk.'
147 config: |
148 disabled: no
149 discoverer:
150 snmp:
151 rescan_interval: 1h
152 credentials:
153 - name: public-v2c
154 version: 2c
155 community: ${env:SNMP_V2C_COMMUNITY}
156 - name: secure-v3
157 version: 3
158 security_level: authPriv
159 username: netdata-monitor
160 auth_protocol: sha256
161 auth_password: ${env:SNMP_V3_AUTH}
162 priv_protocol: aes256
163 priv_password: ${env:SNMP_V3_PRIV}
164 networks:
165 - subnet: 192.168.10.0/24
166 credential: public-v2c
167 - subnet: 10.20.30.0/24
168 credential: secure-v3
169 services:
170 - id: snmp
171 match: '{{ true }}'
172 - name: 'IPv6 subnet'
173 description: 'Scan a small IPv6 range with SNMPv2c.'
174 config: |
175 disabled: no
176 discoverer:
177 snmp:
178 credentials:
179 - name: public-v2c
180 version: 2c
181 community: public
182 networks:
183 - subnet: 2001:db8:0:1::/120
184 credential: public-v2c
185 services:
186 - id: snmp
187 match: '{{ true }}'
188 services:
189 description: |
190 A `services:` rule turns each discovered SNMP device into one or more `snmp` collector jobs. Each rule has an `id`, a Go-template `match` expression that decides whether the rule applies to the device, and an optional `config_template` that renders the collector job YAML when the rule matches.
191
192 The default rule shipped with Netdata (`{{ true }}`) creates one job per discovered device and handles both SNMPv2 and SNMPv3 — most users never change it. Customise rules when you want vendor-specific configs (Cisco vs. Juniper, printers vs. routers), per-VLAN overrides, or multiple jobs per device.
193
194 The shared rule model — function reference (sprig + Netdata helpers `match`, `glob`, `promPort`, `toYaml`), `config_template` rendering rules, and the strict-missing-key error semantics — lives on the [Service Discovery](/src/collectors/SERVICE-DISCOVERY.md) hub page. The notes below are SNMP-specific.
195 evaluation:
196 description: |
197 Quick reference — see [Rule evaluation semantics](/src/collectors/SERVICE-DISCOVERY.md#rule-evaluation-semantics) on the hub page for the full model (sequence-output multi-job rendering, module inference from `id`, `missingkey=error`, ordering recommendations).
198 list:
199 - name: 'Skip rule (no config_template)'
200 description: 'A matching rule with no `config_template` drops the device immediately no job, no further rule evaluation. Use it to exclude devices the catch-all would otherwise pick up. Place **before** any template rule.'
201 - name: 'Template rule (with config_template)'
202 description: 'A matching rule with a `config_template` produces one or more jobs and rule evaluation **continues**. A single device can therefore produce jobs from several matching rules.'
203 - name: 'For SNMP specifically'
204 description: 'Set `id: snmp` so the rendered job inherits the `snmp` module name automatically, or include `module: snmp` explicitly inside the `config_template` (required when `id` is anything else, e.g. `cisco`).'
205 template_variables:
206 description: |
207 Available inside both `match` expressions and `config_template` bodies. All variables are strings; empty values render as the empty string.
208 list:
209 - name: '.IPAddress'
210 type: 'string'
211 description: 'IP address of the discovered device. Always set.'
212 - name: '.SysInfo.Descr'
213 type: 'string'
214 description: 'Value of `sysDescr.0` (vendor-supplied free-form description). May be empty.'
215 - name: '.SysInfo.Contact'
216 type: 'string'
217 description: 'Value of `sysContact.0`. May be empty.'
218 - name: '.SysInfo.Name'
219 type: 'string'
220 description: 'Value of `sysName.0` (typically the device hostname or FQDN). Defaults to the literal string `unknown` when the device does not return one.'
221 - name: '.SysInfo.Location'
222 type: 'string'
223 description: 'Value of `sysLocation.0`. May be empty.'
224 - name: '.SysInfo.Organization'
225 type: 'string'
226 description: 'Vendor or organization parsed from `sysObjectID` against the embedded enterprise-numbers table. Defaults to `Unknown` when the OID is not in the table.'
227 - name: '.SysInfo.Vendor'
228 type: 'string'
229 description: 'Vendor name inferred from `sysObjectID` and `sysDescr` via the bundled overrides. Empty when no override matches.'
230 - name: '.SysInfo.Category'
231 type: 'string'
232 description: 'Device category (e.g. `router`, `switch`, `printer`). Sourced from the bundled SNMP overrides; empty when no override matches the device. The set of category values is determined by the overrides, not a closed enum.'
233 - name: '.SysInfo.Model'
234 type: 'string'
235 description: 'Device model inferred from `sysObjectID` and `sysDescr` via the bundled overrides. Empty when no override matches.'
236 - name: '.Credential.Name'
237 type: 'string'
238 description: 'Name of the credential entry that successfully probed the device.'
239 - name: '.Credential.Version'
240 type: 'string'
241 description: 'Configured version string: `1`, `2`, `2c`, or `3`. Use `eq .Credential.Version "1" "2" "2c"` to branch v1/v2c vs v3.'
242 - name: '.Credential.Community'
243 type: 'string'
244 description: 'Community string (SNMPv1/v2c). Empty for SNMPv3.'
245 - name: '.Credential.UserName'
246 type: 'string'
247 description: 'SNMPv3 USM user name. Empty for v1/v2c.'
248 - name: '.Credential.SecurityLevel'
249 type: 'string'
250 description: 'SNMPv3 security level (`noAuthNoPriv`, `authNoPriv`, `authPriv`).'
251 - name: '.Credential.AuthProtocol'
252 type: 'string'
253 description: 'SNMPv3 auth protocol (`md5`, `sha`, `sha224`–`sha512`).'
254 - name: '.Credential.AuthPassphrase'
255 type: 'string'
256 description: 'SNMPv3 authentication passphrase. **YAML key for the same value: `auth_password`** (see [credentials option](#option-credentials)).'
257 - name: '.Credential.PrivacyProtocol'
258 type: 'string'
259 description: 'SNMPv3 privacy protocol (`des`, `aes`, `aes192`, `aes256`, `aes192c`, `aes256c`).'
260 - name: '.Credential.PrivacyPassphrase'
261 type: 'string'
262 description: 'SNMPv3 privacy passphrase. **YAML key for the same value: `priv_password`** (see [credentials option](#option-credentials)).'
263 examples:
264 description: 'Each example shows one or more entries from the `services:` array. Order matters see [How rules are evaluated](#how-rules-are-evaluated).'
265 list:
266 - name: 'Default catch-all rule'
267 description: |
268 Generate one `snmp` collector job per discovered device. This is the rule produced by the stock conf and is sufficient for most deployments — it handles both SNMPv2 and SNMPv3 by branching on `.Credential.Version`. The `id: snmp` makes the module name infer to `snmp` automatically.
269 config: |
270 - id: snmp
271 match: '{{ true }}'
272 config_template: |
273 {{- if .SysInfo.Name }}
274 name: {{ .SysInfo.Name }}-ip-{{ .IPAddress }}
275 {{- else }}
276 name: ip-{{ .IPAddress }}
277 {{- end }}
278 hostname: {{ .IPAddress }}
279 options:
280 version: {{ .Credential.Version }}
281 {{- if eq .Credential.Version "1" "2" "2c" }}
282 community: {{ .Credential.Community }}
283 {{- else }}
284 user:
285 name: {{ .Credential.UserName }}
286 level: {{ .Credential.SecurityLevel }}
287 auth_proto: {{ .Credential.AuthProtocol }}
288 auth_key: {{ .Credential.AuthPassphrase }}
289 priv_proto: {{ .Credential.PrivacyProtocol }}
290 priv_key: {{ .Credential.PrivacyPassphrase }}
291 {{- end }}
292 - name: 'Skip rule for management VIPs'
293 description: |
294 Drop devices whose `sysName` starts with `vip-` so they are not monitored. A skip rule is a rule with **no** `config_template`. Place it before the catch-all so its match wins first. (The second rule below is the [Default catch-all rule](#default-catch-all-rule) — paste its full body in place of the placeholder comment.)
295 config: |
296 - id: skip-vips
297 match: '{{ glob .SysInfo.Name "vip-*" }}'
298 - id: snmp
299 match: '{{ true }}'
300 config_template: |
301 # paste the body from the "Default catch-all rule" example here
302 - name: 'Vendor-specific override (Cisco) with catch-all suppressed'
303 description: |
304 Apply a Cisco-specific config to devices whose vendor matches `Cisco*`, then prevent the catch-all from producing a duplicate job for the same devices. This is the recommended three-rule pattern for any vendor-specific override:
305
306 1. **Specific template rule** (`cisco`) — renders the Cisco-tuned job. `id: cisco` does **not** map to a real collector module, so `module: snmp` is set explicitly in the template.
307 2. **Skip rule** (`skip-cisco-from-catchall`) — drops Cisco devices from the remaining pipeline so step 3 does not also fire for them.
308 3. **Catch-all template rule** (`snmp`) — handles every non-Cisco device.
309 config: |
310 - id: cisco
311 match: '{{ glob .SysInfo.Vendor "Cisco*" }}'
312 config_template: |
313 module: snmp
314 name: cisco-{{ .SysInfo.Name }}-{{ .IPAddress }}
315 hostname: {{ .IPAddress }}
316 options:
317 version: {{ .Credential.Version }}
318 {{- if eq .Credential.Version "1" "2" "2c" }}
319 community: {{ .Credential.Community }}
320 {{- else }}
321 user:
322 name: {{ .Credential.UserName }}
323 level: {{ .Credential.SecurityLevel }}
324 auth_proto: {{ .Credential.AuthProtocol }}
325 auth_key: {{ .Credential.AuthPassphrase }}
326 priv_proto: {{ .Credential.PrivacyProtocol }}
327 priv_key: {{ .Credential.PrivacyPassphrase }}
328 {{- end }}
329
330 - id: skip-cisco-from-catchall
331 match: '{{ glob .SysInfo.Vendor "Cisco*" }}'
332
333 - id: snmp
334 match: '{{ true }}'
335 config_template: |
336 # ... (same as the catch-all in the Default catch-all rule example above)
337 - name: 'Category-based rule (HP printers)'
338 description: |
339 Match by `.SysInfo.Category` to apply a printer-specific config. Category values are populated from the bundled SNMP overrides — `printer` is one of the standard categories produced by the override file shipped with Netdata. Pair with a follow-up skip rule the same way as the Cisco example if you want to suppress the catch-all for printers.
340 config: |
341 - id: hp-printer
342 match: '{{ and (eq .SysInfo.Category "printer") (glob .SysInfo.Vendor "HP*" "Hewlett*") }}'
343 config_template: |
344 module: snmp
345 name: printer-{{ .SysInfo.Name }}-{{ .IPAddress }}
346 hostname: {{ .IPAddress }}
347 update_every: 30
348 options:
349 version: {{ .Credential.Version }}
350 community: {{ .Credential.Community }}
351 verify:
352 description: 'After enabling the discoverer, confirm it is finding devices and producing jobs.'
353 checks:
354 list:
355 - name: 'Confirm devices are being probed'
356 description: |
357 Watch the agent log for SNMP discoverer messages. On a successful probe you should see lines like:
358
359 ```text
360 discoverer=snmp ... device '192.168.1.10': successfully discovered (sysName: 'sw01.example.com', network: '192.168.1.0/24')
361 ```
362
363 With systemd:
364
365 ```bash
366 journalctl _SYSTEMD_INVOCATION_ID="$(systemctl show --value --property=InvocationID netdata)" --namespace=netdata --grep "discoverer=snmp"
367 ```
368
369 Without systemd:
370
371 ```bash
372 grep "discoverer=snmp" /var/log/netdata/collector.log
373 ```
374 - name: 'Confirm jobs are being created'
375 description: |
376 Discovered devices should produce `snmp` collector jobs. In the Netdata UI go to `Collectors -> go.d -> snmp` — each discovered device appears as a job named according to your `config_template` (the default catch-all renders `<sysName>-ip-<address>`).
377 - name: 'Confirm metrics are being collected'
378 description: |
379 Once a job exists, the `snmp` collector takes over and starts collecting metrics. Charts for each device appear under the SNMP integration on the dashboard. If a job is created but metrics never appear, the problem is in the `snmp` collector configuration (rendered by your `config_template`), not in the discoverer.
380 troubleshooting:
381 problems:
382 list:
383 - name: 'No devices are discovered'
384 description: |
385 Check the agent log for `discoverer=snmp` messages. Common causes:
386
387 - The configured subnets do not match where your devices live. Verify with `ping` / `arp` from the Netdata host.
388 - UDP port 161 is blocked between the Netdata host and the devices. Test with `nc -zu <ip> 161` or `snmpwalk -v2c -c <community> <ip> sysDescr.0`.
389 - The credentials do not match what the devices accept. SNMPv3 mismatches commonly produce `authentication failure` or `decryption error` log lines.
390 - A configured subnet exceeds the 512-IP cap and the discoverer rejected it at startup. Look for `subnet '...' exceeds maximum size of /23` in the log.
391 - name: 'Wrong devices are matched by a rule'
392 description: |
393 Rule order matters — see [How rules are evaluated](#how-rules-are-evaluated). Place vendor-specific or device-specific rules **before** the catch-all. If you need to suppress the catch-all for a subset of devices, follow the specific rule with a skip rule (no `config_template`) keyed on the same condition.
394 - name: 'Generated collector jobs fail to start'
395 description: |
396 The discoverer creates jobs but does not run them — the `snmp` collector does. Check the `snmp` collector log and the rendered job YAML in the agent's debug output. Common causes:
397
398 - The rendered `config_template` produces invalid YAML for some discovered field values (for example, unescaped colons in `sysName`). YAML-quote dynamic values when in doubt.
399 - Module name mismatch — the rule `id` (or explicit `module:` field) does not match `snmp`.
400 - SNMPv3 credentials succeeded for `system` MIB during discovery but the collector cannot read other OIDs (different VACM view); confirm with `snmpwalk` against the device.