aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/network/nftables.md
blob: 66c3f25050ff3f44ac9b9a8ac68768fa8ac74564 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# nftables

[Nftables][nftables] is a stateful Linux firewall which uses the
[netfilter][netfilter] kernel hooks.
It is used for stateless, stateful packet filtering and all sorts of NAT.

Nftables is the successor to [iptables][iptabes].

In nftables, `rules` are organized with `chains` and `tables`.
- `chain`: Orders `rules`. Chains exist in two kinds:
    - `base chain`: Entry point from netfilter hooks (network stack).
    - `regular chain`: Can be used as jump target to group rules for better organization.
- `table`: Groups chains together. Tables are defined by a `name` and an
  `address family` (eg `inet`, `ip`, `ip6`, ..).

## Ruleset
```bash
nft list ruleset        # List all tables/chains/rules (whole ruleset).
nft flush ruleset       # Clear whole ruleset.
```

## Examples: Save rules to files and re-apply
```bash
nft list ruleset > nft.rules
nft flush ruleset
nft -f nft.rules
```

## Example: Fully trace evaluation of nftables rules
```text
table ip traceall {
    chain filter_prerouting {
        # Install chain with higher priority as the RAW standard priority.
        type filter hook prerouting priority raw - 50; policy accept;
        # Trace each and every packet (very verbose).
        #meta nftrace set 1;
        # Trace packet to port 80/81/8081 from localhost.
        tcp dport { 80, 81, 8081 } ip saddr 127.0.0.1 meta nftrace set 1;
    }
}
```

Use `nft monitor trace` to get trace output on tty.

## Example: IPv4 port forwarding
```text
table ip fwd {
    chain nat_preroute {
        # Register this chain to the PREROUTE:NAT hook (stateful packet tracking via conntrack).
        type nat hook prerouting priority dstnat + 10 ; policy accept;
        meta nfproto ipv4 tcp dport 81 redirect to :8081
    }
}
```

## Example: Base vs regular chain
```text
# Table named 'playground' handling 'ip' (ipv4) address family.
table ip playground {
    # Base chain.
    chain filter_input_base {
        # Register this chain to the INPUT:FILTER hook in the netfilter package flow.
        # Specify a prioirty relative to the inbuilt 'filter' priority (smaller
        # number means higher priority).
        # Set the default policy to ACCEPT, to let every packet pass by default.
        type filter hook input priority filter - 10; policy accept;

        # Create a rule for tcp packets arriving on either port 8000 or 8100.
        tcp dport { 8000, 8100 } jump input_reg_log;
        # Create a rule for tcp packets arriving on port 8200.
        tcp dport 8200 jump input_reg_log_all;
    }

    # Regular chain.
    chain input_reg_log {
        # Log every packet traversing this chain.
        # Message lands in the kernel ring buffer.
        log;
    }

    # Regular chain.
    chain input_reg_log_all {
        # Log every packet with all flags traversing this chain.
        log flags all;
    }
}
```

```bash
# Load the nf rules.
sudo nft -f playground.rules
# Create test servers.
nc -lk 0.0.0.0 8000
nc -lk 0.0.0.0 8100
nc -lk 0.0.0.0 8200
# See the nftables logging in the kernel ring buffer.
sudo dmesg -w
# Make some client connections.
nc localhost 8000
nc localhost 8200
```

## Mental model for netfilter packet flow
![nf_pkt_flow.png](assets/nf_pkt_flow.png)

[netfilter]: https://nftables.org
[nftables]: https://nftables.org/projects/nftables/index.html
[iptabes]: https://nftables.org/projects/iptables/index.html