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