Skip to content

neo (MokerLink, 10.7.7.2) stopped answering SNMP — ICMP and TCP/80 succeed, UDP/161 does not #22

Description

@Gerrrt

Area: SNMP / network devices

What should happen

snmp-exporter polls 10.7.7.2 every 60s with module=mokerlink, auth=auth_mokerlink, and
up{job="snmp",instance="10.7.7.2"} is 1. docs/observability.md lists the switch as a
collected source, and ./scripts/snmp-verify.sh --device neo reports PASS with a sysDescr
string.

What happens instead

The target has never been up. Not "went down during the SNMP community rotation" — never, for the
entire retention window:

max_over_time(up{job="snmp",instance="10.7.7.2"}[30d])    # 0
count_over_time(up{job="snmp",instance="10.7.7.2"}[30d])  # 23070 samples

SnmpTargetUnreachable and InstanceDown have been firing continuously as a result — alert
fatigue on a rule that is working correctly.

The switch is reachable at layer 3 from the monitoring host (10.0.99.20): ICMP succeeds and
TCP/80 (its management web UI) is open, both routed via pfSense. Only UDP/161 fails. Probes with
the current community from SOPS, and separately with public and private, all time out —
inconclusive by construction, because SNMPv2c has no "wrong community" reply and a rejecting
device is indistinguishable from a silent one.

Because ICMP and TCP replies already reach 10.0.99.20, the switch's return path is working. That
rules out a missing default gateway or route on the switch, and leaves two candidates:

  1. The switch's SNMP agent is disabled, has no read community, or restricts the NMS to a host
    list that does not include 10.0.99.20.
  2. pfSense passes ICMP and TCP/80 from 10.0.99.2010.7.7.2 but not UDP/161.
    docs/network.md lists 10.7.7.0/24 as reaching "Nothing", so the poll depends on a rule that
    is deliberately not published in this repository. The rotation runbook already flagged that rule
    as the first suspect; the ICMP/TCP-pass, UDP-fail split narrows it from "the rule is missing" to
    "the rule may not cover this protocol and port".

Relevant output

$ ./scripts/snmp-verify.sh

Current community
  PASS morpheus   10.0.99.1    <sysDescr>
  PASS mjolnir    10.0.99.10   <sysDescr>
  FAIL neo        10.7.7.2     no response (wrong community, filtered, or down)
  PASS shiva      10.0.30.10   <sysDescr>

snmp verification failed
$ ping -c 3 10.7.7.2        # 0% packet loss, ~3ms
$ ip route get 10.7.7.2     # via 10.0.99.1
$ tcp/80                    # open

Diagnostic sequence

Steps 0–2 change nothing. The point is to reach step 3 knowing which hypothesis is being fixed —
widening a firewall rule that did not need touching is the failure mode here.

0. Baseline, from the monitoring host:

ping -c 3 10.7.7.2
nc -vz -w 3 10.7.7.2 80
./scripts/snmp-verify.sh --device neo --dry-run   # confirms IP / auth / secret key name
./scripts/snmp-verify.sh --device neo

1. Ask pfSense whether the packet even left — the discriminator, no config change.
Status → System Logs → Firewall, filtered on 10.7.7.2 / 161 / UDP, then re-run the probe.
A block entry confirms hypothesis 2 — stop touching the switch. No entry is only weakly
informative, since pass rules do not log by default, so also check Diagnostics → States for a
udp state to :161. Then read the rule under Firewall → Rules: one written for TCP, or for
any port but TCP-only, produces exactly this signature. Record only that the rule exists and what
protocol it covers — rule bodies are deliberately unpublished.

2. Prove the agent from the switch's own segment, bypassing the firewall entirely — a host on
10.7.7.0/24. Answers there but not from 10.0.99.20 → hypothesis 2. Times out there too →
hypothesis 1, and no firewall change will help.

Avoid snmpget -c '<community>' from pfSense's shell: it puts the live community into root's
history and /proc/<pid>/cmdline — the exact leak scripts/snmp-verify.sh exists to close. If
you do it anyway, treat that community as burned and rotate the switch again afterwards.

3. Switch UIhttp://10.7.7.2SNMP, read-only inspection, in order: is the agent
globally enabled (most likely answer — switches in this class often ship with it off); is v1/v2c
enabled; is there a read-only community and does it match SNMP_COMMUNITY_MOKERLINK; is there an
NMS/manager allow-list excluding 10.0.99.20 (plausible, since it is on a different subnet), or an
agent bound to a specific management VLAN. Delete any public/private entries while there.

4. Fix. Hypothesis 1 → the runbook's §2.1 MokerLink row, then §2.2–§2.5. Hypothesis 2 → a
firewall change, which goes through the change.yml issue path with its segmentation checklist.

5. Either way, no redeploy. The community is already in SOPS and already in the rendered
snmp.yaml, so configuring the switch with it needs no repository change: the next 60-second
scrape goes green on its own. No make render, no make reload, no commit.

Related

  • Blocks the last device in Rotate the SNMP communities on all four devices #9. Until the switch answers, ./scripts/snmp-verify.sh --old returns
    SKIP for it by design, so whether it still accepts the community leaked in this repository's
    history is unknown, not proven clean. That unknown is why Rotate the SNMP communities on all four devices #9 stays open.
  • docs/observability.md lists the switch as a collected source. That row is aspirational today
    and will be true again once this is fixed, so it is deliberately left unedited.
  • The roadmap item "Add ifXTable (64-bit counters) to the mokerlink SNMP module" is unreachable
    until this is fixed — there are no 32-bit counters to improve on yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions