nftables-workstation.nft: mention the IPv6 Neighbor Discovery RFC
[config/nftables.git] / nftables-workstation.nft
1 #!/usr/sbin/nft -f
2 #
3 # nftables ruleset for an End Node acting as a workstation in a LAN.
4 #
5 # Copyright (C) 2018  Antonio Ospite <ao2@ao2.it>
6 # SPDX-License-Identifier: MIT
7 #
8 # Based on:
9 # https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Simple_IP.2FIPv6_Firewall
10 # https://wiki.archlinux.org/index.php/Nftables#Workstation
11 # https://stosb.com/blog/explaining-my-configs-nftables/
12
13 flush ruleset
14
15 table inet filter {
16
17     define common_open_ports = {
18             xmpp-client,
19             xmpp-server,
20             5298, # Link-local XMPP, for backward compatibility, XEP-0174
21     }
22
23     set tcp_open_ports {
24         type inet_service
25         flags interval
26
27         elements = {
28             $common_open_ports,
29         }
30     }
31
32     set udp_open_ports {
33         type inet_service
34         flags interval
35
36         elements = {
37             $common_open_ports,
38         }
39     }
40
41     chain input {
42         type filter hook input priority 0
43         policy drop
44
45         iif lo accept
46
47         ip protocol icmp icmp type {
48             echo-reply,
49             echo-request,
50             time-exceeded,
51             parameter-problem,
52             destination-unreachable
53         } accept
54
55         # ICMPv6 configuration based on:
56         # https://github.com/intel/intel-iot-refkit/blob/master/meta-refkit-core/recipes-security/nftables-settings-default/files/firewall.template
57         ip6 nexthdr ipv6-icmp icmpv6 type {
58             echo-reply,
59             echo-request,
60             time-exceeded,
61             parameter-problem,
62             destination-unreachable,
63             packet-too-big
64         } accept
65
66         # Allow IPv6 Neighbor Discovery (RFC4861).
67         ip6 nexthdr ipv6-icmp icmpv6 type {
68             nd-router-advert,
69             nd-router-solicit,
70             nd-neighbor-advert,
71             nd-neighbor-solicit
72         } ip6 hoplimit 255 accept
73
74         # Allow multicast listener discovery on link-local addresses.
75         # RFC2710 specifies that a Hop-by-Hop Options header is used.
76         hbh nexthdr ipv6-icmp icmpv6 type {
77             mld-listener-query,
78             mld-listener-report,
79             mld-listener-reduction
80         } ip6 saddr fe80::/10 accept
81
82         # Allow multicast router discovery messages on link-local addresses (hop limit 1).
83         ip6 nexthdr ipv6-icmp icmpv6 type {
84             nd-router-advert,
85             nd-router-solicit
86         } ip6 hoplimit 1 ip6 saddr fe80::/10 accept
87
88         # Allow IGMPv3 queries.
89         ip protocol igmp ip daddr 224.0.0.1 accept
90
91         # Stateful filtering for anything else.
92         ct state established,related accept
93         ct state invalid drop
94         ct state new jump in-new
95
96         # Silently drop other incoming broadcast and multicast traffic.
97         meta pkttype {broadcast, multicast} drop
98
99         limit rate 3/minute burst 10 packets log prefix "[INPUT]: "
100         counter reject
101     }
102
103     chain in-new {
104         # Silently drop DHCPv4 Discover and Request packets from other clients.
105         ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp sport bootpc udp dport bootps drop
106
107         # Silently drop DHCPv6 from other clients.
108         ip6 saddr fe80::/64 ip6 daddr fe80::/64 udp sport dhcpv6-client udp dport dhcpv6-server drop
109
110         # mDNS (ZeroConf/Bonjour)
111         ip  daddr 224.0.0.251 udp dport mdns accept
112         ip6 daddr ff02::fb    udp dport mdns accept
113
114         # SSDP: https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol
115         ip daddr 239.255.255.250 udp dport 1900 accept
116         ip6 daddr {
117             ff02::c,
118             ff05::c,
119             ff08::c,
120             ff0e::c
121         } udp dport 1900 accept
122
123         tcp dport @tcp_open_ports tcp flags & (fin | syn | rst | ack) == syn accept
124         udp dport @udp_open_ports accept
125     }
126
127     chain forward {
128         type filter hook forward priority 0
129         policy drop
130
131         limit rate 3/minute burst 10 packets log prefix "[FORWARD]: "
132         counter reject
133     }
134
135     chain output {
136         type filter hook output priority 0
137         policy drop
138
139         counter accept
140     }
141 }