#!/usr/sbin/nft -f # # nftables ruleset for an End Node acting as a workstation in a LAN. # # Copyright (C) 2018 Antonio Ospite # SPDX-License-Identifier: MIT # # Based on: # https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Simple_IP.2FIPv6_Firewall # https://wiki.archlinux.org/index.php/Nftables#Workstation # https://stosb.com/blog/explaining-my-configs-nftables/ flush ruleset table inet filter { define common_open_ports = { xmpp-client, xmpp-server, 5298, # Link-local XMPP, for backward compatibility, XEP-0174 } set tcp_open_ports { type inet_service flags interval elements = { $common_open_ports, } } set udp_open_ports { type inet_service flags interval elements = { $common_open_ports, } } chain input { type filter hook input priority 0 policy drop iif lo accept ip protocol icmp icmp type { echo-reply, echo-request, time-exceeded, parameter-problem, destination-unreachable } accept # ICMPv6 configuration based on: # https://github.com/intel/intel-iot-refkit/blob/master/meta-refkit-core/recipes-security/nftables-settings-default/files/firewall.template ip6 nexthdr ipv6-icmp icmpv6 type { echo-reply, echo-request, time-exceeded, parameter-problem, destination-unreachable, packet-too-big } accept # Allow IPv6 Neighbor Discovery (RFC4861). ip6 nexthdr ipv6-icmp icmpv6 type { nd-router-advert, nd-router-solicit, nd-neighbor-advert, nd-neighbor-solicit } ip6 hoplimit 255 accept # Allow multicast listener discovery on link-local addresses. # RFC2710 specifies that a Hop-by-Hop Options header is used. hbh nexthdr ipv6-icmp icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-reduction } ip6 saddr fe80::/10 accept # Allow multicast router discovery messages on link-local addresses (hop limit 1). ip6 nexthdr ipv6-icmp icmpv6 type { nd-router-advert, nd-router-solicit } ip6 hoplimit 1 ip6 saddr fe80::/10 accept # Allow IGMPv3 queries. ip protocol igmp ip daddr 224.0.0.1 accept # Stateful filtering for anything else. ct state established,related accept ct state invalid drop ct state new jump in-new # Silently drop other incoming broadcast and multicast traffic. meta pkttype {broadcast, multicast} drop limit rate 3/minute burst 10 packets log prefix "[INPUT]: " counter reject } chain in-new { # Silently drop DHCPv4 Discover and Request packets from other clients. ip saddr 0.0.0.0 ip daddr 255.255.255.255 udp sport bootpc udp dport bootps drop # Silently drop DHCPv6 from other clients. ip6 saddr fe80::/64 ip6 daddr fe80::/64 udp sport dhcpv6-client udp dport dhcpv6-server drop # mDNS (ZeroConf/Bonjour) ip daddr 224.0.0.251 udp dport mdns accept ip6 daddr ff02::fb udp dport mdns accept # SSDP: https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol ip daddr 239.255.255.250 udp dport 1900 accept ip6 daddr { ff02::c, ff05::c, ff08::c, ff0e::c } udp dport 1900 accept tcp dport @tcp_open_ports tcp flags & (fin | syn | rst | ack) == syn accept udp dport @udp_open_ports accept } chain forward { type filter hook forward priority 0 policy drop limit rate 3/minute burst 10 packets log prefix "[FORWARD]: " counter reject } chain output { type filter hook output priority 0 policy drop counter accept } }