a00aa51f3f1cb55683cd185676e940f24b915d55
[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 # Silently drop DHCPv4 Discover and Request packets from other clients.
41 ipt -A in-new -s 0.0.0.0 -d 255.255.255.255 -p udp -m udp --sport bootpc --dport bootps -j DROP
42
43 # Silently drop DHCPv6 from other clients.
44 ip6t -A in-new -s fe80::/64 -d fe80::/64 -p udp -m udp --sport dhcpv6-client --dport dhcpv6-server -j DROP
45
46 # mDNS (ZeroConf/Bonjour)
47 ipt  -A in-new -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
48 ip6t -A in-new -d ff02::fb    -p udp -m udp --dport 5353 -j ACCEPT
49
50 # SSDP: https://en.wikipedia.org/wiki/Simple_Service_Discovery_Protocol
51 ipt  -A in-new -d 239.255.255.250 -p udp -m udp --dport 1900 -j ACCEPT
52 ip6t -A in-new -d ff02::c         -p udp -m udp --dport 1900 -j ACCEPT
53 ip6t -A in-new -d ff05::c         -p udp -m udp --dport 1900 -j ACCEPT
54 ip6t -A in-new -d ff08::c         -p udp -m udp --dport 1900 -j ACCEPT
55 ip6t -A in-new -d ff0e::c         -p udp -m udp --dport 1900 -j ACCEPT
56
57
58 for port in "${TCP_OPEN_PORTS[@]}";
59 do
60   ip46t -A in-new -p tcp -m tcp --dport "$port" --syn -j ACCEPT
61 done
62
63 for port in "${UDP_OPEN_PORTS[@]}";
64 do
65   ip46t -A in-new -p udp -m udp --dport "$port" -j ACCEPT
66 done
67
68
69 ### INPUT chain
70 ip46t -P INPUT DROP
71
72 # Allow all loopback traffic.
73 ip46t -A INPUT -i lo -j ACCEPT
74
75 # Allow ICMP traffic.
76 ipt -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
77 ipt -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
78 ipt -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
79 ipt -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT
80 ipt -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
81
82 # Allow ICMPv6 traffic
83 ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT
84 ip6t -A INPUT -p ipv6-icmp --icmpv6-type echo-request -j ACCEPT
85 ip6t -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT
86 ip6t -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT
87 ip6t -A INPUT -p ipv6-icmp --icmpv6-type destination-unreachable -j ACCEPT
88 ip6t -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT
89
90 # Allow IPv6 Neighbor Discovery (RFC4861).
91 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -m hl --hl-eq 255 -j ACCEPT
92 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
93 ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
94 ip6t -A INPUT -p ipv6-icmp --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
95
96 # Allow multicast listener discovery on link-local addresses.
97 # RFC2710 specifies that a Hop-by-Hop Options header is used.
98 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 130 -s fe80::/10 -j ACCEPT
99 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 131 -s fe80::/10 -j ACCEPT
100 ip6t -A INPUT -p ipv6-icmp --icmpv6-type 132 -s fe80::/10 -j ACCEPT
101
102 # Allow multicast router discovery messages on link-local addresses (hop limit 1).
103 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
104 ip6t -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -s fe80::/10 -m hl --hl-eq 1 -j ACCEPT
105
106 # Allow IGMPv3 queries.
107 ipt -A INPUT -d 224.0.0.1 -p igmp -j DROP
108
109
110 # Stateful filtering for anything else.
111 ip46t -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
112 ip46t -A INPUT -m state --state INVALID -j DROP
113 ip46t -A INPUT -m state --state NEW -j in-new
114
115 # Silently drop other incoming broadcast and multicast traffic.
116 ip46t -A INPUT -m pkttype --pkt-type broadcast -j DROP
117 ip46t -A INPUT -m pkttype --pkt-type multicast -j DROP
118
119 ip46t -A INPUT -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[INPUT]: "
120 ip46t -A INPUT -j REJECT
121
122
123 ### OUTPUT chain
124 ip46t -P OUTPUT DROP
125
126 ip46t -A OUTPUT -j ACCEPT
127
128
129 ### FORWARD chain
130 ip46t -P FORWARD DROP
131
132 ip46t -A FORWARD -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[FORWARD]: "
133 ip46t -A FORWARD -j REJECT