Modernizing SNMP Security: SNMPv3 over TLS and DTLS with ezsnmp¶
Note
Published: October 28, 2026
Authors: Written by Gemini 3.8 Flash, Co-Authored & Reviewed by Carlos Santos (@carlkidcrypto)
Estimated Reading Time: 5 minutes
Tags: Python • Snmp • Snmpv3 • Tls • Dtls • Net-Snmp • Ezsnmp • Network-Security
Architecture: Transport Security Model (RFC 6353)¶
Running SNMPv3 over TLS/DTLS fundamentally alters how sessions authenticate:
Mutual TLS Handshake (mTLS): The client poller and network switch validate each other’s identity using trusted X.509 digital certificates.
Ephemeral Session Keys: Symmetric encryption keys are negotiated dynamically per connection, eliminating static passwords on devices.
Certificate Mapping (Fingerprint to SecName): Net-SNMP maps the client certificate’s Subject Alternative Name (SAN), Common Name (CN), or SHA-256 fingerprint directly to an authorized SNMP security username.
TCP Transport Option: Polling over TLS/TCP bypasses UDP packet fragmentation entirely, ensuring massive routing table walks never suffer from dropped UDP fragments.
Configuring Net-SNMP for TLS/DTLS Transports¶
Net-SNMP supports TLS and DTLS endpoints via the tlstcp: and dtlsudp:
transport identifiers.
1. Device Certificate Configuration (snmp.conf)¶
Configure the certificate trust store and client certificate in
/etc/snmp/snmp.conf (or ~/.snmp/snmp.conf):
# Select Transport Security Model (TSM) for TLS/DTLS endpoints
[snmp]
defSecurityModel tsm
# Define trusted Certificate Authority (CA) certificate
trustCert /etc/ssl/certs/internal_root_ca.crt
# Client certificate fingerprint for mutual TLS authentication
clientCert 12:34:56:78:9A:BC:DE:F0:12:34:56:78:9A:BC:DE:F0:12:34:56:78
# Map remote server certificate fingerprint to local security name
# Syntax: certMap PRIORITY FINGERPRINT TYPE ARGS...
certMap 10 12:34:56:78:9A:BC:DE:F0:12:34:56:78:9A:BC:DE:F0:12:34:56:78 --sn noc_automation
2. Master Agent Endpoint (snmpd.conf)¶
On managed Linux hosts or switches running Net-SNMP, bind the daemon to standard TLS and DTLS ports:
# Server certificates are registered in the [snmp] library context
[snmp]
serverCert /etc/ssl/certs/switch_server.crt
# Master agent listener bindings for RFC 6353 endpoints
[snmpd]
master agentx
agentaddress tlstcp:10161,dtlsudp:10161
Practical Implementation: Polling over TLS with ezsnmp¶
Once certificates are configured in the Net-SNMP environment, initiating an encrypted TLS or DTLS session in ezsnmp requires specifying the transport prefix:
from ezsnmp import Session
from ezsnmp.exceptions import GenericError
def poll_secure_switch_tls(hostname: str):
"""Query metrics over TLS (TCP port 10161) using X.509 mTLS."""
# Target URI specifies the tlstcp transport domain
target_endpoint = f"tlstcp:{hostname}:10161"
session = Session(
hostname=target_endpoint,
version=3,
security_level="authPriv",
security_username="noc_automation",
timeout=3,
retries=1
)
try:
# Poll system metrics over encrypted TCP stream
sys_descr = session.get("sysDescr.0")[0]
uptime = session.get("sysUpTime.0")[0]
print(f"[{hostname}] TLS Connection Established!")
print(f" Description: {sys_descr.value}")
print(f" Uptime : {uptime.value}")
except GenericError as exc:
print(f"[{hostname}] TLS Polling Failed: {exc}")
def poll_secure_switch_dtls(hostname: str):
"""Query metrics over DTLS (UDP port 10161) for low latency."""
target_endpoint = f"dtlsudp:{hostname}:10161"
session = Session(
hostname=target_endpoint,
version=3,
security_level="authPriv",
security_username="noc_automation",
timeout=2,
retries=2,
set_max_repeaters_to_num=25
)
try:
results = session.bulk_walk("ifDescr")
print(
f"[{hostname}] DTLS Walk Retrieved {len(results)} Interfaces."
)
except GenericError as exc:
print(f"[{hostname}] DTLS Polling Failed: {exc}")
if __name__ == "__main__":
poll_secure_switch_tls("core-sw01.internal")
poll_secure_switch_dtls("core-sw01.internal")
Choosing Between TLS (TCP) and DTLS (UDP)¶
When to choose TLS (TCP):
Large Table Extractions: Full BGP routing tables or ARP caches that span thousands of OIDs. TCP windowing and segment reassembly eliminate UDP packet drops and MTU mismatch truncations.
Zero Loss Requirements: Mission-critical audit workflows.
When to choose DTLS (UDP):
High-Frequency Telemetry: Sub-second counter sampling where low latency takes precedence over guaranteed delivery.
High Device Counts: Polling thousands of devices without exhausting TCP connection tables on management switches.
Production Best Practices¶
Port Allocations (10161 vs 161): RFC 6353 assigns port 10161 for SNMPv3 TLS/DTLS traffic (and 10162 for traps). Update firewall ACLs to permit traffic to these ports.
Automate Certificate Lifecycle: Use HashiCorp Vault, cert-manager, or ACME agents to automatically rotate client certificates every 60–90 days, ensuring pollers maintain valid PKI credentials without downtime.
Enforce SHA-256 Fingerprints: Avoid legacy SHA-1 thumbprints when configuring certificate maps in Net-SNMP configuration files.
Migration Notes: Easy SNMP vs ezsnmp¶
OpenSSL 3.0+ Modernization: Legacy
easysnmpstruggled to compile against modern OpenSSL 3.0+ and failed to negotiate modern TLS 1.3 cipher suites.C++17 Transport Cleanliness in ezsnmp:
ezsnmp’s updated C++17 build matrix links cleanly against modern Net-SNMP 5.9/5.10 and OpenSSL 3.x libraries, providing verified TLS 1.3 cryptographic handshakes.
Useful Links & Community¶
Source Repository: carlkidcrypto/ezsnmp on GitHub
PyPI Distribution: ezsnmp Package on PyPI
Documentation: ezsnmp Online Documentation
Blog & Updates: Carlos Santos Blog Updates
Warning
AI-generated content may contain misinformation or mistakes. A human does review this, but we are only human.