policy¶
The policy file sets the default action for traffic between zones — the verdict applied
to a connection that no more-specific rules-file entry has already accepted. It is the
fail-closed backstop of the filtering core.
Each non-comment line is one policy:
#SOURCE DEST ACTION [LOG LEVEL] [LIMIT:BURST]
Columns are whitespace-separated. Blank lines and # comments (whole-line or trailing) are
ignored. The file is preprocessed first, so params
substitution and ?if/?FORMAT directives apply.
Columns¶
| Column | Index | Required | Value |
|---|---|---|---|
SOURCE |
0 | yes | A declared zone, the firewall zone, or the wildcard all. |
DEST |
1 | yes | A declared zone, the firewall zone, or the wildcard all. |
ACTION |
2 | yes | ACCEPT, DROP, or REJECT. |
LOG LEVEL |
3 | no | An nftables log level — logs the connection before applying the verdict. |
LIMIT:BURST |
4 | no | <rate>/<interval>[:<burst>] — rate-limits new connections the policy defaults (see LIMIT:BURST below). |
A line with fewer than three columns, an unknown zone, an unknown action, an unsupported log
level, or any sixth column is a hard error: the compiler stops with a file:line message
rather than guess. Shorewall's CONNLIMIT column is not implemented, so it is rejected rather
than silently dropped.
SOURCE / DEST¶
Zone names must already be declared in the zones file (the firewall zone
included). all is the wildcard zone. Zones are matched by interface: the source zone
matches on iifname, the destination zone on oifname, against the interface(s) bound to that
zone in the interfaces file. The firewall zone and all contribute no
interface match — the firewall zone is the host itself, and all is a wildcard — so an
all all policy compiles to a bare verdict.
A policy that names a normal zone with no interfaces cannot be matched and is a hard error (fail-closed) rather than an empty match.
ACTION¶
| Action | nftables verdict |
|---|---|
ACCEPT |
accept |
DROP |
drop (silently discard) |
REJECT |
reject (discard and send an ICMP/RST error) |
LOG LEVEL¶
When present, the compiler emits an nftables log level <lvl> statement immediately before the
verdict. Accepted levels are the nftables (syslog) keywords plus audit:
emerg alert crit err warn notice info debug audit
Shorewall's alternate syslog spellings (warning, error, panic), numeric levels, and
NFLOG/ULOG targets are not accepted — an unsupported level is a hard error. No log
prefix is emitted, and REJECT logging is not distinguished from DROP/ACCEPT logging.
LIMIT:BURST¶
<rate>/<interval>[:<burst>] — the same rate-spec grammar as the rules file's
RATE LIMIT column:
| Field | Value |
|---|---|
rate |
A positive integer. |
interval |
One of sec, min, hour, day (maps to nftables' second/minute/hour/day). |
burst |
Optional positive integer packet-burst allowance; nftables' default applies when omitted. |
When present, the compiler emits an nftables limit rate statement on the policy rule itself,
immediately before the verdict — rate-limiting the new connections that reach the policy
fall-through (traffic a rules-file entry hasn't already matched). Over-rate new connections
fall through past the policy to the chain's built-in default (see
Implicit defaults). Shorewall's named/shared limiters (a name or s:/d:
selector before the rate) are not implemented and are rejected. The policy CONNLIMIT
column is not implemented.
How policies compile¶
Each policy becomes one rule appended to a base filter chain, after the always-on stateful and
loopback accepts and after any rules-file entries, so it is the last thing evaluated in the
chain.
Chain selection follows the role of the firewall zone:
| Policy | Chain |
|---|---|
DEST is the firewall zone |
input (traffic to the firewall host) |
SOURCE is the firewall zone |
output (traffic from the firewall host) |
| neither side is the firewall zone | forward (inter-zone forwarded traffic) |
Source-firewall takes precedence, so a degenerate $fw $fw policy lands in output.
Ordering is by specificity, not file order: a specific zone pair is emitted first, a policy
with one all side next, and all all last. This keeps a specific pair from being shadowed by
a wildcard catch-all. Within one specificity tier, file order is preserved.
all all is the inter-zone catch-all, not a universal default
Because all all has neither side as the firewall zone, it compiles to a forward rule
only — it does not govern traffic to or from the firewall host. Consequences worth
noting:
all all DROPis harmless (theinputbase chain already drops).all all REJECTleaves firewall-bound traffic dropped rather than rejected.all all ACCEPTdoes not open the firewall host —inputstays closed.
A config that wants firewall-host defaults writes explicit $fw/→ $fw policies. This is a
deliberate divergence from Shorewall's universal all all.
Implicit defaults¶
You do not have to write a policy for every chain. Absent any matching policy, the base filter
chains fall back to their built-in verdicts — input drop, forward drop, output accept —
and the always-on rules accept established/related connections and loopback traffic. The result
is fail-closed inbound and forwarded traffic with outbound allowed.
Example¶
A small three-zone setup — a WAN zone net, a LAN zone loc, and the firewall zone fw:
#SOURCE DEST ACTION LOG LEVEL LIMIT:BURST
loc net ACCEPT - 100/sec:20
loc fw ACCEPT
fw net ACCEPT
net all DROP info
all all REJECT info
This allows the LAN out to the internet, capped at 100 new connections/second (burst 20); lets
the LAN reach the firewall host and the firewall reach the internet; logs-and-drops everything
arriving from net; and logs-and-rejects any remaining inter-zone traffic. More specific rows
are evaluated before the all catch-alls regardless of the order written.
Inspecting compiled policies¶
shorewallnf show policies <config_dir> renders the inter-zone default-policy matrix —
SOURCE -> DEST -> ACTION, plus the log level when one is set (- when not). Because policies
are a compile-time declaration and not recoverable from live nft state, this verb reads the
config directory (unlike show rules, which reads the running kernel). list/ls are exact
synonyms; it is read-only.
$ shorewallnf show policies /etc/shorewallnf
Policies
SOURCE DEST ACTION LOG
loc net ACCEPT -
net all DROP info
all all REJECT -
Rows are shown in file order (the specificity re-ordering above is a compile-time concern). A valid config that declares no policies renders an empty-but-valid section.
See also¶
rules— per-connection rules and DNAT, evaluated before these defaults.zones/interfaces— where zones and their interfaces are declared.