Rules configuration¶
Note
This page is still work in progress, and may have errors or missing content.
Rules indicate what traffic is allowed or not allowed. Rules work in conjuction with policies to determine the full ruleset. If a rule for certain kind of traffic does not exist, it will be blocked or allowed depending on the policy configuration.
Rules are interpreted and placed in the ruleset in the same order they are defined, with a slight exception related to include_directory (see below).
In essence, there are four basic components to a successful rule definition:
Source: Where the traffic originates from. This can be a zone or a single ip/CIDR or a list of ips/CIDRs within a zone
Destination: Where the traffic is going to. This can be a zone or a single ip/CIDR or a list of ips/CIDRs within a zone.
Type: this can be a protocol, protocol with a port number or a combination of supported options.
Action: Indicates what to do when a match has occurred.
A simple rule file with one rule looks something like this:
---
# A rule file must have 'rules' as the top level element
rules:
- comment: Allow incoming SSH traffic from the lan zone
action: accept
source: lan
dest: fw
proto: tcp
destport: 22
Note
If you need to simply allow all traffic from a zone to another, essentially ignoring the “type” of traffic, you should consider making it a policy rather than a rule.
Rule options¶
comment¶
This is simply a comment attached to the rule. It does not affect the rule outcome, but will be attached to the generated rule as an nftables comment field.
comment: Here lies a comment about what this rule does
action¶
The action to take with traffic matching this rule. The options are:
accept¶
The connection is accepted.
reject¶
The connection is rejected.
drop¶
The connection is dropped. This is different from reject only in that
drop simply drops the connection and does nothing to indicate to the
other end that it is not allowed. This can cause the sender to get “stuck”
waiting for the connection to be opened, depending on the protocol.
source¶
Matches the source of traffic. Source must contain a zone, and optionally other parameters.
The shortest form for a source expression is:
source: lan
This would match all traffic coming from the ‘lan’ zone.
The above rule can also be written as:
source:
zone: lan
If you need to match an ip within a zone:
source:
zone: lan
ip: 10.1.1.1/32
You can also specify a list of ips. Mixing IPv4 and IPv6 addresses in the same rule is also allowed:
source:
zone: lan
ip:
- 10.1.1.1/32
- fd11:22:33:44::1/64
dest¶
The dest expression is similar to source, but indicates the
destination of traffic. It has the same format, only difference is the keyword:
This example matches all traffic destined for the firewall machine:
dest: fw
And can also be expressed via the longer form:
dest:
zone: fw
IP matching also works. This is an example where the destination is in a zone called “dmz”.
dest:
zone: dmz
ip: 192.168.1.1/32
proto¶
The proto expression matches a specific protocol. At this time, the
following protocols are supported (others may work but are untested):
tcp
udp
icmp
icmpv6
Example:
proto: tcp
Multiple protocols can also be specified. However, this will result in essentially duplicated rules on the final ruleset, one for each protocol. Also beware that this feature should be used with care, as some protocol combinations may produce errors or a ruleset that might get refused by nftables.
proto: [tcp, udp]
type¶
Only for icmp or icmpv6.
proto: icmp
type: echo-reply
destport¶
The destport expression indicates the destination port for protocols
that use them. It should normally be combined with the use of a
proto expression.
Example which matches a single port (53 is the port used for regular DNS):
destport: 53
Multiple ports can also be defined:
destport: [80, 443]
or:
destport:
- 80
- 443
sourceport¶
The sourceport expression is identical with destport, but matches the port on the sending host. This is usually required only for some specific cases.
A simple example, match incoming NTP traffic:
sourceport: 123
Note: This NTP example should not be required for NTP to work, unless state tracking is disabled. ConiFW does not manage state tracking at the time of this writing.
log¶
The log expression is a simple boolean to indicate if the matching traffic should be logged by nftables. The default is false, which means traffic matching the given rule will not be logged.
Example:
log: true
Including rules from files¶
Rules may also be included from other files or directories. Simply place the
include or include_directory expression in place of a rule and
the contents of that file/directory will be placed in that position of the
rule stack.
Any included rule file must have the same formatting as the main rules file.
include¶
Includes a single file from path of your choosing. Will result in an error if the file cannot be read or the file does not conform to the rule file format.
Example for each:
include: /path/to/default/rules.yml
include_directory¶
This will include an entire directory of rules. Any files with the suffix
.yml or .yaml will be processed. In order to achieve predictable
predictable results, the files from that directory will be sorted by name
before reading their contents.
include_directory: path/to/many/files/
Note
include_directory only supports relative imports at this time. Recursion is also unsupported for now.
Examples¶
A more concrete example with include/include_directory¶
---
# A rule file must have 'rules' as the top level element
rules:
- comment: Allow DNS traffic from firewall to lan
action: accept
source: fw
dest: lan
proto: [tcp, udp]
destport: [53, 853]
# This could be a set of rules shared by multiple configs
- include_directory: path/to/shared/rules.yml
# Process more rules from a single file
- include: my_rules.yml
# Another rule that will be placed last on the ruleset
- comment: Allow incoming SSH traffic from the lan zone
action: accept
source: lan
dest: fw
proto: tcp
destport: 22