Wazuh fix note · FortiGate syslog

FortiGate logs not showing in Wazuh

Two causes, both measured on Wazuh 4.14.7. Every FortiGate traffic log, denied or allowed, stops at stock rule 81618 with level 1, and the manager only writes alerts from level 3 by default, so denied traffic never reaches the dashboard. And if FortiGate sends syslog in CSV format, the events still decode, but srcip holds the whole rest of the line, which breaks anything keyed on the source address.

Dong Nguyen, ATK New Technology · 2 October 2026 · measured on Wazuh 4.14.7 (manager container, syslog over UDP 514)

Stuck on this right now? Email your custom rules or decoders, one sample log line and your Wazuh version to dongnx@atkvn.com. We run them on that exact version and reply within 24 hours with what we find. Free. Remove hostnames, IPs and usernames first. Rather not send them? Run the free pre-check in your browser; your files never leave your machine. Rather have it fixed? USD 149 fixed price per problem, reproduced on your version, and you pay only after it works on your system. Our first three customers pay USD 49 for one fix, in exchange for an anonymised write-up we can publish.


How to check in one minute

1. Are the logs arriving? With <logall>yes</logall> on for a few minutes:

grep 'devname=' /var/ossec/logs/archives/archives.log | tail -n 3

Nothing there: check the <remote> syslog block and <allowed-ips> on the manager, and the syslog server address and port on the FortiGate. Turn logall off afterwards.

2. Which format? date=2026-10-02 time=15:00:01 devname="FGT60F" ... with spaces between fields is the default format. The same fields joined by commas (date=2026-10-02,time=15:00:01,devname="FGT60F",...) is CSV.

3. What does Wazuh do with one denied-traffic line? Paste it into /var/ossec/bin/wazuh-logtest. On 4.14.7 it decodes as fortigate-firewall-v5 and stops at rule 81618, level: '1'. Then compare with your threshold:

grep log_alert_level /var/ossec/etc/ossec.conf

Anything below that level is not written to alerts.json, so it is not in the dashboard.

Why it happens

Cause 1: traffic logs sit at level 1

In ruleset/rules/0391-fortigate_rules.xml on 4.14.7, rule 81618 matches any FortiGate log with type=traffic at level 1. It does not look at action, so denied and allowed sessions land on the same rule. The default <log_alert_level> in ossec.conf is 3. The only traffic rule above it is 81619, level 3, after 18 traffic events from one source within 45 seconds.

We sent one denied-traffic line (action="deny", SSH from outside to an internal host) and one Admin login failed line over UDP syslog to a 4.14.7 manager. alerts.json got the login failure (rule 81606, level 4) and nothing for the denied session.

Cause 2: CSV format corrupts srcip

The stock decoder reads key=value pairs separated by spaces. In CSV format the separator is a comma, so the capture for srcip runs to the next space. Measured over UDP on 4.14.7, the login-failed event in CSV format produced an alert whose data.srcip was:

203.0.113.5,dstip=192.168.1.99,action="login",status="failed",...

The rule still fires, but the address is not an address: GeoIP, <same_source_ip> correlation and active response (firewall-drop) all read srcip.

Fix

1. Send the default format. On the FortiGate CLI, for the syslog server Wazuh listens on:

config log syslogd setting
    set format default
end

(syslogd2, syslogd3… for additional servers.) FortiOS also offers cef and rfc5424; we have not measured those against the stock decoders.

2. Raise denied traffic to an alert. In /var/ossec/etc/rules/local_rules.xml:

<group name="local,fortigate,">
  <rule id="100210" level="5">
    <if_sid>81618</if_sid>
    <action>deny</action>
    <description>FortiGate: traffic denied by policy.</description>
    <group>firewall_block,</group>
  </rule>
</group>

On 4.14.7 this loaded cleanly, and the same denied line that produced nothing produced a level 5 alert with srcip and dstport intact. Use an ID in your own range. An internet-facing FortiGate denies a lot; narrow it further (an interface, a port, a destination) if the volume is too high.

Write it with the <action> tag, not <field name="action">. action is a static field. With the <field> form, 4.14.7 logged ERROR: Failure to read rule 100210. Field 'action' is static. and the manager did not start: no alerts at all, not only for FortiGate.

Limits of what we measured

Measured on a Wazuh 4.14.7 manager container receiving syslog over UDP 514 from 127.0.0.1, and in wazuh-logtest. We did not run a FortiGate: the log lines were written by us in the FortiOS key=value layout, for one denied forward session and one failed admin login, and converted to CSV by replacing the field separator. We have not measured the cef or rfc5424 formats, other log types (UTM, VPN, IPS), other FortiOS versions, or other Wazuh versions. The CLI syntax is from Fortinet's config log syslogd setting reference, not run on a device.

Have it working

Need FortiGate, or another log source, decoded and alerting the way you want? Send 5–10 sample lines (masked) and your Wazuh version to dongnx@atkvn.com. We write the decoder and rules, test them on your exact version, and send the files with apply and rollback steps. USD 149 per log source, paid after it works on your system.