uniq cidrs
[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 cat "$@" | 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 # try to recreate sets faster than one-at-a-time by generating restore rules
82 function ipset_restore_from_cidr(){
83 local vmatch
84 local set_name="$1"
85
86 for v in '' '6'
87 do
88 case "$v" in
89 6) vmatch=':';;
90 *) vmatch='\.';;
91 esac
92 # extract existing set configuration to create temporary set
93 (set -o pipefail; $IPSET save "${set_name}${v}" 2>/dev/null | grep -m 1 '^create ' | sed "s/\(create ${set_name}${v}\)/\1-tmp/") || continue
94 # populate with new data
95 decommentcat "${set_name}.cidr" "${set_name}.cidr.$(hostname -s)" 2>/dev/null | sed -n 's/\(.*'"${vmatch}"'.*\)/add '"${set_name}${v}-tmp"' \1/p' | sort -n | uniq
96 done
97 }
98
99 function reload_cidr_sets(){
100 local v n
101 local set_name="$1"
102
103 ipset_restore_from_cidr "${set_name}" | ipset restore
104 for v in '' 6
105 do
106 n="${set_name}${v}"
107 $IPSET swap "${n}-tmp" "${n}"
108 $IPSET destroy "${n}-tmp"
109 $IPSET list -t "${n}"
110 done
111 }
112
113 function _old_reload_cidr_sets(){
114 local sfx n s v
115 local set_name="$1"
116 shift
117
118 # init new temporary sets
119 echo "updating set '${set_name}'"
120
121 create_set "${set_name}-tmp" hash:net "$@"
122 create_set "${set_name}6-tmp" hash:net "$@" family inet6
123
124 # populate them
125 for sfx in '' .$(hostname -s)
126 do
127 cidrfile="${set_name}.cidr${sfx}"
128 if [ -e "${cidrfile}" ]
129 then
130 for s in $(decommentcat "${cidrfile}")
131 do
132 case "${s}" in
133 *.*) table="${set_name}-tmp" ;;
134 *:*) table="${set_name}6-tmp" ;;
135 *)
136 echo "unknown entry '${s}' in '${cidrfile}'" 1>&2
137 continue
138 ;;
139 esac
140 $IPSET add "${table}" "${s}"
141 done
142 fi
143 done
144
145 # take new sets live
146 for v in '' 6
147 do
148 n="${set_name}${v}"
149 $IPSET swap "${n}-tmp" "${n}"
150 $IPSET destroy "${n}-tmp"
151 $IPSET list -t "${n}"
152 done
153 }
154
155 function add_service_entry(){
156 local port proto
157 port=$(echo "$1" | cut -d/ -f1)
158 proto=$(echo "$1" | cut -d/ -f2)
159 $IPSET -exist add allowed_${proto} ${port}
160 }
161
162 function allow_services(){
163 local s
164 for s in "$@"
165 do
166 case "${s}" in
167 */*) add_service_entry "${s}"
168 ;;
169 *) for svc in $(egrep "^${s}\s+" /etc/services | decommentcat | awk '{print $2}')
170 do
171 add_service_entry "${svc}"
172 done
173 ;;
174 esac
175 done
176 }
177