Should I enable ICMP? (Pt. 2)
Intro¶
This is part two of another post I wrote: Should I enable ICMP?
The goals of this firewall ruleset are as follows:
- Enforce sane limits over the number of automated ICMP responses that can be elicited by sources on the internet; mitigating ICMP amplification while still allowing some symbolance of networking mechanisms that rely on ICMP to function.
- Establish the basis for a “zero trust” model by ensuring the use of end-to-end encrypted protocols for necessary egress traffic (primarily NTPSEC and DoTLS.) This is necessary in an environment where protocols like
NDP-RA
are in use because of the possibility that other users on a network can advertise routes themselves which can potentially be used to hijack another user’s traffic. Unauthorized route advertisements can certainly be mitigated with multicast filtering/snooping however it is not necessarily consistent from one network to the next. - Providing an abstract ruleset such that it can be the basis for application virtually anywhere while minimizing the amount of overhead that can be potentially introduced by abstraction as much as possible (YMMV)
The simplest way to go about this is to start at the filter state / configuration format section.
Preparation¶
This demo uses Debian on Parallels, updated from bullseye
to bookworm
:
1sed -i 's/http:\/\//https:\/\//g' /etc/apt/sources.list
2sed -i 's/bullseye/bookworm/g' apt/sources.list
3apt update && apt -y dist-upgrade
4apt -y install nftables chrony systemd-resolved && reboot
Chrony (NTPSEC)¶
Unencrypted NTP (UDP 123) destinations will only be permitted in the NFTables ruleset if they are local networks, if you need internet time setup chrony
Disable systemd-timesyncd
if it is enabled:
replace /etc/chrony.conf
with:
1confdir /etc/chrony/conf.d
2server time.cloudflare.com nts iburst
3sourcedir /run/chrony-dhcp
4sourcedir /etc/chrony/sources.d
5keyfile /etc/chrony/chrony.keys
6driftfile /var/lib/chrony/chrony.drift
7ntsdumpdir /var/lib/chrony
8logdir /var/log/chrony
9maxupdateskew 100.0
10rtcsync
11makestep 1 3
12leapsectz right/UTC
Enable the Chrony
service:
(a list of other NTS-enabled NTP servers is available.)
DNSoTLS¶
Unencrypted DNS (UDP 53) destinations will only be permitted in the NFTables ruleset if they are local networks, if you need internet DNS setup systemd-resolved
with DoTLS
then
replace the contents of /etc/systemd/resolved.conf
with:
1[Resolve]
2DNS=1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001
3DNSSEC=yes
4DNSOverTLS=yes
start systemd-resolved
:
Creating the default table¶
Chains¶
1nft add chain inet filter input '{ type filter hook input priority filter; policy accept; }'
2nft add chain inet filter forward '{ type filter hook forward priority filter; policy accept; }'
3nft add chain inet filter output '{ type filter hook output priority filter; policy accept; }'
4nft add chain inet filter prerouting '{ type nat hook prerouting priority 100; policy accept; }'
5nft add chain inet filter postrouting '{ type nat hook postrouting priority 100; policy accept; }'
6nft add chain inet filter masq
7nft add chain inet filter ether_in
8nft add chain inet filter ether_out
9nft add chain inet filter ether_forward
10nft add chain inet filter icmp_in
11nft add chain inet filter icmp_out
12nft add chain inet filter icmp_forward
13nft add chain inet filter icmp_echo_reply_rate_limit
14nft add chain inet filter reject_with_icmp_port_unreachable_metered
15nft add chain inet filter reject_with_icmp_port_unreachable
16nft add chain inet filter reject_with_icmp_host_unreachable_metered
17nft add chain inet filter reject_with_icmp_host_unreachable
18nft add chain inet filter reject_with_icmp_no_route_metered
19nft add chain inet filter reject_with_icmp_no_route
20nft add chain inet filter reject_with_icmp_admin_prohibited_metered
21nft add chain inet filter reject_with_icmp_admin_prohibited
22nft add chain inet filter tcp_in
23nft add chain inet filter tcp_out
24nft add chain inet filter tcp_forward
25nft add chain inet filter udp_in
26nft add chain inet filter udp_out
27nft add chain inet filter udp_forward
28nft add chain inet filter bogon
29nft add rule inet filter bogon log prefix "bogon" group 1
30nft add rule inet filter bogon counter drop
31nft add chain inet filter wont_forward
32nft add rule inet filter wont_forward log prefix "wont_forward" group 1
33nft add rule inet filter wont_forward counter drop
Meter sets¶
1nft add set inet filter icmp_egress_meter4 '{ type ipv4_addr; size 8; flags timeout, dynamic; }'
2nft add set inet filter icmp_egress_meter6 '{ type ipv6_addr; size 8; flags timeout, dynamic; }'
Verdict maps and sets¶
IPv4 bogons¶
1nft add map inet filter drop_bogons4 '{ type ipv4_addr : verdict; flags interval; }'
2nft add element inet filter drop_bogons4 '{ 224.0.0.0/4 : continue }'
3nft add element inet filter drop_bogons4 '{ 192.168.0.0/16 : continue }'
4nft add element inet filter drop_bogons4 '{ 10.0.0.0/8 : continue }'
5nft add element inet filter drop_bogons4 '{ 172.16.0.0/12 : continue }'
6nft add element inet filter drop_bogons4 '{ 169.254.0.0/16 : continue }'
7nft add element inet filter drop_bogons4 '{ 100.64.0.0/10 : jump bogon }'
8nft add element inet filter drop_bogons4 '{ 0.0.0.0/8 : jump bogon }'
9nft add element inet filter drop_bogons4 '{ 127.0.0.0/8 : jump bogon }'
10nft add element inet filter drop_bogons4 '{ 192.0.0.0/24 : jump bogon }'
11nft add element inet filter drop_bogons4 '{ 192.0.2.0/24 : jump bogon }'
12nft add element inet filter drop_bogons4 '{ 198.18.0.0/15 : jump bogon }'
13nft add element inet filter drop_bogons4 '{ 198.51.100.0/24 : jump bogon }'
14nft add element inet filter drop_bogons4 '{ 203.0.113.0/24 : jump bogon }'
15nft add element inet filter drop_bogons4 '{ 240.0.0.0/4 : jump bogon }'
Local networks¶
1nft add set inet filter local_networks '{ type ipv4_addr; flags interval; }'
2nft add element inet filter local_networks '{ 169.254.0.0/16, 10.0.0.0/8, 172.17.0.0/12, 192.168.0.0/16 }'
TODO¶
- Class E / limited broadcast (240.0.0.0/4)
IPv6 bogons¶
1nft add map inet filter drop_bogons6 '{ type ipv6_addr : verdict; flags interval; }'
2nft add element inet filter drop_bogons6 '{ fe80::/10 : continue }'
3nft add element inet filter drop_bogons6 '{ fc00::/7 : continue }'
4nft add element inet filter drop_bogons6 '{ ff00::/8 : continue }'
5nft add element inet filter drop_bogons6 '{ ::ffff:0:0/96 : jump bogon }'
6nft add element inet filter drop_bogons6 '{ ::/96 : jump bogon }'
7nft add element inet filter drop_bogons6 '{ 100::/64 : jump bogon }'
8nft add element inet filter drop_bogons6 '{ 2001:10::/28 : jump bogon }'
9nft add element inet filter drop_bogons6 '{ 2001:db8::/32 : jump bogon }'
10nft add element inet filter drop_bogons6 '{ fec0::/10 : jump bogon }'
11nft add element inet filter drop_bogons6 '{ 2002::/24 : jump bogon }'
12nft add element inet filter drop_bogons6 '{ 2002:a00::/24 : jump bogon }'
13nft add element inet filter drop_bogons6 '{ 2002:7f00::/24 : jump bogon }'
14nft add element inet filter drop_bogons6 '{ 2002:a9fe::/32 : jump bogon }'
15nft add element inet filter drop_bogons6 '{ 2002:ac10::/28 : jump bogon }'
16nft add element inet filter drop_bogons6 '{ 2002:c000::/40 : jump bogon }'
17nft add element inet filter drop_bogons6 '{ 2002:c000:200::/40 : jump bogon }'
18nft add element inet filter drop_bogons6 '{ 2002:c0a8::/32 : jump bogon }'
19nft add element inet filter drop_bogons6 '{ 2002:c612::/31 : jump bogon }'
20nft add element inet filter drop_bogons6 '{ 2002:c633:6400::/40 : jump bogon }'
21nft add element inet filter drop_bogons6 '{ 2002:cb00:7100::/40 : jump bogon }'
22nft add element inet filter drop_bogons6 '{ 2002:e000::/20 : jump bogon }'
23nft add element inet filter drop_bogons6 '{ 2002:f000::/20 : jump bogon }'
24nft add element inet filter drop_bogons6 '{ 2001::/40 : jump bogon }'
25nft add element inet filter drop_bogons6 '{ 2001:0:a00::/40 : jump bogon }'
26nft add element inet filter drop_bogons6 '{ 2001:0:7f00::/40 : jump bogon }'
27nft add element inet filter drop_bogons6 '{ 2001:0:a9fe::/48 : jump bogon }'
28nft add element inet filter drop_bogons6 '{ 2001:0:ac10::/44 : jump bogon }'
29nft add element inet filter drop_bogons6 '{ 2001:0:c000::/56 : jump bogon }'
30nft add element inet filter drop_bogons6 '{ 2001:0:c000:200::/56 : jump bogon }'
31nft add element inet filter drop_bogons6 '{ 2001:0:c0a8::/48 : jump bogon }'
32nft add element inet filter drop_bogons6 '{ 2001:0:c612::/47 : jump bogon }'
33nft add element inet filter drop_bogons6 '{ 2001:0:c633:6400::/56 : jump bogon }'
34nft add element inet filter drop_bogons6 '{ 2001:0:cb00:7100::/56 : jump bogon }'
35nft add element inet filter drop_bogons6 '{ 2001:0:e000::/36 : jump bogon }'
36nft add element inet filter drop_bogons6 '{ 2001:0:f000::/36 : jump bogon }'
TODO¶
- Multicast scopes; node-local
ff01::
vs. link-localff02::
vs. site-localff05::
- variable scope
- more info: https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
IPv4 reject or drop¶
1nft add map inet filter reject_or_drop_port4 '{ typeof ip saddr . ip daddr : verdict; flags interval; }'
2nft add element inet filter reject_or_drop_port4 '{ 10.0.0.0/8 . 10.0.0.0/8 : jump reject_with_icmp_port_unreachable }'
3nft add element inet filter reject_or_drop_port4 '{ 172.16.0.0/12 . 172.16.0.0/12 : jump reject_with_icmp_port_unreachable }'
4nft add element inet filter reject_or_drop_port4 '{ 192.168.0.0/16 . 192.168.0.0/16 : jump reject_with_icmp_port_unreachable }'
5nft add element inet filter reject_or_drop_port4 '{ 169.254.0.0/16 . 169.254.0.0/16 : jump reject_with_icmp_port_unreachable }'
6nft add element inet filter reject_or_drop_port4 '{ 0.0.0.0/0 . 0.0.0.0/0 : jump reject_with_icmp_port_unreachable_metered }'
IPv6 reject or drop¶
1nft add map inet filter reject_or_drop_port6 '{ typeof ip6 saddr . ip6 daddr : verdict; flags interval; }'
2nft add element inet filter reject_or_drop_port6 '{ fe80::/10 . fe80::/10 : jump reject_with_icmp_port_unreachable }'
3nft add element inet filter reject_or_drop_port6 '{ fc00::/7 . fc00::/7 : jump reject_with_icmp_port_unreachable }'
4nft add element inet filter reject_or_drop_port6 '{ ::/0 . ::/0 : jump reject_with_icmp_port_unreachable_metered }'
IPv4 ingress ICMP types¶
1nft add map inet filter icmp_types_in4 '{ typeof ip saddr . ip daddr . icmp type : verdict; flags interval; }'
2nft add element inet filter icmp_types_in4 '{ 0.0.0.0/0 . 0.0.0.0/0 . echo-request : accept }'
3nft add element inet filter icmp_types_in4 '{ 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : accept }'
4nft add element inet filter icmp_types_in4 '{ 0.0.0.0/0 . 0.0.0.0/0 . destination-unreachable : accept }'
IPv6 ingress ICMP types¶
1nft add map inet filter icmp_types_in6 '{ typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict; flags interval; }'
2nft add element inet filter icmp_types_in6 '{ fe80::/10 . fe80::/10 . echo-request : accept }'
3nft add element inet filter icmp_types_in6 '{ fe80::/10 . ff00::/8 . echo-request : accept }'
4nft add element inet filter icmp_types_in6 '{ fc00::/7 . fc00::/7 . echo-request : accept }'
5nft add element inet filter icmp_types_in6 '{ fe80::/10 . fe80::/10 . echo-reply : accept }'
6nft add element inet filter icmp_types_in6 '{ fe80::/10 . ff00::/8 . echo-reply : accept }'
7nft add element inet filter icmp_types_in6 '{ fc00::/7 . fc00::/7 . echo-reply : accept }'
8nft add element inet filter icmp_types_in6 '{ fe80::/10 . fe80::/10 . nd-neighbor-solicit : accept }'
9nft add element inet filter icmp_types_in6 '{ fc00::/7 . ff00::/8 . nd-neighbor-solicit : accept }'
10nft add element inet filter icmp_types_in6 '{ fc00::/7 . fc00::/7 . nd-neighbor-solicit : accept }'
11nft add element inet filter icmp_types_in6 '{ fc00::/7 . fc00::/7 . nd-neighbor-advert : accept }'
12nft add element inet filter icmp_types_in6 '{ fe80::/10 . fe80::/10 . nd-neighbor-advert : accept }'
13nft add element inet filter icmp_types_in6 '{ fe80::/10 . ff00::/8 . nd-router-advert : accept }'
14nft add element inet filter icmp_types_in6 '{ fe80::/10 . fe80::/10 . nd-router-advert : accept }'
TODO¶
- NDP for GUA
IPv4 ingress TCP ports¶
1nft add map inet filter tcp_ports_in4 '{ typeof ip saddr . ip daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_in4 '{ 0.0.0.0/0 . 0.0.0.0/0 . 22 : accept }'
IPv6 ingress TCP ports¶
1nft add map inet filter tcp_ports_in6 '{ typeof ip6 saddr . ip6 daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_in6 '{ ::/0 . ::/0 . 22 : accept }'
IPv4 ingress UDP ports¶
1nft add map inet filter udp_ports_in4 '{ typeof ip saddr . ip daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_in4 '{ 169.254.0.0/16 . 169.254.0.0/16 . 68 : accept }'
3nft add element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 68 : accept }'
4nft add element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 68 : accept }'
5nft add element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 192.168.0.0/16 . 68 : accept }'
6nft add element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept }'
7nft add element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept }'
8nft add element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 192.168.0.0/16 . 137 : accept }'
9nft add element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 5353 : accept }'
10nft add element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 5353 : accept }'
11nft add element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 192.168.0.0/16 . 5353 : accept }'
12nft add element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept }'
13nft add element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
14nft add element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
IPv6 ingress UDP ports¶
1nft add map inet filter udp_ports_in6 '{ typeof ip6 saddr . ip6 daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_in6 '{ fe80::/10 . ff00::/8 . 546 : accept }'
3nft add element inet filter udp_ports_in6 '{ fe80::/10 . ff00::/8 . 5353 : accept }'
4nft add element inet filter udp_ports_in6 '{ fc00::/7 . ff00::/8 . 5353 : accept }'
IPv4 default forward networks¶
1nft add map inet filter default_forward4 '{ typeof ip saddr . ip daddr . ct state : verdict; flags interval; }'
2nft add element inet filter default_forward4 '{ 169.254.0.0/16 . 0.0.0.0/0 . new : jump wont_forward }'
3nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 169.254.0.0/16 . new : jump wont_forward }'
4nft add element inet filter default_forward4 '{ 10.0.0.0/8 . 172.16.0.0/12 . new : jump reject_with_icmp_no_route }'
5nft add element inet filter default_forward4 '{ 10.0.0.0/8 . 192.168.0.0/16 . new : jump reject_with_icmp_no_route }'
6nft add element inet filter default_forward4 '{ 172.16.0.0/12 . 10.0.0.0/8 . new : jump reject_with_icmp_no_route }'
7nft add element inet filter default_forward4 '{ 172.16.0.0/12 . 192.168.0.0/16 . new : jump reject_with_icmp_no_route }'
8nft add element inet filter default_forward4 '{ 192.168.0.0/16 . 10.0.0.0/8 . new : jump reject_with_icmp_no_route }'
9nft add element inet filter default_forward4 '{ 192.168.0.0/16 . 172.16.0.0/12 . new : jump reject_with_icmp_no_route }'
10nft add element inet filter default_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . new : continue }'
11nft add element inet filter default_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . established : accept }'
12nft add element inet filter default_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . new : continue }'
13nft add element inet filter default_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . established : accept }'
14nft add element inet filter default_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . new : continue }'
15nft add element inet filter default_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . established : accept }'
16nft add element inet filter default_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . new : continue }'
17nft add element inet filter default_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . new : continue }'
18nft add element inet filter default_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . new : continue }'
19nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 10.0.0.0/8 . established : accept }'
20nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 172.16.0.0/12 . established : accept }'
21nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 192.168.0.0/16 . established : accept }'
IPv6 default forward networks¶
1nft add map inet filter default_forward6 '{ typeof ip6 saddr . ip6 daddr . ct state : verdict; flags interval; }'
2nft add element inet filter default_forward6 '{ fe80::/10 . ::/0 . new : jump wont_forward }'
3nft add element inet filter default_forward6 '{ ::/0 . fe80::/10 . new : jump wont_forward }'
4nft add element inet filter default_forward6 '{ fc00::/7 . fc00::/7 . new : continue }'
5nft add element inet filter default_forward6 '{ fc00::/7 . fc00::/7 . established : accept }'
IPv4 egress ICMP types¶
1nft add map inet filter icmp_types_out4 '{ typeof ip saddr . ip daddr . icmp type : verdict; flags interval; }'
2nft add element inet filter icmp_types_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . echo-request : accept }'
3nft add element inet filter icmp_types_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . echo-request : accept }'
4nft add element inet filter icmp_types_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . echo-request : accept }'
5nft add element inet filter icmp_types_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . echo-reply : accept }'
6nft add element inet filter icmp_types_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . echo-reply : accept }'
7nft add element inet filter icmp_types_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . echo-reply : accept }'
8nft add element inet filter icmp_types_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . destination-unreachable : accept }'
9nft add element inet filter icmp_types_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . destination-unreachable : accept }'
10nft add element inet filter icmp_types_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . destination-unreachable : accept }'
11nft add element inet filter icmp_types_out4 '{ 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : jump icmp_echo_reply_rate_limit }'
IPv6 egress ICMP types¶
1nft add map inet filter icmp_types_out6 '{ typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict; flags interval; }'
2nft add element inet filter icmp_types_out6 '{ fe80::/10 . ff00::/8 . echo-request : accept }'
3nft add element inet filter icmp_types_out6 '{ fc00::/7 . fc00::/7 . echo-reply : accept }'
4nft add element inet filter icmp_types_out6 '{ 2000::/3 . ::/0 . echo-reply : jump icmp_echo_reply_rate_limit }'
5nft add element inet filter icmp_types_out6 '{ fc00::/7 . fc00::/7 . nd-neighbor-advert : accept }'
6nft add element inet filter icmp_types_out6 '{ fe80::/10 . fe80::/10 . nd-neighbor-advert : accept }'
7nft add element inet filter icmp_types_out6 '{ fc00::/7 . ff00::/8 . nd-neighbor-solicit : accept }'
8nft add element inet filter icmp_types_out6 '{ fe80::/10 . fc00::/7 . nd-neighbor-solicit : accept }'
9nft add element inet filter icmp_types_out6 '{ fe80::/10 . fe80::/10 . nd-neighbor-solicit : accept }'
10nft add element inet filter icmp_types_out6 '{ fe80::/10 . ff00::/8 . nd-router-solicit : accept }'
GUA prefixes¶
The same rules apply, but it’s less than ideal to use an over-reaching prefix like 2000::/3
because 2000::/3
should be metered.
That is, anything except local GUA prefixes should be metered.
IPv4 egress TCP ports¶
Ports 21
, 23
, 25
, 53
, and 80
can be omitted if the point is to ensure that no egress traffic will ever be destined for unencrypted protocols. With this particular ruleset they are limited to the following destinations:
169.254.0.0/16
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
This is covered later in the hardening section.
1nft add map inet filter tcp_ports_out4 '{ typeof ip saddr . ip daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 22 : accept }'
3nft add element inet filter tcp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 22 : accept }'
4nft add element inet filter tcp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 22 : accept }'
5nft add element inet filter tcp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept }'
6nft add element inet filter tcp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept }'
7nft add element inet filter tcp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept }'
8nft add element inet filter tcp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 853 : accept }'
9nft add element inet filter tcp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 853 : accept }'
10nft add element inet filter tcp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 853 : accept }'
11nft add element inet filter tcp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 4460 : accept }'
12nft add element inet filter tcp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 4460 : accept }'
13nft add element inet filter tcp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 4460 : accept }'
14nft add element inet filter tcp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 5349 : accept }'
15nft add element inet filter tcp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 5349 : accept }'
16nft add element inet filter tcp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 5349 : accept }'
IPv6 egress TCP ports¶
Ports 21
, 23
, 25
, 53
, and 80
can be omitted if the point is to ensure that no egress traffic will ever be destined for unencrypted protocols. With this particular ruleset they are limited to the following destinations:
fc00::/7
(ULA)
This is covered later in the hardening section.
1nft add map inet filter tcp_ports_out6 '{ typeof ip6 saddr . ip6 daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_out6 '{ fc00::/7 . fc00::/7 . 443 : accept }'
3nft add element inet filter tcp_ports_out6 '{ fc00::/7 . fc00::/7 . 853 : accept }'
4nft add element inet filter tcp_ports_out6 '{ fc00::/7 . fc00::/7 . 4460 : accept }'
5nft add element inet filter tcp_ports_out6 '{ fc00::/7 . fc00::/7 . 5349 : accept }'
6nft add element inet filter tcp_ports_out6 '{ 2000::/3 . 2000::/3 . 443 : accept }'
7nft add element inet filter tcp_ports_out6 '{ 2000::/3 . 2000::/3 . 853 : accept }'
8nft add element inet filter tcp_ports_out6 '{ 2000::/3 . 2000::/3 . 4460 : accept }'
9nft add element inet filter tcp_ports_out6 '{ 2000::/3 . 2000::/3 . 5349 : accept }'
IPv4 egress UDP ports¶
Ports 53
, 67
, 137
can be omitted if the point is to ensure that no egress traffic will ever be destined for unencrypted protocols. With this particular ruleset they are limited to the following destinations:
169.254.0.0/16
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Port 5353
is used for mDNS
. It can be safely omitted, but it is useful for enumeration of hostnames on local networks (zeroconf). Currently mDNS doesn’t use any encryption as of 1-26-2023, and I would say it should be omitted in environments that use NDP-RA
. For more information on mDNS, refer to: https://datatracker.ietf.org/doc/html/draft-rafiee-dnssd-mdns-threatmodel-01
This is covered later in the hardening section.
1nft add map inet filter udp_ports_out4 '{ typeof ip saddr . ip daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 67 : accept }'
3nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 67 : accept }'
4nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 67 : accept }'
5nft add element inet filter udp_ports_out4 '{ 169.254.0.0/16 . 169.254.0.0/16 . 67 : accept }'
6nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept }'
7nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept }'
8nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept }'
9nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept }'
10nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept }'
11nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 137 : accept }'
12nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept }'
13nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
14nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 224.0.0.0/4 . 5353 : accept }'
15nft add element inet filter udp_ports_out4 '{ 169.254.0.0/16 . 224.0.0.0/4 . 5353 : accept }'
16nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept }'
17nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept }'
18nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept }'
19nft add element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 1194 : accept }'
20nft add element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 1194 : accept }'
21nft add element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 1194 : accept }'
IPv6 egress UDP ports¶
1nft add map inet filter udp_ports_out6 '{ typeof ip6 saddr . ip6 daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_out6 '{ fe80::/10 . ff00::/8 . 547 : accept }'
3nft add element inet filter udp_ports_out6 '{ 2000::/3 . ::/0 . 443 : accept }'
4nft add element inet filter udp_ports_out6 '{ fc00::/7 . ff00::/8 . 5353 : accept }'
IPv4 forward ICMP types¶
1nft add map inet filter icmp_types_forward4 '{ typeof ip saddr . ip daddr . icmp type : verdict; flags interval; }'
2nft add element inet filter icmp_types_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . echo-request : accept }'
3nft add element inet filter icmp_types_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . echo-request : accept }'
4nft add element inet filter icmp_types_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . echo-request : accept }'
5nft add element inet filter icmp_types_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . echo-reply : accept }'
6nft add element inet filter icmp_types_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . echo-reply : accept }'
7nft add element inet filter icmp_types_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . echo-reply : accept }'
8nft add element inet filter icmp_types_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . destination-unreachable : accept }'
9nft add element inet filter icmp_types_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . destination-unreachable : accept }'
10nft add element inet filter icmp_types_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . destination-unreachable : accept }'
11nft add element inet filter icmp_types_forward4 '{ 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : jump icmp_echo_reply_rate_limit }'
IPv6 forward ICMP types¶
1nft add map inet filter icmp_types_forward6 '{ typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict; flags interval; }'
2nft add element inet filter icmp_types_forward6 '{ fe80::/10 . ff00::/8 . echo-request : accept }'
3nft add element inet filter icmp_types_forward6 '{ fc00::/7 . fc00::/7 . echo-reply : accept }'
4nft add element inet filter icmp_types_forward6 '{ 2000::/3 . ::/0 . echo-reply : jump icmp_echo_reply_rate_limit }'
IPv4 forward TCP ports¶
1nft add map inet filter tcp_ports_forward4 '{ typeof ip saddr . ip daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 21 : accept }'
3nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 21 : accept }'
4nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 21 : accept }'
5nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 23 : accept }'
6nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 23 : accept }'
7nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 23 : accept }'
8nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 25 : accept }'
9nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 25 : accept }'
10nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 25 : accept }'
11nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept }'
12nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept }'
13nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept }'
14nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 80 : accept }'
15nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 80 : accept }'
16nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 80 : accept }'
17nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 22 : accept }'
18nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 22 : accept }'
19nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 22 : accept }'
20nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept }'
21nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept }'
22nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept }'
23nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 853 : accept }'
24nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 853 : accept }'
25nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 853 : accept }'
26nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 4460 : accept }'
27nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 4460 : accept }'
28nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 4460 : accept }'
29nft add element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 5349 : accept }'
30nft add element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 5349 : accept }'
31nft add element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 5349 : accept }'
IPv6 forward TCP ports¶
1nft add map inet filter tcp_ports_forward6 '{ typeof ip6 saddr . ip6 daddr . tcp dport : verdict; flags interval; }'
2nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 21 : accept }'
3nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 23 : accept }'
4nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 25 : accept }'
5nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 53 : accept }'
6nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 80 : accept }'
7nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 443 : accept }'
8nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 853 : accept }'
9nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 4460 : accept }'
10nft add element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 5349 : accept }'
11nft add element inet filter tcp_ports_forward6 '{ 2000::/3 . 2000::/3 . 443 : accept }'
12nft add element inet filter tcp_ports_forward6 '{ 2000::/3 . 2000::/3 . 853 : accept }'
13nft add element inet filter tcp_ports_forward6 '{ 2000::/3 . 2000::/3 . 4460 : accept }'
14nft add element inet filter tcp_ports_forward6 '{ 2000::/3 . 2000::/3 . 5349 : accept }'
IPv4 forward UDP ports¶
1nft add map inet filter udp_ports_forward4 '{ typeof ip saddr . ip daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept }'
3nft add element inet filter udp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept }'
4nft add element inet filter udp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept }'
5nft add element inet filter udp_ports_forward4 '{ 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept }'
6nft add element inet filter udp_ports_forward4 '{ 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept }'
7nft add element inet filter udp_ports_forward4 '{ 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept }'
IPv6 forward UDP ports¶
1nft add map inet filter udp_ports_forward6 '{ typeof ip6 saddr . ip6 daddr . udp dport : verdict; flags interval; }'
2nft add element inet filter udp_ports_forward6 '{ 2000::/3 . ::/0 . 443 : accept }'
NAT Forwarding ports for IPv4¶
1nft add map inet filter tcp_ports_nat_forward4 '{ type inet_service : ipv4_addr; }'
2nft add map inet filter udp_ports_nat_forward4 '{ type inet_service : ipv4_addr; }'
Masquerading¶
1nft add map inet filter masquerade_networks4 '{ typeof oif . ip saddr : verdict; flags interval; }'
Rules¶
Metered ICMP port unreachable¶
1nft add rule inet filter reject_with_icmp_port_unreachable_metered add @icmp_egress_meter4 '{ ip daddr timeout 4s limit rate 3/second }' counter reject with icmpx type port-unreachable
2nft add rule inet filter reject_with_icmp_port_unreachable_metered add @icmp_egress_meter6 '{ ip6 daddr timeout 4s limit rate 3/second }' counter reject with icmpx type port-unreachable
Un-metered ICMP port unreachable¶
1nft add rule inet filter reject_with_icmp_port_unreachable counter reject with icmpx type port-unreachable
Metered ICMP host unreachable¶
1nft add rule inet filter reject_with_icmp_host_unreachable_metered add @icmp_egress_meter4 '{ ip daddr timeout 4s limit rate 3/second }' counter reject with icmpx type host-unreachable
2nft add rule inet filter reject_with_icmp_host_unreachable_metered add @icmp_egress_meter6 '{ ip6 daddr timeout 4s limit rate 3/second }' counter reject with icmpx type host-unreachable
Un-Metered ICMP host unreachable¶
1nft add rule inet filter reject_with_icmp_host_unreachable counter reject with icmpx type host-unreachable
Metered ICMP no route¶
1nft add rule inet filter reject_with_icmp_no_route_metered add @icmp_egress_meter4 '{ ip daddr timeout 4s limit rate 3/second }' counter reject with icmpx type no-route
2nft add rule inet filter reject_with_icmp_no_route_metered add @icmp_egress_meter6 '{ ip6 daddr timeout 4s limit rate 3/second }' counter reject with icmpx type no-route
Un-Metered ICMP no route¶
1nft add rule inet filter reject_with_icmp_no_route counter reject with icmpx type no-route
Metered ICMP admin prohibited¶
1nft add rule inet filter reject_with_icmp_admin_prohibited add @icmp_egress_meter4 '{ ip daddr timeout 4s limit rate 3/second }' counter reject with icmpx type admin-prohibited
2nft add rule inet filter reject_with_icmp_admin_prohibited_metered add @icmp_egress_meter6 '{ ip6 daddr timeout 4s limit rate 3/second }' counter reject with icmpx type admin-prohibited
Un-Metered ICMP admin-prohibited¶
1nft add rule inet filter reject_with_icmp_admin_prohibited counter reject with icmpx type admin-prohibited
icmp_in¶
1nft add rule inet filter icmp_in ip saddr . ip daddr . icmp type vmap @icmp_types_in4
2nft add rule inet filter icmp_in ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_in6
tcp_in¶
1nft add rule inet filter tcp_in ct state established accept
2nft add rule inet filter tcp_in ip saddr . ip daddr . tcp dport vmap @tcp_ports_in4
3nft add rule inet filter tcp_in ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_in6
udp_in¶
1nft add rule inet filter udp_in ct state established accept
2nft add rule inet filter udp_in ip saddr . ip daddr . udp dport vmap @udp_ports_in4
3nft add rule inet filter udp_in ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_in6
ether_in¶
1nft add rule inet filter ether_in ip protocol vmap '{ tcp : jump tcp_in, udp : jump udp_in , icmp : jump icmp_in }'
2nft add rule inet filter ether_in ip6 nexthdr vmap '{ tcp : jump tcp_in, udp : jump udp_in , icmpv6 : jump icmp_in, ipv6-icmp: jump icmp_in }'
input¶
1nft add rule inet filter input meta iiftype vmap '{ loopback: accept }'
2nft add rule inet filter input ip saddr vmap @drop_bogons4
3nft add rule inet filter input ip6 saddr vmap @drop_bogons6
4nft add rule inet filter input meta iiftype vmap '{ ether: jump ether_in }'
icmp_forward¶
1nft add rule inet filter icmp_forward ip saddr . ip daddr . icmp type vmap @icmp_types_forward4
2nft add rule inet filter icmp_forward ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_forward6
tcp_forward¶
1nft add rule inet filter tcp_forward ct state established accept
2nft add rule inet filter tcp_forward ip saddr . ip daddr . tcp dport vmap @tcp_ports_forward4
3nft add rule inet filter tcp_forward ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_forward6
udp_forward¶
1nft add rule inet filter udp_forward ct state established accept
2nft add rule inet filter udp_forward ip saddr . ip daddr . udp dport vmap @udp_ports_forward4
3nft add rule inet filter udp_forward ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_forward6
ether_forward¶
1nft add rule inet filter ether_forward ip saddr . ip daddr . ct state vmap @default_forward4
2nft add rule inet filter ether_forward ip6 saddr . ip6 daddr . ct state vmap @default_forward6
3nft add rule inet filter ether_forward ip protocol vmap '{ tcp : jump tcp_forward, udp : jump udp_forward , icmp : jump icmp_forward }'
forward¶
1nft add rule inet filter forward ip saddr vmap @drop_bogons4
2nft add rule inet filter forward ip6 saddr vmap @drop_bogons6
3nft add rule inet filter forward meta oiftype vmap '{ ether: jump ether_forward }'
ICMP echo-reply rate limit¶
1nft add rule inet filter icmp_echo_reply_rate_limit add @icmp_egress_meter4 '{ ip saddr timeout 4s limit rate 3/second }' accept
2nft add rule inet filter icmp_echo_reply_rate_limit add @icmp_egress_meter6 '{ ip6 saddr timeout 4s limit rate 3/second }' accept
icmp_out¶
1nft add rule inet filter icmp_out ip saddr . ip daddr . icmp type vmap @icmp_types_out4
2nft add rule inet filter icmp_out ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_out6
tcp_out¶
1nft add rule inet filter tcp_out ct state established accept
2nft add rule inet filter tcp_out ip saddr . ip daddr . tcp dport vmap @tcp_ports_out4
3nft add rule inet filter tcp_out ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_out6
udp_out¶
1nft add rule inet filter udp_out ct state established accept
2nft add rule inet filter udp_out ip saddr . ip daddr . udp dport vmap @udp_ports_out4
3nft add rule inet filter udp_out ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_out6
ether_out¶
1nft add rule inet filter ether_out ip protocol vmap '{ tcp : jump tcp_out, udp : jump udp_out, icmp : jump icmp_out }'
2nft add rule inet filter ether_out ip6 nexthdr vmap '{ tcp : jump tcp_out, udp : jump udp_out, icmpv6 : jump icmp_out, ipv6-icmp: jump icmp_out }'
masq¶
1nft add rule inet filter masq ip daddr vmap @drop_bogons4
2nft add rule inet filter masq ip daddr @local_networks return
3nft add rule inet filter masq masquerade
output¶
1nft add rule inet filter output meta oiftype vmap '{ loopback: accept }'
2nft add rule inet filter output ip daddr vmap @drop_bogons4
3nft add rule inet filter output ip6 daddr vmap @drop_bogons6
4nft add rule inet filter output meta oiftype vmap '{ ether: jump ether_out }'
prerouting¶
1nft add rule inet filter prerouting ip protocol tcp dnat to tcp dport map @tcp_ports_nat_forward4
2nft add rule inet filter prerouting ip protocol udp dnat to udp dport map @udp_ports_nat_forward4
postrouting¶
1nft add rule inet filter postrouting oif . ip saddr vmap @masquerade_networks4
Default chain policies¶
1nft add chain inet filter input '{ policy drop; }'
2nft add chain inet filter forward '{ policy drop; }'
3nft add chain inet filter output '{ policy drop; }'
Logging¶
1nft add rule inet filter input log prefix "input" group 1
2nft add rule inet filter input counter
3
4nft add rule inet filter forward log prefix "forward" group 1
5nft add rule inet filter forward counter
6
7nft add rule inet filter output log prefix "output" group 1
8nft add rule inet filter output counter
Viewing logged packets¶
Dropped packets are logged in pcap format: tcpdump -vvv -n -e -ttt -i nflog:1 -XX
1 00:00:00.000207 version 0, resource ID 1, family IPv4 (2), length 128: (tos 0x10, ttl 64, id 39694, offset 0, flags [DF], proto UDP (17), length 76)
2 10.211.55.11.50429 > 108.59.2.24.123: [bad udp cksum 0xb07a -> 0x5c51!] NTPv4, Client, length 48
3 Leap indicator: (0), Stratum 0 (unspecified), poll 0 (1s), precision 0
4 Root Delay: 0.000000, Root dispersion: 0.000000, Reference-ID: (unspec)
5 Reference Timestamp: 0.000000000
6 Originator Timestamp: 0.000000000
7 Receive Timestamp: 0.000000000
8 Transmit Timestamp: 3883429715.031809542 (2023-01-23T02:28:35Z)
9 Originator - Receive Timestamp: 0.000000000
10 Originator - Transmit Timestamp: 3883429715.031809542 (2023-01-23T02:28:35Z)
11 0x0000: 0200 0001 0800 0100 0800 0300 0b00 0a00 ................
12 0x0010: 6f75 7470 7574 0000 0800 0500 0000 0002 output..........
13 0x0020: 0800 0b00 0000 0069 0800 0e00 0000 006f .......i.......o
14 0x0030: 5000 0900 4510 004c 9b0e 4000 4011 ef51 P...E..L..@.@..Q
15 0x0040: 0ad3 370b 6c3b 0218 c4fd 007b 0038 b07a ..7.l;.....{.8.z
16 0x0050: 2300 0000 0000 0000 0000 0000 0000 0000 #...............
17 0x0060: 0000 0000 0000 0000 0000 0000 0000 0000 ................
18 0x0070: 0000 0000 0000 0000 e778 6f53 0824 ab92 .........xoS.$..
Per-chain logging¶
Metered ICMP port unreachable¶
1nft add rule inet filter reject_with_icmp_port_unreachable_metered log prefix "reject_with_icmp_port_unreachable_metered" group 1
2nft add rule inet filter reject_with_icmp_port_unreachable_metered counter drop
Metered ICMP host unreachable¶
1nft add rule inet filter reject_with_icmp_host_unreachable_metered log prefix "reject_with_icmp_host_unreachable_metered" group 1
2nft add rule inet filter reject_with_icmp_host_unreachable_metered counter drop
Metered ICMP no route¶
1nft add rule inet filter reject_with_icmp_no_route_metered log prefix "reject_with_icmp_no_route_metered" group 1
2nft add rule inet filter reject_with_icmp_no_route_metered counter drop
Metered ICMP admin prohibited¶
1nft add rule inet filter reject_with_icmp_admin_prohibited_metered log prefix "reject_with_icmp_admin_prohibited_metered" group 1
2nft add rule inet filter reject_with_icmp_admin_prohibited_metered counter drop
Ingress ICMP¶
1nft add rule inet filter icmp_in log prefix "icmp_in" group 1
2nft add rule inet filter icmp_in counter drop
Ingress TCP¶
1nft add rule inet filter tcp_in log prefix "tcp_in" group 1
2nft add rule inet filter tcp_in counter drop
Ingress UDP¶
1nft add rule inet filter udp_in log prefix "udp_in" group 1
2nft add rule inet filter udp_in counter drop
Ingress Ether¶
1nft add rule inet filter ether_in log prefix "ether_in" group 1
2nft add rule inet filter ether_in counter drop
Forward ICMP¶
1nft add rule inet filter icmp_forward log prefix "icmp_forward" group 1
2nft add rule inet filter icmp_forward counter drop
Forward TCP¶
1nft add rule inet filter tcp_forward log prefix "tcp_forward" group 1
2nft add rule inet filter tcp_forward counter drop
Forward UDP¶
1nft add rule inet filter udp_forward log prefix "udp_forward" group 1
2nft add rule inet filter udp_forward counter drop
Forward Ether¶
1nft add rule inet filter ether_forward log prefix "ether_forward" group 1
2nft add rule inet filter ether_forward counter drop
Egress ICMP echo replies¶
1nft add rule inet filter icmp_echo_reply_rate_limit log prefix "icmp_echo_reply_rate_limit" group 1
2nft add rule inet filter icmp_echo_reply_rate_limit counter drop
Egress ICMP¶
1nft add rule inet filter icmp_out log prefix "icmp_out" group 1
2nft add rule inet filter icmp_out counter drop
Egress TCP¶
1nft add rule inet filter tcp_out log prefix "tcp_out" group 1
2nft add rule inet filter tcp_out counter drop
Egress UDP¶
1nft add rule inet filter udp_out log prefix "udp_out" group 1
2nft add rule inet filter udp_out counter drop
Egress Ether¶
1nft add rule inet filter ether_out log prefix "ether_out" group 1
2nft add rule inet filter ether_out counter drop
Filter state persistence¶
Configuration format¶
If you are starting from here you can copy / paste this section to /etc/nftables.conf
. Otherwise the current filter state can be made to persist with:
nft -a -s list ruleset | tee /etc/nftables.conf
1table inet filter { # handle 60
2 set icmp_egress_meter4 { # handle 34
3 type ipv4_addr
4 size 8
5 flags dynamic,timeout
6 }
7
8 set icmp_egress_meter6 { # handle 35
9 type ipv6_addr
10 size 8
11 flags dynamic,timeout
12 }
13
14 map drop_bogons4 { # handle 36
15 type ipv4_addr : verdict
16 flags interval
17 elements = { 0.0.0.0/8 : jump bogon, 10.0.0.0/8 : continue,
18 100.64.0.0/10 : jump bogon, 127.0.0.0/8 : jump bogon,
19 169.254.0.0/16 : continue, 172.16.0.0/12 : continue,
20 192.0.0.0/24 : jump bogon, 192.0.2.0/24 : jump bogon,
21 192.168.0.0/16 : continue, 198.18.0.0/15 : jump bogon,
22 198.51.100.0/24 : jump bogon, 203.0.113.0/24 : jump bogon,
23 224.0.0.0/4 : continue, 240.0.0.0/4 : jump bogon }
24 }
25
26 set local_networks { # handle 37
27 type ipv4_addr
28 flags interval
29 elements = { 10.0.0.0/8, 169.254.0.0/16,
30 172.16.0.0/12, 192.168.0.0/16 }
31 }
32
33 map drop_bogons6 { # handle 38
34 type ipv6_addr : verdict
35 flags interval
36 elements = { ::/96 : jump bogon,
37 ::ffff:0.0.0.0/96 : jump bogon,
38 100::/64 : jump bogon,
39 2001::/40 : jump bogon,
40 2001:0:a00::/40 : jump bogon,
41 2001:0:7f00::/40 : jump bogon,
42 2001:0:a9fe::/48 : jump bogon,
43 2001:0:ac10::/44 : jump bogon,
44 2001:0:c000::/56 : jump bogon,
45 2001:0:c000:200::/56 : jump bogon,
46 2001:0:c0a8::/48 : jump bogon,
47 2001:0:c612::/47 : jump bogon,
48 2001:0:c633:6400::/56 : jump bogon,
49 2001:0:cb00:7100::/56 : jump bogon,
50 2001:0:e000::/36 : jump bogon,
51 2001:0:f000::/36 : jump bogon,
52 2001:10::/28 : jump bogon,
53 2001:db8::/32 : jump bogon,
54 2002::/24 : jump bogon,
55 2002:a00::/24 : jump bogon,
56 2002:7f00::/24 : jump bogon,
57 2002:a9fe::/32 : jump bogon,
58 2002:ac10::/28 : jump bogon,
59 2002:c000::/40 : jump bogon,
60 2002:c000:200::/40 : jump bogon,
61 2002:c0a8::/32 : jump bogon,
62 2002:c612::/31 : jump bogon,
63 2002:c633:6400::/40 : jump bogon,
64 2002:cb00:7100::/40 : jump bogon,
65 2002:e000::/20 : jump bogon,
66 2002:f000::/20 : jump bogon,
67 fc00::/7 : continue,
68 fe80::/10 : continue,
69 fec0::/10 : jump bogon,
70 ff00::/8 : continue }
71 }
72
73 map reject_or_drop_port4 { # handle 39
74 typeof ip saddr . ip daddr : verdict
75 flags interval
76 elements = { 10.0.0.0/8 . 10.0.0.0/8 : jump reject_with_icmp_port_unreachable,
77 172.16.0.0/12 . 172.16.0.0/12 : jump reject_with_icmp_port_unreachable,
78 192.168.0.0/16 . 192.168.0.0/16 : jump reject_with_icmp_port_unreachable,
79 169.254.0.0/16 . 169.254.0.0/16 : jump reject_with_icmp_port_unreachable,
80 0.0.0.0/0 . 0.0.0.0/0 : jump reject_with_icmp_port_unreachable_metered }
81 }
82
83 map reject_or_drop_port6 { # handle 40
84 typeof ip6 saddr . ip6 daddr : verdict
85 flags interval
86 elements = { fe80::/10 . fe80::/10 : jump reject_with_icmp_port_unreachable,
87 fc00::/7 . fc00::/7 : jump reject_with_icmp_port_unreachable,
88 ::/0 . ::/0 : jump reject_with_icmp_port_unreachable_metered }
89 }
90
91 map icmp_types_in4 { # handle 41
92 typeof ip saddr . ip daddr . icmp type : verdict
93 flags interval
94 elements = { 0.0.0.0/0 . 0.0.0.0/0 . echo-request : accept,
95 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : accept,
96 0.0.0.0/0 . 0.0.0.0/0 . destination-unreachable : accept }
97 }
98
99 map icmp_types_in6 { # handle 42
100 typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict
101 flags interval
102 elements = { fe80::/10 . fe80::/10 . echo-request : accept,
103 fe80::/10 . ff00::/8 . echo-request : accept,
104 fc00::/7 . fc00::/7 . echo-request : accept,
105 fe80::/10 . fe80::/10 . echo-reply : accept,
106 fe80::/10 . ff00::/8 . echo-reply : accept,
107 fc00::/7 . fc00::/7 . echo-reply : accept,
108 fe80::/10 . fe80::/10 . nd-neighbor-solicit : accept,
109 fc00::/7 . ff00::/8 . nd-neighbor-solicit : accept,
110 fc00::/7 . fc00::/7 . nd-neighbor-solicit : accept,
111 fc00::/7 . fc00::/7 . nd-neighbor-advert : accept,
112 fe80::/10 . fe80::/10 . nd-neighbor-advert : accept,
113 fe80::/10 . ff00::/8 . nd-router-advert : accept,
114 fe80::/10 . fe80::/10 . nd-router-advert : accept }
115 }
116
117 map tcp_ports_in4 { # handle 43
118 typeof ip saddr . ip daddr . tcp dport : verdict
119 flags interval
120 elements = { 0.0.0.0/0 . 0.0.0.0/0 . 22 : accept }
121 }
122
123 map tcp_ports_in6 { # handle 44
124 typeof ip6 saddr . ip6 daddr . tcp dport : verdict
125 flags interval
126 elements = { ::/0 . ::/0 . 22 : accept }
127 }
128
129 map udp_ports_in4 { # handle 45
130 typeof ip saddr . ip daddr . udp dport : verdict
131 flags interval
132 elements = { 169.254.0.0/16 . 169.254.0.0/16 . 68 : accept,
133 10.0.0.0/8 . 10.0.0.0/8 . 68 : accept,
134 172.16.0.0/12 . 172.16.0.0/12 . 68 : accept,
135 192.160.0.0/12 . 192.168.0.0/16 . 68 : accept,
136 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept,
137 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept,
138 192.160.0.0/12 . 192.168.0.0/16 . 137 : accept,
139 10.0.0.0/8 . 10.0.0.0/8 . 5353 : accept,
140 172.16.0.0/12 . 172.16.0.0/12 . 5353 : accept,
141 192.160.0.0/12 . 192.168.0.0/16 . 5353 : accept,
142 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept,
143 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept,
144 192.160.0.0/12 . 224.0.0.0/4 . 5353 : accept }
145 }
146
147 map udp_ports_in6 { # handle 46
148 typeof ip6 saddr . ip6 daddr . udp dport : verdict
149 flags interval
150 elements = { fe80::/10 . ff00::/8 . 546 : accept,
151 fe80::/10 . ff00::/8 . 5353 : accept,
152 fc00::/7 . ff00::/8 . 5353 : accept }
153 }
154
155 map default_forward4 { # handle 47
156 typeof ip saddr . ip daddr . ct state : verdict
157 flags interval
158 elements = { 169.254.0.0/16 . 0.0.0.0/0 . new : jump wont_forward,
159 0.0.0.0/0 . 169.254.0.0/16 . new : jump wont_forward,
160 10.0.0.0/8 . 172.16.0.0/12 . new : jump reject_with_icmp_no_route,
161 10.0.0.0/8 . 192.168.0.0/16 . new : jump reject_with_icmp_no_route,
162 172.16.0.0/12 . 10.0.0.0/8 . new : jump reject_with_icmp_no_route,
163 172.16.0.0/12 . 192.168.0.0/16 . new : jump reject_with_icmp_no_route,
164 192.168.0.0/16 . 10.0.0.0/8 . new : jump reject_with_icmp_no_route,
165 192.168.0.0/16 . 172.16.0.0/12 . new : jump reject_with_icmp_no_route,
166 10.0.0.0/8 . 10.0.0.0/8 . new : continue,
167 10.0.0.0/8 . 10.0.0.0/8 . established : accept,
168 172.16.0.0/12 . 172.16.0.0/12 . new : continue,
169 172.16.0.0/12 . 172.16.0.0/12 . established : accept,
170 192.168.0.0/16 . 192.168.0.0/16 . new : continue,
171 192.168.0.0/16 . 192.168.0.0/16 . established : accept,
172 10.0.0.0/8 . 0.0.0.0/0 . new : continue,
173 172.16.0.0/12 . 0.0.0.0/0 . new : continue,
174 192.168.0.0/16 . 0.0.0.0/0 . new : continue,
175 0.0.0.0/0 . 10.0.0.0/8 . established : accept,
176 0.0.0.0/0 . 172.16.0.0/12 . established : accept,
177 0.0.0.0/0 . 192.168.0.0/16 . established : accept }
178 }
179
180 map default_forward6 { # handle 48
181 typeof ip6 saddr . ip6 daddr . ct state : verdict
182 flags interval
183 elements = { fe80::/10 . ::/0 . new : jump wont_forward,
184 ::/0 . fe80::/10 . new : jump wont_forward,
185 fc00::/7 . fc00::/7 . new : continue,
186 fc00::/7 . fc00::/7 . established : accept }
187 }
188
189 map icmp_types_out4 { # handle 49
190 typeof ip saddr . ip daddr . icmp type : verdict
191 flags interval
192 elements = { 10.0.0.0/8 . 0.0.0.0/0 . echo-request : accept,
193 172.16.0.0/12 . 0.0.0.0/0 . echo-request : accept,
194 192.168.0.0/16 . 0.0.0.0/0 . echo-request : accept,
195 10.0.0.0/8 . 10.0.0.0/8 . echo-reply : accept,
196 172.16.0.0/12 . 172.16.0.0/12 . echo-reply : accept,
197 192.168.0.0/16 . 192.168.0.0/16 . echo-reply : accept,
198 10.0.0.0/8 . 10.0.0.0/8 . destination-unreachable : accept,
199 172.16.0.0/12 . 172.16.0.0/12 . destination-unreachable : accept,
200 192.168.0.0/16 . 192.168.0.0/16 . destination-unreachable : accept,
201 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : jump icmp_echo_reply_rate_limit }
202 }
203
204 map icmp_types_out6 { # handle 50
205 typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict
206 flags interval
207 elements = { fe80::/10 . ff00::/8 . echo-request : accept,
208 fc00::/7 . fc00::/7 . echo-reply : accept,
209 2000::/3 . ::/0 . echo-reply : jump icmp_echo_reply_rate_limit,
210 fc00::/7 . fc00::/7 . nd-neighbor-advert : accept,
211 fe80::/10 . fe80::/10 . nd-neighbor-advert : accept,
212 fc00::/7 . ff00::/8 . nd-neighbor-solicit : accept,
213 fe80::/10 . fc00::/7 . nd-neighbor-solicit : accept,
214 fe80::/10 . fe80::/10 . nd-neighbor-solicit : accept,
215 fe80::/10 . ff00::/8 . nd-router-solicit : accept }
216 }
217
218 map tcp_ports_out4 { # handle 51
219 typeof ip saddr . ip daddr . tcp dport : verdict
220 flags interval
221 elements = { 10.0.0.0/8 . 0.0.0.0/0 . 22 : accept,
222 172.16.0.0/12 . 0.0.0.0/0 . 22 : accept,
223 192.168.0.0/16 . 0.0.0.0/0 . 22 : accept,
224 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept,
225 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept,
226 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept,
227 10.0.0.0/8 . 0.0.0.0/0 . 853 : accept,
228 172.16.0.0/12 . 0.0.0.0/0 . 853 : accept,
229 192.168.0.0/16 . 0.0.0.0/0 . 853 : accept,
230 10.0.0.0/8 . 0.0.0.0/0 . 4460 : accept,
231 172.16.0.0/12 . 0.0.0.0/0 . 4460 : accept,
232 192.168.0.0/16 . 0.0.0.0/0 . 4460 : accept,
233 10.0.0.0/8 . 0.0.0.0/0 . 5349 : accept,
234 172.16.0.0/12 . 0.0.0.0/0 . 5349 : accept,
235 192.168.0.0/16 . 0.0.0.0/0 . 5349 : accept }
236 }
237
238 map tcp_ports_out6 { # handle 52
239 typeof ip6 saddr . ip6 daddr . tcp dport : verdict
240 flags interval
241 elements = { fc00::/7 . fc00::/7 . 443 : accept,
242 fc00::/7 . fc00::/7 . 853 : accept,
243 fc00::/7 . fc00::/7 . 4460 : accept,
244 fc00::/7 . fc00::/7 . 5349 : accept,
245 2000::/3 . 2000::/3 . 443 : accept,
246 2000::/3 . 2000::/3 . 853 : accept,
247 2000::/3 . 2000::/3 . 4460 : accept,
248 2000::/3 . 2000::/3 . 5349 : accept }
249 }
250
251 map udp_ports_out4 { # handle 53
252 typeof ip saddr . ip daddr . udp dport : verdict
253 flags interval
254 elements = { 10.0.0.0/8 . 10.0.0.0/8 . 67 : accept,
255 172.16.0.0/12 . 172.16.0.0/12 . 67 : accept,
256 192.168.0.0/16 . 192.168.0.0/16 . 67 : accept,
257 169.254.0.0/16 . 169.254.0.0/16 . 67 : accept,
258 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept,
259 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept,
260 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept,
261 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept,
262 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept,
263 192.168.0.0/16 . 192.168.0.0/16 . 137 : accept,
264 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept,
265 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept,
266 192.168.0.0/16 . 224.0.0.0/4 . 5353 : accept,
267 169.254.0.0/16 . 224.0.0.0/4 . 5353 : accept,
268 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept,
269 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept,
270 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept,
271 10.0.0.0/8 . 0.0.0.0/0 . 1194 : accept,
272 172.16.0.0/12 . 0.0.0.0/0 . 1194 : accept,
273 192.168.0.0/16 . 0.0.0.0/0 . 1194 : accept }
274 }
275
276 map udp_ports_out6 { # handle 54
277 typeof ip6 saddr . ip6 daddr . udp dport : verdict
278 flags interval
279 elements = { fe80::/10 . ff00::/8 . 547 : accept,
280 2000::/3 . ::/0 . 443 : accept,
281 fc00::/7 . ff00::/8 . 5353 : accept }
282 }
283
284 map icmp_types_forward4 { # handle 55
285 typeof ip saddr . ip daddr . icmp type : verdict
286 flags interval
287 elements = { 10.0.0.0/8 . 0.0.0.0/0 . echo-request : accept,
288 172.16.0.0/12 . 0.0.0.0/0 . echo-request : accept,
289 192.168.0.0/16 . 0.0.0.0/0 . echo-request : accept,
290 10.0.0.0/8 . 10.0.0.0/8 . echo-reply : accept,
291 172.16.0.0/12 . 172.16.0.0/12 . echo-reply : accept,
292 192.168.0.0/16 . 192.168.0.0/16 . echo-reply : accept,
293 10.0.0.0/8 . 10.0.0.0/8 . destination-unreachable : accept,
294 172.16.0.0/12 . 172.16.0.0/12 . destination-unreachable : accept,
295 192.168.0.0/16 . 192.168.0.0/16 . destination-unreachable : accept,
296 0.0.0.0/0 . 0.0.0.0/0 . echo-reply : jump icmp_echo_reply_rate_limit }
297 }
298
299 map icmp_types_forward6 { # handle 56
300 typeof ip6 saddr . ip6 daddr . icmpv6 type : verdict
301 flags interval
302 elements = { fe80::/10 . ff00::/8 . echo-request : accept,
303 fc00::/7 . fc00::/7 . echo-reply : accept,
304 2000::/3 . ::/0 . echo-reply : jump icmp_echo_reply_rate_limit }
305 }
306
307 map tcp_ports_forward4 { # handle 57
308 typeof ip saddr . ip daddr . tcp dport : verdict
309 flags interval
310 elements = { 10.0.0.0/8 . 10.0.0.0/8 . 21 : accept,
311 172.16.0.0/12 . 172.16.0.0/12 . 21 : accept,
312 192.168.0.0/16 . 192.168.0.0/16 . 21 : accept,
313 10.0.0.0/8 . 10.0.0.0/8 . 23 : accept,
314 172.16.0.0/12 . 172.16.0.0/12 . 23 : accept,
315 192.168.0.0/16 . 192.168.0.0/16 . 23 : accept,
316 10.0.0.0/8 . 10.0.0.0/8 . 25 : accept,
317 172.16.0.0/12 . 172.16.0.0/12 . 25 : accept,
318 192.168.0.0/16 . 192.168.0.0/16 . 25 : accept,
319 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept,
320 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept,
321 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept,
322 10.0.0.0/8 . 10.0.0.0/8 . 80 : accept,
323 172.16.0.0/12 . 172.16.0.0/12 . 80 : accept,
324 192.168.0.0/16 . 192.168.0.0/16 . 80 : accept,
325 10.0.0.0/8 . 0.0.0.0/0 . 22 : accept,
326 172.16.0.0/12 . 0.0.0.0/0 . 22 : accept,
327 192.168.0.0/16 . 0.0.0.0/0 . 22 : accept,
328 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept,
329 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept,
330 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept,
331 10.0.0.0/8 . 0.0.0.0/0 . 853 : accept,
332 172.16.0.0/12 . 0.0.0.0/0 . 853 : accept,
333 192.168.0.0/16 . 0.0.0.0/0 . 853 : accept,
334 10.0.0.0/8 . 0.0.0.0/0 . 4460 : accept,
335 172.16.0.0/12 . 0.0.0.0/0 . 4460 : accept,
336 192.168.0.0/16 . 0.0.0.0/0 . 4460 : accept,
337 10.0.0.0/8 . 0.0.0.0/0 . 5349 : accept,
338 172.16.0.0/12 . 0.0.0.0/0 . 5349 : accept,
339 192.168.0.0/16 . 0.0.0.0/0 . 5349 : accept }
340 }
341
342 map tcp_ports_forward6 { # handle 58
343 typeof ip6 saddr . ip6 daddr . tcp dport : verdict
344 flags interval
345 elements = { fc00::/7 . fc00::/7 . 21 : accept,
346 fc00::/7 . fc00::/7 . 23 : accept,
347 fc00::/7 . fc00::/7 . 25 : accept,
348 fc00::/7 . fc00::/7 . 53 : accept,
349 fc00::/7 . fc00::/7 . 80 : accept,
350 fc00::/7 . fc00::/7 . 443 : accept,
351 fc00::/7 . fc00::/7 . 853 : accept,
352 fc00::/7 . fc00::/7 . 4460 : accept,
353 fc00::/7 . fc00::/7 . 5349 : accept,
354 2000::/3 . 2000::/3 . 443 : accept,
355 2000::/3 . 2000::/3 . 853 : accept,
356 2000::/3 . 2000::/3 . 4460 : accept,
357 2000::/3 . 2000::/3 . 5349 : accept }
358 }
359
360 map udp_ports_forward4 { # handle 59
361 typeof ip saddr . ip daddr . udp dport : verdict
362 flags interval
363 elements = { 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept,
364 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept,
365 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept,
366 10.0.0.0/8 . 0.0.0.0/0 . 443 : accept,
367 172.16.0.0/12 . 0.0.0.0/0 . 443 : accept,
368 192.168.0.0/16 . 0.0.0.0/0 . 443 : accept }
369 }
370
371 map udp_ports_forward6 { # handle 60
372 typeof ip6 saddr . ip6 daddr . udp dport : verdict
373 flags interval
374 elements = { 2000::/3 . ::/0 . 443 : accept }
375 }
376
377 map tcp_ports_nat_forward4 { # handle 61
378 type inet_service : ipv4_addr
379 }
380
381 map udp_ports_nat_forward4 { # handle 62
382 type inet_service : ipv4_addr
383 }
384
385 map masquerade_networks4 { # handle 63
386 typeof oif . ip saddr : verdict
387 flags interval
388 }
389
390 chain input { # handle 1
391 type filter hook input priority filter; policy drop;
392 meta iiftype vmap { loopback : accept } # handle 89
393 ip saddr vmap @drop_bogons4 # handle 90
394 ip6 saddr vmap @drop_bogons6 # handle 91
395 meta iiftype vmap { ether : jump ether_in } # handle 93
396 log prefix "input" group 1 # handle 136
397 counter # handle 137
398 }
399
400 chain forward { # handle 2
401 type filter hook forward priority filter; policy drop;
402 ip saddr vmap @drop_bogons4 # handle 106
403 ip6 saddr vmap @drop_bogons6 # handle 107
404 meta oiftype vmap { ether : jump ether_forward } # handle 109
405 log prefix "forward" group 1 # handle 138
406 counter # handle 139
407 }
408
409 chain output { # handle 3
410 type filter hook output priority filter; policy drop;
411 meta oiftype vmap { loopback : accept } # handle 128
412 ip daddr vmap @drop_bogons4 # handle 129
413 ip6 daddr vmap @drop_bogons6 # handle 130
414 meta oiftype vmap { ether : jump ether_out } # handle 132
415 log prefix "output" group 1 # handle 140
416 counter # handle 141
417 }
418
419 chain prerouting { # handle 4
420 type nat hook prerouting priority 100; policy accept;
421 ip protocol tcp dnat ip to tcp dport map @tcp_ports_nat_forward4 # handle 133
422 ip protocol udp dnat ip to udp dport map @udp_ports_nat_forward4 # handle 134
423 }
424
425 chain postrouting { # handle 5
426 type nat hook postrouting priority srcnat; policy accept;
427 oif . ip saddr vmap @masquerade_networks4 # handle 135
428 }
429
430 chain masq { # handle 6
431 ip daddr vmap @drop_bogons4 # handle 124
432 ip daddr @local_networks return # handle 125
433 masquerade # handle 126
434 }
435
436 chain ether_in { # handle 7
437 ip protocol vmap { icmp : jump icmp_in, tcp : jump tcp_in, udp : jump udp_in } # handle 85
438 ip6 nexthdr vmap { tcp : jump tcp_in, udp : jump udp_in, ipv6-icmp : jump icmp_in } # handle 87
439 log prefix "ether_in" group 1 # handle 156
440 counter drop # handle 157
441 }
442
443 chain ether_out { # handle 8
444 ip protocol vmap { icmp : jump icmp_out, tcp : jump tcp_out, udp : jump udp_out } # handle 121
445 ip6 nexthdr vmap { tcp : jump tcp_out, udp : jump udp_out, ipv6-icmp : jump icmp_out } # handle 123
446 log prefix "ether_out" group 1 # handle 174
447 counter drop # handle 175
448 }
449
450 chain ether_forward { # handle 9
451 ip saddr . ip daddr . ct state vmap @default_forward4 # handle 102
452 ip6 saddr . ip6 daddr . ct state vmap @default_forward6 # handle 103
453 ip protocol vmap { icmp : jump icmp_forward, tcp : jump tcp_forward, udp : jump udp_forward } # handle 105
454 log prefix "ether_forward" group 1 # handle 164
455 counter drop # handle 165
456 }
457
458 chain icmp_in { # handle 10
459 ip saddr . ip daddr . icmp type vmap @icmp_types_in4 # handle 76
460 ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_in6 # handle 77
461 log prefix "icmp_in" group 1 # handle 150
462 counter drop # handle 151
463 }
464
465 chain icmp_out { # handle 11
466 ip saddr . ip daddr . icmp type vmap @icmp_types_out4 # handle 112
467 ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_out6 # handle 113
468 log prefix "icmp_out" group 1 # handle 168
469 counter drop # handle 169
470 }
471
472 chain icmp_forward { # handle 12
473 ip saddr . ip daddr . icmp type vmap @icmp_types_forward4 # handle 94
474 ip6 saddr . ip6 daddr . icmpv6 type vmap @icmp_types_forward6 # handle 95
475 log prefix "icmp_forward" group 1 # handle 158
476 counter drop # handle 159
477 }
478
479 chain icmp_echo_reply_rate_limit { # handle 13
480 add @icmp_egress_meter4 { ip saddr timeout 4s limit rate 3/second } accept # handle 110
481 add @icmp_egress_meter6 { ip6 saddr timeout 4s limit rate 3/second } accept # handle 111
482 log prefix "icmp_echo_reply_rate_limit" group 1 # handle 166
483 counter drop # handle 167
484 }
485
486 chain reject_with_icmp_port_unreachable_metered { # handle 14
487 add @icmp_egress_meter4 { ip daddr timeout 4s limit rate 3/second } counter reject # handle 64
488 add @icmp_egress_meter6 { ip6 daddr timeout 4s limit rate 3/second } counter reject # handle 65
489 log prefix "reject_with_icmp_port_unreachable_metered" group 1 # handle 142
490 counter drop # handle 143
491 }
492
493 chain reject_with_icmp_port_unreachable { # handle 15
494 counter reject # handle 66
495 }
496
497 chain reject_with_icmp_host_unreachable_metered { # handle 16
498 add @icmp_egress_meter4 { ip daddr timeout 4s limit rate 3/second } counter reject with icmpx host-unreachable # handle 67
499 add @icmp_egress_meter6 { ip6 daddr timeout 4s limit rate 3/second } counter reject with icmpx host-unreachable # handle 68
500 log prefix "reject_with_icmp_host_unreachable_metered" group 1 # handle 144
501 counter drop # handle 145
502 }
503
504 chain reject_with_icmp_host_unreachable { # handle 17
505 counter reject with icmpx host-unreachable # handle 69
506 }
507
508 chain reject_with_icmp_no_route_metered { # handle 18
509 add @icmp_egress_meter4 { ip daddr timeout 4s limit rate 3/second } counter reject with icmpx no-route # handle 70
510 add @icmp_egress_meter6 { ip6 daddr timeout 4s limit rate 3/second } counter reject with icmpx no-route # handle 71
511 log prefix "reject_with_icmp_no_route_metered" group 1 # handle 146
512 counter drop # handle 147
513 }
514
515 chain reject_with_icmp_no_route { # handle 19
516 counter reject with icmpx no-route # handle 72
517 }
518
519 chain reject_with_icmp_admin_prohibited_metered { # handle 20
520 add @icmp_egress_meter6 { ip6 daddr timeout 4s limit rate 3/second } counter reject with icmpx admin-prohibited # handle 74
521 log prefix "reject_with_icmp_admin_prohibited_metered" group 1 # handle 148
522 counter drop # handle 149
523 }
524
525 chain reject_with_icmp_admin_prohibited { # handle 21
526 add @icmp_egress_meter4 { ip daddr timeout 4s limit rate 3/second } counter reject with icmpx admin-prohibited # handle 73
527 counter reject with icmpx admin-prohibited # handle 75
528 }
529
530 chain tcp_in { # handle 22
531 ct state established accept # handle 78
532 ip saddr . ip daddr . tcp dport vmap @tcp_ports_in4 # handle 79
533 ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_in6 # handle 80
534 log prefix "tcp_in" group 1 # handle 152
535 counter drop # handle 153
536 }
537
538 chain tcp_out { # handle 23
539 ct state established accept # handle 114
540 ip saddr . ip daddr . tcp dport vmap @tcp_ports_out4 # handle 115
541 ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_out6 # handle 116
542 log prefix "tcp_out" group 1 # handle 170
543 counter drop # handle 171
544 }
545
546 chain tcp_forward { # handle 24
547 ct state established accept # handle 96
548 ip saddr . ip daddr . tcp dport vmap @tcp_ports_forward4 # handle 97
549 ip6 saddr . ip6 daddr . tcp dport vmap @tcp_ports_forward6 # handle 98
550 log prefix "tcp_forward" group 1 # handle 160
551 counter drop # handle 161
552 }
553
554 chain udp_in { # handle 25
555 ct state established accept # handle 81
556 ip saddr . ip daddr . udp dport vmap @udp_ports_in4 # handle 82
557 ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_in6 # handle 83
558 log prefix "udp_in" group 1 # handle 154
559 counter drop # handle 155
560 }
561
562 chain udp_out { # handle 26
563 ct state established accept # handle 117
564 ip saddr . ip daddr . udp dport vmap @udp_ports_out4 # handle 118
565 ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_out6 # handle 119
566 log prefix "udp_out" group 1 # handle 172
567 counter drop # handle 173
568 }
569
570 chain udp_forward { # handle 27
571 ct state established accept # handle 99
572 ip saddr . ip daddr . udp dport vmap @udp_ports_forward4 # handle 100
573 ip6 saddr . ip6 daddr . udp dport vmap @udp_ports_forward6 # handle 101
574 log prefix "udp_forward" group 1 # handle 162
575 counter drop # handle 163
576 }
577
578 chain bogon { # handle 28
579 log prefix "bogon" group 1 # handle 29
580 counter drop # handle 30
581 }
582
583 chain wont_forward { # handle 31
584 log prefix "wont_forward" group 1 # handle 32
585 counter drop # handle 33
586 }
587}
Flushing the ruleset¶
Something that helps me is adding flush ruleset
to the beginning of the new /etc/nftables.conf
file so that the existing state is flushed before loading the file.
Hardening¶
1nft delete element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept }'
2nft delete element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept }'
3nft delete element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 192.168.0.0/16 . 137 : accept }'
4nft delete element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 5353 : accept }'
5nft delete element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 5353 : accept }'
6nft delete element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 192.168.0.0/16 . 5353 : accept }'
7nft delete element inet filter udp_ports_in4 '{ 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept }'
8nft delete element inet filter udp_ports_in4 '{ 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
9nft delete element inet filter udp_ports_in4 '{ 192.168.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
10nft delete element inet filter udp_ports_in6 '{ fe80::/10 . ff00::/8 . 5353 : accept }'
11nft delete element inet filter udp_ports_in6 '{ fc00::/7 . ff00::/8 . 5353 : accept }'
12nft delete element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 21 : accept }'
13nft delete element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 21 : accept }'
14nft delete element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 21 : accept }'
15nft delete element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 23 : accept }'
16nft delete element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 23 : accept }'
17nft delete element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 23 : accept }'
18nft delete element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 25 : accept }'
19nft delete element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 25 : accept }'
20nft delete element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 25 : accept }'
21nft delete element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept }'
22nft delete element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept }'
23nft delete element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept }'
24nft delete element inet filter tcp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 80 : accept }'
25nft delete element inet filter tcp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 80 : accept }'
26nft delete element inet filter tcp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 80 : accept }'
27nft delete element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 21 : accept }'
28nft delete element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 23 : accept }'
29nft delete element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 25 : accept }'
30nft delete element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 53 : accept }'
31nft delete element inet filter tcp_ports_forward6 '{ fc00::/7 . fc00::/7 . 80 : accept }'
32nft delete element inet filter udp_ports_forward4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 53 : accept }'
33nft delete element inet filter udp_ports_forward4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 53 : accept }'
34nft delete element inet filter udp_ports_forward4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 53 : accept }'
35nft delete element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 10.0.0.0/8 . 137 : accept }'
36nft delete element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 172.16.0.0/12 . 137 : accept }'
37nft delete element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 192.168.0.0/16 . 137 : accept }'
38nft delete element inet filter udp_ports_out4 '{ 10.0.0.0/8 . 224.0.0.0/4 . 5353 : accept }'
39nft delete element inet filter udp_ports_out4 '{ 172.16.0.0/12 . 224.0.0.0/4 . 5353 : accept }'
40nft delete element inet filter udp_ports_out4 '{ 192.168.0.0/16 . 224.0.0.0/4 . 5353 : accept }'
41nft delete element inet filter udp_ports_out4 '{ 169.254.0.0/16 . 224.0.0.0/4 . 5353 : accept }'
42nft delete element inet filter udp_ports_out6 '{ fc00::/7 . ff00::/8 . 5353 : accept }'
Testing¶
Testing can be performed from another client using scapy:
1from scapy.all import *; from ipaddress import IPv4Network as N4; [send(IP(src=str(x), dst='10.211.55.11')/ICMP(id=1, seq=1), loop=0) for x, y in zip(N4('65.146.55.0/24').hosts(), range(254))]
On the firewall:
1tcpdump -vvv -n -e -ttt -i nflog:1 -XX
2...
3 00:00:00.000036 version 0, resource ID 1, family IPv4 (2), length 84: (tos 0x0, ttl 64, id 41167, offset 0, flags [none], proto ICMP (1), length 28)
4 10.211.55.11 > 65.146.55.254: ICMP echo reply, id 1, seq 1, length 8
5 0x0000: 0200 0001 0800 0100 0800 0300 1f00 0a00 ................
6 0x0010: 6963 6d70 5f65 6368 6f5f 7265 706c 795f icmp_echo_reply_
7 0x0020: 7261 7465 5f6c 696d 6974 0000 0800 0500 rate_limit......
8 0x0030: 0000 0002 2000 0900 4500 001c a0cf 0000 ........E.......
9 0x0040: 4001 1ea4 0ad3 370b 4192 37fe 0000 fffd @.....7.A.7.....
10 0x0050: 0001 0001 ....
Custom Docker support¶
Preparation¶
1apt -y install docker.io
2systemctl stop docker
3rm -rf /var/lib/docker/*
4rm /etc/docker/key.json
5echo DOCKER_OPTS="-H unix:///var/run/docker.sock --iptables=false --ip-masq=false --userns-remap=default --bip=100.64.80.1/20 --default-address-pool='base=100.64.96.0/20,size=28'" > /etc/default/docker
Custom prefix¶
This example will use the 100.64.0.0/17
prefix for docker. Earlier that prefix was marked to be discarded as a bogon, that
can be changed easily:
1nft delete element inet filter drop_bogons4 '{ 100.64.0.0/10 : jump bogon }'
2nft add element inet filter drop_bogons4 '{ 100.64.0.0/17 : continue }'
3nft add element inet filter drop_bogons4 '{ 100.64.128.0/17 : jump bogon }'
4nft add element inet filter drop_bogons4 '{ 100.65.0.0/16 : jump bogon }'
5nft add element inet filter drop_bogons4 '{ 100.66.0.0/15 : jump bogon }'
6nft add element inet filter drop_bogons4 '{ 100.68.0.0/15 : jump bogon }'
7nft add element inet filter drop_bogons4 '{ 100.70.0.0/15 : jump bogon }'
8nft add element inet filter drop_bogons4 '{ 100.72.0.0/15 : jump bogon }'
9nft add element inet filter drop_bogons4 '{ 100.74.0.0/15 : jump bogon }'
10nft add element inet filter drop_bogons4 '{ 100.76.0.0/15 : jump bogon }'
11nft add element inet filter drop_bogons4 '{ 100.78.0.0/15 : jump bogon }'
12nft add element inet filter drop_bogons4 '{ 100.80.0.0/15 : jump bogon }'
13nft add element inet filter drop_bogons4 '{ 100.82.0.0/15 : jump bogon }'
14nft add element inet filter drop_bogons4 '{ 100.84.0.0/15 : jump bogon }'
15nft add element inet filter drop_bogons4 '{ 100.86.0.0/15 : jump bogon }'
16nft add element inet filter drop_bogons4 '{ 100.88.0.0/15 : jump bogon }'
17nft add element inet filter drop_bogons4 '{ 100.90.0.0/15 : jump bogon }'
18nft add element inet filter drop_bogons4 '{ 100.92.0.0/15 : jump bogon }'
19nft add element inet filter drop_bogons4 '{ 100.94.0.0/15 : jump bogon }'
20nft add element inet filter drop_bogons4 '{ 100.96.0.0/11 : jump bogon }'
21nft add element inet filter local_networks '{ 100.64.0.0/17 }'
Verify this with the nft list map inet filter drop_bogons4
command:
1table inet filter {
2 map drop_bogons4 {
3 type ipv4_addr : verdict
4 flags interval
5 elements = { 0.0.0.0/8 : jump bogon, 10.0.0.0/8 : continue,
6 100.64.0.0/17 : continue, 100.64.128.0/17 : jump bogon,
7 100.65.0.0/16 : jump bogon, 100.66.0.0/15 : jump bogon,
8 100.68.0.0/15 : jump bogon, 100.70.0.0/15 : jump bogon,
9 100.72.0.0/15 : jump bogon, 100.74.0.0/15 : jump bogon,
10 100.76.0.0/15 : jump bogon, 100.78.0.0/15 : jump bogon,
11 100.80.0.0/15 : jump bogon, 100.82.0.0/15 : jump bogon,
12 100.84.0.0/15 : jump bogon, 100.86.0.0/15 : jump bogon,
13 100.88.0.0/15 : jump bogon, 100.90.0.0/15 : jump bogon,
14 100.92.0.0/15 : jump bogon, 100.94.0.0/15 : jump bogon,
15 100.96.0.0/11 : jump bogon, 127.0.0.0/8 : jump bogon,
16 169.254.0.0/16 : continue, 172.16.0.0/12 : continue,
17 192.0.0.0/24 : jump bogon, 192.0.2.0/24 : jump bogon,
18 192.168.0.0/16 : continue, 198.18.0.0/15 : jump bogon,
19 198.51.100.0/24 : jump bogon, 203.0.113.0/24 : jump bogon,
20 224.0.0.0/4 : continue, 240.0.0.0/4 : jump bogon }
21 }
22}
Forward verdict map¶
1nft add element inet filter default_forward4 '{ 100.64.0.0/20 . 0.0.0.0/0 . new : jump reject_with_icmp_no_route }'
2nft add element inet filter default_forward4 '{ 100.64.16.0/20 . 100.64.32.0/20 . new : continue }'
3nft add element inet filter default_forward4 '{ 100.64.32.0/20 . 100.64.16.0/20 . established : accept }'
4nft add element inet filter default_forward4 '{ 100.64.48.0/20 . 100.64.0.0/17 . new : continue }'
5nft add element inet filter default_forward4 '{ 100.64.80.0/20 . 100.64.0.0/17 . new : continue }'
6nft add element inet filter default_forward4 '{ 100.64.48.0/20 . 0.0.0.0/0 . new : continue }'
7nft add element inet filter default_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . new : continue }'
8nft add element inet filter default_forward4 '{ 100.64.48.0/20 . 0.0.0.0/0 . established : accept }'
9nft add element inet filter default_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . established : accept }'
10nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 100.64.48.0/20 . established : accept }'
11nft add element inet filter default_forward4 '{ 0.0.0.0/0 . 100.64.80.0/20 . established : accept }'
12nft add element inet filter default_forward4 '{ 100.64.64.0/20 . 100.64.64.0/20 . new : continue }'
13nft add element inet filter default_forward4 '{ 100.64.96.0/20 . 100.64.96.0/20 . new : continue }'
14nft add element inet filter default_forward4 '{ 100.64.64.0/20 . 100.64.64.0/20 . established : accept }'
15nft add element inet filter default_forward4 '{ 100.64.96.0/20 . 100.64.96.0/20 . established : accept }'
NAT¶
1nft add element inet filter masquerade_networks4 '{ enp0s5 . 100.64.80.0/20 : jump masq }'
2nft add element inet filter masquerade_networks4 '{ enp0s5 . 100.64.48.0/20 : jump masq }'
Allow ICMP out to containers¶
1nft add element inet filter icmp_types_out4 '{ 100.64.0.0/17 . 100.64.0.0/17 . destination-unreachable : accept }'
Allow forwarded ICMP by src/dst/type¶
1nft add element inet filter icmp_types_forward4 '{ 100.64.80.0/20 . 100.64.0.0/17 . echo-request : jump reject_with_icmp_admin_prohibited }'
2nft add element inet filter icmp_types_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . echo-request : accept }'
3nft add element inet filter icmp_types_forward4 '{ 100.64.48.0/20 . 100.64.0.0/17 . echo-request : jump reject_with_icmp_admin_prohibited }'
4nft add element inet filter icmp_types_forward4 '{ 100.64.48.0/20 . 0.0.0.0/0 . echo-request : accept }'
Allow forwarded TCP by src/dst/dport¶
1nft add element inet filter tcp_ports_forward4 '{ 100.64.80.0/20 . 100.64.0.0/17 . 80 : jump reject_with_icmp_admin_prohibited }'
2nft add element inet filter tcp_ports_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . 80 : accept }'
3nft add element inet filter tcp_ports_forward4 '{ 100.64.80.0/20 . 100.64.0.0/17 . 443 : jump reject_with_icmp_admin_prohibited }'
4nft add element inet filter tcp_ports_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . 443 : accept }'
5nft add element inet filter tcp_ports_forward4 '{ 100.64.48.0/20 . 100.64.0.0/17 . 443 : jump reject_with_icmp_admin_prohibited }'
6nft add element inet filter tcp_ports_forward4 '{ 100.64.48.0/20 . 0.0.0.0/0 . 443 : accept }'
Allow forwarded UDP by src/dst/dport¶
1nft add element inet filter udp_ports_forward4 '{ 100.64.80.0/20 . 100.64.0.0/17 . 53 : jump reject_with_icmp_admin_prohibited }'
2nft add element inet filter udp_ports_forward4 '{ 100.64.80.0/20 . 0.0.0.0/0 . 53 : accept }'
TODO¶
This networking scheme is nice for Docker, but it sucks having to specify every address in docker-compose
. I have an IPAM driver for Docker that will allow tags to specified for networks as options to the IPAM driver in compose, but it is a work in progress.
IPAM Driver¶
Network Driver¶
- EVPN/VXLAN transports
- NFTables Flowtables; interface names must be known to the firewall state for offloading