FortiGate Deny Logs - 夜莺博客

FortiGate Deny Logs

原文:FortiGate Deny Logs — theDXT (Daniel Keer)

Image 8

Something that’s annoyed me with FortiGates is that viewing the deny logs isn’t super straight forward. Part of the issue is the fact that Fortinet disables the deny log by default and if you don’t know where to look for it you might not figure it out by clicking around.

Fortinet says that they have the deny logs off by default to optimize the usage of logging space. I however want to see as much info as possible when possible, especially when troubleshooting.

Thankfully turning it on is easy, here’s how to do it and view it.

  • Go to your Policy & Objects and click on Firewall Policy

Image 9

  • Edit your Implicit Deny rule

Image 10

  • Turn on Log IPv4 Violation Traffic

Image 11

  • Now you can view the deny log in Forward Traffic under the Log & Report section

Image 12

You might need to change your filters to find what exactly you are looking for

Image 13

Why the deny log is off by default

Firewall policy is evaluated top down, and the implicit deny sits at the bottom of the table as policy ID 0. Every packet that does not match any policy you wrote lands there and gets dropped. On a busy edge that is a very large number of packets — internet background noise, port scans, misconfigured clients, and the retransmissions that follow them. Fortinet ships with the implicit deny silent because writing one log line per dropped packet can fill local disk, flood FortiAnalyzer, and cost CPU on small appliances.

That default is a sensible trade-off for a low-end unit with limited flash, but it is a terrible default for troubleshooting. When a user says “the VPN is down” or “my server can’t reach the DMZ”, the answer is usually sitting in the deny log: a packet arriving on the wrong interface, a service that is not permitted, or an address object that no longer resolves to the right IP.

Enable logging on the implicit deny policy via the GUI

Log in as a super_admin (or any profile with read-write on firewall policy), then repeat the steps from the original post:

  1. Go to Policy & Objects → Firewall Policy.
  2. Scroll to the bottom of the policy table and edit the Implicit Deny entry (the grey row that shows as “implicit deny”).
  3. In the rule dialog, enable Log Violation Traffic. On FortiOS 7.4 and later the checkboxes are split into Log IPv4 Violation Traffic and Log IPv6 Violation Traffic — enable the one that matches the traffic you are investigating.
  4. Click OK, then open Log & Report → Forward Traffic and filter on the denied traffic.

From that point on, every session the implicit deny blocks produces a Forward Traffic entry with Action = Deny and a policy ID of 0.

Enable logging with the CLI

The GUI checkbox is just a thin wrapper around policy 0. The equivalent CLI is:

config firewall policy
    edit 0
        set logtraffic all
    next
end

On newer FortiOS builds you can also turn on session-start logging, which writes a log entry the moment the session is created instead of when it closes:

config firewall policy
    edit 0
        set logtraffic all
        set logtraffic-start enable
    next
end

If you want the deny log for your own rules as well, set the same option on each policy that uses set action deny:

config firewall policy
    edit 12
        set action deny
        set logtraffic all
    next
end

Finally, save the configuration if your policy management workflow does not commit changes automatically:

execute config-save

Check your log destination and severity first

This is the step that catches most people. Enabling the policy flag does nothing if the destination you are looking at is disabled, or if its severity filter is higher than information — which is the level traffic logs are written at. Memory and disk logging default to a more restrictive severity, so the policy looks correctly configured while the log stays empty.

Enable memory logging (fast, lost on reboot, best for short troubleshooting windows):

config log memory setting
    set status enable
    set severity information
end

Enable disk logging (survives reboot, capped by the configured maximum size):

config log disk setting
    set status enable
    set severity information
    set max-log-file-size 500
end

Keep the memory log from growing without limit on a small unit:

config log memory global-setting
    set max-size 75
end

If logs go to FortiAnalyzer or a syslog collector, enable those too:

config log fortianalyzer setting
    set status enable
    set server "10.20.30.40"
end

config log syslogd setting
    set status enable
    set server "10.20.30.50"
    set port 514
end

Reading the deny log in the GUI

Go to Log & Report → Forward Traffic. The unfiltered view is noise, so narrow it down:

  • Action = Deny — shows only the traffic the firewall blocked.
  • Policy ID = 0 — shows only implicit-deny hits, i.e. traffic that matched no policy at all.
  • Source / Destination / Service — use these when you already know which host or port is failing.
  • Set the time range before you filter; a one-hour window with a deny filter answers most questions far faster than a one-day window without one.

Clicking a log entry expands the packet details: ingress and egress interface, source and destination port, NAT information, session ID, and the policy that produced it. That interface pair is often the whole answer — the packet arriving on wan1 when you expected internal7 means you have a routing or interface-role problem, not an ACL problem.

Reading the deny log from the CLI

You do not need the GUI for a quick look. The CLI log viewer works against the same memory log:

execute log filter reset
execute log filter category traffic
execute log filter field action deny
execute log filter dump
execute log display

Narrow it further with any other field, for example only dropped TCP/443 traffic:

execute log filter field dstport 443
execute log display

When you are looking at a live problem instead of history, the flow debug is faster. It prints the policy lookup decision, including the implicit deny, as packets arrive:

diagnose debug flow filter addr 192.0.2.25
diagnose debug flow show function-name enable
diagnose debug console timestamp enable
diagnose debug flow trace start 20
diagnose debug enable

Remember to stop it afterwards — an unbounded flow trace on a busy unit is a good way to knock the console over:

diagnose debug disable
diagnose debug reset

Troubleshooting: you turned it on but the log is still empty

  • Destination disabled or severity too high. Re-check config log memory setting and config log disk setting; the severity must be information for traffic logs to be written.
  • The traffic is not being denied. If a policy above the implicit deny permits the session, no deny log is generated for it. Confirm with diagnose debug flow which policy ID is matching.
  • You only see one entry per session. Traffic logs are written when a session is torn down (unless you enabled session-start logging), so a stream of retransmissions from one client is one log line, not hundreds.
  • HA pair. Check both members; with session pickup enabled a session can be processed and logged by the secondary unit. Logging preferences are synchronised, so configuring it once is normally enough.
  • Conserve mode. If the unit has entered conserve mode, logging is cut back to protect memory. Check diagnose sys top and the memory state on the dashboard.
  • Very high deny volume. Thousands of deny entries per second will roll your memory log over in minutes. Rather than living with that, block the noise close to the source with a DoS policy or an ACL, and log only what you actually investigate.

Deny logs are not security event logs

It is worth being precise about which log you need. The deny entries above live in Forward Traffic and record a policy decision: this session was dropped because no policy permitted it, or because a policy with set action deny matched. They say nothing about the payload.

Attack detection is logged elsewhere, under Log & Report → Security Events: IPS, antivirus, web filter, application control and DNS filter hits. A blocked exploit attempt appears there, not in Forward Traffic. Both types usually name the policy ID, so when you are correlating a report of “something got blocked at four in the morning” you may need to look in both places. If you are forwarding logs to a collector, forward all categories — a filter that only ships traffic logs will silently drop exactly the events you care about.

Filters that answer real questions

A few patterns that come up constantly on production FortiGates:

  • “Which internal host is scanning?” Filter Forward Traffic on Action = Deny, then sort by source address or use the GUI’s top-sources widget. A single address with thousands of denied sessions to sequential ports is a host with malware or a broken application.
  • “Is my new allow policy being hit?” Filter on the policy ID you just created. If you see sessions there, the policy is matching; if the sessions still land on policy 0, your source, destination or service object does not match what the client actually sends.
  • “Why can’t this server resolve DNS?” Filter Action = Deny with destination port 53. Seeing the queries denied with the server’s IP as the source tells you the DNS policy or the interface routing is wrong, not the server’s resolver configuration.
  • “Did anything try to reach an admin port from outside?” Filter denied traffic with destination ports 22, 3389 and 5900. On an internet-facing unit the answer is always yes, which is normal background noise — but the source list is useful evidence when someone asks whether the management plane is exposed.

Should you leave deny logging on?

If you have disk space or a FortiAnalyzer, yes. Deny logs are what let you answer “what was the firewall doing at 02:14 last night” months later, and they are the raw material for reports on scan activity, blocked outbound C2 attempts, and clients that keep hammering a service they are not allowed to use. On a small appliance with a full disk, the pragmatic middle ground is disk logging with a modest max-log-file-size, plus forwarding to a central collector so a reboot never costs you the evidence.

Once the logs are flowing, the rest is routine FortiGate work. If you need to rebuild a unit from scratch, see FortiGate防火墙格式化及重装固件; for a wider set of diagnostic commands, keep the FortiOS CLI troubleshooting cheat sheet handy, and if the traffic you are chasing is routing-related rather than policy-related, the flow debug walkthrough in OSPF neighbour stuck in INIT shows the same debugging technique applied to adjacency failures.