# Rules configuration ```{admonition} 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](policy.md) 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: ```yaml --- # 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 ``` ```{admonition} 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](policy.md) rather than a rule. ``` ```{contents} :local: ``` ## 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. ```yaml 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: ```yaml source: lan ``` This would match all traffic coming from the 'lan' zone. The above rule can also be written as: ```yaml source: zone: lan ``` If you need to match an ip within a zone: ```yaml 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: ```yaml 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: ```yaml dest: fw ``` And can also be expressed via the longer form: ```yaml dest: zone: fw ``` IP matching also works. This is an example where the destination is in a zone called "dmz". ```yaml 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: ```yaml 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. ```yaml proto: [tcp, udp] ``` #### ```type``` Only for icmp or icmpv6. ```yaml 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): ```yaml destport: 53 ``` Multiple ports can also be defined: ```yaml destport: [80, 443] ``` or: ```yaml 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: ```yaml 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: ```yaml 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: ```yaml 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. ```yaml include_directory: path/to/many/files/ ``` ```{admonition} 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 ```yaml --- # 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 ```