#!/bin/bash # # iptables ruleset for an End Node acting as a workstation in a LAN. # # Copyright (C) 2018 Antonio Ospite # SPDX-License-Identifier: MIT # # Based on updateipt.sh by Phil Sutter: # https://developers.redhat.com/blog/2017/01/10/migrating-my-iptables-setup-to-nftables/ set -e [ $UID -eq 0 ] || { echo "This script must be run as root" 1>&2; exit 1; } . lib/utils.sh COMMON_OPEN_PORTS=( # XMPP 5222 5269 # Link-local XMPP, for backward compatibility, XEP-0174 5298 ) TCP_OPEN_PORTS=( "${COMMON_OPEN_PORTS[@]}" ) UDP_OPEN_PORTS=( "${COMMON_OPEN_PORTS[@]}" ) flush_ruleset ### Define a custom chain for packets in NEW state. ip46t -N in-new # Accept DHCPv4 Offer ipt -A in-new -p udp -m udp --sport bootps --dport bootpc -j ACCEPT # Silently drop DHCPv4 Discover and Request packets from other clients. ipt -A in-new -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --sport bootpc --dport bootps -j DROP # Silently drop DHCPv6 from other clients. ip6t -A in-new -s fe80::/64 -d fe80::/64 -p udp -m udp --sport dhcpv6-client --dport dhcpv6-server -j DROP # mDNS (ZeroConf/Bonjour) ipt -A in-new -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT ip6t -A in-new -d ff02::fb -p udp -m udp --dport 5353 -j ACCEPT # SSDP: https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol ipt -A in-new -d 239.255.255.250 -p udp -m udp --dport 1900 -j ACCEPT ip6t -A in-new -d ff02::c -p udp -m udp --dport 1900 -j ACCEPT ip6t -A in-new -d ff05::c -p udp -m udp --dport 1900 -j ACCEPT ip6t -A in-new -d ff08::c -p udp -m udp --dport 1900 -j ACCEPT ip6t -A in-new -d ff0e::c -p udp -m udp --dport 1900 -j ACCEPT ip46t -A in-new -p udp -m udp --sport 1900 -j ACCEPT for port in "${TCP_OPEN_PORTS[@]}"; do ip46t -A in-new -p tcp -m tcp --dport "$port" --syn -j ACCEPT done for port in "${UDP_OPEN_PORTS[@]}"; do ip46t -A in-new -p udp -m udp --dport "$port" -j ACCEPT done ### INPUT chain ip46t -P INPUT DROP # Allow all loopback traffic. ip46t -A INPUT -i lo -j ACCEPT # Allow ICMP traffic. ipt -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT ipt -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT # Allow ICMPv6 traffic ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-request -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT # Allow IPv6 Neighbor Discovery (RFC4861). ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT # Allow multicast listener discovery on link-local addresses. # RFC2710 specifies that a Hop-by-Hop Options header is used. ip6t -A INPUT -p ipv6-icmp --icmpv6-type 130 -s fe80::/10 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type 131 -s fe80::/10 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type 132 -s fe80::/10 -j ACCEPT # Allow multicast router discovery messages on link-local addresses (hop limit 1). ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT # Allow IGMPv3 queries. ipt -A INPUT -d 224.0.0.1 -p igmp -j DROP # Stateful filtering for anything else. ip46t -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ip46t -A INPUT -m state --state INVALID -j DROP ip46t -A INPUT -m state --state NEW -j in-new # Silently drop other incoming broadcast and multicast traffic. ip46t -A INPUT -m pkttype --pkt-type broadcast -j DROP ip46t -A INPUT -m pkttype --pkt-type multicast -j DROP ip46t -A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT]: " ip46t -A INPUT -j REJECT ### OUTPUT chain ip46t -P OUTPUT DROP ip46t -A OUTPUT -j ACCEPT ### FORWARD chain ip46t -P FORWARD DROP ip46t -A FORWARD -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[FORWARD]: " ip46t -A FORWARD -j REJECT