312ecdb0c75e10ce793857cd92c41484615f1264
[firewall-squeep] / common.sh
1 #!/bin/sh
2
3 set -e
4
5 IPTABLES=$(which iptables)
6 IP6TABLES=$(which ip6tables)
7 IPSET=$(which ipset)
8 TC=$(which tc)
9
10 err(){
11 echo "$@" 1>&2
12 }
13
14 die(){
15 local status=$1
16 shift
17 err "$@"
18 exit ${status}
19 }
20
21 function decommentcat(){
22 sed 's/\s*#.*$//;/^\s*$/d' "$@"
23 }
24
25 function create_set(){
26 local set_name="$1"
27 shift
28 if ! $IPSET list "${set_name}" >/dev/null 2>&1
29 then
30 echo "creating set '${set_name}'"
31 $IPSET create "${set_name}" "$@"
32 fi
33 }
34
35 function create_drop_chain(){
36 local chain="$1"
37
38 if ! $IPTABLES -L "${chain}" >/dev/null 2>&1
39 then
40 echo "initializing chain '${chain}'"
41 $IPTABLES -N "${chain}" || $IPTABLES -F "${chain}"
42 $IPTABLES -A "${chain}" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
43 $IPTABLES -A "${chain}" -j REJECT --reject-with icmp-port-unreachable
44 $IPTABLES -v -L "${chain}"
45 fi
46
47 if ! $IP6TABLES -L "${chain}" >/dev/null 2>&1
48 then
49 echo "initializing chain '${chain}' ipv6"
50 $IP6TABLES -N "${chain}" || $IP6TABLES -F "${chain}"
51 $IP6TABLES -A "${chain}" -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
52 $IP6TABLES -A "${chain}" -j REJECT --reject-with icmp6-port-unreachable
53 $IP6TABLES -v -L "${chain}"
54 fi
55 }
56
57 function insert_setmatch_rules(){
58 local single=0
59 if [ "x$1" = "x-single-set" ]
60 then
61 single=1
62 shift
63 fi
64 local ipt set_name="$1"
65 shift
66 for v in '' '6'
67 do
68 eval ipt="\$IP${v}TABLES"
69 if [ $single -eq 1 ]
70 then
71 v=''
72 fi
73 if ! $ipt -C INPUT -m set --match-set "${set_name}${v}" src "$@" >/dev/null 2>&1
74 then
75 echo "initializing rule '${set_name}${v}'"
76 $ipt -I INPUT -m set --match-set "${set_name}${v}" src "$@"
77 fi
78 done
79 }
80
81 function reload_cidr_sets(){
82 local set_name="$1"
83 shift
84
85 # init new temporary sets
86 echo "updating set '${set_name}'"
87
88 create_set "${set_name}-tmp" hash:net "$@"
89 create_set "${set_name}6-tmp" hash:net "$@" family inet6
90
91 # populate them
92 for sfx in '' .$(hostname -s)
93 do
94 cidrfile="${set_name}.cidr${sfx}"
95 if [ -e "${cidrfile}" ]
96 then
97 for s in $(decommentcat "${cidrfile}")
98 do
99 case "${s}" in
100 *.*) table="${set_name}-tmp" ;;
101 *:*) table="${set_name}6-tmp" ;;
102 *)
103 echo "unknown entry '${s}' in '${cidrfile}'" 1>&2
104 continue
105 ;;
106 esac
107 $IPSET add "${table}" "${s}"
108 done
109 fi
110 done
111
112 # take new sets live
113 for v in '' 6
114 do
115 n="${set_name}${v}"
116 $IPSET swap "${n}-tmp" "${n}"
117 $IPSET destroy "${n}-tmp"
118 $IPSET list -t "${n}"
119 done
120 }
121
122 function add_service_entry(){
123 local port proto
124 port=$(echo "$1" | cut -d/ -f1)
125 proto=$(echo "$1" | cut -d/ -f2)
126 $IPSET -exist add allowed_${proto} ${port}
127 }
128
129 function allow_services(){
130 local s
131 for s in "$@"
132 do
133 case "${s}" in
134 */*) add_service_entry "${s}"
135 ;;
136 *) for svc in $(getent services "${s}" | awk '{print $2}')
137 do
138 add_service_entry "${svc}"
139 done
140 ;;
141 esac
142 done
143 }
144