Blame doc/statements.txt

Packit c5a612
VERDICT STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~
Packit c5a612
The verdict statement alters control flow in the ruleset and issues policy decisions for packets.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
{*accept* | *drop* | *queue* | *continue* | *return*}
Packit c5a612
{*jump* | *goto*} 'chain'
Packit c5a612
Packit c5a612
*accept* and *drop* are absolute verdicts -- they terminate ruleset evaluation immediately.
Packit c5a612
Packit c5a612
[horizontal]
Packit c5a612
*accept*:: Terminate ruleset evaluation and accept the packet.
Packit c5a612
The packet can still be dropped later by another hook, for instance accept
Packit c5a612
in the forward hook still allows to drop the packet later in the postrouting hook,
Packit c5a612
or another forward base chain that has a higher priority number and is evaluated
Packit c5a612
afterwards in the processing pipeline.
Packit c5a612
*drop*:: Terminate ruleset evaluation and drop the packet.
Packit c5a612
The drop occurs instantly, no further chains or hooks are evaluated.
Packit c5a612
It is not possible to accept the packet in a later chain again, as those
Packit c5a612
are not evaluated anymore for the packet.
Packit c5a612
*queue*:: Terminate ruleset evaluation and queue the packet to userspace.
Packit c5a612
Userspace must provide a drop or accept verdict.  In case of accept, processing
Packit c5a612
resumes with the next base chain hook, not the rule following the queue verdict.
Packit c5a612
*continue*:: Continue ruleset evaluation with the next rule. This
Packit c5a612
 is the default behaviour in case a rule issues no verdict.
Packit c5a612
*return*:: Return from the current chain and continue evaluation at the
Packit c5a612
 next rule in the last chain. If issued in a base chain, it is equivalent to the
Packit c5a612
 base chain policy.
Packit c5a612
*jump* 'chain':: Continue evaluation at the first rule in 'chain'. The current
Packit c5a612
 position in the ruleset is pushed to a call stack and evaluation will continue
Packit c5a612
 there when the new chain is entirely evaluated or a *return* verdict is issued.
Packit c5a612
 In case an absolute verdict is issued by a rule in the chain, ruleset evaluation
Packit c5a612
 terminates immediately and the specific action is taken.
Packit c5a612
*goto* 'chain':: Similar to *jump*, but the current position is not pushed to the
Packit c5a612
 call stack, meaning that after the new chain evaluation will continue at the last
Packit c5a612
 chain instead of the one containing the goto statement.
Packit c5a612
Packit c5a612
.Using verdict statements
Packit c5a612
-------------------
Packit c5a612
# process packets from eth0 and the internal network in from_lan
Packit c5a612
# chain, drop all packets from eth0 with different source addresses.
Packit c5a612
Packit c5a612
filter input iif eth0 ip saddr 192.168.0.0/24 jump from_lan
Packit c5a612
filter input iif eth0 drop
Packit c5a612
-------------------
Packit c5a612
Packit c5a612
PAYLOAD STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
'payload_expression' *set* 'value'
Packit c5a612
Packit c5a612
The payload statement alters packet content. It can be used for example to
Packit c5a612
set ip DSCP (diffserv) header field or ipv6 flow labels.
Packit c5a612
Packit c5a612
.route some packets instead of bridging
Packit c5a612
---------------------------------------
Packit c5a612
# redirect tcp:http from 192.160.0.0/16 to local machine for routing instead of bridging
Packit c5a612
# assumes 00:11:22:33:44:55 is local MAC address.
Packit c5a612
bridge input meta iif eth0 ip saddr 192.168.0.0/16 tcp dport 80 meta pkttype set unicast ether daddr set 00:11:22:33:44:55
Packit c5a612
-------------------------------------------
Packit c5a612
Packit c5a612
.Set IPv4 DSCP header field
Packit c5a612
---------------------------
Packit c5a612
ip forward ip dscp set 42
Packit c5a612
---------------------------
Packit c5a612
Packit c5a612
EXTENSION HEADER STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
'extension_header_expression' *set* 'value'
Packit c5a612
Packit c5a612
The extension header statement alters packet content in variable-sized headers.
Packit c5a612
This can currently be used to alter the TCP Maximum segment size of packets,
Packit c5a612
similar to TCPMSS.
Packit c5a612
Packit c5a612
.change tcp mss
Packit c5a612
---------------
Packit c5a612
tcp flags syn tcp option maxseg size set 1360
Packit c5a612
# set a size based on route information:
Packit c5a612
tcp flags syn tcp option maxseg size set rt mtu
Packit c5a612
---------------
Packit c5a612
Packit c5a612
LOG STATEMENT
Packit c5a612
~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
*log* [*prefix* 'quoted_string'] [*level* 'syslog-level'] [*flags* 'log-flags']
Packit c5a612
*log* *group* 'nflog_group' [*prefix* 'quoted_string'] [*queue-threshold* 'value'] [*snaplen* 'size']
Packit c5a612
*log level audit*
Packit c5a612
Packit c5a612
The log statement enables logging of matching packets. When this statement is
Packit c5a612
used from a rule, the Linux kernel will print some information on all matching
Packit c5a612
packets, such as header fields, via the kernel log (where it can be read with
Packit c5a612
dmesg(1) or read in the syslog).
Packit c5a612
Packit c5a612
In the second form of invocation (if 'nflog_group' is specified), the Linux
Packit c5a612
kernel will pass the packet to nfnetlink_log which will multicast the packet
Packit c5a612
through a netlink socket to the specified multicast group. One or more userspace
Packit c5a612
processes may subscribe to the group to receive the packets, see
Packit c5a612
libnetfilter_queue documentation for details.
Packit c5a612
Packit c5a612
In the third form of invocation (if level audit is specified), the Linux
Packit c5a612
kernel writes a message into the audit buffer suitably formatted for reading
Packit c5a612
with auditd. Therefore no further formatting options (such as prefix or flags)
Packit c5a612
are allowed in this mode.
Packit c5a612
Packit c5a612
This is a non-terminating statement, so the rule evaluation continues after
Packit c5a612
the packet is logged.
Packit c5a612
Packit c5a612
.log statement options
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Keyword | Description | Type
Packit c5a612
|prefix|
Packit c5a612
Log message prefix|
Packit c5a612
quoted string
Packit c5a612
|level|
Packit c5a612
Syslog level of logging |
Packit c5a612
string: emerg, alert, crit, err, warn [default], notice, info, debug, audit
Packit c5a612
|group|
Packit c5a612
NFLOG group to send messages to|
Packit c5a612
unsigned integer (16 bit)
Packit c5a612
|snaplen|
Packit c5a612
Length of packet payload to include in netlink message |
Packit c5a612
unsigned integer (32 bit)
Packit c5a612
|queue-threshold|
Packit c5a612
Number of packets to queue inside the kernel before sending them to userspace |
Packit c5a612
unsigned integer (32 bit)
Packit c5a612
|==================================
Packit c5a612
Packit c5a612
.log-flags
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
| Flag | Description
Packit c5a612
|tcp sequence|
Packit c5a612
Log TCP sequence numbers.
Packit c5a612
|tcp options|
Packit c5a612
Log options from the TCP packet header.
Packit c5a612
|ip options|
Packit c5a612
Log options from the IP/IPv6 packet header.
Packit c5a612
|skuid|
Packit c5a612
Log the userid of the process which generated the packet.
Packit c5a612
|ether|
Packit c5a612
Decode MAC addresses and protocol.
Packit c5a612
|all|
Packit c5a612
Enable all log flags listed above.
Packit c5a612
|==============================
Packit c5a612
Packit c5a612
.Using log statement
Packit c5a612
--------------------
Packit c5a612
# log the UID which generated the packet and ip options
Packit c5a612
ip filter output log flags skuid flags ip options
Packit c5a612
Packit c5a612
# log the tcp sequence numbers and tcp options from the TCP packet
Packit c5a612
ip filter output log flags tcp sequence,options
Packit c5a612
Packit c5a612
# enable all supported log flags
Packit c5a612
ip6 filter output log flags all
Packit c5a612
-----------------------
Packit c5a612
Packit c5a612
REJECT STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
*reject* [ *with* 'REJECT_WITH' ]
Packit c5a612
Packit c5a612
'REJECT_WITH' := *icmp type* 'icmp_code' |
Packit c5a612
                 *icmpv6 type* 'icmpv6_code' |
Packit c5a612
                 *icmpx type* 'icmpx_code' |
Packit c5a612
                 *tcp reset*
Packit c5a612
____
Packit c5a612
Packit c5a612
A reject statement is used to send back an error packet in response to the
Packit c5a612
matched packet otherwise it is equivalent to drop so it is a terminating
Packit c5a612
statement, ending rule traversal. This statement is only valid in the input,
Packit c5a612
forward and output chains, and user-defined chains which are only called from
Packit c5a612
those chains.
Packit c5a612
Packit c5a612
.different ICMP reject variants are meant for use in different table families
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Variant |Family | Type
Packit c5a612
|icmp|
Packit c5a612
ip|
Packit c5a612
icmp_code
Packit c5a612
|icmpv6|
Packit c5a612
ip6|
Packit c5a612
icmpv6_code
Packit c5a612
|icmpx|
Packit c5a612
inet|
Packit c5a612
icmpx_code
Packit c5a612
|==================
Packit c5a612
Packit c5a612
For a description of the different types and a list of supported keywords refer
Packit c5a612
to DATA TYPES section above. The common default reject value is
Packit c5a612
*port-unreachable*. +
Packit c5a612
Packit c5a612
Note that in bridge family, reject statement is only allowed in base chains
Packit c5a612
which hook into input or prerouting.
Packit c5a612
Packit c5a612
COUNTER STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~
Packit c5a612
A counter statement sets the hit count of packets along with the number of bytes.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*counter* *packets* 'number' *bytes* 'number'
Packit c5a612
*counter* { *packets* 'number' | *bytes* 'number' }
Packit c5a612
Packit c5a612
CONNTRACK STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~~~
Packit c5a612
The conntrack statement can be used to set the conntrack mark and conntrack labels.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*ct* {*mark* | *event* | *label* | *zone*} *set* 'value'
Packit c5a612
Packit c5a612
The ct statement sets meta data associated with a connection. The zone id
Packit c5a612
has to be assigned before a conntrack lookup takes place, i.e. this has to be
Packit c5a612
done in prerouting and possibly output (if locally generated packets need to be
Packit c5a612
placed in a distinct zone), with a hook priority of -300.
Packit c5a612
Packit c5a612
.Conntrack statement types
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Keyword| Description| Value
Packit c5a612
|event|
Packit c5a612
conntrack event bits |
Packit c5a612
bitmask, integer (32 bit)
Packit c5a612
|helper|
Packit c5a612
name of ct helper object to assign to the connection |
Packit c5a612
quoted string
Packit c5a612
|mark|
Packit c5a612
Connection tracking mark |
Packit c5a612
mark
Packit c5a612
|label|
Packit c5a612
Connection tracking label|
Packit c5a612
label
Packit c5a612
|zone|
Packit c5a612
conntrack zone|
Packit c5a612
integer (16 bit)
Packit c5a612
|==================
Packit c5a612
Packit c5a612
.save packet nfmark in conntrack
Packit c5a612
--------------------------------
Packit c5a612
ct mark set meta mark
Packit c5a612
--------------------------------
Packit c5a612
Packit c5a612
.set zone mapped via interface
Packit c5a612
------------------------------
Packit c5a612
table inet raw {
Packit c5a612
  chain prerouting {
Packit c5a612
      type filter hook prerouting priority -300;
Packit c5a612
      ct zone set iif map { "eth1" : 1, "veth1" : 2 }
Packit c5a612
  }
Packit c5a612
  chain output {
Packit c5a612
      type filter hook output priority -300;
Packit c5a612
      ct zone set oif map { "eth1" : 1, "veth1" : 2 }
Packit c5a612
  }
Packit c5a612
}
Packit c5a612
------------------------------------------------------
Packit c5a612
Packit c5a612
.restrict events reported by ctnetlink
Packit c5a612
--------------------------------------
Packit c5a612
ct event set new,related,destroy
Packit c5a612
--------------------------------------
Packit c5a612
Packit c5a612
META STATEMENT
Packit c5a612
~~~~~~~~~~~~~~
Packit c5a612
A meta statement sets the value of a meta expression. The existing meta fields
Packit c5a612
are: priority, mark, pkttype, nftrace. +
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*meta* {*mark* | *priority* | *pkttype* | *nftrace*} *set* 'value'
Packit c5a612
Packit c5a612
A meta statement sets meta data associated with a packet. +
Packit c5a612
Packit c5a612
.Meta statement types
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Keyword| Description| Value
Packit c5a612
|priority |
Packit c5a612
TC packet priority|
Packit c5a612
tc_handle
Packit c5a612
|mark|
Packit c5a612
Packet mark |
Packit c5a612
mark
Packit c5a612
|pkttype |
Packit c5a612
packet type |
Packit c5a612
pkt_type
Packit c5a612
|nftrace |
Packit c5a612
ruleset packet tracing on/off. Use *monitor trace* command to watch traces|
Packit c5a612
0, 1
Packit c5a612
|==========================
Packit c5a612
Packit c5a612
LIMIT STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
*limit rate* [*over*] 'packet_number' */* 'TIME_UNIT' [*burst* 'packet_number' *packets*]
Packit c5a612
*limit rate* [*over*] 'byte_number' 'BYTE_UNIT' */* 'TIME_UNIT' [*burst* 'byte_number' 'BYTE_UNIT']
Packit c5a612
Packit c5a612
'TIME_UNIT' := *second* | *minute* | *hour* | *day*
Packit c5a612
'BYTE_UNIT' := *bytes* | *kbytes* | *mbytes*
Packit c5a612
____
Packit c5a612
Packit c5a612
A limit statement matches at a limited rate using a token bucket filter. A rule
Packit c5a612
using this statement will match until this limit is reached. It can be used in
Packit c5a612
combination with the log statement to give limited logging. The optional
Packit c5a612
*over* keyword makes it match over the specified rate.
Packit c5a612
Packit c5a612
.limit statement values
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Value | Description | Type
Packit c5a612
|packet_number |
Packit c5a612
Number of packets |
Packit c5a612
unsigned integer (32 bit)
Packit c5a612
|byte_number |
Packit c5a612
Number of bytes |
Packit c5a612
unsigned integer (32 bit)
Packit c5a612
|========================
Packit c5a612
Packit c5a612
NAT STATEMENTS
Packit c5a612
~~~~~~~~~~~~~~
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
*snat to* 'address' [*:*'port'] ['PRF_FLAGS']
Packit c5a612
*snat to* 'address' *-* 'address' [*:*'port' *-* 'port'] ['PRF_FLAGS']
Packit c5a612
*snat* { *ip* | *ip6* } *to* 'address' *-* 'address' [*:*'port' *-* 'port'] ['PR_FLAGS']
Packit c5a612
*dnat to* 'address' [*:*'port'] ['PRF_FLAGS']
Packit c5a612
*dnat to* 'address' [*:*'port' *-* 'port'] ['PR_FLAGS']
Packit c5a612
*dnat* { *ip* | *ip6* } *to* 'address' [*:*'port' *-* 'port'] ['PR_FLAGS']
Packit c5a612
*masquerade to* [*:*'port'] ['PRF_FLAGS']
Packit c5a612
*masquerade to* [*:*'port' *-* 'port'] ['PRF_FLAGS']
Packit c5a612
*redirect to* [*:*'port'] ['PRF_FLAGS']
Packit c5a612
*redirect to* [*:*'port' *-* 'port'] ['PRF_FLAGS']
Packit c5a612
Packit c5a612
'PRF_FLAGS' := 'PRF_FLAG' [*,* 'PRF_FLAGS']
Packit c5a612
'PR_FLAGS'  := 'PR_FLAG' [*,* 'PR_FLAGS']
Packit c5a612
'PRF_FLAG'  := 'PR_FLAG' | *fully-random*
Packit c5a612
'PR_FLAG'   := *persistent* | *random*
Packit c5a612
____
Packit c5a612
Packit c5a612
The nat statements are only valid from nat chain types. +
Packit c5a612
Packit c5a612
The *snat* and *masquerade* statements specify that the source address of the
Packit c5a612
packet should be modified. While *snat* is only valid in the postrouting and
Packit c5a612
input chains, *masquerade* makes sense only in postrouting. The dnat and
Packit c5a612
redirect statements are only valid in the prerouting and output chains, they
Packit c5a612
specify that the destination address of the packet should be modified. You can
Packit c5a612
use non-base chains which are called from base chains of nat chain type too.
Packit c5a612
All future packets in this connection will also be mangled, and rules should
Packit c5a612
cease being examined.
Packit c5a612
Packit c5a612
The *masquerade* statement is a special form of snat which always uses the
Packit c5a612
outgoing interface's IP address to translate to. It is particularly useful on
Packit c5a612
gateways with dynamic (public) IP addresses.
Packit c5a612
Packit c5a612
The *redirect* statement is a special form of dnat which always translates the
Packit c5a612
destination address to the local host's one. It comes in handy if one only wants
Packit c5a612
to alter the destination port of incoming traffic on different interfaces.
Packit c5a612
Packit c5a612
When used in the inet family (available with kernel 5.2), the dnat and snat
Packit c5a612
statements require the use of the ip and ip6 keyword in case an address is
Packit c5a612
provided, see the examples below.
Packit c5a612
Packit c5a612
Before kernel 4.18 nat statements require both prerouting and postrouting base chains
Packit c5a612
to be present since otherwise packets on the return path won't be seen by
Packit c5a612
netfilter and therefore no reverse translation will take place.
Packit c5a612
Packit c5a612
.NAT statement values
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Expression| Description| Type
Packit c5a612
|address|
Packit c5a612
Specifies that the source/destination address of the packet should be modified.
Packit c5a612
You may specify a mapping to relate a list of tuples composed of arbitrary
Packit c5a612
expression key with address value. |
Packit c5a612
ipv4_addr, ipv6_addr, e.g. abcd::1234, or you can use a mapping, e.g. meta mark map { 10 : 192.168.1.2, 20 : 192.168.1.3 }
Packit c5a612
|port|
Packit c5a612
Specifies that the source/destination address of the packet should be modified. |
Packit c5a612
port number (16 bit)
Packit c5a612
|===============================
Packit c5a612
Packit c5a612
.NAT statement flags
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Flag| Description
Packit c5a612
|persistent |
Packit c5a612
Gives a client the same source-/destination-address for each connection.
Packit c5a612
|random|
Packit c5a612
In kernel 5.0 and newer this is the same as fully-random.
Packit c5a612
In earlier kernels the port mapping will be randomized using a seeded MD5
Packit c5a612
hash mix using source and destination address and destination port.
Packit c5a612
Packit c5a612
|fully-random|
Packit c5a612
If used then port mapping is generated based on a 32-bit pseudo-random algorithm.
Packit c5a612
|=============================
Packit c5a612
Packit c5a612
.Using NAT statements
Packit c5a612
---------------------
Packit c5a612
# create a suitable table/chain setup for all further examples
Packit c5a612
add table nat
Packit c5a612
add chain nat prerouting { type nat hook prerouting priority 0; }
Packit c5a612
add chain nat postrouting { type nat hook postrouting priority 100; }
Packit c5a612
Packit c5a612
# translate source addresses of all packets leaving via eth0 to address 1.2.3.4
Packit c5a612
add rule nat postrouting oif eth0 snat to 1.2.3.4
Packit c5a612
Packit c5a612
# redirect all traffic entering via eth0 to destination address 192.168.1.120
Packit c5a612
add rule nat prerouting iif eth0 dnat to 192.168.1.120
Packit c5a612
Packit c5a612
# translate source addresses of all packets leaving via eth0 to whatever
Packit c5a612
# locally generated packets would use as source to reach the same destination
Packit c5a612
add rule nat postrouting oif eth0 masquerade
Packit c5a612
Packit c5a612
# redirect incoming TCP traffic for port 22 to port 2222
Packit c5a612
add rule nat prerouting tcp dport 22 redirect to :2222
Packit c5a612
Packit c5a612
# inet family:
Packit c5a612
# handle ip dnat:
Packit c5a612
add rule inet nat prerouting dnat ip to 10.0.2.99
Packit c5a612
# handle ip6 dnat:
Packit c5a612
add rule inet nat prerouting dnat ip6 to fe80::dead
Packit c5a612
# this masquerades both ipv4 and ipv6:
Packit c5a612
add rule inet nat postrouting meta oif ppp0 masquerade
Packit c5a612
Packit c5a612
------------------------
Packit c5a612
Packit c5a612
TPROXY STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~
Packit c5a612
Tproxy redirects the packet to a local socket without changing the packet header
Packit c5a612
in any way. If any of the arguments is missing the data of the incoming packet
Packit c5a612
is used as parameter. Tproxy matching requires another rule that ensures the
Packit c5a612
presence of transport protocol header is specified.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*tproxy to* 'address'*:*'port'
Packit c5a612
*tproxy to* {'address' | *:*'port'}
Packit c5a612
Packit c5a612
This syntax can be used in *ip/ip6* tables where network layer protocol is
Packit c5a612
obvious. Either IP address or port can be specified, but at least one of them is
Packit c5a612
necessary.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*tproxy* {*ip* | *ip6*} *to* 'address'[*:*'port']
Packit c5a612
*tproxy to :*'port'
Packit c5a612
Packit c5a612
This syntax can be used in *inet* tables. The *ip/ip6* parameter defines the
Packit c5a612
family the rule will match. The *address* parameter must be of this family.
Packit c5a612
When only *port* is defined, the address family should not be specified. In
Packit c5a612
this case the rule will match for both families.
Packit c5a612
Packit c5a612
.tproxy attributes
Packit c5a612
[options="header"]
Packit c5a612
|=================
Packit c5a612
| Name | Description
Packit c5a612
| address | IP address the listening socket with IP_TRANSPARENT option is bound to.
Packit c5a612
| port | Port the listening socket with IP_TRANSPARENT option is bound to.
Packit c5a612
|=================
Packit c5a612
Packit c5a612
.Example ruleset for tproxy statement
Packit c5a612
-------------------------------------
Packit c5a612
table ip x {
Packit c5a612
    chain y {
Packit c5a612
        type filter hook prerouting priority -150; policy accept;
Packit c5a612
        tcp dport ntp tproxy to 1.1.1.1
Packit c5a612
        udp dport ssh tproxy to :2222
Packit c5a612
    }
Packit c5a612
}
Packit c5a612
table ip6 x {
Packit c5a612
    chain y {
Packit c5a612
       type filter hook prerouting priority -150; policy accept;
Packit c5a612
       tcp dport ntp tproxy to [dead::beef]
Packit c5a612
       udp dport ssh tproxy to :2222
Packit c5a612
    }
Packit c5a612
}
Packit c5a612
table inet x {
Packit c5a612
    chain y {
Packit c5a612
        type filter hook prerouting priority -150; policy accept;
Packit c5a612
        tcp dport 321 tproxy to :ssh
Packit c5a612
        tcp dport 99 tproxy ip to 1.1.1.1:999
Packit c5a612
        udp dport 155 tproxy ip6 to [dead::beef]:smux
Packit c5a612
    }
Packit c5a612
}
Packit c5a612
-------------------------------------
Packit c5a612
Packit c5a612
SYNPROXY STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~~~~
Packit c5a612
This statement will process TCP three-way-handshake parallel in netfilter
Packit c5a612
context to protect either local or backend system. This statement requires
Packit c5a612
connection tracking because sequence numbers need to be translated.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*synproxy* [*mss* 'mss_value'] [*wscale* 'wscale_value'] ['SYNPROXY_FLAGS']
Packit c5a612
Packit c5a612
.synproxy statement attributes
Packit c5a612
[options="header"]
Packit c5a612
|=================
Packit c5a612
| Name | Description
Packit c5a612
| mss | Maximum segment size announced to clients. This must match the backend.
Packit c5a612
| wscale | Window scale announced to clients. This must match the backend.
Packit c5a612
|=================
Packit c5a612
Packit c5a612
.synproxy statement flags
Packit c5a612
[options="header"]
Packit c5a612
|=================
Packit c5a612
| Flag | Description
Packit c5a612
| sack-perm |
Packit c5a612
Pass client selective acknowledgement option to backend (will be disabled if
Packit c5a612
not present).
Packit c5a612
| timestamp |
Packit c5a612
Pass client timestamp option to backend (will be disabled if not present, also
Packit c5a612
needed for selective acknowledgement and window scaling).
Packit c5a612
|=================
Packit c5a612
Packit c5a612
.Example ruleset for synproxy statement
Packit c5a612
---------------------------------------
Packit c5a612
Determine tcp options used by backend, from an external system
Packit c5a612
Packit c5a612
              tcpdump -pni eth0 -c 1 'tcp[tcpflags] == (tcp-syn|tcp-ack)'
Packit c5a612
                  port 80 &
Packit c5a612
              telnet 192.0.2.42 80
Packit c5a612
              18:57:24.693307 IP 192.0.2.42.80 > 192.0.2.43.48757:
Packit c5a612
                  Flags [S.], seq 360414582, ack 788841994, win 14480,
Packit c5a612
                  options [mss 1460,sackOK,
Packit c5a612
                  TS val 1409056151 ecr 9690221,
Packit c5a612
                  nop,wscale 9],
Packit c5a612
                  length 0
Packit c5a612
Packit c5a612
Switch tcp_loose mode off, so conntrack will mark out-of-flow packets as state INVALID.
Packit c5a612
Packit c5a612
              echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose
Packit c5a612
Packit c5a612
Make SYN packets untracked.
Packit c5a612
Packit c5a612
	table ip x {
Packit c5a612
		chain y {
Packit c5a612
			type filter hook prerouting priority raw; policy accept;
Packit c5a612
			tcp flags syn notrack
Packit c5a612
		}
Packit c5a612
	}
Packit c5a612
Packit c5a612
Catch UNTRACKED (SYN  packets) and INVALID (3WHS ACK packets) states and send
Packit c5a612
them to SYNPROXY. This rule will respond to SYN packets with SYN+ACK
Packit c5a612
syncookies, create ESTABLISHED for valid client response (3WHS ACK packets) and
Packit c5a612
drop incorrect cookies. Flags combinations not expected during  3WHS will not
Packit c5a612
match and continue (e.g. SYN+FIN, SYN+ACK). Finally, drop invalid packets, this
Packit c5a612
will be out-of-flow packets that were not matched by SYNPROXY.
Packit c5a612
Packit c5a612
    table ip foo {
Packit c5a612
            chain z {
Packit c5a612
                    type filter hook input priority filter; policy accept;
Packit c5a612
                    ct state { invalid, untracked } synproxy mss 1460 wscale 9 timestamp sack-perm
Packit c5a612
                    ct state invalid drop
Packit c5a612
            }
Packit c5a612
    }
Packit c5a612
Packit c5a612
The outcome ruleset of the steps above should be similar to the one below.
Packit c5a612
Packit c5a612
	table ip x {
Packit c5a612
		chain y {
Packit c5a612
			type filter hook prerouting priority raw; policy accept;
Packit c5a612
	                tcp flags syn notrack
Packit c5a612
		}
Packit c5a612
Packit c5a612
		chain z {
Packit c5a612
			type filter hook input priority filter; policy accept;
Packit c5a612
	                ct state { invalid, untracked } synproxy mss 1460 wscale 9 timestamp sack-perm
Packit c5a612
		        ct state invalid drop
Packit c5a612
	        }
Packit c5a612
	}
Packit c5a612
---------------------------------------
Packit c5a612
Packit c5a612
FLOW STATEMENT
Packit c5a612
~~~~~~~~~~~~~~
Packit c5a612
A flow statement allows us to select what flows you want to accelerate
Packit c5a612
forwarding through layer 3 network stack bypass. You have to specify the
Packit c5a612
flowtable name where you want to offload this flow.
Packit c5a612
Packit c5a612
*flow add @*'flowtable'
Packit c5a612
Packit c5a612
QUEUE STATEMENT
Packit c5a612
~~~~~~~~~~~~~~~
Packit c5a612
This statement passes the packet to userspace using the nfnetlink_queue handler.
Packit c5a612
The packet is put into the queue identified by its 16-bit queue number.
Packit c5a612
Userspace can inspect and modify the packet if desired. Userspace must then drop
Packit c5a612
or re-inject the packet into the kernel. See libnetfilter_queue documentation
Packit c5a612
for details.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
*queue* [*num* 'queue_number'] [*bypass*]
Packit c5a612
*queue* [*num* 'queue_number_from' - 'queue_number_to'] ['QUEUE_FLAGS']
Packit c5a612
Packit c5a612
'QUEUE_FLAGS' := 'QUEUE_FLAG' [*,* 'QUEUE_FLAGS']
Packit c5a612
'QUEUE_FLAG'  := *bypass* | *fanout*
Packit c5a612
____
Packit c5a612
Packit c5a612
Packit c5a612
.queue statement values
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Value | Description | Type
Packit c5a612
|queue_number |
Packit c5a612
Sets queue number, default is 0. |
Packit c5a612
unsigned integer (16 bit)
Packit c5a612
|queue_number_from |
Packit c5a612
Sets initial queue in the range, if fanout is used. |
Packit c5a612
unsigned integer (16 bit)
Packit c5a612
|queue_number_to |
Packit c5a612
Sets closing queue in the range, if fanout is used. |
Packit c5a612
unsigned integer (16 bit)
Packit c5a612
|=====================
Packit c5a612
Packit c5a612
.queue statement flags
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Flag | Description
Packit c5a612
|bypass |
Packit c5a612
Let packets go through if userspace application cannot back off. Before using
Packit c5a612
this flag, read libnetfilter_queue documentation for performance tuning recommendations.
Packit c5a612
|fanout |
Packit c5a612
Distribute packets between several queues.
Packit c5a612
|===============================
Packit c5a612
Packit c5a612
DUP STATEMENT
Packit c5a612
~~~~~~~~~~~~~
Packit c5a612
The dup statement is used to duplicate a packet and send the copy to a different
Packit c5a612
destination.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
*dup to* 'device'
Packit c5a612
*dup to* 'address' *device* 'device'
Packit c5a612
Packit c5a612
.Dup statement values
Packit c5a612
[options="header"]
Packit c5a612
|==================
Packit c5a612
|Expression | Description | Type
Packit c5a612
|address |
Packit c5a612
Specifies that the copy of the packet should be sent to a new gateway.|
Packit c5a612
ipv4_addr, ipv6_addr, e.g. abcd::1234, or you can use a mapping, e.g. ip saddr map { 192.168.1.2 : 10.1.1.1 }
Packit c5a612
|device |
Packit c5a612
Specifies that the copy should be transmitted via device. |
Packit c5a612
string
Packit c5a612
|===================
Packit c5a612
Packit c5a612
Packit c5a612
.Using the dup statement
Packit c5a612
------------------------
Packit c5a612
# send to machine with ip address 10.2.3.4 on eth0
Packit c5a612
ip filter forward dup to 10.2.3.4 device "eth0"
Packit c5a612
Packit c5a612
# copy raw frame to another interface
Packit c5a612
netdetv ingress dup to "eth0"
Packit c5a612
dup to "eth0"
Packit c5a612
Packit c5a612
# combine with map dst addr to gateways
Packit c5a612
dup to ip daddr map { 192.168.7.1 : "eth0", 192.168.7.2 : "eth1" }
Packit c5a612
-----------------------------------
Packit c5a612
Packit c5a612
FWD STATEMENT
Packit c5a612
~~~~~~~~~~~~~
Packit c5a612
The fwd statement is used to redirect a raw packet to another interface. It is
Packit c5a612
only available in the netdev family ingress hook. It is similar to the dup
Packit c5a612
statement except that no copy is made.
Packit c5a612
Packit c5a612
*fwd to* 'device'
Packit c5a612
Packit c5a612
SET STATEMENT
Packit c5a612
~~~~~~~~~~~~~
Packit c5a612
The set statement is used to dynamically add or update elements in a set from
Packit c5a612
the packet path. The set setname must already exist in the given table and must
Packit c5a612
have been created with one or both of the dynamic and the timeout flags. The
Packit c5a612
dynamic flag is required if the set statement expression includes a stateful
Packit c5a612
object. The timeout flag is implied if the set is created with a timeout, and is
Packit c5a612
required if the set statement updates elements, rather than adding them.
Packit c5a612
Furthermore, these sets should specify both a maximum set size (to prevent
Packit c5a612
memory exhaustion), and their elements should have a timeout (so their number
Packit c5a612
will not grow indefinitely) either from the set definition or from the statement
Packit c5a612
that adds or updates them. The set statement can be used to e.g. create dynamic
Packit c5a612
blacklists.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
{*add* | *update*} *@*'setname' *{* 'expression' [*timeout* 'timeout'] [*comment* 'string'] *}*
Packit c5a612
Packit c5a612
.Example for simple blacklist
Packit c5a612
-----------------------------
Packit c5a612
# declare a set, bound to table "filter", in family "ip". Timeout and size are mandatory because we will add elements from packet path.
Packit c5a612
nft add set ip filter blackhole "{ type ipv4_addr; flags timeout; size 65536; }"
Packit c5a612
Packit c5a612
# whitelist internal interface.
Packit c5a612
nft add rule ip filter input meta iifname "internal" accept
Packit c5a612
Packit c5a612
# drop packets coming from blacklisted ip addresses.
Packit c5a612
nft add rule ip filter input ip saddr @blackhole counter drop
Packit c5a612
Packit c5a612
# add source ip addresses to the blacklist if more than 10 tcp connection requests occurred per second and ip address.
Packit c5a612
# entries will timeout after one minute, after which they might be re-added if limit condition persists.
Packit c5a612
nft add rule ip filter input tcp flags syn tcp dport ssh meter flood size 128000 { ip saddr timeout 10s limit rate over 10/second} add @blackhole { ip saddr timeout 1m } drop
Packit c5a612
Packit c5a612
# inspect state of the rate limit meter:
Packit c5a612
nft list meter ip filter flood
Packit c5a612
Packit c5a612
# inspect content of blackhole:
Packit c5a612
nft list set ip filter blackhole
Packit c5a612
Packit c5a612
# manually add two addresses to the set:
Packit c5a612
nft add element filter blackhole { 10.2.3.4, 10.23.1.42 }
Packit c5a612
-----------------------------------------------
Packit c5a612
Packit c5a612
MAP STATEMENT
Packit c5a612
~~~~~~~~~~~~~
Packit c5a612
The map statement is used to lookup data based on some specific input key.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
'expression' *map* *{* 'MAP_ELEMENTS' *}*
Packit c5a612
Packit c5a612
'MAP_ELEMENTS' := 'MAP_ELEMENT' [*,* 'MAP_ELEMENTS']
Packit c5a612
'MAP_ELEMENT'  := 'key' *:* 'value'
Packit c5a612
____
Packit c5a612
Packit c5a612
The 'key' is a value returned by 'expression'.
Packit c5a612
// XXX: Write about where map statement can be used (list of statements?)
Packit c5a612
Packit c5a612
.Using the map statement
Packit c5a612
------------------------
Packit c5a612
# select DNAT target based on TCP dport:
Packit c5a612
# connections to port 80 are redirected to 192.168.1.100,
Packit c5a612
# connections to port 8888 are redirected to 192.168.1.101
Packit c5a612
nft add rule ip nat prerouting dnat tcp dport map { 80 : 192.168.1.100, 8888 : 192.168.1.101 }
Packit c5a612
Packit c5a612
# source address based SNAT:
Packit c5a612
# packets from net 192.168.1.0/24 will appear as originating from 10.0.0.1,
Packit c5a612
# packets from net 192.168.2.0/24 will appear as originating from 10.0.0.2
Packit c5a612
nft add rule ip nat postrouting snat to ip saddr map { 192.168.1.0/24 : 10.0.0.1, 192.168.2.0/24 : 10.0.0.2 }
Packit c5a612
------------------------
Packit c5a612
Packit c5a612
VMAP STATEMENT
Packit c5a612
~~~~~~~~~~~~~~
Packit c5a612
The verdict map (vmap) statement works analogous to the map statement, but
Packit c5a612
contains verdicts as values.
Packit c5a612
Packit c5a612
[verse]
Packit c5a612
____
Packit c5a612
'expression' *vmap* *{* 'VMAP_ELEMENTS' *}*
Packit c5a612
Packit c5a612
'VMAP_ELEMENTS' := 'VMAP_ELEMENT' [*,* 'VMAP_ELEMENTS']
Packit c5a612
'VMAP_ELEMENT'  := 'key' *:* 'verdict'
Packit c5a612
____
Packit c5a612
Packit c5a612
.Using the vmap statement
Packit c5a612
-------------------------
Packit c5a612
# jump to different chains depending on layer 4 protocol type:
Packit c5a612
nft add rule ip filter input ip protocol vmap { tcp : jump tcp-chain, udp : jump udp-chain , icmp : jump icmp-chain }
Packit c5a612
------------------------