By the SNMP Monitoring team · Reviewed July 2026
There's one rule that matters more than any syntax on this page: never expose UDP 161 to the whole internet. An SNMP agent open to 0.0.0.0/0 is found by scanners within minutes and, on v2c, leaks everything to anyone who guesses the community. The fix is boring and effective — allow SNMP only from your manager's IP, and drop everything else. This guide gives the exact rules for iptables, ufw, and firewalld, plus cloud security groups, all scoped the safe way.
Parent: setup. Related: change the port, SNMP ports.
Which ports to allow
SNMP uses two UDP ports, and they live on different hosts. Open only the one each host actually needs:
| Port | Protocol | Where to open it |
|---|---|---|
| 161 | UDP | Inbound on the agent (the monitored device) |
| 162 | UDP | Inbound on the trap receiver (the manager) |
The agent you're monitoring needs UDP 161 inbound, from the poller only. The trap receiver — usually your monitoring server — needs UDP 162 inbound, from the devices that send traps. Both are UDP, not TCP; a common mistake is writing a TCP rule that never matches. Scope each to the specific source address; a bare "allow 161" from anywhere defeats the whole exercise.
iptables rules
For raw iptables, accept UDP 161 from the manager and let your default-drop policy handle the rest:
sudo iptables -A INPUT -p udp -s 10.0.0.5 --dport 161 -j ACCEPT
The disciplined way to apply it:
- Add the accept rule for your manager's IP (above).
- Confirm your chain actually drops by default (
iptables -L INPUTshows policy DROP) — an ACCEPT is meaningless if everything is already allowed. - Repeat the accept line for each additional manager or CIDR.
- Persist the rules (
iptables-save, or netfilter-persistent) so they survive a reboot.
If your default INPUT policy is ACCEPT, add an explicit drop for 161 after the allow, or the rule accomplishes nothing. iptables is order-sensitive: the first matching rule wins, so put the specific accept before any broad drop.
ufw rules (Ubuntu/Debian)
ufw is the friendlier front-end on Debian and Ubuntu. One line scopes SNMP to a source:
sudo ufw allow from 10.0.0.5 to any port 161 proto udp
That allows UDP 161 inbound only from 10.0.0.5. To verify what ufw ended up with:
sudo ufw status verbose
To Action From
-- ------ ----
161/udp ALLOW IN 10.0.0.5
Never use the unscoped ufw allow 161/udp — that opens the port to everyone. Always include the from <ip> clause. For a trap receiver, repeat with port 162. See Ubuntu/Debian setup for where this fits in a fresh install.
firewalld rules (RHEL family)
On Rocky, Alma, RHEL, and Fedora, firewalld's rich rules give you the same source-scoped control:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.5" port port="161" protocol="udp" accept'
sudo firewall-cmd --reload
The --permanent flag writes it to disk; --reload applies it. Confirm with:
sudo firewall-cmd --list-rich-rules
rule family="ipv4" source address="10.0.0.5" port port="161" protocol="udp" accept
Avoid the blunt firewall-cmd --add-service=snmp, which opens 161 to every zone source — the rich rule scoped to your manager's address is the version you want. CentOS/RHEL setup covers the surrounding install and SELinux notes.
Cloud security groups
Off-host firewalls follow the same principle. In AWS security groups, GCP firewall rules, or Azure NSGs, add an inbound allow for UDP 161 with the source restricted to your monitoring host or its security group — never 0.0.0.0/0. The mistake to avoid in the cloud is treating the security group as "just open the port"; the source field is the actual control. If your poller lives in the same VPC, reference its security group as the source rather than a hardcoded IP, so the rule survives an address change.
One caution specific to the cloud: a security group and a host firewall are two independent layers, and a request has to pass both. It's common to open the security group, forget the instance's own ufw or firewalld is still blocking 161, and spend an hour convinced the cloud rule is wrong. Check both layers when SNMP won't connect. The upside of the belt-and-braces approach is real, though — if one layer is misconfigured too loosely, the other still contains the exposure, so keeping both scoped to the manager is worth the small extra effort.
A related point on defence in depth: the firewall is necessary but not sufficient. A source-scoped rule stops the wrong hosts from reaching the port at all, but it does nothing about a manager that's compromised or a community string that leaks to an allowed host. That's why the firewall belongs alongside an OID allowlist and, where you can, SNMPv3 — each layer covers a different failure. Treat the firewall as the outer wall, not the whole castle.
Verify
Prove the rule does both jobs — lets the manager in, keeps others out. From the allowed host:
snmpwalk -v2c -c S3cr3tR0str1ng 10.0.0.20 system
SNMPv2-MIB::sysDescr.0 = STRING: Linux edge01 5.15.0-generic x86_64
SNMPv2-MIB::sysUpTime.0 = Timeticks: (34567890) 3 days, 23:57:58.90
From any other source, the same query should hang and fail:
Timeout: No Response from 10.0.0.20
Data from the manager and a timeout from everywhere else is exactly the outcome you want. If the blocked host still gets through, check for a broader accept rule earlier in the chain overriding your scoped one.
Frequently asked questions
How do I open port 161 in the firewall?
Add a source-scoped UDP rule. ufw: ufw allow from <manager-ip> to any port 161 proto udp. iptables: iptables -A INPUT -p udp -s <manager-ip> --dport 161 -j ACCEPT. firewalld: a rich rule with source address=<manager-ip> port port=161 protocol=udp accept, then --reload. Always restrict the source.
Should I allow SNMP from anywhere?
No — never open UDP 161 to 0.0.0.0/0. An internet-exposed agent is found by scanners quickly, and on v1/v2c the cleartext community offers little protection. Scope every rule to the specific IP or CIDR of your manager(s), and combine it with an OID allowlist and, ideally, SNMPv3.
What port do SNMP traps use?
Traps use UDP 162, and the rule goes on the receiver (your manager), not the agent. Open UDP 162 inbound on the trap receiver, scoped to the source addresses of the devices that send traps. The agent itself only needs 161 inbound for polling.
iptables, ufw, or firewalld — which for SNMP?
Use whichever your distro ships: ufw on Ubuntu/Debian, firewalld on the RHEL family, and raw iptables where neither front-end is present. The rule is identical in effect — allow UDP 161 from your manager's source IP and drop the rest. The front-end only changes the syntax, not the principle.
Key takeaways
- Never expose UDP 161 to
0.0.0.0/0— scope it to your manager's IP/CIDR. - Agent needs 161 inbound; trap receiver needs 162 inbound — both UDP.
- ufw:
ufw allow from <ip> to any port 161 proto udp. - iptables:
iptables -A INPUT -p udp -s <ip> --dport 161 -j ACCEPT(with default DROP). - firewalld: a source-scoped rich rule, then
--reload. - Cloud security groups follow the same rule — restrict the source, never open wide.
- Pair the firewall with an OID allowlist and SNMPv3; see hardening.