Overview
[Client devices]
| SNMP Trap (UDP 162)
v
[OPNsense]
├── snmptrapd → /var/log/snmptrap/snmptrap.log
└── Zabbix Proxy 7.4 (reads trap log, forwards to Zabbix Server)
Important: OPNsense is based on FreeBSD, not Linux. Commands and tools differ from a standard Linux system:
| Linux | FreeBSD/OPNsense |
|---|---|
apt/yum |
pkg |
logrotate |
newsyslog |
systemctl |
service / rc.d |
Step 1: Verify the Zabbix Proxy plugin installation
Check whether the Zabbix Proxy plugin is correctly installed:
pkg info | grep zabbix
Find the configuration file location:
find /usr/local/etc -name "zabbix_proxy.conf"
Typical location for the OPNsense Zabbix Proxy 7.4 plugin:
/usr/local/etc/zabbix74/zabbix_proxy.conf
Also check where the Zabbix binaries are located:
ls /usr/local/sbin/zabbix_proxy
ls /usr/local/share/zabbix*/
Step 2: Verify net-snmp (snmptrapd)
net-snmp is automatically installed as a dependency of os-zabbix74-proxy.
A separate installation is not required.
Verify it is present:
pkg info net-snmp
snmptrapd --version
Note: The users
snmpd(uid 344) andzabbix(uid 122) are also created automatically during plugin installation. No manual user creation needed.
Step 3: Create the trap log directory
mkdir -p /var/log/snmptrap
chown snmpd:zabbix /var/log/snmptrap
chmod 750 /var/log/snmptrap
touch /var/log/snmptrap/snmptrap.log
chown snmpd:zabbix /var/log/snmptrap/snmptrap.log
chmod 640 /var/log/snmptrap/snmptrap.log
Note: snmptrapd runs as user
snmpd(writer) and Zabbix Proxy runs aszabbix(reader). Ownershipsnmpd:zabbixwith mode640gives both the correct access.
Check whether the zabbix user exists:
id zabbix
If the user does not exist:
pw useradd zabbix -d /var/db/zabbix -s /usr/sbin/nologin -c "Zabbix Daemon"
Step 4: Zabbix Trap Receiver script
The script zabbix_trap_receiver.pl processes incoming traps and writes them in the format Zabbix expects.
Check whether Perl is available and note its path:
which perl
Important: On FreeBSD/OPNsense, Perl is located at
/usr/local/bin/perl, not/usr/bin/perl. Use this path in both the script shebang and thetraphandledirective.
If the script is not present after installation, copy it to OPNsense via SCP.
The script zabbix_trap_receiver.pl is located in the same folder as this guide.
Copy the script via SCP (run this from your own machine, not OPNsense):
scp zabbix_trap_receiver.pl root@<opnsense-ip>:/usr/local/bin/zabbix_trap_receiver.pl
Or via the OPNsense shell if transferred by another method (e.g. WinSCP):
# Verify the file is present
ls -la /usr/local/bin/zabbix_trap_receiver.pl
Make the script executable:
chmod +x /usr/local/bin/zabbix_trap_receiver.pl
Test the script syntax:
perl -c /usr/local/bin/zabbix_trap_receiver.pl
Expected output: zabbix_trap_receiver.pl syntax OK
Step 5: Configure snmptrapd
Create the configuration directory if it does not exist:
mkdir -p /usr/local/etc/snmp
Edit or create the configuration file:
vi /usr/local/etc/snmp/snmptrapd.conf
Contents:
# Accept traps from all hosts (restrict as needed)
authCommunity log,execute,net public
authCommunity log,execute,net private
# Forward traps to Zabbix log via the receiver script
traphandle default /usr/local/bin/perl /usr/local/bin/zabbix_trap_receiver.pl
Note: Replace public and private with the community strings used by your devices.
For SNMPv3 (recommended for production), add:
createUser myuser SHA "my_auth_password" AES "my_priv_password"
authUser log,execute,net myuser
Step 6: Configure Zabbix Proxy for SNMP Trapping
Important: OPNsense regenerates
zabbix_proxy.conffrom a Jinja2 template on every reboot. Editing the file directly will be overwritten. The correct approach is a drop-in config via anInclude=directive added to the template.
Step 6a: Add Include to the OPNsense template
cd /usr/local/opnsense/service/templates/OPNsense/Zabbixproxy
python3 -c "
content = open('zabbix_proxy.conf').read()
insert = 'Include=/usr/local/etc/zabbix74/zabbix_proxy.d/*.conf\n'
idx = content.rfind('{% endif %}')
open('zabbix_proxy.conf', 'w').write(content[:idx] + insert + content[idx:])
"
Verify:
tail -5 zabbix_proxy.conf
Expected output:
Include=/usr/local/etc/zabbix74/zabbix_proxy.d/*.conf
{% endif %}
{% endif %}
Step 6b: Create the drop-in config
This file is never touched by OPNsense:
mkdir -p /usr/local/etc/zabbix74/zabbix_proxy.d
cat > /usr/local/etc/zabbix74/zabbix_proxy.d/snmp_trapper.conf << EOF
StartSNMPTrapper=1
SNMPTrapperFile=/var/log/snmptrap/snmptrap.log
EOF
Step 6c: Regenerate the config and verify
configctl template reload OPNsense/Zabbixproxy
grep -E "Include|StartSNMPTrapper|SNMPTrapperFile" /usr/local/etc/zabbix74/zabbix_proxy.conf
Step 7: Enable snmptrapd at boot
Add snmptrapd to /etc/rc.conf.local (OPNsense-safe method — this file is not overwritten by OPNsense upgrades):
echo 'snmptrapd_enable="YES"' >> /etc/rc.conf.local
echo 'snmptrapd_flags="-Lf /var/log/snmptrap/snmptrapd_daemon.log -On -p /var/run/snmptrapd.pid"' >> /etc/rc.conf.local
Do not use
-fin the flags — that runs snmptrapd in the foreground and the terminal will hang.
Start snmptrapd:
service snmptrapd start
Check the status:
service snmptrapd status
sockstat -l | grep 162
If snmptrapd was already running (e.g. started at boot), kill the old process first:
ps aux | grep snmptrapd
kill <PID>
service snmptrapd start
Restart Zabbix Proxy to load the new configuration:
service zabbix_proxy restart
# or depending on the OPNsense plugin name:
# /usr/local/etc/rc.d/zabbix_proxy restart
Step 8: OPNsense Firewall rule for SNMP Traps
Add a firewall rule via the OPNsense GUI:
Firewall → Rules → [Interface where clients reside, e.g. LAN or VLAN]
| Field | Value |
|---|---|
| Action | Pass |
| Interface | LAN / VLAN (your clients) |
| Protocol | UDP |
| Source | Your client network |
| Destination | This Firewall |
| Dest. Port | 162 (SNMPTRAP) |
| Description | Allow SNMP Traps to Zabbix |
Verify the port is open:
sockstat -l | grep 162
Step 9: Log rotation with newsyslog
Important:
/etc/newsyslog.confis auto-generated by OPNsense and must not be edited manually — changes will be overwritten. Always use/usr/local/etc/newsyslog.conf.d/.
First check whether net-snmp already created entries:
cat /usr/local/etc/newsyslog.conf.d/net-snmp.conf
If the entries are already present with owner snmpd:zabbix, nothing needs to be done.
Otherwise, create a file in the persistent directory:
cat > /usr/local/etc/newsyslog.conf.d/snmp-zabbix.conf << EOF
/var/log/snmptrap/snmptrap.log snmpd:zabbix 640 7 10240 * JC
/var/log/snmptrap/snmptrapd_daemon.log snmpd:zabbix 640 7 10240 * JC
EOF
Column explanation:
| Column | Value | Meaning |
|---|---|---|
| 1 | log file path | Full path |
| 2 | owner:group | File ownership after rotation |
| 3 | mode | File permissions |
| 4 | 7 |
Keep 7 rotated files |
| 5 | 10240 |
Rotate at 10 MB (value in KB) |
| 6 | * |
No time-based rotation |
| 7 | J |
Use bzip2 compression |
C |
Create new file if it does not exist |
Test the newsyslog configuration:
# Dry run (test without actually rotating)
newsyslog -nv
# Force rotation now
newsyslog -v /var/log/snmptrap/snmptrap.log
newsyslog runs automatically via cron — no manual cron configuration needed.
Note: The net-snmp package may already add entries for the snmptrap logs in
/usr/local/etc/newsyslog.conf.d/net-snmp.conf. Check for duplicates:cat /usr/local/etc/newsyslog.conf.d/net-snmp.conf grep snmptrap /etc/newsyslog.conf
Step 10: Testing
Test 1: Send a test trap to the local machine
Send a test SNMPv2c trap to localhost:
snmptrap -v 2c -c public localhost '' .1.3.6.1.6.3.1.1.5.1
Send a test from a client machine (replace <opnsense-ip> with the OPNsense IP address):
snmptrap -v 2c -c public <opnsense-ip> '' .1.3.6.1.6.3.1.1.5.1
Test 2: Verify the trap appears in the log
tail -f /var/log/snmptrap/snmptrap.log
Test 3: Check Zabbix Proxy logs
tail -f /var/log/zabbix/zabbix_proxy.log
# or
find /var/log -name "zabbix_proxy*"
Test 4: Monitor network traffic on port 162
tcpdump -i igb1 -nn -A udp port 162
# Replace igb1 with your actual interface name
List available interfaces:
ifconfig | grep "^[a-z]"
Troubleshooting
snmptrapd fails to start
# Check the daemon log
cat /var/log/snmptrap/snmptrapd_daemon.log
# Run in debug/foreground mode (Ctrl+C to stop)
snmptrapd -f -Lo -C -c /usr/local/etc/snmp/snmptrapd.conf
Common causes:
- "Address already in use" — another snmptrapd is already running. Find and kill it:
sockstat -l | grep 162 ps aux | grep snmptrapd kill <PID> - "-f flag" in
snmptrapd_flags— remove it, it runs snmptrapd in the foreground.
Traps arrive (visible in tcpdump) but do not appear in the log
# Check the Perl path — on FreeBSD it must be /usr/local/bin/perl
grep traphandle /usr/local/etc/snmp/snmptrapd.conf
# Check file permissions (snmpd must write, zabbix must read)
ls -la /var/log/snmptrap/
# Test the Perl script manually
echo -e "172.19.30.10\nUDP: [172.19.30.10]:162->[172.19.30.157]:162\n.1.3.6.1.6.3.1.1.4.1.0 .1.3.6.1.6.3.1.1.5.1\n" | /usr/local/bin/perl /usr/local/bin/zabbix_trap_receiver.pl
cat /var/log/snmptrap/snmptrap.log
Traps appear in the log but not in Zabbix
# Verify Include and SNMP settings are present
grep -E "Include|StartSNMPTrapper|SNMPTrapperFile" /usr/local/etc/zabbix74/zabbix_proxy.conf
# Check the drop-in config file
cat /usr/local/etc/zabbix74/zabbix_proxy.d/snmp_trapper.conf
# Check whether the snmp trapper process is running
ps aux | grep "snmp trapper"
# Verify Zabbix Proxy can read the log file
sudo -u zabbix cat /var/log/snmptrap/snmptrap.log
After reboot, StartSNMPTrapper disappears from zabbix_proxy.conf
OPNsense regenerates the config from its template on every reboot. Check whether the Include directive is still in the template:
grep "Include" /usr/local/opnsense/service/templates/OPNsense/Zabbixproxy/zabbix_proxy.conf
If it is missing (e.g. after a plugin update), re-run Step 6a.
Port 162 is not reachable from clients
# Check if snmptrapd is listening
sockstat -l | grep 162
# Check OPNsense firewall rules
pfctl -sr | grep 162
File and location summary
| File / Directory | Purpose |
|---|---|
/usr/local/etc/snmp/snmptrapd.conf |
snmptrapd configuration |
/usr/local/bin/zabbix_trap_receiver.pl |
Zabbix trap receiver script |
/usr/local/etc/zabbix74/zabbix_proxy.conf |
Zabbix Proxy config (generated by OPNsense) |
/usr/local/etc/zabbix74/zabbix_proxy.d/snmp_trapper.conf |
Drop-in config: StartSNMPTrapper (persistent) |
/usr/local/opnsense/service/templates/OPNsense/Zabbixproxy/zabbix_proxy.conf |
OPNsense template (contains Include directive) |
/var/log/snmptrap/snmptrap.log |
SNMP trap log (read by Zabbix, owner snmpd:zabbix) |
/var/log/snmptrap/snmptrapd_daemon.log |
snmptrapd daemon log |
/etc/newsyslog.conf |
Log rotation configuration |
/etc/rc.conf.local |
Startup services (OPNsense-safe) |
Zabbix GUI configuration
After installation, configure the hosts in the Zabbix Server GUI to receive SNMP traps:
- Configuration → Hosts → select the host
- Add an SNMP trap item:
- Type:
SNMP trap - Key:
snmptrap.fallback(for all traps) orsnmptrap[<OID>]for specific traps - Log time format:
yyyyMMdd HHmmss
- Type:
- Make sure the host is linked to the correct Proxy (your OPNsense Zabbix Proxy)
Comments (0)
No comments yet. Be the first!
Leave a comment