iptables-workstation.sh: enable DHCPv4 offers and more SSDP communication
[config/iptables.git] / iptables-workstation.sh
1 #!/bin/bash
2 #
3 # iptables 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 updateipt.sh by Phil Sutter:
9 # https://developers.redhat.com/blog/2017/01/10/migrating-my-iptables-setup-to-nftables/
10
11 set -e
12
13 [ $UID -eq 0 ] || { echo "This script must be run as root" 1>&2; exit 1; }
14
15 . lib/utils.sh
16
17 COMMON_OPEN_PORTS=(
18 # XMPP
19 5222
20 5269
21 # Link-local XMPP, for backward compatibility, XEP-0174
22 5298
23 )
24
25 TCP_OPEN_PORTS=(
26 "${COMMON_OPEN_PORTS[@]}"
27 )
28
29 UDP_OPEN_PORTS=(
30 "${COMMON_OPEN_PORTS[@]}"
31 )
32
33 flush_ruleset
34
35
36 ### Define a custom chain for packets in NEW state.
37
38 ip46t -N in-new
39
40 # Accept DHCPv4 Offer
41 ipt -A in-new -p udp -m udp --sport bootps --dport bootpc -j ACCEPT
42
43 # Silently drop DHCPv4 Discover and Request packets from other clients.
44 ipt -A in-new -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --sport bootpc --dport bootps -j DROP
45
46 # Silently drop DHCPv6 from other clients.
47 ip6t -A in-new -s fe80::/64 -d fe80::/64 -p udp -m udp --sport dhcpv6-client --dport dhcpv6-server -j DROP
48
49 # mDNS (ZeroConf/Bonjour)
50 ipt  -A in-new -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
51 ip6t -A in-new -d ff02::fb    -p udp -m udp --dport 5353 -j ACCEPT
52
53 # SSDP: https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol
54 ipt   -A in-new -d 239.255.255.250 -p udp -m udp --dport 1900 -j ACCEPT
55 ip6t  -A in-new -d ff02::c         -p udp -m udp --dport 1900 -j ACCEPT
56 ip6t  -A in-new -d ff05::c         -p udp -m udp --dport 1900 -j ACCEPT
57 ip6t  -A in-new -d ff08::c         -p udp -m udp --dport 1900 -j ACCEPT
58 ip6t  -A in-new -d ff0e::c         -p udp -m udp --dport 1900 -j ACCEPT
59 ip46t -A in-new                    -p udp -m udp --sport 1900 -j ACCEPT
60
61
62 for port in "${TCP_OPEN_PORTS[@]}";
63 do
64   ip46t -A in-new -p tcp -m tcp --dport "$port" --syn -j ACCEPT
65 done
66
67 for port in "${UDP_OPEN_PORTS[@]}";
68 do
69   ip46t -A in-new -p udp -m udp --dport "$port" -j ACCEPT
70 done
71
72
73 ### INPUT chain
74 ip46t -P INPUT DROP
75
76 # Allow all loopback traffic.
77 ip46t -A INPUT -i lo -j ACCEPT
78
79 # Allow ICMP traffic.
80 ipt -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
81 ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
82 ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
83 ipt -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
84 ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
85
86 # Allow ICMPv6 traffic
87 ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT
88 ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-request -j ACCEPT
89 ip6t -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT
90 ip6t -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT
91 ip6t -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT
92 ip6t -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
93
94 # Allow IPv6 Neighbor Discovery (RFC4861).
95 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT
96 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
97 ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
98 ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
99
100 # Allow multicast listener discovery on link-local addresses.
101 # RFC2710 specifies that a Hop-by-Hop Options header is used.
102 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 130 -s fe80::/10 -j ACCEPT
103 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 131 -s fe80::/10 -j ACCEPT
104 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 132 -s fe80::/10 -j ACCEPT
105
106 # Allow multicast router discovery messages on link-local addresses (hop limit 1).
107 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
108 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
109
110 # Allow IGMPv3 queries.
111 ipt -A INPUT -d 224.0.0.1 -p igmp -j DROP
112
113
114 # Stateful filtering for anything else.
115 ip46t -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
116 ip46t -A INPUT -m state --state INVALID -j DROP
117 ip46t -A INPUT -m state --state NEW -j in-new
118
119 # Silently drop other incoming broadcast and multicast traffic.
120 ip46t -A INPUT -m pkttype --pkt-type broadcast -j DROP
121 ip46t -A INPUT -m pkttype --pkt-type multicast -j DROP
122
123 ip46t -A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT]: "
124 ip46t -A INPUT -j REJECT
125
126
127 ### OUTPUT chain
128 ip46t -P OUTPUT DROP
129
130 ip46t -A OUTPUT -j ACCEPT
131
132
133 ### FORWARD chain
134 ip46t -P FORWARD DROP
135
136 ip46t -A FORWARD -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[FORWARD]: "
137 ip46t -A FORWARD -j REJECT